dev_yi #3
BIN
GCTL_logo.jpg
Normal file
BIN
GCTL_logo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
265
README.md
265
README.md
@ -1,42 +1,249 @@
|
||||

|
||||
|
||||
# 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
|
||||
|
||||
## 致谢
|
||||
|
||||
感谢以下机构和个人的支持:
|
||||
- 浙江大学地球科学学院
|
||||
- 国家自然科学基金委员会
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -34,27 +34,34 @@ 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)
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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)
|
||||
{
|
||||
table_cell empty_cell;
|
||||
for (size_t i = 0; i < table_.size(); i++)
|
||||
{
|
||||
table_[i].push_back(empty_cell);
|
||||
}
|
||||
if (idx <= 0) throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
|
||||
|
||||
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
|
||||
|
109
lib/io/dsv_io.h
109
lib/io/dsv_io.h
@ -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. 文件内可以包含n(默认为0)行不以注释或标记符开始头信息行,保存为头信息变量内,可由用户提取;
|
||||
* 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 设置行类型
|
||||
@ -404,54 +407,50 @@ namespace gctl
|
||||
void row_output(std::string name, switch_type_e s = Disable);
|
||||
|
||||
/**
|
||||
* @brief 在表格末尾添加一个空白列
|
||||
* @brief 在索引为idx的位置插入一个空白列,剩余列后移一位。如果idx大于列数则在表尾添加一列。
|
||||
*
|
||||
* @param idx 列索引
|
||||
* @param name 设置列名称
|
||||
*
|
||||
* @return 索引 返回的索引(大于等于1 小于等于行数或列数)失败则返回-1
|
||||
*/
|
||||
void add_column(std::string name = "");
|
||||
int add_column(std::string name = "", int idx = 9999);
|
||||
|
||||
/**
|
||||
* @brief 在索引为idx的列插入一个空白列
|
||||
*
|
||||
* @param idx 列索引 小于等于0时将在表尾添加一列
|
||||
* @param name 设置列名称
|
||||
*/
|
||||
void add_column(int idx, std::string name = "");
|
||||
|
||||
/**
|
||||
* @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 行索引 小于等于0时将在表尾添加一行
|
||||
* @param idx 行索引
|
||||
* @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 读取三维坐标列
|
||||
*
|
||||
|
@ -153,3 +153,14 @@ 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;
|
||||
}
|
109
lib/io/gmsh_io.h
109
lib/io/gmsh_io.h
@ -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.
|
||||
*
|
||||
|
@ -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.");
|
||||
datas_.push_back(new_data);
|
||||
return;
|
||||
}
|
||||
|
||||
new_data.int_tag[2] = c;
|
||||
new_data.vert_ptrs.resize(c, nullptr);
|
||||
new_data.val.resize(c);
|
||||
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.");
|
||||
|
||||
c = 0;
|
||||
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];
|
||||
@ -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;
|
||||
}
|
204
lib/io/mesh_io.h
204
lib/io/mesh_io.h
@ -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 查找的标签类型(PhysicalTag,GeometryTag或者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_;
|
||||
protected:
|
||||
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_;
|
||||
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];
|
||||
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_;
|
||||
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(); // 对单元体组进行梳理(对网格的元素进行操作后需调用)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user