diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index fcc8b3a..42d3f57 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -26,7 +26,7 @@ add_example(kde_ex OFF) add_example(meshio_ex OFF) add_example(autodiff_ex OFF) add_example(multinary_ex OFF) -add_example(text_io_ex ON) +add_example(text_io_ex OFF) add_example(getoption_ex OFF) add_example(process_ex OFF) add_example(array_ex OFF) diff --git a/example/meshio_ex.cpp b/example/meshio_ex.cpp index b8c739c..c34fc7c 100644 --- a/example/meshio_ex.cpp +++ b/example/meshio_ex.cpp @@ -34,6 +34,22 @@ int main(int argc, char const *argv[]) try { mesh_io mshio; + mshio.read_gmsh_v2_ascii("tmp/example2"); + mshio.info(); +/* + array nodes; + array tris; + //array orinode_ptrs; + //array oriele_ptrs; + + mshio.select_elements("Survey"); + mshio.export_to(tris, nodes); + + gmshio tmp_out; + tmp_out.init_file("tmp", Output); + tmp_out.set_packed(NotPacked, Output); + tmp_out.save_mesh(tris, nodes); +*/ /* mshio.read_tetgen_ascii("tmp/ex1.1"); mshio.edit_group(Disable, GeometryTag, 5); @@ -47,7 +63,7 @@ int main(int argc, char const *argv[]) try mshio.edit_group(GeometryTag, 4, "Body3"); mshio.save_gmsh_v2_ascii("tmp/ex1.1"); */ - +/* mshio.read_gmsh_v2_ascii("tmp/ex1.1"); mshio.convert_tags_to_data(GeometryTag); @@ -70,6 +86,7 @@ int main(int argc, char const *argv[]) try gio.init_file("tmp.msh", Output); gio.set_packed(NotPacked, Output); gio.save_mesh(body2_tets, nodes); +*/ /* mshio.read_gmsh_v2_ascii("tmp/wjb.1"); mshio.edit_group(Disable); diff --git a/lib/io/gmsh_io.h b/lib/io/gmsh_io.h index 6d1e40b..7827e6b 100644 --- a/lib/io/gmsh_io.h +++ b/lib/io/gmsh_io.h @@ -46,7 +46,7 @@ namespace gctl }; /** - * @brief Gmsh文件的IO类,主要为调用下面定义的全局函数 + * @brief Gmsh文件的IO类,主要为调用下面定义的全局函数 (此结构已被废弃,不再更新。可能在未来移除,建议使用mesh_io类型替代) */ class gmshio { diff --git a/lib/io/mesh_io.cpp b/lib/io/mesh_io.cpp index 74fbd35..4ba8336 100644 --- a/lib/io/mesh_io.cpp +++ b/lib/io/mesh_io.cpp @@ -254,6 +254,9 @@ gctl::mesh_io::~mesh_io() void gctl::mesh_io::reset() { + if (!selected_nodes_.empty()) selected_nodes_.clear(); + if (!selected_elems_.empty()) selected_elems_.clear(); + if (!selected_groups_.empty()) selected_groups_.clear(); if (!nodes_.empty()) nodes_.clear(); if (!elems_.empty()) elems_.clear(); if (!nodes_tag_.empty()) nodes_tag_.clear(); @@ -346,33 +349,6 @@ void gctl::mesh_io::info(std::ostream &ss) return; } -void gctl::mesh_io::edit_data(switch_type_e swt, std::string dataname) -{ - if (dataname == "null" && swt == Enable) - { - for (size_t i = 0; i < datas_.size(); i++) - { - datas_[i].enabled = true; - } - } - else if (dataname == "null" && swt == Disable) - { - for (size_t i = 0; i < datas_.size(); i++) - { - datas_[i].enabled = false; - } - } - else - { - for (size_t i = 0; i < datas_.size(); i++) - { - if (datas_[i].str_tag.front() == dataname && swt == Enable) datas_[i].enabled = true; - if (datas_[i].str_tag.front() == dataname && swt == Disable) datas_[i].enabled = false; - } - } - return; -} - void gctl::mesh_io::edit_group(switch_type_e swt, element_type_enum e_type) { for (size_t g = 0; g < groups_.size(); g++) @@ -474,48 +450,65 @@ void gctl::mesh_io::edit_group(element_tag_enum anchor_type, int anchor_group, e return; } -const gctl::array &gctl::mesh_io::get_node_tag() -{ - return nodes_tag_; -} - -int gctl::mesh_io::get_tag(element_tag_enum anchor_type, std::string anchor_name) +int gctl::mesh_io::group_tag(element_tag_enum tag_type, std::string group_name) { for (size_t i = 0; i < groups_.size(); i++) { - if (anchor_type == PhysicalTag && groups_[i].name == anchor_name) return groups_[i].phys_group; - if (anchor_type == GeometryTag && groups_[i].name == anchor_name) return groups_[i].geom_group; - if (anchor_type == PartitionTag && groups_[i].name == anchor_name) return groups_[i].part_group; + if (tag_type == PhysicalTag && groups_[i].name == group_name) return groups_[i].phys_group; + if (tag_type == GeometryTag && groups_[i].name == group_name) return groups_[i].geom_group; + if (tag_type == PartitionTag && groups_[i].name == group_name) return groups_[i].part_group; } return DEFAULT_INVALID_TAG; } -const gctl::array &gctl::mesh_io::get_nodes() +const gctl::array &gctl::mesh_io::get_all_nodes() { return nodes_; } -const gctl::array &gctl::mesh_io::get_elems() +const gctl::array &gctl::mesh_io::get_all_elems() { return elems_; } -size_t gctl::mesh_io::element_size(element_type_enum e_type) +void gctl::mesh_io::select_elements(element_type_enum e_type) { - size_t s = 0; + if (!selected_nodes_.empty()) selected_nodes_.clear(); + if (!selected_elems_.empty()) selected_elems_.clear(); + if (!selected_groups_.empty()) selected_groups_.clear(); + + int vnum; for (size_t i = 0; i < groups_.size(); i++) { if ((e_type == NotSet || groups_[i].type == e_type) && groups_[i].enabled) { - s += groups_[i].elem_ptrs.size(); + selected_groups_.push_back(&groups_[i]); + vnum = elem_size(groups_[i].type); + for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) + { + selected_elems_.push_back(groups_[i].elem_ptrs[e]); + for (size_t v = 0; v < vnum; v++) + { + selected_nodes_.push_back(groups_[i].elem_ptrs[e]->vert_ptrs[v]); + } + } } } - return s; + + std::vector::iterator pos; + std::sort(selected_nodes_.begin(), selected_nodes_.end()); //排序 + pos = std::unique(selected_nodes_.begin(), selected_nodes_.end()); //获取重复序列开始的位置 + selected_nodes_.erase(pos, selected_nodes_.end()); //删除重复点 + return; } -size_t gctl::mesh_io::element_size(element_tag_enum tag_type, int tag) +void gctl::mesh_io::select_elements(element_tag_enum tag_type, int tag) { - size_t s = 0; + if (!selected_nodes_.empty()) selected_nodes_.clear(); + if (!selected_elems_.empty()) selected_elems_.clear(); + if (!selected_groups_.empty()) selected_groups_.clear(); + + int vnum; for (size_t i = 0; i < groups_.size(); i++) { if ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || @@ -523,23 +516,134 @@ size_t gctl::mesh_io::element_size(element_tag_enum tag_type, int tag) (tag_type == PartitionTag && groups_[i].part_group == tag) && groups_[i].enabled) { - s += groups_[i].elem_ptrs.size(); + selected_groups_.push_back(&groups_[i]); + vnum = elem_size(groups_[i].type); + for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) + { + selected_elems_.push_back(groups_[i].elem_ptrs[e]); + for (size_t v = 0; v < vnum; v++) + { + selected_nodes_.push_back(groups_[i].elem_ptrs[e]->vert_ptrs[v]); + } + } } } - return s; + + std::vector::iterator pos; + std::sort(selected_nodes_.begin(), selected_nodes_.end()); //排序 + pos = std::unique(selected_nodes_.begin(), selected_nodes_.end()); //获取重复序列开始的位置 + selected_nodes_.erase(pos, selected_nodes_.end()); //删除重复点 + return; } -size_t gctl::mesh_io::element_size(std::string phys_name) +void gctl::mesh_io::select_elements(std::string phys_name) { - size_t s = 0; + if (!selected_nodes_.empty()) selected_nodes_.clear(); + if (!selected_elems_.empty()) selected_elems_.clear(); + if (!selected_groups_.empty()) selected_groups_.clear(); + + int vnum; for (size_t i = 0; i < groups_.size(); i++) { if (groups_[i].enabled && groups_[i].name == phys_name) { - s += groups_[i].elem_ptrs.size(); + selected_groups_.push_back(&groups_[i]); + vnum = elem_size(groups_[i].type); + for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) + { + selected_elems_.push_back(groups_[i].elem_ptrs[e]); + for (size_t v = 0; v < vnum; v++) + { + selected_nodes_.push_back(groups_[i].elem_ptrs[e]->vert_ptrs[v]); + } + } } } - return s; + + std::vector::iterator pos; + std::sort(selected_nodes_.begin(), selected_nodes_.end()); //排序 + pos = std::unique(selected_nodes_.begin(), selected_nodes_.end()); //获取重复序列开始的位置 + selected_nodes_.erase(pos, selected_nodes_.end()); //删除重复点 + return; +} + +size_t gctl::mesh_io::node_size() +{ + return selected_nodes_.size(); +} + +size_t gctl::mesh_io::element_size() +{ + return selected_elems_.size(); +} + +const gctl::array &gctl::mesh_io::node_tags() +{ + selected_node_tag_.resize(selected_nodes_.size()); + for (size_t i = 0; i < selected_node_tag_.size(); i++) + { + selected_node_tag_[i] = nodes_tag_[selected_nodes_[i]->id]; + } + return selected_node_tag_; +} + +const gctl::array &gctl::mesh_io::element_tags(element_tag_enum tag_type) +{ + selected_elem_tag_.resize(selected_elems_.size()); + + size_t id = 0; + for (size_t i = 0; i < selected_groups_.size(); i++) + { + for (size_t e = 0; e < selected_groups_[i]->elem_ptrs.size(); e++) + { + if (tag_type == PhysicalTag) selected_elem_tag_[id] = selected_groups_[i]->phys_group; + else if (tag_type == GeometryTag) selected_elem_tag_[id] = selected_groups_[i]->geom_group; + else if (tag_type == PartitionTag) selected_elem_tag_[id] = selected_groups_[i]->part_group; + else selected_elem_tag_[id] = DEFAULT_INVALID_TAG; + id++; + } + } + return selected_elem_tag_; +} + +void gctl::mesh_io::get_gmsh_physical_groups(std::vector &g_groups) +{ + if (!g_groups.empty()) g_groups.clear(); + + gmsh_physical_group tmp_group; + bool not_found; + for (size_t i = 0; i < groups_.size(); i++) + { + if (g_groups.empty() && groups_[i].enabled) + { + tmp_group.name = groups_[i].name; + tmp_group.phys_tag = groups_[i].phys_group; + tmp_group.dim_tag = groups_[i].part_group; + g_groups.push_back(tmp_group); + } + else + { + not_found = true; + for (size_t g = 0; g < g_groups.size(); g++) + { + if (groups_[i].part_group == g_groups[g].dim_tag && + groups_[i].phys_group == g_groups[g].phys_tag) + { + not_found = false; + break; + } + } + + if (not_found && groups_[i].enabled) + { + tmp_group.name = groups_[i].name; + tmp_group.phys_tag = groups_[i].phys_group; + tmp_group.dim_tag = groups_[i].part_group; + g_groups.push_back(tmp_group); + } + } + } + return; } void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type) @@ -609,188 +713,6 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type) return; } -void gctl::mesh_io::export_elements_to(array &tris, std::string phys_name) -{ - size_t s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _3NodeTriangle && - (groups_[i].name == phys_name || phys_name == "All")) - { - s += groups_[i].elem_ptrs.size(); - } - } - - tris.resize(s); - - s = 0; - for (size_t i = 0; i < elems_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _3NodeTriangle && - (groups_[i].name == phys_name || phys_name == "All")) - { - for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) - { - tris[s].id = groups_[i].elem_ptrs[e]->id; - tris[s].vert[0] = groups_[i].elem_ptrs[e]->vert_ptrs[0]; - tris[s].vert[1] = groups_[i].elem_ptrs[e]->vert_ptrs[1]; - tris[s].vert[2] = groups_[i].elem_ptrs[e]->vert_ptrs[2]; - s++; - } - } - } - return; -} - -void gctl::mesh_io::export_elements_to(array &tris, element_tag_enum tag_type, int tag) -{ - size_t s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _3NodeTriangle && - ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag))) - { - s += groups_[i].elem_ptrs.size(); - } - } - - tris.resize(s); - - s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _3NodeTriangle && - ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag))) - { - for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) - { - tris[s].id = groups_[i].elem_ptrs[e]->id; - tris[s].vert[0] = groups_[i].elem_ptrs[e]->vert_ptrs[0]; - tris[s].vert[1] = groups_[i].elem_ptrs[e]->vert_ptrs[1]; - tris[s].vert[2] = groups_[i].elem_ptrs[e]->vert_ptrs[2]; - s++; - } - } - } - return; -} - -void gctl::mesh_io::export_elements_to(array &tets, std::string phys_name) -{ - size_t s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron && - (groups_[i].name == phys_name || phys_name == "All")) - { - s += groups_[i].elem_ptrs.size(); - } - } - - tets.resize(s); - - s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron && - (groups_[i].name == phys_name || phys_name == "All")) - { - for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) - { - tets[s].set(groups_[i].elem_ptrs[e]->vert_ptrs[0], - groups_[i].elem_ptrs[e]->vert_ptrs[1], - groups_[i].elem_ptrs[e]->vert_ptrs[2], - groups_[i].elem_ptrs[e]->vert_ptrs[3], - groups_[i].elem_ptrs[e]->id); - s++; - } - } - } - return; -} - -void gctl::mesh_io::export_elements_to(array &tets, element_tag_enum tag_type, int tag) -{ - size_t s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron && - (tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag)) - { - s += groups_[i].elem_ptrs.size(); - } - } - - tets.resize(s); - - s = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron && - (tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag)) - { - for (size_t e = 0; e < groups_[i].elem_ptrs.size(); e++) - { - tets[s].set(groups_[i].elem_ptrs[e]->vert_ptrs[0], - groups_[i].elem_ptrs[e]->vert_ptrs[1], - groups_[i].elem_ptrs[e]->vert_ptrs[2], - groups_[i].elem_ptrs[e]->vert_ptrs[3], - groups_[i].elem_ptrs[e]->id); - s++; - } - } - } - return; -} - -void gctl::mesh_io::get_gmsh_physical_groups(std::vector &g_groups) -{ - if (!g_groups.empty()) g_groups.clear(); - - gmsh_physical_group tmp_group; - bool not_found; - for (size_t i = 0; i < groups_.size(); i++) - { - if (g_groups.empty() && groups_[i].enabled) - { - tmp_group.name = groups_[i].name; - tmp_group.phys_tag = groups_[i].phys_group; - tmp_group.dim_tag = groups_[i].part_group; - g_groups.push_back(tmp_group); - } - else - { - not_found = true; - for (size_t g = 0; g < g_groups.size(); g++) - { - if (groups_[i].part_group == g_groups[g].dim_tag && - groups_[i].phys_group == g_groups[g].phys_tag) - { - not_found = false; - break; - } - } - - if (not_found && groups_[i].enabled) - { - tmp_group.name = groups_[i].name; - tmp_group.phys_tag = groups_[i].phys_group; - tmp_group.dim_tag = groups_[i].part_group; - g_groups.push_back(tmp_group); - } - } - } - return; -} - int gctl::mesh_io::if_saved_data(std::string name, mesh_data_type_e type) { for (size_t i = 0; i < datas_.size(); i++) @@ -815,92 +737,94 @@ gctl::meshio_data *gctl::mesh_io::get_data_ptr(std::string name, mesh_data_type_ return &datas_[id]; } -void gctl::mesh_io::add_node_data(std::string name, const array &data) +void gctl::mesh_io::add_data(std::string name, const array &data, + mesh_data_type_e dtype, output_type_e op) { - size_t s = nodes_.size(); - if (data.size()!= s) throw std::runtime_error("[gctl::mesh_io::create_node_data] Incompatible data size."); + size_t s; + if (dtype == NodeData) s = selected_nodes_.size(); + else s = selected_elems_.size(); - int d_id = if_saved_data(name, NodeData); - if (d_id != -1) + if (data.size()!= s) throw std::runtime_error("[gctl::mesh_io::add_data] Incompatible data size to the selected nodes or elements."); + + int d_id; + if (dtype == NodeData) d_id = if_saved_data(name, NodeData); + else d_id = if_saved_data(name, ElemData); + + if (d_id != -1) // data exist + { + if (op == Append) + { + array tmp_ptrs(s, nullptr); + if (dtype == NodeData) + { + for (size_t i = 0; i < s; i++) + { + tmp_ptrs[i] = selected_nodes_[i]; + } + } + else + { + for (size_t i = 0; i < s; i++) + { + tmp_ptrs[i] = selected_elems_[i]; + } + } + + datas_[d_id].int_tag[2] += s; + datas_[d_id].tar_ptrs.concat(tmp_ptrs); + datas_[d_id].val.concat(data); + } + else // OverWrite + { + datas_[d_id].int_tag[2] = s; + datas_[d_id].tar_ptrs.resize(s, nullptr); + datas_[d_id].val.resize(s, 0.0); + + if (dtype == NodeData) + { + for (size_t i = 0; i < s; i++) + { + datas_[d_id].tar_ptrs[i] = selected_nodes_[i]; + datas_[d_id].val[i] = data[i]; + } + } + else + { + for (size_t i = 0; i < s; i++) + { + datas_[d_id].tar_ptrs[i] = selected_elems_[i]; + datas_[d_id].val[i] = data[i]; + } + } + } + return; + } + + meshio_data new_data; + new_data.enabled = true; + new_data.d_type = NodeData; + new_data.str_tag.resize(1, name); + new_data.real_tag.resize(1, 0.0); + new_data.int_tag.resize(3, 0); + new_data.int_tag[1] = 1; + new_data.int_tag[2] = s; + new_data.tar_ptrs.resize(s, nullptr); + new_data.val.resize(s); + + if (dtype == NodeData) { for (size_t i = 0; i < s; i++) { - datas_[d_id].val[i] = data[i]; + new_data.tar_ptrs[i] = selected_nodes_[i]; + new_data.val[i] = data[i]; } - return; } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = NodeData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = s; - new_data.tar_ptrs.resize(s, nullptr); - new_data.val.resize(s); - - for (size_t i = 0; i < s; i++) + else { - new_data.tar_ptrs[i] = nodes_.get(i); - new_data.val[i] = data[i]; - } - - datas_.push_back(new_data); - return; -} - -void gctl::mesh_io::add_node_data(std::string name, const array &data, const array &boolen) -{ - size_t s = nodes_.size(); - if (data.size()!= s || boolen.size() != s) throw std::runtime_error("[gctl::mesh_io::create_node_data] Incompatible data size."); - - s = 0; - for (size_t i = 0; i < nodes_.size(); i++) - { - if (boolen[i]) s++; - } - - int d_id = if_saved_data(name, NodeData); - if (d_id != -1) - { - datas_[d_id].val.resize(s); - datas_[d_id].tar_ptrs.resize(s, nullptr); - datas_[d_id].int_tag[2] = s; - - s = 0; - for (size_t i = 0; i < nodes_.size(); i++) + for (size_t i = 0; i < s; i++) { - if (boolen[i]) - { - datas_[d_id].tar_ptrs[s] = nodes_.get(i); - datas_[d_id].val[s] = data[i]; - s++; - } - } - return; - } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = NodeData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = s; - new_data.tar_ptrs.resize(s, nullptr); - new_data.val.resize(s); - - s = 0; - for (size_t i = 0; i < nodes_.size(); i++) - { - if (boolen[i]) - { - new_data.tar_ptrs[s] = nodes_.get(i); - new_data.val[s] = data[i]; - s++; + new_data.tar_ptrs[i] = selected_elems_[i]; + new_data.val[i] = data[i]; } } @@ -908,276 +832,30 @@ void gctl::mesh_io::add_node_data(std::string name, const array &data, c return; } -void gctl::mesh_io::add_element_data(std::string name, const array &data, element_type_enum e_type) +void gctl::mesh_io::edit_data(switch_type_e swt, std::string dataname) { - size_t e = 0; - for (size_t i = 0; i < groups_.size(); i++) + if (dataname == "null" && swt == Enable) { - if ((e_type == NotSet || groups_[i].type == e_type) && groups_[i].enabled) e += groups_[i].elem_ptrs.size(); - } - - if (data.size() != e) throw std::runtime_error("[gctl::mesh_io::create_element_data] Incompatible data size."); - - int d_id = if_saved_data(name, ElemData); - if (d_id != -1) - { - datas_[d_id].int_tag[2] = e; - datas_[d_id].tar_ptrs.resize(e, nullptr); - datas_[d_id].val.resize(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) + for (size_t i = 0; i < datas_.size(); i++) { - if ((e_type == NotSet || groups_[i].type == e_type) && groups_[i].enabled) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - datas_[d_id].tar_ptrs[e] = groups_[i].elem_ptrs[j]; - datas_[d_id].val[e] = data[e]; - e++; - } - } - } - return; - } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = ElemData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = e; - new_data.tar_ptrs.resize(e, nullptr); - new_data.val.resize(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if ((e_type == NotSet || groups_[i].type == e_type) && groups_[i].enabled) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j]; - new_data.val[e] = data[e]; - e++; - } + datas_[i].enabled = true; } } - - datas_.push_back(new_data); - return; -} - -void gctl::mesh_io::add_element_data(std::string name, const array &data, element_tag_enum tag_type, int tag) -{ - size_t e = 0; - for (size_t i = 0; i < groups_.size(); i++) + else if (dataname == "null" && swt == Disable) { - if ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag) && - groups_[i].enabled) + for (size_t i = 0; i < datas_.size(); i++) { - e += groups_[i].elem_ptrs.size(); + datas_[i].enabled = false; } } - - if (data.size() != e) throw std::runtime_error("[gctl::mesh_io::create_element_data] Incompatible data size."); - - int d_id = if_saved_data(name, ElemData); - if (d_id != -1) + else { - array more_elem_ptrs(e, nullptr); - array more_val(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) + for (size_t i = 0; i < datas_.size(); i++) { - if ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag) && - groups_[i].enabled) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - more_elem_ptrs[e] = groups_[i].elem_ptrs[j]; - more_val[e] = data[e]; - e++; - } - } - } - - datas_[d_id].int_tag[2] += e; - datas_[d_id].tar_ptrs.concat(more_elem_ptrs); - datas_[d_id].val.concat(more_val); - return; - } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = ElemData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = e; - new_data.tar_ptrs.resize(e, nullptr); - new_data.val.resize(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if ((tag_type == PhysicalTag && groups_[i].phys_group == tag) || - (tag_type == GeometryTag && groups_[i].geom_group == tag) || - (tag_type == PartitionTag && groups_[i].part_group == tag) && - groups_[i].enabled) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j]; - new_data.val[e] = data[e]; - e++; - } + if (datas_[i].str_tag.front() == dataname && swt == Enable) datas_[i].enabled = true; + if (datas_[i].str_tag.front() == dataname && swt == Disable) datas_[i].enabled = false; } } - - datas_.push_back(new_data); - return; -} - -void gctl::mesh_io::add_element_data(std::string name, std::string phys_name, const array &data) -{ - size_t e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - e += groups_[i].elem_ptrs.size(); - } - } - - if (data.size() != e) throw std::runtime_error("[gctl::mesh_io::create_element_data] Incompatible data size."); - - int d_id = if_saved_data(name, ElemData); - if (d_id != -1) - { - array more_elem_ptrs(e, nullptr); - array more_val(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - more_elem_ptrs[e] = groups_[i].elem_ptrs[j]; - more_val[e] = data[e]; - e++; - } - } - } - - datas_[d_id].int_tag[2] += e; - datas_[d_id].tar_ptrs.concat(more_elem_ptrs); - datas_[d_id].val.concat(more_val); - return; - } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = ElemData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = e; - new_data.tar_ptrs.resize(e, nullptr); - new_data.val.resize(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j]; - new_data.val[e] = data[e]; - e++; - } - } - } - - datas_.push_back(new_data); - return; -} - -void gctl::mesh_io::add_element_data(std::string name, std::string phys_name, double phys_val) -{ - size_t e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - e += groups_[i].elem_ptrs.size(); - } - } - - int d_id = if_saved_data(name, ElemData); - if (d_id != -1) - { - array more_elem_ptrs(e, nullptr); - array more_val(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - more_elem_ptrs[e] = groups_[i].elem_ptrs[j]; - more_val[e] = phys_val; - e++; - } - } - } - - datas_[d_id].int_tag[2] += e; - datas_[d_id].tar_ptrs.concat(more_elem_ptrs); - datas_[d_id].val.concat(more_val); - return; - } - - meshio_data new_data; - new_data.enabled = true; - new_data.d_type = ElemData; - new_data.str_tag.resize(1, name); - new_data.real_tag.resize(1, 0.0); - new_data.int_tag.resize(3, 0); - new_data.int_tag[1] = 1; - new_data.int_tag[2] = e; - new_data.tar_ptrs.resize(e, nullptr); - new_data.val.resize(e, 0.0); - - e = 0; - for (size_t i = 0; i < groups_.size(); i++) - { - if (groups_[i].enabled && groups_[i].name == phys_name) - { - for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++) - { - new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j]; - new_data.val[e] = phys_val; - e++; - } - } - } - - datas_.push_back(new_data); return; } @@ -1793,7 +1471,7 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p { if (reinterpret_cast(datas_[i].tar_ptrs[n])->id != DEFAULT_INVALID_TAG) d_size++; } - + if (d_size) { outfile << "$NodeData\n"; @@ -2174,4 +1852,32 @@ void gctl::mesh_io::sort_groups() destroy_vector(tmp_groups); return; +} + +gctl::element_type_enum gctl::mesh_io::match_type(const std::type_info &tinfo) +{ + std::smatch ret; + std::regex pat_triangle("type_triangle"); + std::regex pat_tetrahedron("type_tetrahedron"); + std::regex pat_block("type_block"); + std::regex pat_edge("type_edge"); + std::regex pat_edge2d("type_edge2d"); + std::regex pat_node("type_node"); + std::regex pat_prism("type_prism"); + std::regex pat_rectangle2d("type_rectangle2d"); + std::regex pat_tricone("type_tricone"); + std::regex pat_triangle2d("type_triangle2d"); + + std::string t_str = tinfo.name(); + if (regex_search(t_str, ret, pat_triangle)) return _3NodeTriangle; + else if (regex_search(t_str, ret, pat_tetrahedron)) return _4NodeTetrahedron; + else if (regex_search(t_str, ret, pat_block)) return _8NodeHexahedron; + else if (regex_search(t_str, ret, pat_edge)) return _2NodeLine; + else if (regex_search(t_str, ret, pat_edge2d)) return _2NodeLine; + else if (regex_search(t_str, ret, pat_node)) return _1NodePoint; + else if (regex_search(t_str, ret, pat_prism)) return _6NodePrism; + else if (regex_search(t_str, ret, pat_rectangle2d)) return _4NodeQuadrangle; + else if (regex_search(t_str, ret, pat_tricone)) return _4NodeTetrahedron; + else if (regex_search(t_str, ret, pat_triangle2d)) return _3NodeTriangle; + else return NotSet; } \ No newline at end of file diff --git a/lib/io/mesh_io.h b/lib/io/mesh_io.h index bc8707c..6e3ce22 100644 --- a/lib/io/mesh_io.h +++ b/lib/io/mesh_io.h @@ -194,14 +194,6 @@ namespace gctl */ void info(std::ostream &ss = std::clog); - /** - * @brief 编辑网格数据状态。 - * - * @param swt 使能类型(Enable或Disable) - * @param dataname 数据名称(缺省值为null,表示对所有数据进行操作)。 - */ - void edit_data(switch_type_e swt, std::string dataname = "null"); - /** * @brief 按单元体类型编辑网格单元体组。 * @@ -246,101 +238,78 @@ namespace gctl */ void edit_group(element_tag_enum anchor_type, int anchor_group, element_tag_enum tar_type, int tar_group); - /** - * @brief 返回顶点标签数组的引用。 - * - * @return 整型数组的引用。 - */ - const array &get_node_tag(); - /** * @brief 返回指定类型与名称的标签值 * - * @param anchor_type 查找的标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 - * @param anchor_name 查找的元素组名称。 + * @param tag_type 查找的标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 + * @param group_name 查找的元素组名称。 * @return 标签值 */ - int get_tag(element_tag_enum anchor_type, std::string anchor_name); + int group_tag(element_tag_enum tag_type, std::string group_name); /** * @brief 返回所有顶点数组的引用。 * * @return 顶点数组的引用。 */ - const array &get_nodes(); + const array &get_all_nodes(); /** * @brief 返回所有单元体数组的引用。 * * @return 单元体数组的引用。 */ - const array &get_elems(); + const array &get_all_elems(); /** - * @brief 返回对应类型单元体的数量(注意只会统计有效的单元体组)。 + * @brief 选择所有符合条件的单元体(注意只会统计有效的单元体组)。 * - * @param e_type 单元体类型(缺省为NotSet,返回所有单元体类型的总和)。 - * @return 整型大小。 + * @param e_type 单元体类型(缺省为NotSet,即选择所有单元体类型)。 */ - size_t element_size(element_type_enum e_type = NotSet); + void select_elements(element_type_enum e_type = NotSet); /** - * @brief 返回对应标签类型与标签值的单元体数量(注意只会统计有效的单元体组)。 + * @brief 选择所有符合条件的单元体(注意只会统计有效的单元体组)。 * * @param tag_type 标签类型。 * @param tag 标签值。 - * @return 整型大小。 */ - size_t element_size(element_tag_enum tag_type, int tag); + void select_elements(element_tag_enum tag_type, int tag); /** - * @brief 返回对应名称的单元体数量(注意只会统计有效的单元体组)。 + * @brief 选择所有符合条件的单元体(注意只会统计有效的单元体组)。 * * @param phys_name 单元体组名称 - * @return 整型大小。 */ - size_t element_size(std::string phys_name); + void select_elements(std::string phys_name); /** - * @brief 将对应标签类型转换为网格数据类型 + * @brief 返回已选择的单元体所对应的顶点数量(使用select_elements函数选择)。 * - * @param tag_type 标签类型。 + * @return 顶点数量 */ - void convert_tags_to_data(element_tag_enum tag_type); + size_t node_size(); /** - * @brief 输出对应名称的单元体组到三角形数组。 + * @brief 返回已选择的单元体的数量(使用select_elements函数选择)。 * - * @param tris 输出的三角形数组的引用。 - * @param phys_name 单元体组的名称。 + * @return 单元体数量 */ - void export_elements_to(array &tris, std::string phys_name = "All"); + size_t element_size(); /** - * @brief 输出对应标签类型与标签值的单元体组到三角形数组。 + * @brief 返回已选择的单元体所对应的顶点标签 * - * @param tris 输出的三角形数组的引用。 - * @param tag_type 标签类型。 - * @param tag 标签值。 + * @return 整型数组的引用。 */ - void export_elements_to(array &tris, element_tag_enum tag_type, int tag); + const array &node_tags(); /** - * @brief 输出对应名称的单元体组到四面体数组。 + * @brief 返回已选择的单元体所对应的元素标签 * - * @param tets 输出的四面体数组的引用。 - * @param phys_name 单元体组的名称。 + * @return 整型数组的引用。 */ - void export_elements_to(array &tets, std::string phys_name = "All"); - - /** - * @brief 输出对应标签类型与标签值的单元体组到四面体数组。 - * - * @param tris 输出的四面体数组的引用。 - * @param tag_type 标签类型。 - * @param tag 标签值。 - */ - void export_elements_to(array &tets, element_tag_enum tag_type, int tag); + const array &element_tags(element_tag_enum tag_type); /** * @brief 获取gmsh格式分组表 @@ -349,6 +318,13 @@ namespace gctl */ void get_gmsh_physical_groups(std::vector &g_groups); + /** + * @brief 将对应标签类型转换为网格数据类型 + * + * @param tag_type 标签类型。 + */ + void convert_tags_to_data(element_tag_enum tag_type); + /** * @brief 检查是否存在名为name的数据 * @@ -378,70 +354,23 @@ namespace gctl meshio_data *get_data_ptr(std::string name, mesh_data_type_e type); /** - * @brief 添加一个顶点数据对象。数据将依次添加到所有顶点位置。 + * @brief 添加一个顶点数据对象。数据将依次添加到已选择的顶点位置。 * - * @note 若对应名称的数据已经存在则会覆盖 - * - * @param data 输入的数据数组,长度与网格所有顶点数据相同。 + * @param data 输入的数据数组,长度与已选择的顶点数据相同。 * @param name 新建的数据名称。 + * @param dtype 数据类型。 + * @param op 数据的添加方式(OverWrite或Append)。 */ - void add_node_data(std::string name, const array &data); + void add_data(std::string name, const array &data, + mesh_data_type_e dtype, output_type_e op = OverWrite); /** - * @brief 添加一个顶点数据对象。数据将依次添加到布尔为真的顶点位置。 + * @brief 编辑网格数据状态。 * - * @note 若对应名称的数据已经存在则会覆盖 - * - * @param data 输入的数据数组,长度与网格所有顶点数据相同。 - * @param boolen 输入的布尔,只有为真元素位置的顶点数据将被保存。 - * @param name 新建的数据名称。 + * @param swt 使能类型(Enable或Disable) + * @param dataname 数据名称(缺省值为null,表示对所有数据进行操作)。 */ - void add_node_data(std::string name, const array &data, const array &boolen); - - /** - * @brief 按单元体类型筛选创建一个单元体数据对象。数据将依次添加到所选元素位置。 - * - * @note 若对应名称的数据已经存在则会覆盖 - * - * @param data 输入的数据数组。 - * @param name 新建数据名称。 - * @param e_type 新建数据的单元体类型(缺省值为NotSet,表示选择所有有效的单元体)。 - */ - void add_element_data(std::string name, const array &data, element_type_enum e_type = NotSet); - - /** - * @brief 按单元体标签值筛选创建一个单元体数据对象。 - * - * @note 若对应名称的数据已经存在则会追加 - * - * @param data 输入的数据数组。 - * @param name 新建数据名称。 - * @param tag_type 标签类型。 - * @param tag 标签值。 - */ - void add_element_data(std::string name, const array &data, element_tag_enum tag_type, int tag); - - /** - * @brief 按单元体组的名称筛选创建一个单元体数据对象。 - * - * @note 若对应名称的数据已经存在则会追加 - * - * @param data 输入的数据数组。 - * @param name 新建数据名称。 - * @param phys_name 单元体组的名称。 - */ - void add_element_data(std::string name, std::string phys_name, const array &data); - - /** - * @brief 按单元体组的名称筛选创建一个单元体数据对象。 - * - * @note 若对应名称的数据已经存在则会追加 - * - * @param phys_val 数据初始值 - * @param name 新建数据名称。 - * @param phys_name 单元体组的名称。 - */ - void add_element_data(std::string name, std::string phys_name, double phys_val); + void edit_data(switch_type_e swt, std::string dataname = "null"); /** * @brief 读入triangle软件输出的网格剖分文件。 @@ -492,10 +421,35 @@ namespace gctl * @param refR 参考椭球的长半径(out_coor为Cartesian时无效) */ void save_data_to_xyz(std::string filename, std::string dataname = "null", coordinate_system_e out_coor = Cartesian, double refr = GCTL_Earth_Radius, double refR = GCTL_Earth_Radius); - + + /** + * @brief 提取对应类型和单元体到外部数组。 + * + * @tparam T 单元体类型。 + * @param elems 新生成的单元体数组的引用。 + * @param nodes 新生成的顶点数组的引用。 + */ + template + void export_to(array &elems, array &nodes); + + /** + * @brief 提取对应类型和单元体到外部数组。 + * + * @tparam T 单元体类型。 + * @param elems 新生成的单元体数组的引用。 + * @param nodes 新生成的顶点数组的引用。 + * @param x_id 二维坐标系统的x索引(缺省值为0)。 + * @param y_id 二维坐标系统的y索引(缺省值为1)。 + * + * @note 二维坐标系统的索引表示取xyz坐标中的对应项分别赋值给二维坐标的xy值,{0,1}即为xoy平面、 + * {1,0}即为yox平面、{0,2}即为xoz平面、{1,2}即为yoz平面。 + */ + template + void export_to(array &elems, array &nodes, int x_id = 0, int y_id = 1); + protected: bool initialized_; // 类型是否已经初始化完成 - + // 有效的顶点、单元体和单元体组的数量 size_t valid_node_size_, valid_elem_size_, valid_group_size_; array nodes_; // 网格顶点 当顶点索引为无效值时将不会被输出 @@ -503,7 +457,13 @@ namespace gctl std::vector datas_; // 网格数据 std::vector groups_; // 网格单元体组 array nodes_tag_; // 顶点标签 - + + array selected_node_tag_; // 被选择的顶点的标签 + array selected_elem_tag_; // 被选择的单元体的标签 + std::vector selected_nodes_; // 被选择的顶点 + std::vector selected_elems_; // 被选择的单元体 + std::vector selected_groups_; // 被选择的单元体组 + element_type_enum elem_gmshcode2type_[94]; // gmsh的单元体类型数组 数组索引为gmsh的单元体类型码值 element_type_enum elem_vtkcode2type_[14]; // vtk的单元体类型数组 数组索引为vtk的单元体类型码值 std::map elem_type2gmshcode_; // 单元体类型到gmsh类型码值的映射 @@ -519,7 +479,84 @@ namespace gctl element_type_enum elem_vtk_type(int code); // 获取对应vtk类型码的单元体类型 void update_indexing(); // 更新索引(对网格的元素进行操作后需调用) void sort_groups(); // 对单元体组进行梳理(对网格的元素进行操作后需调用) + element_type_enum match_type(const std::type_info &tinfo); // 根据type_info返回单元体类型 }; + + template + void gctl::mesh_io::export_to(array &elems, array &nodes) + { + const std::type_info &tinfo = typeid(T); + element_type_enum oe_type = match_type(tinfo); + + size_t n = selected_nodes_.size(); + size_t s = selected_elems_.size(); + std::map node_map; + + nodes.resize(n); + for (size_t i = 0; i < n; i++) + { + node_map[selected_nodes_[i]->id] = i; // 原网格顶点索引到新网格顶点索引的映射 + nodes[i].id = i; + nodes[i].x = selected_nodes_[i]->x; + nodes[i].y = selected_nodes_[i]->y; + nodes[i].z = selected_nodes_[i]->z; + } + + int vnum = elem_size(oe_type); + elems.resize(s); + for (size_t i = 0; i < s; i++) + { + if (selected_elems_[i]->type != oe_type) + throw gctl::invalid_argument("[gctl::mesh_io::export_to] The selected element is not " + elem_name(oe_type) + "."); + + elems[i].id = i; + for (size_t v = 0; v < vnum; v++) + elems[i].vert[v] = nodes.get(node_map[selected_elems_[i]->vert_ptrs[v]->id]); + } + + node_map.clear(); + return; + } + + template + void gctl::mesh_io::export_to(array &elems, array &nodes, int x_id, int y_id) + { + const std::type_info &tinfo = typeid(T); + element_type_enum oe_type = match_type(tinfo); + + size_t n = selected_nodes_.size(); + size_t s = selected_elems_.size(); + std::map node_map; + + nodes.resize(n); + double xyz_ref[3]; + for (size_t i = 0; i < n; i++) + { + node_map[selected_nodes_[i]->id] = i; // 原网格顶点索引到新网格顶点索引的映射 + nodes[i].id = i; + + xyz_ref[0] = selected_nodes_[i]->x; + xyz_ref[1] = selected_nodes_[i]->y; + xyz_ref[2] = selected_nodes_[i]->z; + nodes[i].x = xyz_ref[x_id]; + nodes[i].y = xyz_ref[y_id]; + } + + int vnum = elem_size(oe_type); + elems.resize(s); + for (size_t i = 0; i < s; i++) + { + if (selected_elems_[i]->type != oe_type) + throw gctl::invalid_argument("[gctl::mesh_io::export_to] The selected element is not " + elem_name(oe_type) + "."); + + elems[i].id = i; + for (size_t v = 0; v < vnum; v++) + elems[i].vert[v] = nodes.get(node_map[selected_elems_[i]->vert_ptrs[v]->id]); + } + + node_map.clear(); + return; + } }; #endif // _GCTL_MESH_IO_H \ No newline at end of file diff --git a/tool/dsviewer/example.csv b/tool/dsviewer/example.csv new file mode 100644 index 0000000..2b4c765 --- /dev/null +++ b/tool/dsviewer/example.csv @@ -0,0 +1,11 @@ +Name,Age,Gender,Occupation,City,Phone Number,Email,Annual Income,Company,Position +John Doe,28,Male,Engineer,New York,123-456-7890,john.doe@example.com,$75000,ABC Tech,Senior Software Engineer +Jane Smith,34,Female,Teacher,Los Angeles,234-567-8901,jane.smith@example.com,$55000,XYZ School,Math Teacher +Michael Brown,22,Male,Student,Toronto,345-678-9012,michael.brown@example.com,$18000,University of Toronto,Undergraduate Student +Emily Davis,45,Female,Doctor,Chicago,456-789-0123,emily.davis@example.com,$180000,Chicago Medical Center,Cardiologist +David Wilson,30,Male,Designer,San Francisco,567-890-1234,david.wilson@example.com,$90000,DesignWorks,Senior Graphic Designer +Sarah Johnson,29,Female,Marketing Specialist,Seattle,678-901-2345,sarah.johnson@example.com,$85000,MarketingPro,Marketing Manager +Robert Lee,36,Male,Software Developer,Boston,789-012-3456,robert.lee@example.com,$120000,SoftDev Solutions,Lead Developer +Laura Miller,25,Female,Graphic Designer,Denver,890-123-4567,laura.miller@example.com,$60000,Creative Arts,Junior Designer +William Clark,40,Male,Consultant,Atlanta,901-234-5678,william.clark@example.com,$110000,ConsultPro,Business Consultant +Olivia Turner,33,Female,Researcher,Phoenix,012-345-6789,olivia.turner@example.com,$70000,ResearchInnovate,Research Scientist \ No newline at end of file