/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #ifndef _GCTL_MESH_IO_H #define _GCTL_MESH_IO_H // library's head files #include "../core.h" #include "../geometry.h" #include "../utility.h" #include "triangle_io.h" #include "tetgen_io.h" #include "gmsh_io.h" #include "map" namespace gctl { /** * @brief 无效的索引缺省值。 */ #define DEFAULT_INVALID_TAG -9999 /** * @brief 网格单元体名称枚举类型。 */ enum element_type_enum { NotSet, _2NodeLine, _3NodeTriangle, _4NodeQuadrangle, _4NodeTetrahedron, _8NodeHexahedron, _6NodePrism, _5NodePyramid, _3NodeSecondOrderLine, _6NdoeSecondOrderLine, _9NodeSecondOrderQuadrangle, _10NodeSecondOrderTetrahedron, _27NodeSecondOrderHexahedron, _18NodeSecondOrderPrism, _14NodeSecondOrderPyramid, _1NodePoint, _8NodeSecondOrderQuadrangle, _20NdoeSecondOrderHexahedron, _15NodeSecondOrderPrism, _13NodeSecondOrderPyramid, _9NodeThirdOrderIncompleteTriangle, _10NdoeThirdOrderTriangle, _12NodeFourthOrderIncompleteTriangle, _15NodeFourthOrderTriangle, _15NodeFifthOrderCompleteTriangle, _21NodeFifthOrderCompleteTriangle, _4NodeThirdOrderEdge, _5NodeFourthOrderEdge, _6NodeFifthOrderEdge, _20NodeThirdOrderTetrahedron, _35NodeFourthOrderTetrahedron, _56NodeFifithOrderTetrahedron, _64NodeThirdOrderHexahedron, _125NodeFourthOrderHexahedron, }; /** * @brief 网格单元体标签类型枚举类型 * */ enum element_tag_enum { PhysicalTag, GeometryTag, PartitionTag, NodeTag, }; /** * @brief 网格单元体结构体 * */ struct mesh_element { bool enabled; int id; element_type_enum type; array vert_ptrs; array neigh_ptrs; mesh_element(); }; /** * @brief 网格数据结构体 * */ struct mesh_data { bool enabled; mesh_data_type_e d_type; array str_tag; array real_tag; array int_tag; array vert_ptrs; // 两者只能存在一个 array elem_ptrs; // 两者只能存在一个 array val; mesh_data(); /** * @brief 清空数组并重置变量。 * */ void clear(); /** * @brief 检查数据体是否合规 * */ bool pass_check(); }; /** * @brief 网格单元体分组结构体。 * */ struct mesh_element_group { bool enabled; element_type_enum type; int phys_group; int geom_group; int part_group; std::string name; std::vector elem_ptrs; mesh_element_group(); /** * @brief 将组内所有单元体设置为有效状态。 * */ void enable_elements(); /** * @brief 将组内所有单元体设置为无效状态。 * */ void disable_elements(); }; /** * @brief 网格读写类,这个类实现了多种数据格式的网格文件的读写操作。并具备简单的单元体操作功能。 * */ class mesh_io { public: mesh_io(); virtual ~mesh_io(); /** * @brief 重置(清空)网格数据。 * */ void reset(); /** * @brief 输出网格数据信息至指定流。 * * @param ss 指定流(默认为clog) */ 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 按单元体类型编辑网格单元体组。 * * @param swt 使能类型(Enable或Disable) * @param e_type 单元体类型(缺省值值NotSet,表示对所有单元体组进行操作)。 */ void edit_group(switch_type_e swt, element_type_enum e_type = NotSet); /** * @brief 按单元体组名称编辑网格单元体组。 * * @param swt 使能类型(Enable或Disable)。 * @param grp_name 单元体组名称。 */ void edit_group(switch_type_e swt, std::string grp_name); /** * @brief 按单元体组标签编辑网格单元体组。 * * @param swt 使能类型(Enable或Disable)。 * @param tag_type 标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 * @param tag 标签值。 */ void edit_group(switch_type_e swt, element_tag_enum tag_type, int tag); /** * @brief 按单元体组标签编辑网格单元体组的名称。 * * @param anchor_type 搜索的标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 * @param anchor_group 搜索的标签值。 * @param new_name 单元体组的新名称。 */ void edit_group(element_tag_enum anchor_type, int anchor_group, std::string new_name); /** * @brief 按单元体组标签搜索并编辑网格单元体组的标签。 * * @param anchor_type 搜索的标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 * @param anchor_group 搜索的标签值 * @param tar_type 更改的标签类型(PhysicalTag,GeometryTag或者PartitionTag)。 * @param tar_group 更改的标签值 */ 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 返回顶点数组的引用。 * * @return 顶点数组的引用。 */ const array &get_nodes(); /** * @brief 返回单元体数组的引用。 * * @return 单元体数组的引用。 */ const array &get_elems(); /** * @brief 返回对应类型单元体的数量。 * * @param e_type 单元体类型(缺省为NotSet,返回所有单元体类型的总和)。 * @return 整型大小。 */ size_t element_size(element_type_enum e_type = NotSet); /** * @brief 返回对应标签类型与标签值的单元体数量。 * * @param tag_type 标签类型。 * @param tag 标签值。 * @return 整型大小。 */ size_t element_size(element_tag_enum tag_type, int tag); /** * @brief 返回对应名称的单元体数量。 * * @param phys_name 单元体组名称 * @return 整型大小。 */ size_t element_size(std::string phys_name); /** * @brief 将对应标签类型转换为网格数据类型 * * @param tag_type 标签类型。 */ void convert_tags_to_data(element_tag_enum tag_type); /** * @brief 输出对应名称的单元体组到三角形数组。 * * @param tris 输出的三角形数组的引用。 * @param phys_name 单元体组的名称。 */ void export_elements_to(array &tris, std::string phys_name = "All"); /** * @brief 输出对应标签类型与标签值的单元体组到三角形数组。 * * @param tris 输出的三角形数组的引用。 * @param tag_type 标签类型。 * @param tag 标签值。 */ void export_elements_to(array &tris, element_tag_enum tag_type, int tag); /** * @brief 输出对应名称的单元体组到四面体数组。 * * @param tets 输出的四面体数组的引用。 * @param phys_name 单元体组的名称。 */ 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); /** * @brief 创建一个顶点数据对象。 * * @param data 输入的数据数组。 * @param name 新建的数据名称。 */ void create_node_data(const array &data, std::string name); /** * @brief 按单元体类型筛选创建一个单元体数据对象。 * * @param data 输入的数据数组。 * @param name 新建数据名称。 * @param e_type 新建数据的单元体类型(缺省值为NotSet,表示选择所有有效的单元体)。 */ void create_element_data(const array &data, std::string name, element_type_enum e_type = NotSet); /** * @brief 按单元体标签值筛选创建一个单元体数据对象。 * * @param data 输入的数据数组。 * @param name 新建数据名称。 * @param tag_type 标签类型。 * @param tag 标签值。 */ void create_element_data(const array &data, std::string name, element_tag_enum tag_type, int tag); /** * @brief 按单元体组的名称筛选创建一个单元体数据对象。 * * @param data 输入的数据数组。 * @param name 新建数据名称。 * @param phys_name 单元体组的名称。 */ void create_element_data(const array &data, std::string name, std::string phys_name); /** * @brief 读入triangle软件输出的网格剖分文件。 * * @param filename 文件名(.node和.ele文件必须在同一路径下,.neigh文件不是必须的,文件名不包含后缀名)。 * @param is_packed 输入文件的索引值是否从0开始。 */ void read_triangle_ascii(std::string filename, index_packed_e is_packed = Packed); /** * @brief 读入tetgen软件输出的网格剖分文件。 * * @param filename 文件名(.node和.ele文件必须在同一路径下,.neigh文件不是必须的,文件名不包含后缀名)。 * @param is_packed 输入文件的索引值是否从0开始。 */ void read_tetgen_ascii(std::string filename, index_packed_e is_packed = Packed); /** * @brief 读入Gmsh软件输出的网格剖分文件(只支持v2.2的ASCII文件)。 * * @param filename 文件名 * @param is_packed 输入文件的索引值是否从0开始。 */ void read_gmsh_v2_ascii(std::string filename, index_packed_e is_packed = NotPacked); /** * @brief 保存Gmsh软件格式的网格剖分文件(只支持v2.2的ASCII文件)。 * * @param filename 文件名 * @param is_packed 输入文件的索引值是否从0开始。 */ void save_gmsh_v2_ascii(std::string filename, index_packed_e is_packed = NotPacked); /** * @brief 保存Paraview软件格式的网格剖分文件 * * @param filename 文件名 */ void save_vtk_legacy_ascii(std::string filename); /** * @brief 导出数据到点云文件 * * @param filename 输出文件名 * @param dataname 数据名称 * @param out_coor 数据的坐标系(Cartesian或Spherical) * @param refr 参考椭球的短半径(out_coor为Cartesian时无效) * @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); private: bool initialized_; size_t valid_node_size_, valid_elem_size_, valid_group_size_; array nodes_; array elems_; std::vector datas_; std::vector groups_; array nodes_tag_; element_type_enum elem_gmshcode2type_[94]; element_type_enum elem_vtkcode2type_[14]; std::map elem_type2gmshcode_; std::map elem_type2vtkcode_; std::map elem_type2size_; std::map elem_type2name_; std::string elem_name(element_type_enum e_type); int elem_gmsh_code(element_type_enum e_type); int elem_vtk_code(element_type_enum e_type); int elem_size(element_type_enum e_type); element_type_enum elem_gmsh_type(int code); element_type_enum elem_vtk_type(int code); void update_indexing(); void sort_groups(); }; } #endif // _GCTL_MESH_IO_H