452 lines
15 KiB
C
452 lines
15 KiB
C
|
/********************************************************
|
|||
|
* ██████╗ ██████╗████████╗██╗
|
|||
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|||
|
* ██║ ███╗██║ ██║ ██║
|
|||
|
* ██║ ██║██║ ██║ ██║
|
|||
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|||
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|||
|
* 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 <http://www.gnu.org/licenses/>.
|
|||
|
*
|
|||
|
* 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<vertex3dc*> vert_ptrs;
|
|||
|
array<mesh_element*> neigh_ptrs;
|
|||
|
|
|||
|
mesh_element();
|
|||
|
};
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 网格数据结构体
|
|||
|
*
|
|||
|
*/
|
|||
|
struct mesh_data
|
|||
|
{
|
|||
|
bool enabled;
|
|||
|
mesh_data_type_e d_type;
|
|||
|
array<std::string> str_tag;
|
|||
|
array<double> real_tag;
|
|||
|
array<int> int_tag;
|
|||
|
array<vertex3dc*> vert_ptrs; // 两者只能存在一个
|
|||
|
array<mesh_element*> elem_ptrs; // 两者只能存在一个
|
|||
|
array<double> 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<mesh_element*> 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<int> &get_node_tag();
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 返回顶点数组的引用。
|
|||
|
*
|
|||
|
* @return 顶点数组的引用。
|
|||
|
*/
|
|||
|
const array<vertex3dc> &get_nodes();
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 返回单元体数组的引用。
|
|||
|
*
|
|||
|
* @return 单元体数组的引用。
|
|||
|
*/
|
|||
|
const array<mesh_element> &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<triangle> &tris, std::string phys_name = "All");
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 输出对应标签类型与标签值的单元体组到三角形数组。
|
|||
|
*
|
|||
|
* @param tris 输出的三角形数组的引用。
|
|||
|
* @param tag_type 标签类型。
|
|||
|
* @param tag 标签值。
|
|||
|
*/
|
|||
|
void export_elements_to(array<triangle> &tris, element_tag_enum tag_type, int tag);
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 输出对应名称的单元体组到四面体数组。
|
|||
|
*
|
|||
|
* @param tets 输出的四面体数组的引用。
|
|||
|
* @param phys_name 单元体组的名称。
|
|||
|
*/
|
|||
|
void export_elements_to(array<tetrahedron> &tets, std::string phys_name = "All");
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 输出对应标签类型与标签值的单元体组到四面体数组。
|
|||
|
*
|
|||
|
* @param tris 输出的四面体数组的引用。
|
|||
|
* @param tag_type 标签类型。
|
|||
|
* @param tag 标签值。
|
|||
|
*/
|
|||
|
void export_elements_to(array<tetrahedron> &tets, element_tag_enum tag_type, int tag);
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 创建一个顶点数据对象。
|
|||
|
*
|
|||
|
* @param data 输入的数据数组。
|
|||
|
* @param name 新建的数据名称。
|
|||
|
*/
|
|||
|
void create_node_data(const array<double> &data, std::string name);
|
|||
|
|
|||
|
/**
|
|||
|
* @brief 按单元体类型筛选创建一个单元体数据对象。
|
|||
|
*
|
|||
|
* @param data 输入的数据数组。
|
|||
|
* @param name 新建数据名称。
|
|||
|
* @param e_type 新建数据的单元体类型(缺省值为NotSet,表示选择所有有效的单元体)。
|
|||
|
*/
|
|||
|
void create_element_data(const array<double> &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<double> &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<double> &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<vertex3dc> nodes_;
|
|||
|
array<mesh_element> elems_;
|
|||
|
std::vector<mesh_data> datas_;
|
|||
|
std::vector<mesh_element_group> groups_;
|
|||
|
array<int> nodes_tag_;
|
|||
|
|
|||
|
element_type_enum elem_gmshcode2type_[94];
|
|||
|
element_type_enum elem_vtkcode2type_[14];
|
|||
|
std::map<element_type_enum, int> elem_type2gmshcode_;
|
|||
|
std::map<element_type_enum, int> elem_type2vtkcode_;
|
|||
|
std::map<element_type_enum, int> elem_type2size_;
|
|||
|
std::map<element_type_enum, std::string> 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
|