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)
|
# 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;
|
### 1. 核心库 (gctl)
|
||||||
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;
|
- **核心数据结构** (`core/`)
|
||||||
3. **GCTL_WAVELIB**: Use the WaveLIB for preforming the wavelet processes. The default is ON;
|
- 动态数组 (`array.h`, `array_enhanced.h`)
|
||||||
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.
|
- 矩阵操作 (`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`)
|
||||||
|
- 快速傅里叶变换
|
||||||
|
- 频谱分析
|
||||||
|
- 滤波器
|
||||||
|
|
||||||
```
|
- **几何处理** (`geometry/`)
|
||||||
./installer configure && ./installer build && ./installer install
|
- 基础几何 (`basic.h`)
|
||||||
```
|
- 点线面运算
|
||||||
|
- 几何变换
|
||||||
|
- 相交检测
|
||||||
|
- 网格处理 (`mesh.h`)
|
||||||
|
- 网格生成
|
||||||
|
- 网格优化
|
||||||
|
- 质量评估
|
||||||
|
- 形状函数 (`shape.h`)
|
||||||
|
- 几何形状描述
|
||||||
|
- 参数化曲面
|
||||||
|
- 边界表示
|
||||||
|
|
||||||
For more information of the 'installer', use:
|
- **工具函数** (`utility/`)
|
||||||
|
- 通用工具 (`common.h`)
|
||||||
|
- 字符串处理
|
||||||
|
- 时间日期
|
||||||
|
- 日志系统
|
||||||
|
- 算法实现 (`algorithm.h`)
|
||||||
|
- 排序算法
|
||||||
|
- 搜索算法
|
||||||
|
- 图算法
|
||||||
|
|
||||||
```
|
### 2. 扩展库
|
||||||
./installer help
|
- **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(legendre_ex OFF)
|
||||||
add_example(refellipsoid_ex OFF)
|
add_example(refellipsoid_ex OFF)
|
||||||
add_example(kde_ex OFF)
|
add_example(kde_ex OFF)
|
||||||
add_example(meshio_ex OFF)
|
add_example(meshio_ex ON)
|
||||||
add_example(autodiff_ex OFF)
|
add_example(autodiff_ex OFF)
|
||||||
add_example(multinary_ex OFF)
|
add_example(multinary_ex OFF)
|
||||||
add_example(text_io_ex OFF)
|
add_example(text_io_ex OFF)
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
|
|
||||||
using namespace gctl;
|
using namespace gctl;
|
||||||
|
|
||||||
|
double get_x(const point3dc &p)
|
||||||
|
{
|
||||||
|
return p.x;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char const *argv[]) try
|
int main(int argc, char const *argv[]) try
|
||||||
{
|
{
|
||||||
// create a new array and give initial values
|
// create a new array and give initial values
|
||||||
@ -42,7 +47,7 @@ int main(int argc, char const *argv[]) try
|
|||||||
A.linear2log(2);
|
A.linear2log(2);
|
||||||
A.show();
|
A.show();
|
||||||
|
|
||||||
A.parallel_for_each([](double &a, size_t i){a += 1;});
|
A.for_each([](double &a){a += 1;});
|
||||||
A.show();
|
A.show();
|
||||||
|
|
||||||
A.sequence(1.0, 0.5, 3, 4, 1);
|
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.sequence(point3dc(0, 0, 0), point3dc(2, 1, 0.5));
|
||||||
P.show(std::cout, '\n');
|
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
|
// create a new 2D array
|
||||||
matrix<int> C(5, 5, 1);
|
matrix<int> C(5, 5, 1);
|
||||||
C.sequence(0, 1, 10);
|
C.sequence(0, 1, 10);
|
||||||
|
@ -33,28 +33,35 @@ using namespace gctl;
|
|||||||
int main(int argc, char const *argv[]) try
|
int main(int argc, char const *argv[]) try
|
||||||
{
|
{
|
||||||
mesh_io mshio;
|
mesh_io mshio;
|
||||||
|
|
||||||
//mshio.read_tetgen_ascii("tmp/ex1.1");
|
/*
|
||||||
//mshio.edit_group(Disable, GeometryTag, 5);
|
mshio.read_tetgen_ascii("tmp/ex1.1");
|
||||||
//mshio.edit_group(GeometryTag, 1, PhysicalTag, 1);
|
mshio.edit_group(Disable, GeometryTag, 5);
|
||||||
//mshio.edit_group(GeometryTag, 2, PhysicalTag, 2);
|
mshio.edit_group(GeometryTag, 1, PhysicalTag, 1);
|
||||||
//mshio.edit_group(GeometryTag, 3, PhysicalTag, 3);
|
mshio.edit_group(GeometryTag, 2, PhysicalTag, 2);
|
||||||
//mshio.edit_group(GeometryTag, 4, PhysicalTag, 4);
|
mshio.edit_group(GeometryTag, 3, PhysicalTag, 3);
|
||||||
//mshio.edit_group(GeometryTag, 1, "Boundary");
|
mshio.edit_group(GeometryTag, 4, PhysicalTag, 4);
|
||||||
//mshio.edit_group(GeometryTag, 2, "Body1");
|
mshio.edit_group(GeometryTag, 1, "Boundary");
|
||||||
//mshio.edit_group(GeometryTag, 3, "Body2");
|
mshio.edit_group(GeometryTag, 2, "Body1");
|
||||||
//mshio.edit_group(GeometryTag, 4, "Body3");
|
mshio.edit_group(GeometryTag, 3, "Body2");
|
||||||
//mshio.save_gmsh_v2_ascii("tmp/ex1.1");
|
mshio.edit_group(GeometryTag, 4, "Body3");
|
||||||
/*
|
mshio.save_gmsh_v2_ascii("tmp/ex1.1");
|
||||||
|
*/
|
||||||
|
|
||||||
mshio.read_gmsh_v2_ascii("tmp/ex1.1");
|
mshio.read_gmsh_v2_ascii("tmp/ex1.1");
|
||||||
mshio.convert_tags_to_data(GeometryTag);
|
mshio.convert_tags_to_data(GeometryTag);
|
||||||
|
|
||||||
array<double> body_val(mshio.element_size("Body2"), 2.0);
|
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_gmsh_v2_ascii("tmp/ex1.2");
|
||||||
//mshio.save_vtk_legacy_ascii("tmp/ex1.1");
|
//mshio.save_vtk_legacy_ascii("tmp/ex1.1");
|
||||||
mshio.info();
|
mshio.info();
|
||||||
|
|
||||||
array<vertex3dc> nodes = mshio.get_nodes();
|
const array<vertex3dc> &nodes = mshio.get_nodes();
|
||||||
|
|
||||||
array<tetrahedron> body2_tets;
|
array<tetrahedron> body2_tets;
|
||||||
mshio.export_elements_to(body2_tets, "All");
|
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.init_file("tmp.msh", Output);
|
||||||
gio.set_packed(NotPacked, Output);
|
gio.set_packed(NotPacked, Output);
|
||||||
gio.save_mesh(body2_tets, nodes);
|
gio.save_mesh(body2_tets, nodes);
|
||||||
*/
|
/*
|
||||||
|
|
||||||
mshio.read_gmsh_v2_ascii("tmp/wjb.1");
|
mshio.read_gmsh_v2_ascii("tmp/wjb.1");
|
||||||
mshio.edit_group(Disable);
|
mshio.edit_group(Disable);
|
||||||
mshio.edit_group(Enable, GeometryTag, 3);
|
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.edit_group(Enable, GeometryTag, 9);
|
||||||
|
|
||||||
mshio.save_gmsh_v2_ascii("tmp/wjb.2");
|
mshio.save_gmsh_v2_ascii("tmp/wjb.2");
|
||||||
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
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.filt_column("America", "Continent_s", {"Name_s", "Population_n", "GNP_n"}, tout);
|
||||||
//tc.match_column("America", "Continent_s", {}, 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.set_delimeter('|');
|
||||||
tout.save_text("out");
|
tout.save_text("out");
|
||||||
|
|
||||||
|
@ -593,22 +593,45 @@ namespace gctl
|
|||||||
/**
|
/**
|
||||||
* @brief 并行执行指定操作
|
* @brief 并行执行指定操作
|
||||||
*
|
*
|
||||||
* 对数组中的每个元素并行执行给定的操作,第一个参数为数组元素的引用,第二个参数为元素的索引。
|
* 对数组中的每个元素并行执行指定的操作,参数为数组元素的引用。
|
||||||
* 例如:[](ArrValType &a, size_t i){do something here...}
|
* 例如:[](ArrValType &a){do something here...}
|
||||||
*
|
*
|
||||||
* @tparam BiaryOp 二元操作类型 第一个参数为数组元素的引用,第二个参数为元素的索引
|
* @tparam UnaryOp 一元操作类型 参数为数组元素的引用
|
||||||
* @param op 要执行的操作
|
* @param op 要执行的操作
|
||||||
*/
|
*/
|
||||||
template<typename BiaryOp>
|
template <typename UnaryOp>
|
||||||
void parallel_for_each(BiaryOp op)
|
void for_each(UnaryOp op)
|
||||||
{
|
{
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (size_t i = 0; i < length_; i++)
|
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.
|
* @brief Display the elements.
|
||||||
*
|
*
|
||||||
|
@ -531,25 +531,20 @@ namespace gctl
|
|||||||
* @brief 生成一维网格节点数组,其中每一个点都是一个二维坐标点。
|
* @brief 生成一维网格节点数组,其中每一个点都是一个二维坐标点。
|
||||||
*
|
*
|
||||||
* @param out_ps 返回网格节点数组
|
* @param out_ps 返回网格节点数组
|
||||||
* @param[in] xmin x最小值
|
* @param[in] x_st x起始值
|
||||||
* @param[in] xmax x最大值
|
* @param[in] x_ed x终止值
|
||||||
* @param[in] dx x间隔
|
* @param[in] dx x间隔
|
||||||
* @param[in] ele 高程值
|
* @param[in] ele 高程值
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
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)
|
int xnum = round(std::abs((x_ed - x_st)/dx)) + 1;
|
||||||
{
|
|
||||||
throw std::invalid_argument("[gctl::grid_points_1d] Invalid parameters.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int xnum = round((xmax - xmin)/dx) + 1;
|
|
||||||
|
|
||||||
out_ps.resize(xnum);
|
out_ps.resize(xnum);
|
||||||
for (int i = 0; i < xnum; i++)
|
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;
|
out_ps[i].y = ele;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -375,6 +375,20 @@ namespace gctl
|
|||||||
}
|
}
|
||||||
return false;
|
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
|
#endif // _GCTL_POINT2P_H
|
@ -94,22 +94,46 @@ void gctl::dsv_io::get_column_names(std::vector<std::string> &names)
|
|||||||
return;
|
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;
|
table_[0][0].str_ = corner_name;
|
||||||
return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
@ -293,6 +317,29 @@ void gctl::dsv_io::save_text(std::string filename, std::string file_exten)
|
|||||||
outfile << "# " << annotates_[i] << std::endl;
|
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;
|
bool line_st = false;
|
||||||
if (table_[0][0].out_ok_ && table_[0][0].str_ != "")
|
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 << std::endl;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
outfile.close();
|
outfile.close();
|
||||||
return;
|
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)
|
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;
|
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;
|
table_cell empty_cell;
|
||||||
for (size_t i = 0; i < table_.size(); i++)
|
if (idx > col_num_)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < table_.size(); i++)
|
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;
|
table_[0].back().str_ = name;
|
||||||
col_num_++;
|
col_num_++;
|
||||||
|
return col_num_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -547,35 +584,28 @@ void gctl::dsv_io::add_column(int idx, std::string name)
|
|||||||
|
|
||||||
table_[0][idx].str_ = name;
|
table_[0][idx].str_ = name;
|
||||||
col_num_++;
|
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 add_column(name, name_index(id_name));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
std::vector<table_cell> empty_line;
|
||||||
table_.push_back(empty_line);
|
if (idx > row_num_)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
table_.push_back(empty_line);
|
table_.push_back(empty_line);
|
||||||
table_.back().resize(col_num_ + 1);
|
table_.back().resize(col_num_ + 1);
|
||||||
table_.back().front().str_ = name;
|
table_.back().front().str_ = name;
|
||||||
row_num_++;
|
row_num_++;
|
||||||
|
return row_num_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -583,14 +613,14 @@ void gctl::dsv_io::add_row(int idx, std::string name)
|
|||||||
table_[idx].resize(col_num_ + 1);
|
table_[idx].resize(col_num_ + 1);
|
||||||
table_[idx].front().str_ = name;
|
table_[idx].front().str_ = name;
|
||||||
row_num_++;
|
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 add_row(name, name_index(id_name, true));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gctl::dsv_io::filt_column(std::string cnd_str, std::string cnd_col,
|
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_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(row_names);
|
||||||
destroy_vector(io_col);
|
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_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(row_names);
|
||||||
destroy_vector(io_col);
|
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_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(row_names);
|
||||||
destroy_vector(io_col);
|
destroy_vector(io_col);
|
||||||
@ -963,6 +993,29 @@ void gctl::geodsv_io::fill_column_point2dc(const array<point2dc> &data, std::str
|
|||||||
return;
|
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)
|
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
|
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;
|
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)
|
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
|
if (xid > col_num_ || yid > col_num_ || zid > col_num_ || xid == yid || yid == zid || xid == zid
|
||||||
|
111
lib/io/dsv_io.h
111
lib/io/dsv_io.h
@ -113,15 +113,15 @@ namespace gctl
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DSV文本读写类
|
* @brief DSV文本读写类型可以读写并处理一定格式保存的文本数据,具体的格式如下:
|
||||||
*
|
* 1. 所有以注释符(默认为#号)开始的行均会保存至注释变量内,可由用户提取;
|
||||||
* 可以处理的文本数据应该符合下述要求:
|
* 2. 所有以标记符(默认为#!号)开始的行均会保存至标记变量内,可由用户提取;
|
||||||
* 1. 以'#'开始的行均为注释行,标识符可由用户指定;
|
* 3. 文件内可以包含n(默认为0)行不以注释或标记符开始头信息行,保存为头信息变量内,可由用户提取;
|
||||||
* 2. 以'#!'开始的行均为标记行,标识符可由用户指定;
|
* 4. 注释、标记和头信息可出现在文本数据的任意行,且只有在头信息读入结束后才会开始读入数据;
|
||||||
* 3. 文本开始可以包含n行头信息;
|
* 5. 读入的表格保存为一个二维字符串数组,可由用户提取。浮点类型在读入/保存时可设置有效数字位数;
|
||||||
* 4. 数据体为一个row*col大小的表格;
|
* 6. 若制定读入的数据表格存在行或列表头,则读入表格的第一列或第一行将被初始化为对应的行名称或列名称;
|
||||||
* 5. 数据表格文件可以额外包含一列行名称与列名称;
|
* 7. 表格的行与列数据可通过数字索引访问(从1开始计数),也可由具体的行或列名称指定;
|
||||||
* 6. 如论文件内是否包含行头或列头,均可使用内置的行名称R<id>或列名称C<id>指定相应的行或列
|
* 8. 表格可识别内置的行与列名称(格式为为R<id>和C<id>),但不能用于输出文件。
|
||||||
*/
|
*/
|
||||||
class dsv_io
|
class dsv_io
|
||||||
{
|
{
|
||||||
@ -273,16 +273,19 @@ namespace gctl
|
|||||||
/**
|
/**
|
||||||
* @brief 设置行名称
|
* @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 设置列名称
|
* @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 设置行类型
|
* @brief 设置行类型
|
||||||
@ -402,56 +405,52 @@ namespace gctl
|
|||||||
* @param s 设置输出类型
|
* @param s 设置输出类型
|
||||||
*/
|
*/
|
||||||
void row_output(std::string name, switch_type_e s = Disable);
|
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 设置列名称
|
* @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 id_name 索引列名称
|
||||||
* @param 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时将在表尾添加一行
|
* @return 索引 返回的索引(大于等于1 小于等于行数或列数)失败则返回-1
|
||||||
* @param name 设置行名称
|
|
||||||
*/
|
*/
|
||||||
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 id_name 索引行名称
|
||||||
* @param 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 按行过滤并返回符合条件的列数据
|
* @brief 按行过滤并返回符合条件的列数据
|
||||||
*
|
*
|
||||||
|
* @note 过滤后的表格第一列尾用于匹配正则表达式的列,剩余列尾为筛选后符合条件的列数据。
|
||||||
|
*
|
||||||
* @param cnd_str 正则表达式
|
* @param cnd_str 正则表达式
|
||||||
* @param cnd_col 用于匹配正则表达式的列名称
|
* @param cnd_col 用于匹配正则表达式的列名称
|
||||||
* @param out_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);
|
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 填充三维坐标列
|
* @brief 填充三维坐标列
|
||||||
*
|
*
|
||||||
@ -890,6 +909,24 @@ namespace gctl
|
|||||||
*/
|
*/
|
||||||
void get_column_point2dc(array<point2dc> &data, std::string xname, std::string yname);
|
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 读取三维坐标列
|
* @brief 读取三维坐标列
|
||||||
*
|
*
|
||||||
|
@ -152,4 +152,15 @@ void gctl::gmshio::save_physical_groups(const array<gmsh_physical_group> &phy_gr
|
|||||||
}
|
}
|
||||||
gmsh_out << "$EndPhysicalNames\n";
|
gmsh_out << "$EndPhysicalNames\n";
|
||||||
return;
|
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 read_physical_groups(array<gmsh_physical_group> &phy_groups);
|
||||||
void save_physical_groups(const 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<point2dc, A>> &out_nodes);
|
||||||
template <typename A> void read_node(array<vertex<point3dc, 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_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_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);
|
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;
|
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>
|
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)
|
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;
|
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.
|
* @brief Read element index from a Gmsh file.
|
||||||
*
|
*
|
||||||
|
@ -27,43 +27,41 @@
|
|||||||
|
|
||||||
#include "mesh_io.h"
|
#include "mesh_io.h"
|
||||||
|
|
||||||
gctl::mesh_element::mesh_element()
|
gctl::meshio_element::meshio_element()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
id = DEFAULT_INVALID_TAG;
|
id = DEFAULT_INVALID_TAG;
|
||||||
type = NotSet;
|
type = NotSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
gctl::mesh_data::mesh_data()
|
gctl::meshio_data::meshio_data()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
d_type = NodeData;
|
d_type = NodeData;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gctl::mesh_data::clear()
|
void gctl::meshio_data::clear()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
str_tag.clear();
|
str_tag.clear();
|
||||||
real_tag.clear();
|
real_tag.clear();
|
||||||
int_tag.clear();
|
int_tag.clear();
|
||||||
vert_ptrs.clear();
|
tar_ptrs.clear();
|
||||||
elem_ptrs.clear();
|
|
||||||
val.clear();
|
val.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gctl::mesh_data::pass_check()
|
bool gctl::meshio_data::pass_check()
|
||||||
{
|
{
|
||||||
// 检查是否同时连接了顶点和单元体
|
// 检查是否同时连接了顶点和单元体
|
||||||
if (vert_ptrs.empty() && elem_ptrs.empty()) return false;
|
if (tar_ptrs.empty()) return false;
|
||||||
if (!vert_ptrs.empty() && !elem_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 (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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
gctl::mesh_element_group::mesh_element_group()
|
gctl::meshio_element_group::meshio_element_group()
|
||||||
{
|
{
|
||||||
enabled = false;
|
enabled = false;
|
||||||
type = NotSet;
|
type = NotSet;
|
||||||
@ -71,7 +69,7 @@ gctl::mesh_element_group::mesh_element_group()
|
|||||||
phys_group = geom_group = part_group = DEFAULT_INVALID_TAG;
|
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++)
|
for (size_t e = 0; e < elem_ptrs.size(); e++)
|
||||||
{
|
{
|
||||||
@ -80,7 +78,7 @@ void gctl::mesh_element_group::enable_elements()
|
|||||||
return;
|
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++)
|
for (size_t e = 0; e < elem_ptrs.size(); e++)
|
||||||
{
|
{
|
||||||
@ -319,7 +317,7 @@ void gctl::mesh_io::info(std::ostream &ss)
|
|||||||
ss << "nodedata: \"";
|
ss << "nodedata: \"";
|
||||||
for (size_t l = 0; l < datas_[d].val.size(); l++)
|
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]);
|
min = std::min(min, datas_[d].val[l]);
|
||||||
max = std::max(max, 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: \"";
|
ss << "elementdata: \"";
|
||||||
for (size_t l = 0; l < datas_[d].val.size(); l++)
|
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]);
|
min = std::min(min, datas_[d].val[l]);
|
||||||
max = std::max(max, 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_;
|
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()
|
const gctl::array<gctl::vertex3dc> &gctl::mesh_io::get_nodes()
|
||||||
{
|
{
|
||||||
return 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_;
|
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)
|
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()))
|
if (tag_type == NodeTag && (!nodes_tag_.empty()))
|
||||||
{
|
{
|
||||||
tmp_data.enabled = true;
|
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.int_tag[2] = valid_node_size_;
|
||||||
|
|
||||||
tmp_data.val.resize(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;
|
size_t c = 0;
|
||||||
for (size_t i = 0; i < nodes_.size(); i++)
|
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)
|
if (nodes_[i].id != DEFAULT_INVALID_TAG)
|
||||||
{
|
{
|
||||||
tmp_data.val[c] = (double) nodes_tag_[i];
|
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++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,13 +573,12 @@ void gctl::mesh_io::convert_tags_to_data(element_tag_enum tag_type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int t = 0;
|
|
||||||
tmp_data.enabled = true;
|
tmp_data.enabled = true;
|
||||||
tmp_data.d_type = ElemData;
|
tmp_data.d_type = ElemData;
|
||||||
|
|
||||||
if (tag_type == PhysicalTag) {tmp_data.str_tag.resize(1, "Physical Tag"); t = 0;}
|
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"); t = 1;}
|
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"); t = 2;}
|
else if (tag_type == PartitionTag) tmp_data.str_tag.resize(1, "Partition Tag");
|
||||||
|
|
||||||
tmp_data.real_tag.resize(1, 0.0);
|
tmp_data.real_tag.resize(1, 0.0);
|
||||||
tmp_data.int_tag.resize(3, 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.int_tag[2] = valid_elem_size_;
|
||||||
|
|
||||||
tmp_data.val.resize(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;
|
size_t c = 0;
|
||||||
for (size_t g = 0; g < groups_.size(); g++)
|
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 == 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 == GeometryTag) tmp_data.val[c] = (double) groups_[g].geom_group;
|
||||||
if (tag_type == PartitionTag) tmp_data.val[c] = (double) groups_[g].part_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++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -686,7 +694,7 @@ void gctl::mesh_io::export_elements_to(array<tetrahedron> &tets, std::string phy
|
|||||||
tets.resize(s);
|
tets.resize(s);
|
||||||
|
|
||||||
s = 0;
|
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 &&
|
if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron &&
|
||||||
(groups_[i].name == phys_name || phys_name == "All"))
|
(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);
|
tets.resize(s);
|
||||||
|
|
||||||
s = 0;
|
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 &&
|
if (groups_[i].enabled && groups_[i].type == _4NodeTetrahedron &&
|
||||||
(tag_type == PhysicalTag && groups_[i].phys_group == tag) ||
|
(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;
|
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.enabled = true;
|
||||||
new_data.d_type = NodeData;
|
new_data.d_type = NodeData;
|
||||||
new_data.str_tag.resize(1, name);
|
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.resize(3, 0);
|
||||||
new_data.int_tag[1] = 1;
|
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 < s; i++)
|
||||||
for (size_t i = 0; i < nodes_.size(); 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);
|
|
||||||
|
|
||||||
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++)
|
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);
|
if (boolen[i])
|
||||||
new_data.val[c] = data[c];
|
{
|
||||||
c++;
|
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;
|
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;
|
size_t e = 0;
|
||||||
for (size_t i = 0; i < groups_.size(); i++)
|
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.");
|
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.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);
|
new_data.val.resize(e, 0.0);
|
||||||
|
|
||||||
e = 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++)
|
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];
|
new_data.val[e] = data[e];
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
@ -818,15 +970,8 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
|
|||||||
return;
|
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;
|
size_t e = 0;
|
||||||
for (size_t i = 0; i < groups_.size(); i++)
|
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.");
|
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.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);
|
new_data.val.resize(e, 0.0);
|
||||||
|
|
||||||
e = 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++)
|
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];
|
new_data.val[e] = data[e];
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
@ -866,15 +1047,8 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
|
|||||||
return;
|
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;
|
size_t e = 0;
|
||||||
for (size_t i = 0; i < groups_.size(); i++)
|
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.");
|
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.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);
|
new_data.val.resize(e, 0.0);
|
||||||
|
|
||||||
e = 0;
|
e = 0;
|
||||||
for (size_t i = 0; i < groups_.size(); i++)
|
for (size_t i = 0; i < groups_.size(); i++)
|
||||||
{
|
{
|
||||||
if (groups_[i].enabled && groups_[i].name == phys_name)
|
if (groups_[i].enabled && groups_[i].name == phys_name)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; j < groups_[i].elem_ptrs.size(); j++)
|
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];
|
new_data.val[e] = data[e];
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
@ -908,6 +1115,72 @@ void gctl::mesh_io::create_element_data(const array<double> &data, std::string n
|
|||||||
return;
|
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)
|
void gctl::mesh_io::read_triangle_ascii(std::string filename, index_packed_e is_packed)
|
||||||
{
|
{
|
||||||
if (initialized_ == true)
|
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.type = elems_[0].type;
|
||||||
tmp_group.phys_group = int_tag[0][0];
|
tmp_group.phys_group = int_tag[0][0];
|
||||||
tmp_group.geom_group = int_tag[0][1];
|
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.type = elems_[0].type;
|
||||||
tmp_group.phys_group = int_tag[0][0];
|
tmp_group.phys_group = int_tag[0][0];
|
||||||
tmp_group.geom_group = int_tag[0][1];
|
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 p_size = 0;
|
||||||
size_t n_size = 0;
|
size_t n_size = 0;
|
||||||
array<gmsh_physical_group> phys;
|
array<gmsh_physical_group> phys;
|
||||||
|
|
||||||
while(getline(infile,tmp_str))
|
while(getline(infile,tmp_str))
|
||||||
{
|
{
|
||||||
if (tmp_str == "$PhysicalNames")
|
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;
|
int i_size, type_code, attri_num, vt_idx;
|
||||||
array<array<int> > int_tag;
|
array<array<int> > file_itag;
|
||||||
while(getline(infile,tmp_str))
|
while(getline(infile,tmp_str))
|
||||||
{
|
{
|
||||||
if (tmp_str == "$Elements")
|
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;
|
valid_elem_size_ = i_size;
|
||||||
elems_.resize(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++)
|
for (size_t i = 0; i < i_size; i++)
|
||||||
{
|
{
|
||||||
getline(infile,tmp_str);
|
getline(infile,tmp_str);
|
||||||
str2ss(tmp_str, tmp_ss);
|
str2ss(tmp_str, tmp_ss);
|
||||||
tmp_ss >> elems_[i].id >> type_code >> attri_num;
|
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].type = elem_gmsh_type(type_code);
|
||||||
elems_[i].vert_ptrs.resize(elem_size(elems_[i].type));
|
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);
|
tmp_ss >> file_itag[i][a];
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t v = 0; v < elems_[i].vert_ptrs.size(); v++)
|
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))
|
while(getline(infile,tmp_str))
|
||||||
{
|
{
|
||||||
if (!infile.good()) break;
|
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)
|
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());
|
tmp_data.val.resize(tmp_data.int_tag.back());
|
||||||
for (size_t i = 0; i < tmp_data.val.size(); i++)
|
for (size_t i = 0; i < tmp_data.val.size(); i++)
|
||||||
{
|
{
|
||||||
getline(infile,tmp_str);
|
getline(infile,tmp_str);
|
||||||
str2ss(tmp_str, tmp_ss);
|
str2ss(tmp_str, tmp_ss);
|
||||||
tmp_ss >> vt_idx >> tmp_data.val[i];
|
tmp_ss >> vt_idx >> tmp_data.val[i];
|
||||||
if (is_packed == Packed) tmp_data.vert_ptrs[i] = nodes_.get(vt_idx);
|
if (is_packed == Packed) tmp_data.tar_ptrs[i] = nodes_.get(vt_idx);
|
||||||
else tmp_data.vert_ptrs[i] = nodes_.get(vt_idx - 1);
|
else tmp_data.tar_ptrs[i] = nodes_.get(vt_idx - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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());
|
tmp_data.val.resize(tmp_data.int_tag.back());
|
||||||
for (size_t i = 0; i < tmp_data.val.size(); i++)
|
for (size_t i = 0; i < tmp_data.val.size(); i++)
|
||||||
{
|
{
|
||||||
getline(infile,tmp_str);
|
getline(infile,tmp_str);
|
||||||
str2ss(tmp_str, tmp_ss);
|
str2ss(tmp_str, tmp_ss);
|
||||||
tmp_ss >> vt_idx >> tmp_data.val[i];
|
tmp_ss >> vt_idx >> tmp_data.val[i];
|
||||||
if (is_packed == Packed) tmp_data.elem_ptrs[i] = elems_.get(vt_idx);
|
if (is_packed == Packed) tmp_data.tar_ptrs[i] = elems_.get(vt_idx);
|
||||||
else tmp_data.elem_ptrs[i] = elems_.get(vt_idx - 1);
|
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();
|
infile.close();
|
||||||
|
|
||||||
// 整理单元体组
|
// 整理单元体组
|
||||||
mesh_element_group tmp_group;
|
meshio_element_group tmp_group;
|
||||||
tmp_group.type = elems_[0].type;
|
tmp_group.type = elems_[0].type;
|
||||||
tmp_group.phys_group = int_tag[0][0];
|
tmp_group.phys_group = file_itag[0][0];
|
||||||
tmp_group.geom_group = int_tag[0][1];
|
tmp_group.geom_group = file_itag[0][1];
|
||||||
tmp_group.part_group = int_tag[0][2];
|
tmp_group.part_group = file_itag[0][2];
|
||||||
tmp_group.elem_ptrs.push_back(elems_.get(0));
|
tmp_group.elem_ptrs.push_back(elems_.get(0));
|
||||||
groups_.push_back(tmp_group);
|
groups_.push_back(tmp_group);
|
||||||
|
|
||||||
|
// 元素类型与三个标记都一致的元素将被分到同一组
|
||||||
bool not_found;
|
bool not_found;
|
||||||
for (size_t i = 1; i < elems_.size(); i++)
|
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++)
|
for (size_t g = 0; g < groups_.size(); g++)
|
||||||
{
|
{
|
||||||
if (groups_[g].type == elems_[i].type &&
|
if (groups_[g].type == elems_[i].type &&
|
||||||
groups_[g].phys_group == int_tag[i][0] &&
|
groups_[g].phys_group == file_itag[i][0] &&
|
||||||
groups_[g].geom_group == int_tag[i][1] &&
|
groups_[g].geom_group == file_itag[i][1] &&
|
||||||
groups_[g].part_group == int_tag[i][2])
|
groups_[g].part_group == file_itag[i][2])
|
||||||
{
|
{
|
||||||
groups_[g].elem_ptrs.push_back(elems_.get(i));
|
groups_[g].elem_ptrs.push_back(elems_.get(i));
|
||||||
not_found = false;
|
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.elem_ptrs.clear();
|
||||||
tmp_group.type = elems_[i].type;
|
tmp_group.type = elems_[i].type;
|
||||||
tmp_group.phys_group = int_tag[i][0];
|
tmp_group.phys_group = file_itag[i][0]; // 物理组
|
||||||
tmp_group.geom_group = int_tag[i][1];
|
tmp_group.geom_group = file_itag[i][1]; // 几何组
|
||||||
tmp_group.part_group = int_tag[i][2];
|
tmp_group.part_group = file_itag[i][2]; // 剖分组(一般以元素的维度区分)
|
||||||
tmp_group.elem_ptrs.push_back(elems_.get(i));
|
tmp_group.elem_ptrs.push_back(elems_.get(i));
|
||||||
groups_.push_back(tmp_group);
|
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())
|
if (!phys.empty())
|
||||||
{
|
{
|
||||||
|
// 遍历所有元素组 按物理组为标准为元素组命名 并以将元素维度赋值为剖分组
|
||||||
for (size_t g = 0; g < groups_.size(); g++)
|
for (size_t g = 0; g < groups_.size(); g++)
|
||||||
{
|
{
|
||||||
for (size_t p = 0; p < phys.size(); p++)
|
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 << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
|
||||||
|
|
||||||
outfile << "$PhysicalNames\n" << valid_group_size_ << "\n";
|
std::vector<gmsh_physical_group> gmsh_groups;
|
||||||
for (size_t i = 0; i < groups_.size(); i++)
|
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";
|
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 if (groups_[i].enabled) outfile << groups_[i].part_group << " 0 \"" << groups_[i].name << "\"\n";
|
else outfile << gmsh_groups[i].dim_tag << " 0 \"" << gmsh_groups[i].name << "\"\n";
|
||||||
}
|
}
|
||||||
outfile << "$EndPhysicalNames\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;
|
d_size = 0;
|
||||||
for (size_t n = 0; n < datas_[i].val.size(); n++)
|
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)
|
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";
|
outfile << d_size << "\n";
|
||||||
|
|
||||||
|
int tmp_id;
|
||||||
for (size_t a = 0; a < datas_[i].val.size(); a++)
|
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";
|
tmp_id = reinterpret_cast<vertex3dc*>(datas_[i].tar_ptrs[a])->id;
|
||||||
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";
|
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";
|
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;
|
d_size = 0;
|
||||||
for (size_t n = 0; n < datas_[i].val.size(); n++)
|
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)
|
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";
|
outfile << d_size << "\n";
|
||||||
|
|
||||||
|
int tmp_id;
|
||||||
|
bool d_ok;
|
||||||
for (size_t a = 0; a < datas_[i].val.size(); a++)
|
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";
|
tmp_id = reinterpret_cast<meshio_element*>(datas_[i].tar_ptrs[a])->id;
|
||||||
else if (datas_[i].elem_ptrs[a]->enabled) outfile << datas_[i].elem_ptrs[a]->id + 1 << " " << std::setprecision(12) << datas_[i].val[a] << "\n";
|
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";
|
outfile << "$EndElementData\n";
|
||||||
}
|
}
|
||||||
@ -1662,7 +1933,7 @@ void gctl::mesh_io::save_vtk_legacy_ascii(std::string filename)
|
|||||||
d_size = 0;
|
d_size = 0;
|
||||||
for (size_t n = 0; n < datas_[i].val.size(); n++)
|
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_)
|
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++)
|
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;
|
d_size = 0;
|
||||||
for (size_t n = 0; n < datas_[i].val.size(); n++)
|
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_)
|
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++)
|
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)
|
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)
|
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);
|
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";
|
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
|
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);
|
pc = point3dc(0.0, 0.0, 0.0);
|
||||||
tmp_size = datas_[i].elem_ptrs[e]->vert_ptrs.size();
|
tmp_size = mptr->vert_ptrs.size();
|
||||||
for (size_t v = 0; v < datas_[i].elem_ptrs[e]->vert_ptrs.size(); v++)
|
for (size_t v = 0; v < mptr->vert_ptrs.size(); v++)
|
||||||
{
|
{
|
||||||
pc.x += datas_[i].elem_ptrs[e]->vert_ptrs[v]->x;
|
pc.x += mptr->vert_ptrs[v]->x;
|
||||||
pc.y += datas_[i].elem_ptrs[e]->vert_ptrs[v]->y;
|
pc.y += mptr->vert_ptrs[v]->y;
|
||||||
pc.z += datas_[i].elem_ptrs[e]->vert_ptrs[v]->z;
|
pc.z += mptr->vert_ptrs[v]->z;
|
||||||
}
|
}
|
||||||
pc.x /= tmp_size;
|
pc.x /= tmp_size;
|
||||||
pc.y /= tmp_size;
|
pc.y /= tmp_size;
|
||||||
@ -1850,7 +2123,7 @@ void gctl::mesh_io::update_indexing()
|
|||||||
void gctl::mesh_io::sort_groups()
|
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++)
|
for (size_t i = 0; i < groups_.size(); i++)
|
||||||
@ -1861,7 +2134,7 @@ void gctl::mesh_io::sort_groups()
|
|||||||
|
|
||||||
// 整理单元体组
|
// 整理单元体组
|
||||||
bool not_found;
|
bool not_found;
|
||||||
mesh_element_group tmp_group;
|
meshio_element_group tmp_group;
|
||||||
for (size_t i = 0; i < tmp_groups.size(); i++)
|
for (size_t i = 0; i < tmp_groups.size(); i++)
|
||||||
{
|
{
|
||||||
tmp_group = tmp_groups[i];
|
tmp_group = tmp_groups[i];
|
||||||
@ -1898,5 +2171,7 @@ void gctl::mesh_io::sort_groups()
|
|||||||
{
|
{
|
||||||
if (groups_[i].enabled) valid_group_size_++;
|
if (groups_[i].enabled) valid_group_size_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy_vector(tmp_groups);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
208
lib/io/mesh_io.h
208
lib/io/mesh_io.h
@ -93,43 +93,42 @@ namespace gctl
|
|||||||
*/
|
*/
|
||||||
enum element_tag_enum
|
enum element_tag_enum
|
||||||
{
|
{
|
||||||
PhysicalTag,
|
PhysicalTag, // 元素的物理分组标签
|
||||||
GeometryTag,
|
GeometryTag, // 元素的几何分组标签
|
||||||
PartitionTag,
|
PartitionTag, // 元素的剖分分组标签
|
||||||
NodeTag,
|
NodeTag, // 顶点的标签(仅用于输出顶点标签数据)
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 网格单元体结构体
|
* @brief 网格单元体结构体
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct mesh_element
|
struct meshio_element
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled; // 单元体是否有效
|
||||||
int id;
|
int id; // 单元体编号
|
||||||
element_type_enum type;
|
element_type_enum type; // 单元体类型
|
||||||
array<vertex3dc*> vert_ptrs;
|
array<vertex3dc*> vert_ptrs; // 顶点指针数组
|
||||||
array<mesh_element*> neigh_ptrs;
|
array<meshio_element*> neigh_ptrs; // 相邻单元体指针数组
|
||||||
|
|
||||||
mesh_element();
|
meshio_element();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 网格数据结构体
|
* @brief 网格数据结构体
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct mesh_data
|
struct meshio_data
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled; // 数据体是否有效
|
||||||
mesh_data_type_e d_type;
|
mesh_data_type_e d_type; // 数据类型
|
||||||
array<std::string> str_tag;
|
array<std::string> str_tag; // 字符串类型的标签(默认为一个,即为数据的名称)
|
||||||
array<double> real_tag;
|
array<double> real_tag; // 实数类型的标签(默认为一个,等于0.0)
|
||||||
array<int> int_tag;
|
array<int> int_tag; // 整数类型的标签(最少三个,最后一个为数据的长度)
|
||||||
array<vertex3dc*> vert_ptrs; // 两者只能存在一个
|
array<void*> tar_ptrs; // 数据连接的对象指针数组 具体类型为vertex3dc*或meshio_element*
|
||||||
array<mesh_element*> elem_ptrs; // 两者只能存在一个
|
array<double> val; // 数据值(目前仅支持标量数据,后续再添加对矢量数据的支持)
|
||||||
array<double> val;
|
|
||||||
|
|
||||||
mesh_data();
|
meshio_data();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 清空数组并重置变量。
|
* @brief 清空数组并重置变量。
|
||||||
@ -148,17 +147,17 @@ namespace gctl
|
|||||||
* @brief 网格单元体分组结构体。
|
* @brief 网格单元体分组结构体。
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct mesh_element_group
|
struct meshio_element_group
|
||||||
{
|
{
|
||||||
bool enabled;
|
bool enabled; // 组是否有效
|
||||||
element_type_enum type;
|
element_type_enum type; // 组内单元体类型
|
||||||
int phys_group;
|
int phys_group; // 物理分组标签
|
||||||
int geom_group;
|
int geom_group; // 几何分组标签
|
||||||
int part_group;
|
int part_group; // 剖分分组标签
|
||||||
std::string name;
|
std::string name; // 组名
|
||||||
std::vector<mesh_element*> elem_ptrs;
|
std::vector<meshio_element*> elem_ptrs; // 组内单元体指针数组
|
||||||
|
|
||||||
mesh_element_group();
|
meshio_element_group();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 将组内所有单元体设置为有效状态。
|
* @brief 将组内所有单元体设置为有效状态。
|
||||||
@ -256,21 +255,30 @@ namespace gctl
|
|||||||
const array<int> &get_node_tag();
|
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 顶点数组的引用。
|
* @return 顶点数组的引用。
|
||||||
*/
|
*/
|
||||||
const array<vertex3dc> &get_nodes();
|
const array<vertex3dc> &get_nodes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 返回单元体数组的引用。
|
* @brief 返回所有单元体数组的引用。
|
||||||
*
|
*
|
||||||
* @return 单元体数组的引用。
|
* @return 单元体数组的引用。
|
||||||
*/
|
*/
|
||||||
const array<mesh_element> &get_elems();
|
const array<meshio_element> &get_elems();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 返回对应类型单元体的数量。
|
* @brief 返回对应类型单元体的数量(注意只会统计有效的单元体组)。
|
||||||
*
|
*
|
||||||
* @param e_type 单元体类型(缺省为NotSet,返回所有单元体类型的总和)。
|
* @param e_type 单元体类型(缺省为NotSet,返回所有单元体类型的总和)。
|
||||||
* @return 整型大小。
|
* @return 整型大小。
|
||||||
@ -278,7 +286,7 @@ namespace gctl
|
|||||||
size_t element_size(element_type_enum e_type = NotSet);
|
size_t element_size(element_type_enum e_type = NotSet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 返回对应标签类型与标签值的单元体数量。
|
* @brief 返回对应标签类型与标签值的单元体数量(注意只会统计有效的单元体组)。
|
||||||
*
|
*
|
||||||
* @param tag_type 标签类型。
|
* @param tag_type 标签类型。
|
||||||
* @param tag 标签值。
|
* @param tag 标签值。
|
||||||
@ -287,7 +295,7 @@ namespace gctl
|
|||||||
size_t element_size(element_tag_enum tag_type, int tag);
|
size_t element_size(element_tag_enum tag_type, int tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 返回对应名称的单元体数量。
|
* @brief 返回对应名称的单元体数量(注意只会统计有效的单元体组)。
|
||||||
*
|
*
|
||||||
* @param phys_name 单元体组名称
|
* @param phys_name 单元体组名称
|
||||||
* @return 整型大小。
|
* @return 整型大小。
|
||||||
@ -336,40 +344,105 @@ namespace gctl
|
|||||||
void export_elements_to(array<tetrahedron> &tets, element_tag_enum tag_type, int tag);
|
void export_elements_to(array<tetrahedron> &tets, element_tag_enum tag_type, int tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建一个顶点数据对象。
|
* @brief 获取gmsh格式分组表
|
||||||
*
|
*
|
||||||
* @param data 输入的数据数组。
|
* @param g_groups gmsh格式表
|
||||||
* @param name 新建的数据名称。
|
|
||||||
*/
|
*/
|
||||||
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 data 输入的数据数组。
|
||||||
* @param name 新建数据名称。
|
* @param name 新建数据名称。
|
||||||
* @param e_type 新建数据的单元体类型(缺省值为NotSet,表示选择所有有效的单元体)。
|
* @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 按单元体标签值筛选创建一个单元体数据对象。
|
* @brief 按单元体标签值筛选创建一个单元体数据对象。
|
||||||
*
|
*
|
||||||
|
* @note 若对应名称的数据已经存在则会追加
|
||||||
|
*
|
||||||
* @param data 输入的数据数组。
|
* @param data 输入的数据数组。
|
||||||
* @param name 新建数据名称。
|
* @param name 新建数据名称。
|
||||||
* @param tag_type 标签类型。
|
* @param tag_type 标签类型。
|
||||||
* @param tag 标签值。
|
* @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 按单元体组的名称筛选创建一个单元体数据对象。
|
* @brief 按单元体组的名称筛选创建一个单元体数据对象。
|
||||||
*
|
*
|
||||||
|
* @note 若对应名称的数据已经存在则会追加
|
||||||
|
*
|
||||||
* @param data 输入的数据数组。
|
* @param data 输入的数据数组。
|
||||||
* @param name 新建数据名称。
|
* @param name 新建数据名称。
|
||||||
* @param phys_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软件输出的网格剖分文件。
|
* @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);
|
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:
|
protected:
|
||||||
bool initialized_;
|
bool initialized_; // 类型是否已经初始化完成
|
||||||
|
|
||||||
size_t valid_node_size_, valid_elem_size_, valid_group_size_;
|
|
||||||
array<vertex3dc> nodes_;
|
|
||||||
array<mesh_element> elems_;
|
|
||||||
std::vector<mesh_data> datas_;
|
|
||||||
std::vector<mesh_element_group> groups_;
|
|
||||||
array<int> nodes_tag_;
|
|
||||||
|
|
||||||
element_type_enum elem_gmshcode2type_[94];
|
// 有效的顶点、单元体和单元体组的数量
|
||||||
element_type_enum elem_vtkcode2type_[14];
|
size_t valid_node_size_, valid_elem_size_, valid_group_size_;
|
||||||
std::map<element_type_enum, int> elem_type2gmshcode_;
|
array<vertex3dc> nodes_; // 网格顶点 当顶点索引为无效值时将不会被输出
|
||||||
std::map<element_type_enum, int> elem_type2vtkcode_;
|
array<meshio_element> elems_; // 网格元素
|
||||||
std::map<element_type_enum, int> elem_type2size_;
|
std::vector<meshio_data> datas_; // 网格数据
|
||||||
std::map<element_type_enum, std::string> elem_type2name_;
|
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);
|
std::string elem_name(element_type_enum e_type); // 获取单元体名称字符串
|
||||||
int elem_gmsh_code(element_type_enum e_type);
|
int elem_gmsh_code(element_type_enum e_type); // 获取单元体gmsh类型码值
|
||||||
int elem_vtk_code(element_type_enum e_type);
|
int elem_vtk_code(element_type_enum e_type); // 获取单元体vtk类型码值
|
||||||
int elem_size(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_gmsh_type(int code); // 获取对应gmsh类型码的单元体类型
|
||||||
element_type_enum elem_vtk_type(int code);
|
element_type_enum elem_vtk_type(int code); // 获取对应vtk类型码的单元体类型
|
||||||
void update_indexing();
|
void update_indexing(); // 更新索引(对网格的元素进行操作后需调用)
|
||||||
void sort_groups();
|
void sort_groups(); // 对单元体组进行梳理(对网格的元素进行操作后需调用)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,12 @@ namespace gctl
|
|||||||
return deg*GCTL_Pi/180.0;
|
return deg*GCTL_Pi/180.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T deg(T arc)
|
||||||
|
{
|
||||||
|
return arc*180.0/GCTL_Pi;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T sind(T deg)
|
inline T sind(T deg)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user