Merge pull request 'dev_yi' (#3) from dev_yi into main

Reviewed-on: #3
This commit is contained in:
张壹 2025-02-03 11:25:03 +08:00
commit 78190f9b58
16 changed files with 1205 additions and 356 deletions

BIN
GCTL_logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

265
README.md
View File

@ -1,42 +1,249 @@
![logo](GCTL_logo.jpg)
# Geophysical Computational Tools & Library (GCTL)
GCTL is a package of computational tools and C++ library for geophysical studies. The complete package is composed of a core library and additional libraries and command line tools. A full list of GCTL's libraries are listed as:
GCTL 是一个用于地球物理研究的计算工具和 C++ 库。完整的软件包由核心库和额外的库以及命令行工具组成。本库采用现代 C++ 设计,提供高性能的数值计算和数据处理功能。
1. **gctl**: the core library (stored at this repository);
2. **gctl_potential**: library of the algorithms for working with the potential field data (i.e., gravitational and magnetic data);
3. **gctl_seismic**: library of the algorithms for working with the seismic/earthquake data;
4. **gctl_elecmag**: library of the algorithms for working with the elecmagnetic/magnetotelluric data;
5. **gctl_optimization**: library of the optimization algorithms;
6. **gctl_ai**: library of the artificial intelligence algorithms;
6. **gctl_graphic**: library for data visualization;
7. **gctl_examples**: executable examples;
8. **gctl_toolkits**: command line tools.
## 主要特性
## Dependences
- **高性能**: 采用现代 C++ 技术,支持并行计算和 SIMD 优化
- **易用性**: 直观的 API 设计,完善的文档和示例
- **可扩展**: 模块化设计,支持自定义扩展
- **可靠性**: 完整的单元测试,异常安全保证
- **跨平台**: 支持 Linux、macOS 和 Windows
There are several third-party libraries that could be employed by the GCTL during the compilation to enable extral functionalities. The inclusion of the exterior libraries are controlled using the CMake compile options as `-D<option>=ON|OFF`. And the availiable options are:
## 库结构
1. **GCTL_OPENMP**: Enable OpenMP support. The default is ON;
2. **GCTL_NETCDF**: Use the netCDF libraries for reading and writing .nc files. This option requires the netCDF and netCDF_CXX libraries. The default is ON;
3. **GCTL_WAVELIB**: Use the WaveLIB for preforming the wavelet processes. The default is ON;
4. **GCTL_FFTW3**: Use the FFTW library for preforming the Fourier transformations. The default is ON;
5. **GCTL_OPENBLAS**: Use the openblas library for linear algebras. The default is OFF;
6. **GCTL_EIGEN**: Use the Eigen3 library. This is not a compiling option but could be used in applications to enable Eigen3 support.
7. **GCTL\_CHECK_BOUNDER**: Check indexing validities in all array-like operations. This may affect the computational efficiency. The default is OFF;
8. **GCTL\_CHECK_SIZE**: Check sizes in all array-like operations. This may affect the computational efficiency. The default is OFF.
### 1. 核心库 (gctl)
- **核心数据结构** (`core/`)
- 动态数组 (`array.h`, `array_enhanced.h`)
- 自动内存管理
- 并行算法支持
- 数学运算功能
- 序列化支持
- 矩阵操作 (`matrix.h`)
- 基础矩阵运算
- 线性代数操作
- 分解算法
- 特征值计算
- 稀疏数据结构 (`spmat.h`, `sparray.h`)
- 压缩存储格式
- 高效稀疏运算
- 内存优化
- 向量模板 (`vector_t.h`)
- 2D/3D 向量运算
- 几何变换
- 坐标系转换
- 枚举定义 (`enum.h`)
- 类型安全枚举
- 状态定义
- 错误码
## Installation
- **输入输出** (`io/`)
- DSV 文件操作 (`dsv_io.h`)
- CSV/TSV 格式支持
- 自定义分隔符
- 表头处理
- 文本文件操作 (`text_io.h`)
- 文本读写
- 编码转换
- 流式处理
- NetCDF 支持 (`netcdf_io.h`)
- 科学数据格式
- 多维数组支持
- 元数据处理
- 网格文件操作 (`mesh_io.h`)
- 多种网格格式
- 网格转换
- 拓扑处理
You can use the enclosed shell script 'installer' to install.
- **数学计算** (`maths/`)
- 线性代数 (`linear_algebra.h`)
- 矩阵分解
- 特征值计算
- 线性方程组求解
- 数学函数 (`mathfunc.h`)
- 基础数学函数
- 特殊函数
- 插值函数
- 形状函数 (`shapefunc.h`)
- 有限元基函数
- 节点形函数
- 边界条件
- FFT 变换 (`fft.h`)
- 快速傅里叶变换
- 频谱分析
- 滤波器
```
./installer configure && ./installer build && ./installer install
```
- **几何处理** (`geometry/`)
- 基础几何 (`basic.h`)
- 点线面运算
- 几何变换
- 相交检测
- 网格处理 (`mesh.h`)
- 网格生成
- 网格优化
- 质量评估
- 形状函数 (`shape.h`)
- 几何形状描述
- 参数化曲面
- 边界表示
For more information of the 'installer', use:
- **工具函数** (`utility/`)
- 通用工具 (`common.h`)
- 字符串处理
- 时间日期
- 日志系统
- 算法实现 (`algorithm.h`)
- 排序算法
- 搜索算法
- 图算法
```
./installer help
```
### 2. 扩展库
- **gctl_potential**: 势场数据处理库
- 重力数据处理
- 磁场数据处理
- 势场反演
- 场源解释
- **gctl_seismic**: 地震数据处理库
- 波形处理
- 震相识别
- 速度建模
- 层析成像
- **gctl_elecmag**: 电磁数据处理库
- MT数据处理
- 电磁反演
- 各向异性分析
- 噪声处理
- **gctl_optimization**: 优化算法库
- 线性规划
- 非线性优化
- 全局优化
- 约束优化
- **gctl_ai**: 人工智能算法库
- 神经网络
- 机器学习
- 深度学习
- 模式识别
- **gctl_graphic**: 数据可视化库
- 2D绘图
- 3D可视化
- 等值线图
- 矢量场图
## 系统要求
### 编译器支持
- GCC 7.0 或更高版本
- Clang 6.0 或更高版本
- MSVC 2019 或更高版本
### 操作系统
- Linux (Ubuntu 18.04+, CentOS 7+)
- macOS (10.14+)
- Windows (10, 11)
### 依赖库版本
- CMake 3.10+
- OpenMP 4.0+
- NetCDF 4.6+
- FFTW 3.3+
- OpenBLAS 0.3+
- Eigen 3.3+
## 性能优化
### 1. 并行计算
- OpenMP 多线程并行
- 自动线程分配
- 负载均衡
- 缓存优化
- SIMD 向量化
- AVX/AVX2 指令集
- 自动向量化
- 手动优化
- GPU 加速(可选)
- CUDA 支持
- OpenCL 支持
- 异构计算
### 2. 内存管理
- 智能指针管理
- 内存池技术
- 缓存对齐
- 零拷贝优化
### 3. 算法优化
- 自适应算法选择
- 数值稳定性保证
- 计算精度控制
- 资源使用优化
## 应用领域
### 1. 地球物理勘探
- 重力勘探
- 磁法勘探
- 地震勘探
- 电磁勘探
### 2. 地球科学研究
- 地壳结构研究
- 地球内部成像
- 地球动力学模拟
- 地震预测研究
### 3. 工程应用
- 矿产资源勘探
- 工程地质调查
- 环境地球物理
- 灾害监测预警
## 贡献指南
### 代码规范
- 遵循现代 C++ 规范
- 代码格式化要求
- 命名规范
- 注释规范
### 开发流程
1. Fork 项目
2. 创建特性分支
3. 提交变更
4. 发起 Pull Request
### 测试要求
- 单元测试覆盖
- 集成测试
- 性能测试
- 回归测试
## 版本历史
### v1.0.0 (2024-01)
- 初始版本发布
- 核心功能实现
- 基础文档完成
### 开发计划
- GPU 加速支持
- 分布式计算
- 深度学习集成
- 实时处理优化
## 联系方式
### 技术支持
- **邮箱**: yizhang-geo@zju.edu.cn
## 致谢
感谢以下机构和个人的支持:
- 浙江大学地球科学学院
- 国家自然科学基金委员会

View File

@ -23,7 +23,7 @@ add_example(windowfunc_ex OFF)
add_example(legendre_ex OFF)
add_example(refellipsoid_ex OFF)
add_example(kde_ex OFF)
add_example(meshio_ex OFF)
add_example(meshio_ex ON)
add_example(autodiff_ex OFF)
add_example(multinary_ex OFF)
add_example(text_io_ex OFF)

View File

@ -30,6 +30,11 @@
using namespace gctl;
double get_x(const point3dc &p)
{
return p.x;
}
int main(int argc, char const *argv[]) try
{
// create a new array and give initial values
@ -42,7 +47,7 @@ int main(int argc, char const *argv[]) try
A.linear2log(2);
A.show();
A.parallel_for_each([](double &a, size_t i){a += 1;});
A.for_each([](double &a){a += 1;});
A.show();
A.sequence(1.0, 0.5, 3, 4, 1);
@ -64,6 +69,10 @@ int main(int argc, char const *argv[]) try
P.sequence(point3dc(0, 0, 0), point3dc(2, 1, 0.5));
P.show(std::cout, '\n');
//array<double> Px = P.extract<double>([](const point3dc &p)->double{return p.x;});
array<double> Px = P.extract<double>(get_x);
Px.show();
// create a new 2D array
matrix<int> C(5, 5, 1);
C.sequence(0, 1, 10);

View File

@ -33,28 +33,35 @@ using namespace gctl;
int main(int argc, char const *argv[]) try
{
mesh_io mshio;
//mshio.read_tetgen_ascii("tmp/ex1.1");
//mshio.edit_group(Disable, GeometryTag, 5);
//mshio.edit_group(GeometryTag, 1, PhysicalTag, 1);
//mshio.edit_group(GeometryTag, 2, PhysicalTag, 2);
//mshio.edit_group(GeometryTag, 3, PhysicalTag, 3);
//mshio.edit_group(GeometryTag, 4, PhysicalTag, 4);
//mshio.edit_group(GeometryTag, 1, "Boundary");
//mshio.edit_group(GeometryTag, 2, "Body1");
//mshio.edit_group(GeometryTag, 3, "Body2");
//mshio.edit_group(GeometryTag, 4, "Body3");
//mshio.save_gmsh_v2_ascii("tmp/ex1.1");
/*
/*
mshio.read_tetgen_ascii("tmp/ex1.1");
mshio.edit_group(Disable, GeometryTag, 5);
mshio.edit_group(GeometryTag, 1, PhysicalTag, 1);
mshio.edit_group(GeometryTag, 2, PhysicalTag, 2);
mshio.edit_group(GeometryTag, 3, PhysicalTag, 3);
mshio.edit_group(GeometryTag, 4, PhysicalTag, 4);
mshio.edit_group(GeometryTag, 1, "Boundary");
mshio.edit_group(GeometryTag, 2, "Body1");
mshio.edit_group(GeometryTag, 3, "Body2");
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);
array<double> body_val(mshio.element_size("Body2"), 2.0);
mshio.create_data(body_val, "BodyValue", "Body2");
mshio.add_element_data("BodyValue", "Body2", body_val);
array<double> body_val2(mshio.element_size("Body3"), 1.0);
mshio.add_element_data("BodyValue", "Body3", body_val2);
mshio.save_gmsh_v2_ascii("tmp/ex1.2");
//mshio.save_vtk_legacy_ascii("tmp/ex1.1");
mshio.info();
array<vertex3dc> nodes = mshio.get_nodes();
const array<vertex3dc> &nodes = mshio.get_nodes();
array<tetrahedron> body2_tets;
mshio.export_elements_to(body2_tets, "All");
@ -63,8 +70,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);
mshio.edit_group(Enable, GeometryTag, 3);
@ -72,6 +78,7 @@ int main(int argc, char const *argv[]) try
mshio.edit_group(Enable, GeometryTag, 9);
mshio.save_gmsh_v2_ascii("tmp/wjb.2");
*/
return 0;
}
catch(std::exception &e)

View File

@ -44,6 +44,13 @@ int main(int argc, char const *argv[]) try
tc.filt_column("America", "Continent_s", {"Name_s", "Population_n", "GNP_n"}, tout);
//tc.match_column("America", "Continent_s", {}, tout);
//tout.add_column("GNP_n2", "Population_n");
//array<int> GNP_n2(tout.row_number(), 1000.0);
//tout.fill_column(GNP_n2, "GNP_n2");
int lr_id = tout.add_row();
tout.fill_row(array<std::string>{"Asia", "China", "14000000", "1949"}, lr_id);
tout.set_delimeter('|');
tout.save_text("out");

View File

@ -593,22 +593,45 @@ namespace gctl
/**
* @brief
*
*
* [](ArrValType &a, size_t i){do something here...}
*
* [](ArrValType &a){do something here...}
*
* @tparam BiaryOp
* @tparam UnaryOp
* @param op
*/
template<typename BiaryOp>
void parallel_for_each(BiaryOp op)
template <typename UnaryOp>
void for_each(UnaryOp op)
{
#pragma omp parallel for
for (size_t i = 0; i < length_; i++)
{
op(val_[i], i);
op(val_[i]);
}
return;
}
/**
* @brief
*
*
* [](const ArrValType &a)->OutType{do something here...}
*
* @tparam UnaryOp
* @param op
*/
template <typename OutType, typename UnaryOp>
array<OutType> extract(UnaryOp op)
{
array<OutType> arr(length_);
#pragma omp parallel for
for (size_t i = 0; i < length_; i++)
{
arr[i] = op(val_[i]);
}
return arr;
}
/**
* @brief Display the elements.
*

View File

@ -531,25 +531,20 @@ namespace gctl
* @brief
*
* @param out_ps
* @param[in] xmin x最小
* @param[in] xmax x最大
* @param[in] x_st x起始
* @param[in] x_ed x终止
* @param[in] dx x间隔
* @param[in] ele
*/
template <typename T>
void grid_points_1d(array<point2c<T>> &out_ps, T xmin, T xmax, T dx, T ele)
void grid_points_1d(array<point2c<T>> &out_ps, T x_st, T x_ed, T dx, T ele)
{
if (xmin >= xmax || xmin + dx > xmax || dx <= 0)
{
throw std::invalid_argument("[gctl::grid_points_1d] Invalid parameters.");
}
int xnum = round((xmax - xmin)/dx) + 1;
int xnum = round(std::abs((x_ed - x_st)/dx)) + 1;
out_ps.resize(xnum);
for (int i = 0; i < xnum; i++)
{
out_ps[i].x = xmin + dx*i;
out_ps[i].x = x_st + dx*i;
out_ps[i].y = ele;
}
return;

View File

@ -375,6 +375,20 @@ namespace gctl
}
return false;
}
template <typename T>
void grid_points_1d(array<point2p<T>> &obsp, T deg_st, T deg_ed, T ddeg, T rad)
{
int m = round(std::abs((deg_st - deg_ed)/ddeg)) + 1;
obsp.resize(m);
for (size_t i = 0; i < m; i++)
{
obsp[i].arc = arc(deg_st + i*ddeg);
obsp[i].rad = rad;
}
return;
}
}
#endif // _GCTL_POINT2P_H

View File

@ -94,22 +94,46 @@ void gctl::dsv_io::get_column_names(std::vector<std::string> &names)
return;
}
void gctl::dsv_io::set_row_names(const std::vector<std::string> &names, std::string corner_name)
void gctl::dsv_io::set_row_names(const std::vector<std::string> &names, const std::vector<int> &idx, std::string corner_name)
{
for (size_t i = 1; i <= std::min(row_num_, (int) names.size()); i++)
if (!idx.empty())
{
table_[i][0].str_ = names[i - 1];
if (idx.size() != names.size()) throw std::runtime_error("[gctl::dsv_io] The size of idx and names must be the same.");
for (size_t i = 0; i < names.size(); i++)
{
table_[idx[i]][0].str_ = names[i];
}
}
else
{
for (size_t i = 1; i <= std::min(row_num_, (int) names.size()); i++)
{
table_[i][0].str_ = names[i - 1];
}
}
table_[0][0].str_ = corner_name;
return;
}
void gctl::dsv_io::set_column_names(const std::vector<std::string> &names)
void gctl::dsv_io::set_column_names(const std::vector<std::string> &names, const std::vector<int> &idx)
{
for (size_t i = 1; i <= std::min(col_num_, (int) names.size()); i++)
if (!idx.empty())
{
table_[0][i].str_ = names[i - 1];
if (idx.size() != names.size()) throw std::runtime_error("[gctl::dsv_io] The size of idx and names must be the same.");
for (size_t i = 0; i < names.size(); i++)
{
table_[0][idx[i]].str_ = names[i];
}
}
else
{
for (size_t i = 1; i <= std::min(col_num_, (int) names.size()); i++)
{
table_[0][i].str_ = names[i - 1];
}
}
return;
}
@ -293,6 +317,29 @@ void gctl::dsv_io::save_text(std::string filename, std::string file_exten)
outfile << "# " << annotates_[i] << std::endl;
}
// 探测是否有行头
bool col_st = 1;
for (int i = 0; i <= row_num_; i++)
{
if (table_[i][0].out_ok_ && table_[i][0].str_ != "")
{
col_st = 0;
break;
}
}
for (int i = 0; i <= row_num_; i++)
{
// 单独处理第一列 即行头
outfile << table_[i][col_st].str_;
for (int j = col_st + 1; j <= col_num_; j++)
{
if (table_[i][j].out_ok_) outfile << deli_sym_ << table_[i][j].str_;
}
outfile << std::endl;
}
/*
// 单独处理第一行 即列头
bool line_st = false;
if (table_[0][0].out_ok_ && table_[0][0].str_ != "")
@ -336,7 +383,7 @@ void gctl::dsv_io::save_text(std::string filename, std::string file_exten)
}
outfile << std::endl;
}
*/
outfile.close();
return;
}
@ -508,27 +555,16 @@ void gctl::dsv_io::row_output(int idx, switch_type_e s)
void gctl::dsv_io::row_output(std::string name, switch_type_e s)
{
row_output(name_index(name), s);
row_output(name_index(name, true), s);
return;
}
void gctl::dsv_io::add_column(std::string name)
int gctl::dsv_io::add_column(std::string name, int idx)
{
if (idx <= 0) throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
table_cell empty_cell;
for (size_t i = 0; i < table_.size(); i++)
{
table_[i].push_back(empty_cell);
}
table_[0].back().str_ = name;
col_num_++;
return;
}
void gctl::dsv_io::add_column(int idx, std::string name)
{
table_cell empty_cell;
if (idx <= 0)
if (idx > col_num_)
{
for (size_t i = 0; i < table_.size(); i++)
{
@ -537,6 +573,7 @@ void gctl::dsv_io::add_column(int idx, std::string name)
table_[0].back().str_ = name;
col_num_++;
return col_num_;
}
else
{
@ -547,35 +584,28 @@ void gctl::dsv_io::add_column(int idx, std::string name)
table_[0][idx].str_ = name;
col_num_++;
return idx;
}
return;
return -1;
}
void gctl::dsv_io::add_column(std::string id_name, std::string name)
int gctl::dsv_io::add_column(std::string name, std::string id_name)
{
add_column(name_index(id_name), name);
return;
return add_column(name, name_index(id_name));
}
void gctl::dsv_io::add_row(std::string name)
int gctl::dsv_io::add_row(std::string name, int idx)
{
if (idx <= 0) throw std::runtime_error("[gctl::dsv_io] Invalid row index.");
std::vector<table_cell> empty_line;
table_.push_back(empty_line);
table_.back().resize(col_num_ + 1);
table_.back().front().str_ = name;
row_num_++;
return;
}
void gctl::dsv_io::add_row(int idx, std::string name)
{
std::vector<table_cell> empty_line;
if (idx <= 0)
if (idx > row_num_)
{
table_.push_back(empty_line);
table_.back().resize(col_num_ + 1);
table_.back().front().str_ = name;
row_num_++;
return row_num_;
}
else
{
@ -583,14 +613,14 @@ void gctl::dsv_io::add_row(int idx, std::string name)
table_[idx].resize(col_num_ + 1);
table_[idx].front().str_ = name;
row_num_++;
return idx;
}
return;
return -1;
}
void gctl::dsv_io::add_row(std::string id_name, std::string name)
int gctl::dsv_io::add_row(std::string name, std::string id_name)
{
add_row(name_index(id_name), name);
return;
return add_row(name, name_index(id_name, true));
}
void gctl::dsv_io::filt_column(std::string cnd_str, std::string cnd_col,
@ -668,7 +698,7 @@ void gctl::dsv_io::filt_column(std::string cnd_str, std::string cnd_col,
}
out_table.set_column_names(io_col);
out_table.set_row_names(row_names, table_[0][0].str_);
out_table.set_row_names(row_names, {}, table_[0][0].str_);
destroy_vector(row_names);
destroy_vector(io_col);
@ -743,7 +773,7 @@ void gctl::dsv_io::filt_column(rowbool_func_t func, const std::vector<std::strin
}
out_table.set_column_names(io_col);
out_table.set_row_names(row_names, table_[0][0].str_);
out_table.set_row_names(row_names, {}, table_[0][0].str_);
destroy_vector(row_names);
destroy_vector(io_col);
@ -911,7 +941,7 @@ void gctl::dsv_io::filt_column(std::string cnd_str, const std::vector<std::strin
}
out_table.set_column_names(io_col);
out_table.set_row_names(row_names, table_[0][0].str_);
out_table.set_row_names(row_names, {}, table_[0][0].str_);
destroy_vector(row_names);
destroy_vector(io_col);
@ -963,6 +993,29 @@ void gctl::geodsv_io::fill_column_point2dc(const array<point2dc> &data, std::str
return;
}
void gctl::geodsv_io::fill_column_point2dp(const array<point2dp> &data, int rid, int cid, int p)
{
if (rid > col_num_ || cid > col_num_ || rid == cid || rid <= 0 || cid <= 0)
{
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
}
std::stringstream ss;
std::string s;
for (size_t i = 1; i <= std::min(row_num_, (int) data.size()); i++)
{
table_[i][rid].value(data[i - 1].rad, p);
table_[i][cid].value(data[i - 1].arc, p);
}
return;
}
void gctl::geodsv_io::fill_column_point2dp(const array<point2dp> &data, std::string rname, std::string cname, int p)
{
fill_column_point2dp(data, name_index(rname, false), name_index(cname, false), p);
return;
}
void gctl::geodsv_io::fill_column_point3dc(const array<point3dc> &data, int xid, int yid, int zid, int p)
{
if (xid > col_num_ || yid > col_num_ || zid > col_num_ || xid == yid || yid == zid || xid == zid
@ -1035,6 +1088,28 @@ void gctl::geodsv_io::get_column_point2dc(array<point2dc> &data, std::string xna
return;
}
void gctl::geodsv_io::get_column_point2dp(array<point2dp> &data, int rid, int cid)
{
if (rid > col_num_ || cid > col_num_ || rid == cid || rid <= 0 || cid <= 0)
{
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
}
data.resize(row_num_);
for (size_t i = 1; i <= row_num_; i++)
{
data[i - 1].rad = table_[i][rid].value<double>();
data[i - 1].arc = table_[i][cid].value<double>();
}
return;
}
void gctl::geodsv_io::get_column_point2dp(array<point2dp> &data, std::string rname, std::string cname)
{
get_column_point2dp(data, name_index(rname, false), name_index(cname, false));
return;
}
void gctl::geodsv_io::get_column_point3dc(array<point3dc> &data, int xid, int yid, int zid)
{
if (xid > col_num_ || yid > col_num_ || zid > col_num_ || xid == yid || yid == zid || xid == zid

View File

@ -113,15 +113,15 @@ namespace gctl
};
/**
* @brief DSV文本读写类
*
*
* 1. '#'
* 2. '#!'
* 3. n行头信息
* 4. row*col大小的表格
* 5.
* 6. 使R<id>C<id>
* @brief DSV文本读写类型可以读写并处理一定格式保存的文本数据
* 1. #
* 2. #!
* 3. n0
* 4.
* 5. /
* 6.
* 7. 访1
* 8. R<id>C<id>
*/
class dsv_io
{
@ -273,16 +273,19 @@ namespace gctl
/**
* @brief
*
* @param names
* @param names
* @param idx
* @param corner_name RowNames
*/
void set_row_names(const std::vector<std::string> &names, std::string corner_name = "row-idx");
void set_row_names(const std::vector<std::string> &names, const std::vector<int> &idx = {}, std::string corner_name = "RowNames");
/**
* @brief
*
* @param names
* @param names
* @param idx
*/
void set_column_names(const std::vector<std::string> &names);
void set_column_names(const std::vector<std::string> &names, const std::vector<int> &idx = {});
/**
* @brief
@ -402,56 +405,52 @@ namespace gctl
* @param s
*/
void row_output(std::string name, switch_type_e s = Disable);
/**
* @brief
*
* @param name
*/
void add_column(std::string name = "");
/**
* @brief idx的列插入一个空白列
* @brief idx的位置插入一个空白列idx大于列数则在表尾添加一列
*
* @param idx 0
* @param idx
* @param name
*
* @return 1 -1
*/
void add_column(int idx, std::string name = "");
int add_column(std::string name = "", int idx = 9999);
/**
* @brief id_name的列插入一个空白列
* @brief id_name的列的位置插入一个空白列
*
* @param id_name
* @param name
*/
void add_column(std::string id_name, std::string name = "");
/**
* @brief
*
* @param name
* @return 1 -1
*/
void add_row(std::string name = "");
int add_column(std::string name, std::string id_name);
/**
* @brief idx的列插入一个空白行
* @brief idx的位置插入一个空白行idx大于等于行数则在表尾添加一行
*
* @param idx
* @param name
*
* @param idx 0
* @param name
* @return 1 -1
*/
void add_row(int idx, std::string name = "");
int add_row(std::string name = "", int idx = 9999);
/**
* @brief id_name的列插入一个空白行
* @brief id_name的行的位置插入一个空白行
*
* @param id_name
* @param name
*
* @return 1 -1
*/
void add_row(std::string id_name, std::string name = "");
int add_row(std::string name, std::string id_name);
/**
* @brief
*
* @note
*
* @param cnd_str
* @param cnd_col
* @param out_col
@ -828,6 +827,26 @@ namespace gctl
*/
void fill_column_point2dc(const array<point2dc> &data, std::string xname, std::string yname, int p = 6);
/**
* @brief
*
* @param rid rad坐标列索引 1
* @param cid arc坐标列索引 1
* @param data
* @param p
*/
void fill_column_point2dp(const array<point2dp> &data, int rid, int cid, int p = 6);
/**
* @brief
*
* @param rname rad坐标列名称
* @param cname arc坐标列名称
* @param data
* @param p
*/
void fill_column_point2dp(const array<point2dp> &data, std::string rname, std::string cname, int p = 6);
/**
* @brief
*
@ -890,6 +909,24 @@ namespace gctl
*/
void get_column_point2dc(array<point2dc> &data, std::string xname, std::string yname);
/**
* @brief
*
* @param rid rad坐标列索引 1
* @param cid arc坐标列索引 1
* @param data
*/
void get_column_point2dp(array<point2dp> &data, int rid, int cid);
/**
* @brief
*
* @param rname rad坐标列名称
* @param cname arc坐标列名称
* @param data
*/
void get_column_point2dp(array<point2dp> &data, std::string rname, std::string cname);
/**
* @brief
*

View File

@ -152,4 +152,15 @@ void gctl::gmshio::save_physical_groups(const array<gmsh_physical_group> &phy_gr
}
gmsh_out << "$EndPhysicalNames\n";
return;
}
int gctl::gmshio::physical_name2tag(const array<gmsh_physical_group> &phy_groups, std::string name)
{
for (size_t i = 0; i < phy_groups.size(); i++)
{
if (phy_groups[i].name == name) return phy_groups[i].phys_tag;
}
throw std::runtime_error("[gctl::gmshio::physical_name2tag] Physical group name not found.");
return -1;
}

View File

@ -61,9 +61,11 @@ namespace gctl
void read_physical_groups(array<gmsh_physical_group> &phy_groups);
void save_physical_groups(const array<gmsh_physical_group> &phy_groups);
int physical_name2tag(const array<gmsh_physical_group> &phy_groups, std::string name);
template <typename A> void read_node(array<vertex<point2dc, A>> &out_nodes);
template <typename A> void read_node(array<vertex<point3dc, A>> &out_nodes);
template <typename E, typename A> void read_element(array<type_edge2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
template <typename E, typename A> void read_element(array<type_triangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
template <typename E, typename A> void read_element(array<type_triangle2d2o<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
template <typename E, typename A> void read_element(array<type_rectangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
@ -150,6 +152,14 @@ namespace gctl
return;
}
template <typename E, typename A>
void gmshio::read_element(array<type_edge2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
{
initialized(Input);
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
return;
}
template <typename E, typename A>
void gmshio::read_element(array<type_triangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
{
@ -1134,6 +1144,105 @@ namespace gctl
return;
}
/**
* @brief Read element index from a Gmsh file.
*
* @param[in] infile The input file stream
* @param element The output element object array
* @param node The node array
* @param[in] packed Indicates whether the index in the node file starts from zero. The
* index is deemed to be started with one if this option is false. The default value of this
* variable is true.
* @param[in] ele_tag Return elements' tags by a 2D integer vector.
*
*/
template <typename E, typename A>
void read_gmsh_element(std::ifstream &infile, array<type_edge2d<E>> &element,
const array<vertex<point2dc, A>> &node, index_packed_e packed = Packed,
_2i_vector *ele_tag = nullptr)
{
if (node.empty())
throw runtime_error("The input array is empty. From gctl::read_gmsh_element(...)");
// 重置数据
if (!element.empty()) element.clear();
// 重置标签
if (ele_tag != nullptr && !ele_tag->empty()) ele_tag->clear();
// 将文件指针重置到文件头
infile.clear(std::ios::goodbit);
infile.seekg(std::ios::beg);
int i_size = 0, ele_count = 0;
int tmp_int, ele_type, attri_num;
int tmp_index[2];
std::string tmp_str;
std::stringstream tmp_ss;
while(getline(infile,tmp_str))
{
if (tmp_str == "$Elements") //读入模型空间顶点集 msh文件版本为2.2
{
getline(infile,tmp_str);
gctl::str2ss(tmp_str, tmp_ss);
tmp_ss >> i_size; //第一个数为顶点的个数
// 我们先用一个临时的向量来储存元素
edge2d tmp_edge;
std::vector<edge2d> element_vec;
std::vector<int> tmp_tag;
for (int i = 0; i < i_size; i++)
{
getline(infile,tmp_str);
str2ss(tmp_str, tmp_ss);
tmp_ss >> tmp_int >> ele_type >> attri_num;
if (ele_type == 1)
{
tmp_edge.id = ele_count;
tmp_tag.clear();
for (int a = 0; a < attri_num; a++)
{
tmp_ss >> tmp_int;
tmp_tag.push_back(tmp_int);
}
if (ele_tag != nullptr)
ele_tag->push_back(tmp_tag);
tmp_ss >> tmp_index[0] >> tmp_index[1];
if (packed == NotPacked)
{
for (int j = 0; j < 2; j++)
tmp_edge.vert[j] = node.get(tmp_index[j]-1);
}
else
{
for (int j = 0; j < 2; j++)
tmp_edge.vert[j] = node.get(tmp_index[j]);
}
element_vec.push_back(tmp_edge);
ele_count++;
}
}
//将元素转移到向量上来
element.resize(element_vec.size());
for (int i = 0; i < element.size(); i++)
{
element[i].id = element_vec[i].id;
for (int j = 0; j < 2; j++)
element[i].vert[j] = element_vec[i].vert[j];
}
destroy_vector(element_vec);
break;
}
}
return;
}
/**
* @brief Read element index from a Gmsh file.
*

View File

@ -27,43 +27,41 @@
#include "mesh_io.h"
gctl::mesh_element::mesh_element()
gctl::meshio_element::meshio_element()
{
enabled = false;
id = DEFAULT_INVALID_TAG;
type = NotSet;
}
gctl::mesh_data::mesh_data()
gctl::meshio_data::meshio_data()
{
enabled = false;
d_type = NodeData;
}
void gctl::mesh_data::clear()
void gctl::meshio_data::clear()
{
enabled = false;
str_tag.clear();
real_tag.clear();
int_tag.clear();
vert_ptrs.clear();
elem_ptrs.clear();
tar_ptrs.clear();
val.clear();
return;
}
bool gctl::mesh_data::pass_check()
bool gctl::meshio_data::pass_check()
{
// 检查是否同时连接了顶点和单元体
if (vert_ptrs.empty() && elem_ptrs.empty()) return false;
if (!vert_ptrs.empty() && !elem_ptrs.empty()) return false;
if (tar_ptrs.empty()) return false;
if (int_tag[2] != val.size()) return false;
if (tar_ptrs.size() != val.size()) return false;
if (str_tag.empty() || real_tag.empty() || int_tag.size() < 3) return false;
if (!vert_ptrs.empty() && (vert_ptrs.size() != val.size() || int_tag[2] != val.size())) return false;
if (!elem_ptrs.empty() && (elem_ptrs.size() != val.size() || int_tag[2] != val.size())) return false;
return true;
}
gctl::mesh_element_group::mesh_element_group()
gctl::meshio_element_group::meshio_element_group()
{
enabled = false;
type = NotSet;
@ -71,7 +69,7 @@ gctl::mesh_element_group::mesh_element_group()
phys_group = geom_group = part_group = DEFAULT_INVALID_TAG;
}
void gctl::mesh_element_group::enable_elements()
void gctl::meshio_element_group::enable_elements()
{
for (size_t e = 0; e < elem_ptrs.size(); e++)
{
@ -80,7 +78,7 @@ void gctl::mesh_element_group::enable_elements()
return;
}
void gctl::mesh_element_group::disable_elements()
void gctl::meshio_element_group::disable_elements()
{
for (size_t e = 0; e < elem_ptrs.size(); e++)
{
@ -319,7 +317,7 @@ void gctl::mesh_io::info(std::ostream &ss)
ss << "nodedata: \"";
for (size_t l = 0; l < datas_[d].val.size(); l++)
{
if (datas_[d].vert_ptrs[l]->id != DEFAULT_INVALID_TAG)
if (reinterpret_cast<vertex3dc*>(datas_[d].tar_ptrs[l])->id != DEFAULT_INVALID_TAG)
{
min = std::min(min, datas_[d].val[l]);
max = std::max(max, datas_[d].val[l]);
@ -332,7 +330,7 @@ void gctl::mesh_io::info(std::ostream &ss)
ss << "elementdata: \"";
for (size_t l = 0; l < datas_[d].val.size(); l++)
{
if (datas_[d].elem_ptrs[l]->enabled)
if (reinterpret_cast<meshio_element*>(datas_[d].tar_ptrs[l])->enabled)
{
min = std::min(min, datas_[d].val[l]);
max = std::max(max, datas_[d].val[l]);
@ -481,12 +479,23 @@ const gctl::array<int> &gctl::mesh_io::get_node_tag()
return nodes_tag_;
}
int gctl::mesh_io::get_tag(element_tag_enum anchor_type, std::string anchor_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;
}
return DEFAULT_INVALID_TAG;
}
const gctl::array<gctl::vertex3dc> &gctl::mesh_io::get_nodes()
{
return nodes_;
}
const gctl::array<gctl::mesh_element> &gctl::mesh_io::get_elems()
const gctl::array<gctl::meshio_element> &gctl::mesh_io::get_elems()
{
return elems_;
}
@ -535,7 +544,7 @@ size_t gctl::mesh_io::element_size(std::string phys_name)
void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
{
mesh_data tmp_data;
meshio_data tmp_data;
if (tag_type == NodeTag && (!nodes_tag_.empty()))
{
tmp_data.enabled = true;
@ -547,7 +556,7 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
tmp_data.int_tag[2] = valid_node_size_;
tmp_data.val.resize(valid_node_size_);
tmp_data.vert_ptrs.resize(valid_node_size_);
tmp_data.tar_ptrs.resize(valid_node_size_);
size_t c = 0;
for (size_t i = 0; i < nodes_.size(); i++)
@ -555,7 +564,7 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
if (nodes_[i].id != DEFAULT_INVALID_TAG)
{
tmp_data.val[c] = (double) nodes_tag_[i];
tmp_data.vert_ptrs[c] = nodes_.get(i);
tmp_data.tar_ptrs[c] = nodes_.get(i);
c++;
}
}
@ -564,13 +573,12 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
}
else
{
int t = 0;
tmp_data.enabled = true;
tmp_data.d_type = ElemData;
if (tag_type == PhysicalTag) {tmp_data.str_tag.resize(1, "Physical Tag"); t = 0;}
else if (tag_type == GeometryTag) {tmp_data.str_tag.resize(1, "Geometry Tag"); t = 1;}
else if (tag_type == PartitionTag) {tmp_data.str_tag.resize(1, "Partition Tag"); t = 2;}
if (tag_type == PhysicalTag) tmp_data.str_tag.resize(1, "Physical Tag");
else if (tag_type == GeometryTag) tmp_data.str_tag.resize(1, "Geometry Tag");
else if (tag_type == PartitionTag) tmp_data.str_tag.resize(1, "Partition Tag");
tmp_data.real_tag.resize(1, 0.0);
tmp_data.int_tag.resize(3, 0);
@ -578,7 +586,7 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
tmp_data.int_tag[2] = valid_elem_size_;
tmp_data.val.resize(valid_elem_size_);
tmp_data.elem_ptrs.resize(valid_elem_size_);
tmp_data.tar_ptrs.resize(valid_elem_size_);
size_t c = 0;
for (size_t g = 0; g < groups_.size(); g++)
@ -590,7 +598,7 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
if (tag_type == PhysicalTag) tmp_data.val[c] = (double) groups_[g].phys_group;
if (tag_type == GeometryTag) tmp_data.val[c] = (double) groups_[g].geom_group;
if (tag_type == PartitionTag) tmp_data.val[c] = (double) groups_[g].part_group;
tmp_data.elem_ptrs[c] = groups_[g].elem_ptrs[e];
tmp_data.tar_ptrs[c] = groups_[g].elem_ptrs[e];
c++;
}
}
@ -686,7 +694,7 @@ void gctl::mesh_io::export_elements_to(array<tetrahedron> &tets, std::string phy
tets.resize(s);
s = 0;
for (size_t i = 0; i < elems_.size(); i++)
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"))
@ -722,7 +730,7 @@ void gctl::mesh_io::export_elements_to(array<tetrahedron> &tets, element_tag_enu
tets.resize(s);
s = 0;
for (size_t i = 0; i < elems_.size(); i++)
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) ||
@ -743,35 +751,156 @@ void gctl::mesh_io::export_elements_to(array<tetrahedron> &tets, element_tag_enu
return;
}
void gctl::mesh_io::create_node_data(const array<double> &data, std::string name)
void gctl::mesh_io::get_gmsh_physical_groups(std::vector<gmsh_physical_group> &g_groups)
{
mesh_data new_data;
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++)
{
if (datas_[i].str_tag.front() == name &&
datas_[i].d_type == type) return i;
}
return -1;
}
gctl::meshio_data &gctl::mesh_io::get_data(std::string name, mesh_data_type_e type)
{
int id = if_saved_data(name, type);
if (id == -1) throw std::runtime_error("[gctl::mesh_io::get_data] Data not found.");
return datas_[id];
}
gctl::meshio_data *gctl::mesh_io::get_data_ptr(std::string name, mesh_data_type_e type)
{
int id = if_saved_data(name, type);
if (id == -1) throw std::runtime_error("[gctl::mesh_io::get_data] Data not found.");
return &datas_[id];
}
void gctl::mesh_io::add_node_data(std::string name, const array<double> &data)
{
size_t s = nodes_.size();
if (data.size()!= s) throw std::runtime_error("[gctl::mesh_io::create_node_data] Incompatible data size.");
int d_id = if_saved_data(name, NodeData);
if (d_id != -1)
{
for (size_t i = 0; i < s; 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);
size_t c = 0;
for (size_t i = 0; i < nodes_.size(); i++)
for (size_t i = 0; i < s; i++)
{
if (nodes_[i].id != DEFAULT_INVALID_TAG) c++;
new_data.tar_ptrs[i] = nodes_.get(i);
new_data.val[i] = data[i];
}
if (data.size() != c) throw std::runtime_error("[gctl::mesh_io::create_node_data] Incompatible data size.");
new_data.int_tag[2] = c;
new_data.vert_ptrs.resize(c, nullptr);
new_data.val.resize(c);
datas_.push_back(new_data);
return;
}
c = 0;
void gctl::mesh_io::add_node_data(std::string name, const array<double> &data, const array<bool> &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 (nodes_[i].id != DEFAULT_INVALID_TAG)
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++)
{
new_data.vert_ptrs[c] = nodes_.get(i);
new_data.val[c] = data[c];
c++;
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++;
}
}
@ -779,15 +908,8 @@ void gctl::mesh_io::create_node_data(const array<double> &data, std::string name
return;
}
void gctl::mesh_io::create_element_data(const array<double> &data, std::string name, element_type_enum e_type)
void gctl::mesh_io::add_element_data(std::string name, const array<double> &data, element_type_enum e_type)
{
mesh_data new_data;
new_data.enabled = true;
new_data.d_type = ElemData;
new_data.str_tag.resize(1, name);
new_data.int_tag.resize(3, 0);
new_data.int_tag[1] = 1;
size_t e = 0;
for (size_t i = 0; i < groups_.size(); i++)
{
@ -796,8 +918,38 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
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++)
{
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.elem_ptrs.resize(e, nullptr);
new_data.tar_ptrs.resize(e, nullptr);
new_data.val.resize(e, 0.0);
e = 0;
@ -807,7 +959,7 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
{
for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++)
{
new_data.elem_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.val[e] = data[e];
e++;
}
@ -818,15 +970,8 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
return;
}
void gctl::mesh_io::create_element_data(const array<double> &data, std::string name, element_tag_enum tag_type, int tag)
void gctl::mesh_io::add_element_data(std::string name, const array<double> &data, element_tag_enum tag_type, int tag)
{
mesh_data new_data;
new_data.enabled = true;
new_data.d_type = ElemData;
new_data.str_tag.resize(1, name);
new_data.int_tag.resize(3, 0);
new_data.int_tag[1] = 1;
size_t e = 0;
for (size_t i = 0; i < groups_.size(); i++)
{
@ -841,8 +986,44 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
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<void*> more_elem_ptrs(e, nullptr);
array<double> more_val(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++)
{
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.elem_ptrs.resize(e, nullptr);
new_data.tar_ptrs.resize(e, nullptr);
new_data.val.resize(e, 0.0);
e = 0;
@ -855,7 +1036,7 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
{
for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++)
{
new_data.elem_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.val[e] = data[e];
e++;
}
@ -866,15 +1047,8 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
return;
}
void gctl::mesh_io::create_element_data(const array<double> &data, std::string name, std::string phys_name)
void gctl::mesh_io::add_element_data(std::string name, std::string phys_name, const array<double> &data)
{
mesh_data new_data;
new_data.enabled = true;
new_data.d_type = ElemData;
new_data.str_tag.resize(1, name);
new_data.int_tag.resize(3, 0);
new_data.int_tag[1] = 1;
size_t e = 0;
for (size_t i = 0; i < groups_.size(); i++)
{
@ -886,18 +1060,51 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
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<void*> more_elem_ptrs(e, nullptr);
array<double> 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.elem_ptrs.resize(e, nullptr);
new_data.tar_ptrs.resize(e, nullptr);
new_data.val.resize(e, 0.0);
e = 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.elem_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.tar_ptrs[e] = groups_[i].elem_ptrs[j];
new_data.val[e] = data[e];
e++;
}
@ -908,6 +1115,72 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
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<void*> more_elem_ptrs(e, nullptr);
array<double> 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;
}
void gctl::mesh_io::read_triangle_ascii(std::string filename, index_packed_e is_packed)
{
if (initialized_ == true)
@ -963,7 +1236,7 @@ void gctl::mesh_io::read_triangle_ascii(std::string filename, index_packed_e is_
}
// 整理单元体组
mesh_element_group tmp_group;
meshio_element_group tmp_group;
tmp_group.type = elems_[0].type;
tmp_group.phys_group = int_tag[0][0];
tmp_group.geom_group = int_tag[0][1];
@ -1112,7 +1385,7 @@ void gctl::mesh_io::read_tetgen_ascii(std::string filename, index_packed_e is_pa
}
// 整理单元体组
mesh_element_group tmp_group;
meshio_element_group tmp_group;
tmp_group.type = elems_[0].type;
tmp_group.phys_group = int_tag[0][0];
tmp_group.geom_group = int_tag[0][1];
@ -1205,7 +1478,7 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
size_t p_size = 0;
size_t n_size = 0;
array<gmsh_physical_group> phys;
while(getline(infile,tmp_str))
{
if (tmp_str == "$PhysicalNames")
@ -1246,7 +1519,7 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
// 读入模型空间元素集
int i_size, type_code, attri_num, vt_idx;
array<array<int> > int_tag;
array<array<int> > file_itag;
while(getline(infile,tmp_str))
{
if (tmp_str == "$Elements")
@ -1257,39 +1530,26 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
valid_elem_size_ = i_size;
elems_.resize(i_size);
int_tag.resize(valid_elem_size_);
file_itag.resize(valid_elem_size_);
for (size_t i = 0; i < i_size; i++)
{
getline(infile,tmp_str);
str2ss(tmp_str, tmp_ss);
tmp_ss >> elems_[i].id >> type_code >> attri_num;
if (is_packed == NotPacked) elems_[i].id -= 1;
elems_[i].type = elem_gmsh_type(type_code);
elems_[i].vert_ptrs.resize(elem_size(elems_[i].type));
// 这里暂时不考虑单元体的邻居关系 相关功能不应该由IO类型实现
//elems_[i].neigh_ptrs.resize(elem_size(elems_[i].type), nullptr);
if (attri_num >= 3) // default tags will be assgined to DEFAULT_INVALID_TAG
// we get at least three tags. see below for tag types
// default tags will be assgined to DEFAULT_INVALID_TAG
file_itag[i].resize(GCTL_MAX(3, attri_num), DEFAULT_INVALID_TAG);
for (size_t a = 0; a < attri_num; a++)
{
int_tag[i].resize(attri_num);
for (size_t a = 0; a < attri_num; a++)
{
tmp_ss >> int_tag[i][a];
}
}
else if (attri_num == 2)
{
int_tag[i].resize(3, DEFAULT_INVALID_TAG);
tmp_ss >> int_tag[i][0];
tmp_ss >> int_tag[i][1];
}
else if (attri_num == 1)
{
int_tag[i].resize(3, DEFAULT_INVALID_TAG);
tmp_ss >> int_tag[i][0];
}
else
{
int_tag[i].resize(3, DEFAULT_INVALID_TAG);
tmp_ss >> file_itag[i][a];
}
for (size_t v = 0; v < elems_[i].vert_ptrs.size(); v++)
@ -1304,7 +1564,7 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
}
// 读入数据模块
mesh_data tmp_data;
meshio_data tmp_data;
while(getline(infile,tmp_str))
{
if (!infile.good()) break;
@ -1352,28 +1612,28 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
if (tmp_data.d_type == NodeData)
{
tmp_data.vert_ptrs.resize(tmp_data.int_tag.back());
tmp_data.tar_ptrs.resize(tmp_data.int_tag.back());
tmp_data.val.resize(tmp_data.int_tag.back());
for (size_t i = 0; i < tmp_data.val.size(); i++)
{
getline(infile,tmp_str);
str2ss(tmp_str, tmp_ss);
tmp_ss >> vt_idx >> tmp_data.val[i];
if (is_packed == Packed) tmp_data.vert_ptrs[i] = nodes_.get(vt_idx);
else tmp_data.vert_ptrs[i] = nodes_.get(vt_idx - 1);
if (is_packed == Packed) tmp_data.tar_ptrs[i] = nodes_.get(vt_idx);
else tmp_data.tar_ptrs[i] = nodes_.get(vt_idx - 1);
}
}
else
{
tmp_data.elem_ptrs.resize(tmp_data.int_tag.back());
tmp_data.tar_ptrs.resize(tmp_data.int_tag.back());
tmp_data.val.resize(tmp_data.int_tag.back());
for (size_t i = 0; i < tmp_data.val.size(); i++)
{
getline(infile,tmp_str);
str2ss(tmp_str, tmp_ss);
tmp_ss >> vt_idx >> tmp_data.val[i];
if (is_packed == Packed) tmp_data.elem_ptrs[i] = elems_.get(vt_idx);
else tmp_data.elem_ptrs[i] = elems_.get(vt_idx - 1);
if (is_packed == Packed) tmp_data.tar_ptrs[i] = elems_.get(vt_idx);
else tmp_data.tar_ptrs[i] = elems_.get(vt_idx - 1);
}
}
@ -1384,14 +1644,15 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
infile.close();
// 整理单元体组
mesh_element_group tmp_group;
meshio_element_group tmp_group;
tmp_group.type = elems_[0].type;
tmp_group.phys_group = int_tag[0][0];
tmp_group.geom_group = int_tag[0][1];
tmp_group.part_group = int_tag[0][2];
tmp_group.phys_group = file_itag[0][0];
tmp_group.geom_group = file_itag[0][1];
tmp_group.part_group = file_itag[0][2];
tmp_group.elem_ptrs.push_back(elems_.get(0));
groups_.push_back(tmp_group);
// 元素类型与三个标记都一致的元素将被分到同一组
bool not_found;
for (size_t i = 1; i < elems_.size(); i++)
{
@ -1399,9 +1660,9 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
for (size_t g = 0; g < groups_.size(); g++)
{
if (groups_[g].type == elems_[i].type &&
groups_[g].phys_group == int_tag[i][0] &&
groups_[g].geom_group == int_tag[i][1] &&
groups_[g].part_group == int_tag[i][2])
groups_[g].phys_group == file_itag[i][0] &&
groups_[g].geom_group == file_itag[i][1] &&
groups_[g].part_group == file_itag[i][2])
{
groups_[g].elem_ptrs.push_back(elems_.get(i));
not_found = false;
@ -1413,9 +1674,9 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
{
tmp_group.elem_ptrs.clear();
tmp_group.type = elems_[i].type;
tmp_group.phys_group = int_tag[i][0];
tmp_group.geom_group = int_tag[i][1];
tmp_group.part_group = int_tag[i][2];
tmp_group.phys_group = file_itag[i][0]; // 物理组
tmp_group.geom_group = file_itag[i][1]; // 几何组
tmp_group.part_group = file_itag[i][2]; // 剖分组(一般以元素的维度区分)
tmp_group.elem_ptrs.push_back(elems_.get(i));
groups_.push_back(tmp_group);
}
@ -1423,6 +1684,7 @@ void gctl::mesh_io::read_gmsh_v2_ascii(std::string filename, index_packed_e is_p
if (!phys.empty())
{
// 遍历所有元素组 按物理组为标准为元素组命名 并以将元素维度赋值为剖分组
for (size_t g = 0; g < groups_.size(); g++)
{
for (size_t p = 0; p < phys.size(); p++)
@ -1460,11 +1722,14 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p
outfile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
outfile << "$PhysicalNames\n" << valid_group_size_ << "\n";
for (size_t i = 0; i < groups_.size(); i++)
std::vector<gmsh_physical_group> gmsh_groups;
get_gmsh_physical_groups(gmsh_groups);
outfile << "$PhysicalNames\n" << gmsh_groups.size() << "\n";
for (size_t i = 0; i < gmsh_groups.size(); i++)
{
if (groups_[i].enabled && groups_[i].phys_group != DEFAULT_INVALID_TAG) outfile << groups_[i].part_group << " " << groups_[i].phys_group << " \"" << groups_[i].name << "\"\n";
else if (groups_[i].enabled) outfile << groups_[i].part_group << " 0 \"" << groups_[i].name << "\"\n";
if (gmsh_groups[i].phys_tag != DEFAULT_INVALID_TAG) outfile << gmsh_groups[i].dim_tag << " " << gmsh_groups[i].phys_tag << " \"" << gmsh_groups[i].name << "\"\n";
else outfile << gmsh_groups[i].dim_tag << " 0 \"" << gmsh_groups[i].name << "\"\n";
}
outfile << "$EndPhysicalNames\n";
@ -1526,7 +1791,7 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p
d_size = 0;
for (size_t n = 0; n < datas_[i].val.size(); n++)
{
if (datas_[i].vert_ptrs[n]->id != DEFAULT_INVALID_TAG) d_size++;
if (reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[n])->id != DEFAULT_INVALID_TAG) d_size++;
}
if (d_size)
@ -1551,10 +1816,12 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p
}
outfile << d_size << "\n";
int tmp_id;
for (size_t a = 0; a < datas_[i].val.size(); a++)
{
if (datas_[i].vert_ptrs[a]->id != DEFAULT_INVALID_TAG && is_packed == Packed) outfile << datas_[i].vert_ptrs[a]->id << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
else if (datas_[i].vert_ptrs[a]->id != DEFAULT_INVALID_TAG) outfile << datas_[i].vert_ptrs[a]->id + 1 << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
tmp_id = reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[a])->id;
if (tmp_id != DEFAULT_INVALID_TAG && is_packed == Packed) outfile << tmp_id << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
else if (tmp_id != DEFAULT_INVALID_TAG) outfile << tmp_id + 1 << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
}
outfile << "$EndNodeData\n";
}
@ -1564,7 +1831,7 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p
d_size = 0;
for (size_t n = 0; n < datas_[i].val.size(); n++)
{
if (datas_[i].elem_ptrs[n]->enabled) d_size++;
if (reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[n])->enabled) d_size++;
}
if (d_size)
@ -1589,10 +1856,14 @@ void gctl::mesh_io::save_gmsh_v2_ascii(std::string filename, index_packed_e is_p
}
outfile << d_size << "\n";
int tmp_id;
bool d_ok;
for (size_t a = 0; a < datas_[i].val.size(); a++)
{
if (datas_[i].elem_ptrs[a]->enabled && is_packed == Packed) outfile << datas_[i].elem_ptrs[a]->id << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
else if (datas_[i].elem_ptrs[a]->enabled) outfile << datas_[i].elem_ptrs[a]->id + 1 << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
tmp_id = reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[a])->id;
d_ok = reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[a])->enabled;
if (d_ok && is_packed == Packed) outfile << tmp_id << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
else if (d_ok) outfile << tmp_id + 1 << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
}
outfile << "$EndElementData\n";
}
@ -1662,7 +1933,7 @@ void gctl::mesh_io::save_vtk_legacy_ascii(std::string filename)
d_size = 0;
for (size_t n = 0; n < datas_[i].val.size(); n++)
{
if (datas_[i].vert_ptrs[n]->id != DEFAULT_INVALID_TAG) d_size++;
if (reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[n])->id != DEFAULT_INVALID_TAG) d_size++;
}
if (d_size && d_size == valid_node_size_)
@ -1674,7 +1945,7 @@ void gctl::mesh_io::save_vtk_legacy_ascii(std::string filename)
for (size_t a = 0; a < datas_[i].val.size(); a++)
{
if (datas_[i].vert_ptrs[a]->id != DEFAULT_INVALID_TAG) outfile << std::setprecision(16) << datas_[i].val[a] << "\n";
if (reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[a])->id != DEFAULT_INVALID_TAG) outfile << std::setprecision(16) << datas_[i].val[a] << "\n";
}
}
}
@ -1683,7 +1954,7 @@ void gctl::mesh_io::save_vtk_legacy_ascii(std::string filename)
d_size = 0;
for (size_t n = 0; n < datas_[i].val.size(); n++)
{
if (datas_[i].elem_ptrs[n]->enabled) d_size++;
if (reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[n])->enabled) d_size++;
}
if (d_size && d_size == valid_elem_size_)
@ -1695,7 +1966,7 @@ void gctl::mesh_io::save_vtk_legacy_ascii(std::string filename)
for (size_t a = 0; a < datas_[i].val.size(); a++)
{
if (datas_[i].elem_ptrs[a]->enabled) outfile << std::setprecision(16) << datas_[i].val[a] << "\n";
if (reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[a])->enabled) outfile << std::setprecision(16) << datas_[i].val[a] << "\n";
}
}
}
@ -1724,13 +1995,14 @@ void gctl::mesh_io::save_data_to_xyz(std::string filename, std::string dataname,
if (datas_[i].d_type == NodeData)
{
for (size_t n = 0; n < datas_[i].vert_ptrs.size(); n++)
for (size_t n = 0; n < datas_[i].tar_ptrs.size(); n++)
{
if (datas_[i].vert_ptrs[n]->id != DEFAULT_INVALID_TAG)
vertex3dc* vptr = reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[n]);
if (vptr->id != DEFAULT_INVALID_TAG)
{
if (out_coor == Spherical)
{
ps = datas_[i].vert_ptrs[n]->c2s();
ps = vptr->c2s();
ps.rad -= ellipse_radius_2d(refR, refr, ps.lat*M_PI/180.0);
ofile << ps.lon << " " << ps.lat << " " << ps.rad << " " << datas_[i].val[n] << "\n";
@ -1742,17 +2014,18 @@ void gctl::mesh_io::save_data_to_xyz(std::string filename, std::string dataname,
}
else
{
for (size_t e = 0; e < datas_[i].elem_ptrs.size(); e++)
for (size_t e = 0; e < datas_[i].tar_ptrs.size(); e++)
{
if (datas_[i].elem_ptrs[e]->enabled)
meshio_element* mptr = reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[e]);
if (mptr->enabled)
{
pc = point3dc(0.0, 0.0, 0.0);
tmp_size = datas_[i].elem_ptrs[e]->vert_ptrs.size();
for (size_t v = 0; v < datas_[i].elem_ptrs[e]->vert_ptrs.size(); v++)
tmp_size = mptr->vert_ptrs.size();
for (size_t v = 0; v < mptr->vert_ptrs.size(); v++)
{
pc.x += datas_[i].elem_ptrs[e]->vert_ptrs[v]->x;
pc.y += datas_[i].elem_ptrs[e]->vert_ptrs[v]->y;
pc.z += datas_[i].elem_ptrs[e]->vert_ptrs[v]->z;
pc.x += mptr->vert_ptrs[v]->x;
pc.y += mptr->vert_ptrs[v]->y;
pc.z += mptr->vert_ptrs[v]->z;
}
pc.x /= tmp_size;
pc.y /= tmp_size;
@ -1850,7 +2123,7 @@ void gctl::mesh_io::update_indexing()
void gctl::mesh_io::sort_groups()
{
// 拷贝到临时组
std::vector<mesh_element_group> tmp_groups = groups_;
std::vector<meshio_element_group> tmp_groups = groups_;
// 清空对象
for (size_t i = 0; i < groups_.size(); i++)
@ -1861,7 +2134,7 @@ void gctl::mesh_io::sort_groups()
// 整理单元体组
bool not_found;
mesh_element_group tmp_group;
meshio_element_group tmp_group;
for (size_t i = 0; i < tmp_groups.size(); i++)
{
tmp_group = tmp_groups[i];
@ -1898,5 +2171,7 @@ void gctl::mesh_io::sort_groups()
{
if (groups_[i].enabled) valid_group_size_++;
}
destroy_vector(tmp_groups);
return;
}

View File

@ -93,43 +93,42 @@ namespace gctl
*/
enum element_tag_enum
{
PhysicalTag,
GeometryTag,
PartitionTag,
NodeTag,
PhysicalTag, // 元素的物理分组标签
GeometryTag, // 元素的几何分组标签
PartitionTag, // 元素的剖分分组标签
NodeTag, // 顶点的标签(仅用于输出顶点标签数据)
};
/**
* @brief
*
*/
struct mesh_element
struct meshio_element
{
bool enabled;
int id;
element_type_enum type;
array<vertex3dc*> vert_ptrs;
array<mesh_element*> neigh_ptrs;
bool enabled; // 单元体是否有效
int id; // 单元体编号
element_type_enum type; // 单元体类型
array<vertex3dc*> vert_ptrs; // 顶点指针数组
array<meshio_element*> neigh_ptrs; // 相邻单元体指针数组
mesh_element();
meshio_element();
};
/**
* @brief
*
*/
struct mesh_data
struct meshio_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;
bool enabled; // 数据体是否有效
mesh_data_type_e d_type; // 数据类型
array<std::string> str_tag; // 字符串类型的标签(默认为一个,即为数据的名称)
array<double> real_tag; // 实数类型的标签默认为一个等于0.0
array<int> int_tag; // 整数类型的标签(最少三个,最后一个为数据的长度)
array<void*> tar_ptrs; // 数据连接的对象指针数组 具体类型为vertex3dc*或meshio_element*
array<double> val; // 数据值(目前仅支持标量数据,后续再添加对矢量数据的支持)
mesh_data();
meshio_data();
/**
* @brief
@ -148,17 +147,17 @@ namespace gctl
* @brief
*
*/
struct mesh_element_group
struct meshio_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;
bool enabled; // 组是否有效
element_type_enum type; // 组内单元体类型
int phys_group; // 物理分组标签
int geom_group; // 几何分组标签
int part_group; // 剖分分组标签
std::string name; // 组名
std::vector<meshio_element*> elem_ptrs; // 组内单元体指针数组
mesh_element_group();
meshio_element_group();
/**
* @brief
@ -256,21 +255,30 @@ namespace gctl
const array<int> &get_node_tag();
/**
* @brief
* @brief
*
* @param anchor_type PhysicalTagGeometryTag或者PartitionTag
* @param anchor_name
* @return
*/
int get_tag(element_tag_enum anchor_type, std::string anchor_name);
/**
* @brief
*
* @return
*/
const array<vertex3dc> &get_nodes();
/**
* @brief
* @brief
*
* @return
*/
const array<mesh_element> &get_elems();
const array<meshio_element> &get_elems();
/**
* @brief
* @brief
*
* @param e_type NotSet
* @return
@ -278,7 +286,7 @@ namespace gctl
size_t element_size(element_type_enum e_type = NotSet);
/**
* @brief
* @brief
*
* @param tag_type
* @param tag
@ -287,7 +295,7 @@ namespace gctl
size_t element_size(element_tag_enum tag_type, int tag);
/**
* @brief
* @brief
*
* @param phys_name
* @return
@ -336,40 +344,105 @@ namespace gctl
void export_elements_to(array<tetrahedron> &tets, element_tag_enum tag_type, int tag);
/**
* @brief
* @brief gmsh格式分组表
*
* @param data
* @param name
* @param g_groups gmsh格式表
*/
void create_node_data(const array<double> &data, std::string name);
void get_gmsh_physical_groups(std::vector<gmsh_physical_group> &g_groups);
/**
* @brief
* @brief name的数据
*
* @param name
* @param type
*
* @return -1
*/
int if_saved_data(std::string name, mesh_data_type_e type);
/**
* @brief
*
* @param name
* @param type
* @return
*/
meshio_data &get_data(std::string name, mesh_data_type_e type);
/**
* @brief
*
* @param name
* @param type
* @return
*/
meshio_data *get_data_ptr(std::string name, mesh_data_type_e type);
/**
* @brief
*
* @note
*
* @param data
* @param name
*/
void add_node_data(std::string name, const array<double> &data);
/**
* @brief
*
* @note
*
* @param data
* @param boolen
* @param name
*/
void add_node_data(std::string name, const array<double> &data, const array<bool> &boolen);
/**
* @brief
*
* @note
*
* @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);
void add_element_data(std::string name, const array<double> &data, element_type_enum e_type = NotSet);
/**
* @brief
*
* @note
*
* @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);
void add_element_data(std::string name, const array<double> &data, element_tag_enum tag_type, int tag);
/**
* @brief
*
* @note
*
* @param data
* @param name
* @param phys_name
*/
void create_element_data(const array<double> &data, std::string name, std::string phys_name);
void add_element_data(std::string name, std::string phys_name, const array<double> &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);
/**
* @brief triangle软件输出的网格剖分文件
@ -421,31 +494,32 @@ namespace gctl
*/
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_;
protected:
bool initialized_; // 类型是否已经初始化完成
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_;
// 有效的顶点、单元体和单元体组的数量
size_t valid_node_size_, valid_elem_size_, valid_group_size_;
array<vertex3dc> nodes_; // 网格顶点 当顶点索引为无效值时将不会被输出
array<meshio_element> elems_; // 网格元素
std::vector<meshio_data> datas_; // 网格数据
std::vector<meshio_element_group> groups_; // 网格单元体组
array<int> nodes_tag_; // 顶点标签
element_type_enum elem_gmshcode2type_[94]; // gmsh的单元体类型数组 数组索引为gmsh的单元体类型码值
element_type_enum elem_vtkcode2type_[14]; // vtk的单元体类型数组 数组索引为vtk的单元体类型码值
std::map<element_type_enum, int> elem_type2gmshcode_; // 单元体类型到gmsh类型码值的映射
std::map<element_type_enum, int> elem_type2vtkcode_; // 单元体类型到vtk类型码值的映射
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();
std::string elem_name(element_type_enum e_type); // 获取单元体名称字符串
int elem_gmsh_code(element_type_enum e_type); // 获取单元体gmsh类型码值
int elem_vtk_code(element_type_enum e_type); // 获取单元体vtk类型码值
int elem_size(element_type_enum e_type); // 获取单元体顶点数量
element_type_enum elem_gmsh_type(int code); // 获取对应gmsh类型码的单元体类型
element_type_enum elem_vtk_type(int code); // 获取对应vtk类型码的单元体类型
void update_indexing(); // 更新索引(对网格的元素进行操作后需调用)
void sort_groups(); // 对单元体组进行梳理(对网格的元素进行操作后需调用)
};
}

View File

@ -48,6 +48,12 @@ namespace gctl
return deg*GCTL_Pi/180.0;
}
template <typename T>
inline T deg(T arc)
{
return arc*180.0/GCTL_Pi;
}
template <typename T>
inline T sind(T deg)
{