3863 lines
113 KiB
C++
3863 lines
113 KiB
C++
/********************************************************
|
||
* ██████╗ ██████╗████████╗██╗
|
||
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
||
* ██║ ███╗██║ ██║ ██║
|
||
* ██║ ██║██║ ██║ ██║
|
||
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
||
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||
* Geophysical Computational Tools & Library (GCTL)
|
||
*
|
||
* Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn)
|
||
*
|
||
* GCTL is distributed under a dual licensing scheme. You can redistribute
|
||
* it and/or modify it under the terms of the GNU Lesser General Public
|
||
* License as published by the Free Software Foundation, either version 2
|
||
* of the License, or (at your option) any later version. You should have
|
||
* received a copy of the GNU Lesser General Public License along with this
|
||
* program. If not, see <http://www.gnu.org/licenses/>.
|
||
*
|
||
* If the terms and conditions of the LGPL v.2. would prevent you from using
|
||
* the GCTL, please consider the option to obtain a commercial license for a
|
||
* fee. These licenses are offered by the GCTL's original author. As a rule,
|
||
* licenses are provided "as-is", unlimited in time for a one time fee. Please
|
||
* send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget
|
||
* to include some description of your company and the realm of its activities.
|
||
* Also add information on how to contact you by electronic and paper mail.
|
||
******************************************************/
|
||
|
||
#ifndef _GCTL_GMSH_IO_H
|
||
#define _GCTL_GMSH_IO_H
|
||
|
||
// library's head files
|
||
#include "../core/matrix.h"
|
||
#include "../poly/node.h"
|
||
#include "../poly/sphere.h"
|
||
#include "../poly/triangle2d.h"
|
||
#include "../poly/triangle2d2o.h"
|
||
#include "../poly/rectangle2d.h"
|
||
#include "../poly/edge2d.h"
|
||
#include "../poly/block.h"
|
||
#include "../poly/prism.h"
|
||
#include "../poly/tesseroid.h"
|
||
#include "../poly/tetrahedron.h"
|
||
#include "../poly/tri_cone.h"
|
||
#include "../poly/triangle.h"
|
||
#include "../poly/edge.h"
|
||
#include "file_io.h"
|
||
|
||
#ifdef GCTL_EIGEN
|
||
#include "Eigen/Dense"
|
||
#endif // GCTL_EIGEN
|
||
|
||
namespace gctl
|
||
{
|
||
struct gmsh_physical_group
|
||
{
|
||
size_t dim_tag, phys_tag;
|
||
std::string name;
|
||
};
|
||
|
||
/**
|
||
* @brief Gmsh文件的IO类,主要为调用下面定义的全局函数
|
||
*/
|
||
class gmshio
|
||
{
|
||
public:
|
||
gmshio();
|
||
gmshio(std::string filename, file_direction_e f_direct);
|
||
virtual ~gmshio();
|
||
void init_file(std::string filename, file_direction_e f_direct);
|
||
void reset_file(std::string filename, file_direction_e f_direct);
|
||
void set_packed(index_packed_e is_packed, file_direction_e f_direct);
|
||
bool initialized(file_direction_e f_direct);
|
||
|
||
void read_physical_groups(array<gmsh_physical_group> &phy_groups);
|
||
void save_physical_groups(const array<gmsh_physical_group> &phy_groups);
|
||
int physical_name2tag(const array<gmsh_physical_group> &phy_groups, std::string name);
|
||
|
||
template <typename A> void read_node(array<vertex<point2dc, A>> &out_nodes);
|
||
template <typename A> void read_node(array<vertex<point3dc, A>> &out_nodes);
|
||
template <typename E, typename A> void read_element(array<type_edge2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_triangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_triangle2d2o<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_rectangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_node<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_edge<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_triangle<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_tetrahedron<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_block<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_tricone<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_element(array<type_prism<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
|
||
template <typename E, typename A> void read_mesh(array<type_triangle2d<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_triangle2d2o<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_rectangle2d<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_node<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_edge<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_triangle<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_tetrahedron<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_block<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_tricone<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
template <typename E, typename A> void read_mesh(array<type_prism<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag = nullptr);
|
||
|
||
template <typename T> void read_data(array<T> &out_data, std::string data_name = "");
|
||
template <typename T> void read_data(array<T> &out_data, array<size_t> &out_index, std::string data_name = "");
|
||
template <typename T> void read_data(std::vector<std::vector<T> > &out_data, std::vector<std::string> &out_name,
|
||
mesh_data_type_e d_type, std::vector<std::vector<size_t> > *out_index = nullptr);
|
||
|
||
template <typename E, typename A> void save_mesh(const array<type_triangle2d<E>> &element, const array<vertex<point2dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_triangle2d2o<E>> &element, const array<vertex<point2dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_rectangle2d<E>> &element, const array<vertex<point2dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_triangle<E>> &element, const array<vertex<point3dc, A>> &node, array<bool> *out_ele_tag = nullptr, array<bool> *out_node_tag = nullptr);
|
||
template <typename E, typename A> void save_mesh(const array<type_tetrahedron<E>> &element, const array<vertex<point3dc, A>> &node, array<bool> *output_tag = nullptr);
|
||
template <typename E, typename A> void save_mesh(const array<type_block<E>> &element, const array<vertex<point3dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_tricone<E>> &element, const array<vertex<point3dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_prism<E>> &element, const array<vertex<point3dc, A>> &node);
|
||
template <typename E, typename A> void save_mesh(const array<type_tesseroid<E>> &element, const array<vertex<point3dc, A>> &node);
|
||
|
||
template <typename E> void save_mesh(const array<type_tetrahedron<E>> &element);
|
||
|
||
template <typename T> void save_data(std::string dataname, const T *in_data, size_t in_size, mesh_data_type_e datatype, const size_t *in_index = nullptr);
|
||
template <typename T> void save_data(std::string dataname, const array<T> &in_data, mesh_data_type_e datatype, const array<size_t> *in_index = nullptr);
|
||
template <typename T> void save_data(std::string dataname, const std::vector<T> &in_data, mesh_data_type_e datatype, const std::vector<size_t> *in_index = nullptr);
|
||
template <typename T> void save_data(std::string dataname, const array<point3c<T>> &in_data, mesh_data_type_e datatype, const array<size_t> *in_index = nullptr);
|
||
template <typename T> void save_data(std::string dataname, const std::vector<point3c<T>> &in_data, mesh_data_type_e datatype, const std::vector<size_t> *in_index = nullptr);
|
||
|
||
#ifdef GCTL_EIGEN
|
||
|
||
template <typename T> void save_data(std::string dataname, const Eigen::Matrix<T, Eigen::Dynamic, 1> &in_data, mesh_data_type_e datatype, const Eigen::Matrix<T, Eigen::Dynamic, 1> *in_index = nullptr);
|
||
|
||
#endif // GCTL_EIGEN
|
||
|
||
template <typename E> void element_register(const array<type_triangle2d<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_triangle2d2o<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_rectangle2d<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_node<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_triangle<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_tetrahedron<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_block<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_tricone<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
template <typename E> void element_register(const array<type_prism<E>> &element, const _2i_matrix *tag_ptr = nullptr, array<size_t> *rgst_index = nullptr);
|
||
|
||
template <typename A> void save_registered_mesh(const array<vertex<point2dc, A>> &node, array<gmsh_physical_group> *phys_ptr = nullptr);
|
||
template <typename A> void save_registered_mesh(const array<vertex<point3dc, A>> &node, array<gmsh_physical_group> *phys_ptr = nullptr);
|
||
|
||
protected:
|
||
std::ifstream gmsh_in; // Input stream
|
||
std::ofstream gmsh_out; // Output stream
|
||
index_packed_e in_packed, out_packed; // Whether the input/output node indexes are starting from zero
|
||
std::vector<std::vector<int> > rgst_elem; // registered elements
|
||
};
|
||
|
||
template <typename A>
|
||
void gmshio::read_node(array<vertex<point2dc, A>> &out_nodes)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_node(gmsh_in, out_nodes, in_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename A>
|
||
void gmshio::read_node(array<vertex<point3dc, A>> &out_nodes)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_node(gmsh_in, out_nodes, in_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_edge2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_triangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_triangle2d2o<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_rectangle2d<E>> &out_elements, const array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_node<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_edge<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_triangle<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_tetrahedron<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_block<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_tricone<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_element(array<type_prism<E>> &out_elements, const array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_element(gmsh_in, out_elements, nodes, in_packed, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_triangle2d<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_triangle2d2o<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_rectangle2d<E>> &out_elements, array<vertex<point2dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_node<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_edge<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_triangle<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_tetrahedron<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_block<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_tricone<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::read_mesh(array<type_prism<E>> &out_elements, array<vertex<point3dc, A>> &nodes, _2i_vector *ele_tag)
|
||
{
|
||
read_node(nodes);
|
||
read_element(out_elements, nodes, ele_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::read_data(array<T> &out_data, std::string data_name)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_data(gmsh_in, out_data, data_name);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::read_data(array<T> &out_data, array<size_t> &out_index, std::string data_name)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_data(gmsh_in, out_data, out_index, data_name, in_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::read_data(std::vector<std::vector<T> > &out_data, std::vector<std::string> &out_name,
|
||
mesh_data_type_e d_type, std::vector<std::vector<size_t> > *out_index)
|
||
{
|
||
initialized(Input);
|
||
read_gmsh_data(gmsh_in, out_data, out_name, d_type, out_index, in_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_triangle2d<E>> &element, const array<vertex<point2dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_triangle2d2o<E>> &element, const array<vertex<point2dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_rectangle2d<E>> &element, const array<vertex<point2dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_triangle<E>> &element, const array<vertex<point3dc, A>> &node,
|
||
array<bool> *out_ele_tag, array<bool> *out_node_tag)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed, out_ele_tag, out_node_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_tetrahedron<E>> &element, const array<vertex<point3dc, A>> &node, array<bool> *output_tag)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed, output_tag);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_block<E>> &element, const array<vertex<point3dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_tricone<E>> &element, const array<vertex<point3dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_prism<E>> &element, const array<vertex<point3dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void gmshio::save_mesh(const array<type_tesseroid<E>> &element, const array<vertex<point3dc, A>> &node)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, node, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::save_mesh(const array<type_tetrahedron<E>> &element)
|
||
{
|
||
initialized(Output);
|
||
save2gmsh(gmsh_out, element, out_packed);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const T *in_data, size_t in_size, mesh_data_type_e datatype, const size_t *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, in_size, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const array<T> &in_data, mesh_data_type_e datatype, const array<size_t> *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const std::vector<T> &in_data, mesh_data_type_e datatype, const std::vector<size_t> *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const array<point3c<T>> &in_data, mesh_data_type_e datatype, const array<size_t> *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const std::vector<point3c<T>> &in_data, mesh_data_type_e datatype, const std::vector<size_t> *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
#ifdef GCTL_EIGEN
|
||
|
||
template <typename T>
|
||
void gmshio::save_data(std::string dataname, const Eigen::Matrix<T, Eigen::Dynamic, 1> &in_data, mesh_data_type_e datatype, const Eigen::Matrix<T, Eigen::Dynamic, 1> *in_index)
|
||
{
|
||
initialized(Output);
|
||
save_gmsh_data(gmsh_out, dataname, in_data, datatype, out_packed, in_index);
|
||
return;
|
||
}
|
||
|
||
#endif // GCTL_EIGEN
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_triangle2d<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(5 + c_size);
|
||
tmp_elem[0] = 2; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 3; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(5);
|
||
tmp_elem[0] = 2; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 3; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_triangle2d2o<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(8 + c_size);
|
||
tmp_elem[0] = 9; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 6; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(8);
|
||
tmp_elem[0] = 9; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 6; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_rectangle2d<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(6 + c_size);
|
||
tmp_elem[0] = 3; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(6);
|
||
tmp_elem[0] = 3; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_node<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(3 + c_size);
|
||
tmp_elem[0] = 15; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
tmp_elem[2+c_size] = element[i].vert[0]->id;
|
||
if (out_packed == NotPacked) tmp_elem[2+c_size] += 1;
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(3);
|
||
tmp_elem[0] = 15; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
tmp_elem[2] = element[i].vert[0]->id;
|
||
if (out_packed == NotPacked) tmp_elem[2] += 1;
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_triangle<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(5 + c_size);
|
||
tmp_elem[0] = 2; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 3; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(5);
|
||
tmp_elem[0] = 2; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 3; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_tetrahedron<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(6 + c_size);
|
||
tmp_elem[0] = 4; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(6);
|
||
tmp_elem[0] = 4; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_block<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(10 + c_size);
|
||
tmp_elem[0] = 5; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 8; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(10);
|
||
tmp_elem[0] = 5; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 8; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_tricone<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(6 + c_size);
|
||
tmp_elem[0] = 4; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(6);
|
||
tmp_elem[0] = 4; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 4; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void gmshio::element_register(const array<type_prism<E>> &element, const _2i_matrix *tag_ptr, array<size_t> *rgst_index)
|
||
{
|
||
if (tag_ptr != nullptr && tag_ptr->row_size() != element.size())
|
||
{
|
||
throw runtime_error("Tag size doesn't match with the element size. From gctl::gmshio::element_register(...)");
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->resize(element.size());
|
||
|
||
rgst_elem.reserve(rgst_elem.size() + element.size());
|
||
|
||
std::vector<int> tmp_elem;
|
||
if (tag_ptr != nullptr)
|
||
{
|
||
size_t c_size = tag_ptr->col_size();
|
||
tmp_elem.resize(8 + c_size);
|
||
tmp_elem[0] = 6; tmp_elem[1] = c_size;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < c_size; j++)
|
||
{
|
||
tmp_elem[j+2] = tag_ptr->at(i, j);
|
||
}
|
||
|
||
for (size_t j = 0; j < 6; j++)
|
||
{
|
||
tmp_elem[j+2+c_size] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2+c_size] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_elem.resize(8);
|
||
tmp_elem[0] = 6; tmp_elem[1] = 0;
|
||
for (size_t i = 0; i < element.size(); i++)
|
||
{
|
||
for (size_t j = 0; j < 6; j++)
|
||
{
|
||
tmp_elem[j+2] = element[i].vert[j]->id;
|
||
if (out_packed == NotPacked) tmp_elem[j+2] += 1;
|
||
}
|
||
|
||
if (rgst_index != nullptr) rgst_index->at(i) = rgst_elem.size();
|
||
rgst_elem.push_back(tmp_elem);
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename A>
|
||
void gmshio::save_registered_mesh(const array<vertex<point2dc, A>> &node, array<gmsh_physical_group> *phys_ptr)
|
||
{
|
||
initialized(Output);
|
||
|
||
if (rgst_elem.empty())
|
||
{
|
||
throw runtime_error("No registered elemets found. From gmshio::save_registered_mesh(...)");
|
||
}
|
||
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
gmsh_out.clear(std::ios::goodbit);
|
||
gmsh_out.seekp(0, std::ios::beg);
|
||
|
||
gmsh_out << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
|
||
if (phys_ptr != nullptr)
|
||
{
|
||
gmsh_out << "$PhysicalNames\n";
|
||
gmsh_out << phys_ptr->size() << "\n";
|
||
for (size_t i = 0; i < phys_ptr->size(); i++)
|
||
{
|
||
gmsh_out << phys_ptr->at(i).dim_tag << " " << phys_ptr->at(i).phys_tag << " \"" << phys_ptr->at(i).name << "\"\n";
|
||
}
|
||
gmsh_out << "$EndPhysicalNames\n";
|
||
}
|
||
|
||
// save node
|
||
save2gmsh_node(gmsh_out, node.get(), node.size(), out_packed);
|
||
|
||
// save elements
|
||
gmsh_out << "$Elements" << std::endl << rgst_elem.size() <<std::endl;
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
for (int i = 0; i < rgst_elem.size(); i++)
|
||
{
|
||
if (out_packed == Packed) gmsh_out << i;
|
||
else gmsh_out << i+1;
|
||
|
||
for (size_t j = 0; j < rgst_elem[i].size(); j++)
|
||
{
|
||
gmsh_out << " " << rgst_elem[i][j];
|
||
}
|
||
gmsh_out << std::endl;
|
||
}
|
||
gmsh_out << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename A>
|
||
void gmshio::save_registered_mesh(const array<vertex<point3dc, A>> &node, array<gmsh_physical_group> *phys_ptr)
|
||
{
|
||
initialized(Output);
|
||
|
||
if (rgst_elem.empty())
|
||
{
|
||
throw runtime_error("No registered elemets found. From gmshio::save_registered_mesh(...)");
|
||
}
|
||
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
gmsh_out.clear(std::ios::goodbit);
|
||
gmsh_out.seekp(0, std::ios::beg);
|
||
|
||
gmsh_out << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
|
||
if (phys_ptr != nullptr)
|
||
{
|
||
gmsh_out << "$PhysicalNames\n";
|
||
gmsh_out << phys_ptr->size() << "\n";
|
||
for (size_t i = 0; i < phys_ptr->size(); i++)
|
||
{
|
||
gmsh_out << phys_ptr->at(i).dim_tag << " " << phys_ptr->at(i).phys_tag << " \"" << phys_ptr->at(i).name << "\"\n";
|
||
}
|
||
gmsh_out << "$EndPhysicalNames\n";
|
||
}
|
||
|
||
// save node
|
||
save2gmsh_node(gmsh_out, node.get(), node.size(), out_packed);
|
||
|
||
// save elements
|
||
gmsh_out << "$Elements" << std::endl << rgst_elem.size() <<std::endl;
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
for (int i = 0; i < rgst_elem.size(); i++)
|
||
{
|
||
if (out_packed == Packed) gmsh_out << i;
|
||
else gmsh_out << i+1;
|
||
|
||
for (size_t j = 0; j < rgst_elem[i].size(); j++)
|
||
{
|
||
gmsh_out << " " << rgst_elem[i][j];
|
||
}
|
||
gmsh_out << std::endl;
|
||
}
|
||
gmsh_out << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Read nodes from a Gmsh file.
|
||
*
|
||
* @param[in] infile The input file stream
|
||
* @param node The output 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.
|
||
*
|
||
*/
|
||
template <typename A>
|
||
void read_gmsh_node(std::ifstream &infile, array<vertex<point2dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
// 重置数据
|
||
if (!node.empty()) node.clear();
|
||
|
||
// 将文件指针重置到文件头
|
||
infile.clear(std::ios::goodbit);
|
||
infile.seekg(std::ios::beg);
|
||
|
||
int n_size = 0;
|
||
std::string tmp_str;
|
||
std::stringstream tmp_ss;
|
||
while(getline(infile,tmp_str))
|
||
{
|
||
if (tmp_str == "$Nodes") //读入模型空间顶点集 msh文件版本为2.2
|
||
{
|
||
getline(infile, tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> n_size; //第一个数为顶点的个数
|
||
node.resize(n_size);
|
||
|
||
for (int i = 0; i < n_size; i++)
|
||
{
|
||
getline(infile, tmp_str);
|
||
str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> node[i].id >> node[i].x >> node[i].y;
|
||
if (packed == NotPacked)
|
||
node[i].id -= 1;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Read nodes from a Gmsh file.
|
||
*
|
||
* @param[in] infile The input file stream
|
||
* @param node an array<vertex3dc> object
|
||
* @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.
|
||
*
|
||
*/
|
||
template <typename A>
|
||
void read_gmsh_node(std::ifstream &infile, array<vertex<point3dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
// 重置数据
|
||
if (!node.empty()) node.clear();
|
||
|
||
// 将文件指针重置到文件头
|
||
infile.clear(std::ios::goodbit);
|
||
infile.seekg(std::ios::beg);
|
||
|
||
int n_size = 0;
|
||
std::string tmp_str;
|
||
std::stringstream tmp_ss;
|
||
while(getline(infile,tmp_str))
|
||
{
|
||
if (tmp_str == "$Nodes") //读入模型空间顶点集 msh文件版本为2.2
|
||
{
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> n_size; //第一个数为顶点的个数
|
||
node.resize(n_size);
|
||
|
||
for (int i = 0; i < n_size; i++)
|
||
{
|
||
getline(infile,tmp_str);
|
||
str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> node[i].id >> node[i].x >> node[i].y >> node[i].z;
|
||
if (packed == NotPacked)
|
||
node[i].id -= 1;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
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.
|
||
*
|
||
* @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_triangle2d<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[3];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
triangle2d tmp_tri;
|
||
std::vector<triangle2d> 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 == 2)
|
||
{
|
||
tmp_tri.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] >> tmp_index[2];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
element_vec.push_back(tmp_tri);
|
||
|
||
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 < 3; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
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_triangle2d2o<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[6];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
triangle2d2o tmp_tri;
|
||
std::vector<triangle2d2o> 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 == 9)
|
||
{
|
||
tmp_tri.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] >> tmp_index[2]
|
||
>> tmp_index[3] >> tmp_index[4] >> tmp_index[5];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]-1);
|
||
|
||
tmp_tri.vert[5] = node.get(tmp_index[3]-1);
|
||
tmp_tri.vert[3] = node.get(tmp_index[4]-1);
|
||
tmp_tri.vert[4] = node.get(tmp_index[5]-1);
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]);
|
||
|
||
tmp_tri.vert[5] = node.get(tmp_index[3]);
|
||
tmp_tri.vert[3] = node.get(tmp_index[4]);
|
||
tmp_tri.vert[4] = node.get(tmp_index[5]);
|
||
}
|
||
element_vec.push_back(tmp_tri);
|
||
|
||
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 < 6; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_rectangle2d<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[4];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
rectangle2d tmp_rect;
|
||
std::vector<rectangle2d> 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 == 3)
|
||
{
|
||
tmp_rect.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] >> tmp_index[2] >> tmp_index[3];
|
||
if (packed == NotPacked)
|
||
{
|
||
tmp_rect.dl = node.get(tmp_index[0]-1);
|
||
tmp_rect.ur = node.get(tmp_index[2]-1);
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
tmp_rect.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_rect.dl = node.get(tmp_index[0]);
|
||
tmp_rect.ur = node.get(tmp_index[2]);
|
||
for (int j = 0; j < 4; j++)
|
||
tmp_rect.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
element_vec.push_back(tmp_rect);
|
||
|
||
ele_count++;
|
||
}
|
||
}
|
||
|
||
//将元素转移到向量上来
|
||
element.resize(element_vec.size());
|
||
for (int i = 0; i < element.size(); i++)
|
||
{
|
||
element[i].id = element_vec[i].id;
|
||
element[i].dl = element_vec[i].dl;
|
||
element[i].ur = element_vec[i].ur;
|
||
for (int j = 0; j < 4; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_node<E>> &element,
|
||
const array<vertex<point3dc, 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;
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
enode tmp_node;
|
||
std::vector<enode> 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 == 15)
|
||
{
|
||
tmp_node.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;
|
||
|
||
if (packed == NotPacked) tmp_node.vert[0] = node.get(tmp_index-1);
|
||
else tmp_node.vert[0] = node.get(tmp_index);
|
||
|
||
element_vec.push_back(tmp_node);
|
||
ele_count++;
|
||
}
|
||
}
|
||
|
||
//将元素转移到向量上来
|
||
element.resize(element_vec.size());
|
||
for (int i = 0; i < element.size(); i++)
|
||
{
|
||
element[i].id = element_vec[i].id;
|
||
element[i].vert[0] = element_vec[i].vert[0];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_edge<E>> &element,
|
||
const array<vertex<point3dc, 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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
edge tmp_tri;
|
||
std::vector<edge> 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_tri.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_tri.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 2; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
element_vec.push_back(tmp_tri);
|
||
|
||
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;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_triangle<E>> &element,
|
||
const array<vertex<point3dc, 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[3];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
triangle tmp_tri;
|
||
std::vector<triangle> 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 == 2)
|
||
{
|
||
tmp_tri.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] >> tmp_index[2];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
tmp_tri.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
element_vec.push_back(tmp_tri);
|
||
|
||
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 < 3; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_tetrahedron<E>> &element,
|
||
const array<vertex<point3dc, 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[4];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
tetrahedron tmp_tet;
|
||
std::vector<tetrahedron> 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 == 4)
|
||
{
|
||
tmp_tet.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] >> tmp_index[2] >> tmp_index[3];
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 4; j++)
|
||
tmp_tet.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 4; j++)
|
||
tmp_tet.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
element_vec.push_back(tmp_tet);
|
||
|
||
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 < 4; j++)
|
||
{
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
element[i].deter_vert_order();
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_block<E>> &element,
|
||
const array<vertex<point3dc, 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[8];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
block tmp_block;
|
||
std::vector<block> 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 == 5)
|
||
{
|
||
tmp_block.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);
|
||
|
||
for (int a = 0; a < 8; a++)
|
||
tmp_ss >> tmp_index[a];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
tmp_block.dl = node.get(tmp_index[0]-1);
|
||
tmp_block.ur = node.get(tmp_index[6]-1);
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
tmp_block.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
tmp_block.dl = node.get(tmp_index[0]);
|
||
tmp_block.ur = node.get(tmp_index[6]);
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
tmp_block.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
}
|
||
element_vec.push_back(tmp_block);
|
||
|
||
ele_count++;
|
||
}
|
||
}
|
||
|
||
//将元素转移到向量上来
|
||
element.resize(element_vec.size());
|
||
for (int i = 0; i < element.size(); i++)
|
||
{
|
||
element[i].id = element_vec[i].id;
|
||
element[i].dl = element_vec[i].dl;
|
||
element[i].ur = element_vec[i].ur;
|
||
for (int j = 0; j < 8; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_tricone<E>> &element,
|
||
const array<vertex<point3dc, 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[3];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
tri_cone tmp_cone;
|
||
std::vector<tri_cone> 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 == 2)
|
||
{
|
||
tmp_cone.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] >> tmp_index[2];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
tmp_cone.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
tmp_cone.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
}
|
||
element_vec.push_back(tmp_cone);
|
||
|
||
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 < 3; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void read_gmsh_element(std::ifstream &infile, array<type_prism<E>> &element,
|
||
const array<vertex<point3dc, 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[6];
|
||
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; //第一个数为顶点的个数
|
||
|
||
// 我们先用一个临时的向量来储存元素
|
||
prism tmp_prism;
|
||
std::vector<prism> 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 == 6)
|
||
{
|
||
tmp_prism.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] >> tmp_index[2]
|
||
>> tmp_index[3] >> tmp_index[4] >> tmp_index[5];
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int j = 0; j < 6; j++)
|
||
{
|
||
tmp_prism.vert[j] = node.get(tmp_index[j]-1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < 6; j++)
|
||
{
|
||
tmp_prism.vert[j] = node.get(tmp_index[j]);
|
||
}
|
||
}
|
||
element_vec.push_back(tmp_prism);
|
||
|
||
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 < 6; j++)
|
||
element[i].vert[j] = element_vec[i].vert[j];
|
||
}
|
||
destroy_vector(element_vec);
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Read data block from a Gmsh .msh file.
|
||
*
|
||
* @param infile The input file stream
|
||
* @param out_data Output data name
|
||
* @param[in] data_name Name of the data block that will be output. The first data block will
|
||
* be output if this no data name is given.
|
||
*/
|
||
template <typename T>
|
||
void read_gmsh_data(std::ifstream &infile, array<T> &out_data, std::string data_name = "")
|
||
{
|
||
std::string requst_name = "";
|
||
if (data_name != "")
|
||
requst_name = "\"" + data_name + "\"";
|
||
|
||
// 将文件指针重置到文件头
|
||
infile.clear(std::ios::goodbit);
|
||
infile.seekg(std::ios::beg);
|
||
|
||
bool data_found = false;
|
||
int tmp_int, data_size;
|
||
std::string tmp_str;
|
||
std::stringstream tmp_ss;
|
||
while(getline(infile, tmp_str))
|
||
{
|
||
if (tmp_str == "$NodeData" || tmp_str == "$ElementData")
|
||
{
|
||
//先读入元素块的名称 添加到数组
|
||
for (int i = 0; i < 2; i++)
|
||
getline(infile, tmp_str);
|
||
|
||
if (requst_name == "" || requst_name == tmp_str)
|
||
{
|
||
data_found = true;
|
||
//跳过元素属性前面的值 最后一次为当前元素块的个数
|
||
for (int i = 0; i < 6; i++)
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> data_size;
|
||
out_data.resize(data_size);
|
||
|
||
for (int i = 0; i < data_size; i++)
|
||
{
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> tmp_int >> out_data[i];
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!data_found)
|
||
{
|
||
throw runtime_error("data not found for: " + data_name + ". From void gctl::read_gmsh_data(..)");
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Read data block from a Gmsh .msh file.
|
||
*
|
||
* @param infile The input file stream
|
||
* @param out_data Output data name
|
||
* @param out_index Output data index
|
||
* @param[in] data_name Name of the data block that will be output. The first data block will
|
||
* be output if this no data name is given.
|
||
* @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.
|
||
*/
|
||
template <typename T>
|
||
void read_gmsh_data(std::ifstream &infile, array<T> &out_data, array<size_t> &out_index,
|
||
std::string data_name = "", index_packed_e packed = Packed)
|
||
{
|
||
std::string requst_name = "";
|
||
if (data_name != "")
|
||
requst_name = "\"" + data_name + "\"";
|
||
|
||
// 将文件指针重置到文件头
|
||
infile.clear(std::ios::goodbit);
|
||
infile.seekg(std::ios::beg);
|
||
|
||
bool data_found = false;
|
||
int tmp_int, data_size;
|
||
std::string tmp_str;
|
||
std::stringstream tmp_ss;
|
||
while(getline(infile, tmp_str))
|
||
{
|
||
if (tmp_str == "$NodeData" || tmp_str == "$ElementData")
|
||
{
|
||
//先读入元素块的名称 添加到数组
|
||
for (int i = 0; i < 2; i++)
|
||
getline(infile, tmp_str);
|
||
|
||
if (requst_name == "" || requst_name == tmp_str)
|
||
{
|
||
data_found = true;
|
||
//跳过元素属性前面的值 最后一次为当前元素块的个数
|
||
for (int i = 0; i < 6; i++)
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> data_size;
|
||
out_data.resize(data_size);
|
||
out_index.resize(data_size, -1);
|
||
|
||
for (int i = 0; i < data_size; i++)
|
||
{
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> out_index[i] >> out_data[i];
|
||
}
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (int i = 0; i < data_size; i++)
|
||
out_index[i] -= 1;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!data_found)
|
||
{
|
||
throw runtime_error("data not found for: " + data_name + ". From void gctl::read_gmsh_data(..)");
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename T>
|
||
void read_gmsh_data(std::ifstream &infile, std::vector<std::vector<T> > &out_data,
|
||
std::vector<std::string> &out_name, mesh_data_type_e d_type,
|
||
std::vector<std::vector<size_t> > *out_index = nullptr, index_packed_e packed = NotPacked)
|
||
{
|
||
// 将文件指针重置到文件头
|
||
infile.clear(std::ios::goodbit);
|
||
infile.seekg(std::ios::beg);
|
||
|
||
std::string tar_str;
|
||
if (d_type == NodeData) tar_str = "$NodeData";
|
||
else if (d_type == ElemData) tar_str = "$ElementData";
|
||
else throw std::runtime_error("Invalid mesh data type. From gctl::read_gmsh_data(...)");
|
||
|
||
int tmp_int, data_size;
|
||
std::string tmp_str;
|
||
std::stringstream tmp_ss;
|
||
std::vector<T> tmp_data;
|
||
std::vector<size_t> tmp_index;
|
||
while(getline(infile, tmp_str))
|
||
{
|
||
if (tmp_str == tar_str)
|
||
{
|
||
//先读入元素块的名称 添加到数组
|
||
for (int i = 0; i < 2; i++)
|
||
getline(infile, tmp_str);
|
||
|
||
tmp_str.erase(0, 1); // 删除第一个引号
|
||
tmp_str.erase(tmp_str.end() - 1); // 删除末尾的引号
|
||
out_name.push_back(tmp_str);
|
||
|
||
//跳过元素属性前面的值 最后一次为当前元素块的个数
|
||
for (int i = 0; i < 6; i++)
|
||
getline(infile, tmp_str);
|
||
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> data_size;
|
||
tmp_data.clear();
|
||
tmp_data.resize(data_size, 0.0);
|
||
|
||
if(out_index != nullptr)
|
||
{
|
||
tmp_index.clear();
|
||
tmp_index.resize(data_size);
|
||
|
||
for (int i = 0; i < data_size; i++)
|
||
{
|
||
getline(infile, tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> tmp_index[i] >> tmp_data[i];
|
||
}
|
||
|
||
if (packed == NotPacked)
|
||
{
|
||
for (size_t i = 0; i < data_size; i++)
|
||
{
|
||
tmp_index[i] -= 1;
|
||
}
|
||
}
|
||
|
||
out_data.push_back(tmp_data);
|
||
out_index->push_back(tmp_index);
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < data_size; i++)
|
||
{
|
||
getline(infile,tmp_str);
|
||
gctl::str2ss(tmp_str, tmp_ss);
|
||
tmp_ss >> tmp_int >> tmp_data[i];
|
||
}
|
||
|
||
out_data.push_back(tmp_data);
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save Gmsh node block.
|
||
*
|
||
* @warning This function is designed for internal usage. Don't call this function directly.
|
||
*
|
||
* @tparam A Attribute type of the vertex
|
||
* @param outfile Output file stream
|
||
* @param node_x Pointer of the node array
|
||
* @param node_size Size of the node array
|
||
* @param packed Whether the nodes' indexes start from zero (Packed) or one (NotPacked)
|
||
* @param output_tag Whether to output indexed vertex. A vertex will not be output if the tag is false.
|
||
* Note that passing a output_tag array will reset index of associated vertexes. Use this will caution.
|
||
*/
|
||
template <typename A>
|
||
void save2gmsh_node(std::ofstream &outfile, vertex<point2dc, A> *node_x, int node_size,
|
||
index_packed_e packed = Packed, bool *output_tag = nullptr)
|
||
{
|
||
// 将文件指针重置到文件尾
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(0, std::ios::end);
|
||
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
if (packed == Packed)
|
||
{
|
||
if (output_tag != nullptr)
|
||
{
|
||
int valid_count = 0;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i]) valid_count++;
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Nodes" << std::endl << valid_count << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
node_x[i].id = valid_id; valid_id++;
|
||
outfile << node_x[i].id << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " 0.0" << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
outfile << "$Nodes" << std::endl << node_size << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
outfile << node_x[i].id << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " 0.0" << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (output_tag != nullptr)
|
||
{
|
||
int valid_count = 0;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i]) valid_count++;
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Nodes" << std::endl << valid_count << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
node_x[i].id = valid_id; valid_id++;
|
||
outfile << node_x[i].id + 1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " 0.0" << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
outfile << "$Nodes" << std::endl << node_size << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
outfile << node_x[i].id + 1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " 0.0" << std::endl;
|
||
}
|
||
}
|
||
}
|
||
outfile<<"$EndNodes"<<std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save Gmsh node block.
|
||
*
|
||
* @warning This function is designed for internal usage. Don't call this function directly.
|
||
*
|
||
* @tparam A Attribute type of the vertex
|
||
* @param outfile Output file stream
|
||
* @param node_x Pointer of the node array
|
||
* @param node_size Size of the node array
|
||
* @param packed Whether the nodes' indexes start from zero (Packed) or one (NotPacked)
|
||
* @param output_tag Whether to output indexed vertex. A vertex will not be output if the tag is false.
|
||
* Note that passing a output_tag array will reset index of associated vertexes. Use this will caution.
|
||
*/
|
||
template <typename A>
|
||
void save2gmsh_node(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
index_packed_e packed = Packed, bool *output_tag = nullptr)
|
||
{
|
||
// 将文件指针重置到文件尾
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(0, std::ios::end);
|
||
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
if (packed == Packed)
|
||
{
|
||
if (output_tag != nullptr)
|
||
{
|
||
int valid_count = 0;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i]) valid_count++;
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Nodes" << std::endl << valid_count << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
node_x[i].id = valid_id; valid_id++;
|
||
outfile << node_x[i].id << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " " << node_x[i].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
outfile << "$Nodes" << std::endl << node_size << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
outfile << node_x[i].id << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " " << node_x[i].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (output_tag != nullptr)
|
||
{
|
||
int valid_count = 0;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i]) valid_count++;
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Nodes" << std::endl << valid_count << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
node_x[i].id = valid_id; valid_id++;
|
||
outfile << node_x[i].id + 1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " " << node_x[i].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
outfile << "$Nodes" << std::endl << node_size << std::endl;
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
outfile << node_x[i].id + 1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< node_x[i].x << " " << node_x[i].y << " " << node_x[i].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
outfile << "$EndNodes" << std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save 2D/3D meshes to a Gmsh's mesh file.
|
||
*
|
||
* @param[in] outfile Output file stream.
|
||
* @param[in] node_x The vertex2dc array of nodes' coordinates.
|
||
* @param[in] node_size The number of node.
|
||
* @param[in] ele_index The triangle2d array of element's index.
|
||
* @param[in] ele_size The number of element.
|
||
* @param[in] pack Indicates whether to set the starting index of nodes to zero. The
|
||
* node's ordering will start with one if this option is false. The default value of this
|
||
* variable is true.
|
||
*
|
||
* @return status of the function.
|
||
*/
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point2dc, A> *node_x, int node_size,
|
||
const type_triangle2d<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size <<std::endl;
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save 2D/3D meshes to a Gmsh's mesh file.
|
||
*
|
||
* @param[in] outfile Output file stream.
|
||
* @param[in] node_x The vertex2dc array of nodes' coordinates.
|
||
* @param[in] node_size The number of node.
|
||
* @param[in] ele_index The triangle2d2o array of element's index.
|
||
* @param[in] ele_size The number of element.
|
||
* @param[in] pack Indicates whether to set the starting index of nodes to zero. The
|
||
* node's ordering will start with one if this option is false. The default value of this
|
||
* variable is true.
|
||
*
|
||
* @return status of the function.
|
||
*/
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point2dc, A> *node_x, int node_size,
|
||
const type_triangle2d2o<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size <<std::endl;
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 9 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << " " << ele_index[i].vert[5]->id;
|
||
outfile << " " << ele_index[i].vert[3]->id;
|
||
outfile << " " << ele_index[i].vert[4]->id;
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 9 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << " " << ele_index[i].vert[5]->id + 1;
|
||
outfile << " " << ele_index[i].vert[3]->id + 1;
|
||
outfile << " " << ele_index[i].vert[4]->id + 1;
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point2dc, A> *node_x, int node_size,
|
||
const type_rectangle2d<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 3 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 3 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_triangle<E> *ele_index, int ele_size, index_packed_e packed = Packed,
|
||
bool *out_ele_tag = nullptr, bool *out_node_tag = nullptr)
|
||
{
|
||
// Set the file stream to the head
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
// Output head info
|
||
outfile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
|
||
// Count for valid output elements if out_ele_tag is not nullptr
|
||
if (out_ele_tag != nullptr && out_node_tag != nullptr)
|
||
{
|
||
array<int> index_backup(node_size); // Backup nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
index_backup[i] = node_x[i].id;
|
||
}
|
||
|
||
array<bool> valid_tag(node_size, false);
|
||
for (size_t i = 0; i < node_size; i++)
|
||
{
|
||
valid_tag[i] = out_node_tag[i];
|
||
}
|
||
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (!valid_tag[i])
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
valid_tag[ele_index[i].vert[j]->id] = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Save nodes
|
||
save2gmsh_node(outfile, node_x, node_size, packed, valid_tag.get());
|
||
|
||
// Save elements
|
||
int valid_ele_count = 0;
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
valid_ele_count++;
|
||
}
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Elements" << std::endl << valid_ele_count << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
outfile << valid_id << " 2 0"; valid_id++;
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
outfile << valid_id + 1 << " 2 0"; valid_id++;
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
outfile << "$EndElements" << std::endl;
|
||
|
||
// Restore nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
node_x[i].id = index_backup[i];
|
||
}
|
||
}
|
||
else if (out_ele_tag != nullptr)
|
||
{
|
||
array<int> index_backup(node_size); // Backup nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
index_backup[i] = node_x[i].id;
|
||
}
|
||
|
||
array<bool> valid_tag(node_size, false);
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
valid_tag[ele_index[i].vert[j]->id] = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Save nodes
|
||
save2gmsh_node(outfile, node_x, node_size, packed, valid_tag.get());
|
||
|
||
// Save elements
|
||
int valid_ele_count = 0;
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
valid_ele_count++;
|
||
}
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Elements" << std::endl << valid_ele_count << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
outfile << valid_id << " 2 0"; valid_id++;
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (out_ele_tag[i])
|
||
{
|
||
outfile << valid_id + 1 << " 2 0"; valid_id++;
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
outfile << "$EndElements" << std::endl;
|
||
|
||
// Restore nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
node_x[i].id = index_backup[i];
|
||
}
|
||
}
|
||
else if (out_node_tag != nullptr)
|
||
{
|
||
array<int> index_backup(node_size); // Backup nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
index_backup[i] = node_x[i].id;
|
||
}
|
||
|
||
// Save nodes
|
||
save2gmsh_node(outfile, node_x, node_size, packed, out_node_tag);
|
||
|
||
// Save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements" << std::endl;
|
||
|
||
// Restore nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
node_x[i].id = index_backup[i];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Save nodes
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// Save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements" << std::endl;
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_tetrahedron<E> *ele_index, int ele_size, index_packed_e packed = Packed,
|
||
bool *output_tag = nullptr)
|
||
{
|
||
// Set the file stream to the head
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
// Output head info
|
||
outfile << "$MeshFormat\n2.2 0 8\n$EndMeshFormat\n";
|
||
// Count for valid output elements if output_tag is not nullptr
|
||
if (output_tag != nullptr)
|
||
{
|
||
array<int> index_backup(node_size); // Backup nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
index_backup[i] = node_x[i].id;
|
||
}
|
||
|
||
array<bool> valid_tag(node_size, false);
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
valid_tag[ele_index[i].vert[j]->id] = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Save nodes
|
||
save2gmsh_node(outfile, node_x, node_size, packed, valid_tag.get());
|
||
|
||
// Save elements
|
||
int valid_ele_count = 0;
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
valid_ele_count++;
|
||
}
|
||
}
|
||
|
||
int valid_id = 0;
|
||
outfile << "$Elements" << std::endl << valid_ele_count << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
outfile << valid_id << " 4 0"; valid_id++;
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
if (output_tag[i])
|
||
{
|
||
outfile << valid_id + 1 << " 4 0"; valid_id++;
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
|
||
// Restore nodes' indexes
|
||
for (int i = 0; i < node_size; i++)
|
||
{
|
||
node_x[i].id = index_backup[i];
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 4 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 4 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_block<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 5 0";
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 5 0";
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_tricone<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 2 0";
|
||
for (int j = 0; j < 3; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_prism<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 6 0";
|
||
for (int j = 0; j < 6; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 6 0";
|
||
for (int j = 0; j < 6; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, vertex<point3dc, A> *node_x, int node_size,
|
||
const type_tesseroid<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
// save node
|
||
save2gmsh_node(outfile, node_x, node_size, packed);
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 5 0";
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 5 0";
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void save2gmsh(std::ofstream &outfile, const type_tetrahedron<E> *ele_index, int ele_size, index_packed_e packed = Packed)
|
||
{
|
||
// save head info
|
||
// 将文件指针重置到文件头 保险一点
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(std::ios::beg);
|
||
|
||
outfile << "$MeshFormat" << std::endl
|
||
<< "2.2 0 8" << std::endl
|
||
<< "$EndMeshFormat "<<std::endl;
|
||
|
||
// sort node
|
||
std::vector<vertex3dc*> node_index;
|
||
node_index.reserve(4*ele_size);
|
||
for (int i = 0; i < ele_size; ++i)
|
||
{
|
||
for (int j = 0; j < 4; ++j)
|
||
{
|
||
node_index.push_back(ele_index[i].vert[j]);
|
||
}
|
||
}
|
||
|
||
std::vector<vertex3dc*>::iterator pos;
|
||
std::sort(node_index.begin(), node_index.end()); //对顶点序列由小到大排序
|
||
pos = std::unique(node_index.begin(), node_index.end()); //获取重复序列开始的位置
|
||
node_index.erase(pos, node_index.end()); //删除重复点
|
||
|
||
outfile << "$Nodes" << std::endl << node_index.size() << std::endl;
|
||
// it is better to set the first vertex index to 1 to avoid a display bug in Gmsh
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < node_index.size(); i++)
|
||
{
|
||
outfile << node_index[i]->id << " " << std::setprecision(16)
|
||
<< node_index[i]->x << " " << node_index[i]->y << " " << node_index[i]->z << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < node_index.size(); i++)
|
||
{
|
||
outfile << node_index[i]->id + 1 << " " << std::setprecision(16)
|
||
<< node_index[i]->x << " " << node_index[i]->y << " " << node_index[i]->z << std::endl;
|
||
}
|
||
}
|
||
outfile<<"$EndNodes"<<std::endl;
|
||
|
||
destroy_vector(node_index);
|
||
|
||
// save elements
|
||
outfile << "$Elements" << std::endl << ele_size << std::endl;
|
||
if (packed == Packed)
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i << " 4 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < ele_size; i++)
|
||
{
|
||
outfile << i + 1 << " 4 0";
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
outfile << " " << ele_index[i].vert[j]->id + 1;
|
||
}
|
||
outfile << std::endl;
|
||
}
|
||
}
|
||
outfile << "$EndElements"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save 2D/3D meshes to Gmsh .msh files.
|
||
*
|
||
* @param outfile Output file stream.
|
||
* @param[in] element Output element array
|
||
* @param[in] node Output vertice array
|
||
* @param[in] packed Indicates whether to set the starting index to zero. The
|
||
* node and element's ordering will start with one if this option is false.
|
||
* The default value of this variable is true.
|
||
*/
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_triangle2d<E>> &element,
|
||
const array<vertex<point2dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_triangle2d2o<E>> &element,
|
||
const array<vertex<point2dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_rectangle2d<E>> &element,
|
||
const array<vertex<point2dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_triangle<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed,
|
||
array<bool> *out_ele_tag = nullptr, array<bool> *out_node_tag = nullptr)
|
||
{
|
||
if (out_ele_tag != nullptr && out_node_tag != nullptr)
|
||
{
|
||
if (element.size() != out_ele_tag->size() || node.size() != out_node_tag->size())
|
||
{
|
||
throw gctl::runtime_error("Incompatible tag size. From save2gmsh(...)");
|
||
return;
|
||
}
|
||
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed, out_ele_tag->get(), out_node_tag->get());
|
||
}
|
||
else if (out_ele_tag != nullptr)
|
||
{
|
||
if (element.size() != out_ele_tag->size())
|
||
{
|
||
throw gctl::runtime_error("Incompatible tag size. From save2gmsh(...)");
|
||
return;
|
||
}
|
||
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed, out_ele_tag->get());
|
||
}
|
||
else if (out_node_tag != nullptr)
|
||
{
|
||
if (node.size() != out_node_tag->size())
|
||
{
|
||
throw gctl::runtime_error("Incompatible tag size. From save2gmsh(...)");
|
||
return;
|
||
}
|
||
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed, nullptr, out_node_tag->get());
|
||
}
|
||
else
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_tetrahedron<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed,
|
||
array<bool> *output_tag = nullptr)
|
||
{
|
||
if (output_tag != nullptr)
|
||
{
|
||
if (element.size() != output_tag->size())
|
||
{
|
||
throw gctl::runtime_error("Incompatible tag size. From save2gmsh(...)");
|
||
return;
|
||
}
|
||
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed, output_tag->get());
|
||
}
|
||
else
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
}
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_block<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_tricone<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_prism<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E, typename A>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_tesseroid<E>> &element,
|
||
const array<vertex<point3dc, A>> &node, index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, node.get(), node.size(), element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
template <typename E>
|
||
void save2gmsh(std::ofstream &outfile, const array<type_tetrahedron<E>> &element,
|
||
index_packed_e packed = Packed)
|
||
{
|
||
save2gmsh(outfile, element.get(), element.size(), packed);
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save a Gmsh data block to a given file.
|
||
*
|
||
* @param[in] filename The filename of the file that in_data is going to be added into.
|
||
* @param[in] dataname Name of the data that is going to be saved.
|
||
* @param[in] in_data Pointer of the double array of the input data.
|
||
* @param[in] d_size Number of the input data.
|
||
* @param[in] in_index Pointer of the int array of the input data's index. The size of in_index
|
||
* must be equal to in_data.
|
||
* @param[in] data_type The data type to be save. This enum could be equals to NODE_DATA
|
||
* or ELEMENT_DATA.
|
||
* @param[in] pack Indicates whether to set the starting index of data to zero.
|
||
* The data ordering will start with one if this option is false. The default value of
|
||
* this variable is true.
|
||
*
|
||
* @return status of the function
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const T *in_data,
|
||
int d_size, mesh_data_type_e datatype, index_packed_e packed = Packed, const size_t *in_index = nullptr)
|
||
{
|
||
if (in_data == nullptr)
|
||
{
|
||
throw runtime_error("Null data pointer. From void gctl::save_gmsh_data(...)");
|
||
}
|
||
|
||
if (d_size <= 0)
|
||
{
|
||
throw runtime_error("Invalid array size. From void gctl::save_gmsh_data(...)");
|
||
}
|
||
|
||
// 将文件指针重置到文件尾
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(0, std::ios::end);
|
||
|
||
if (datatype == NodeData)
|
||
outfile<<"$NodeData"<<std::endl;
|
||
else if (datatype == ElemData || datatype == ElemData2D || datatype == ElemData3D)
|
||
outfile<<"$ElementData"<<std::endl;
|
||
|
||
int valid_size = 0;
|
||
for (int i = 0; i < d_size; i++)
|
||
{
|
||
if (!std::isnan(in_data[i])) valid_size++;
|
||
}
|
||
|
||
outfile<<1<<std::endl
|
||
<<"\"" << dataname << "\"" <<std::endl
|
||
<<1<<std::endl<<0.0<<std::endl
|
||
<<3<<std::endl<<0<<std::endl
|
||
<<1<<std::endl<<valid_size<<std::endl;
|
||
|
||
if (packed == Packed && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << in_index[j] << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else if (packed == NotPacked && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << in_index[j]+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else if (packed == Packed && in_index == nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << j << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << j+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
|
||
if (datatype == NodeData)
|
||
outfile << "$EndNodeData" << std::endl;
|
||
else
|
||
outfile << "$EndElementData"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief 保存Gmsh模型数据单元
|
||
*
|
||
* @param outfile 输出文件流
|
||
* @param[in] dataname 模型数据名称
|
||
* @param[in] in_data 模型数据数组
|
||
* @param[in] datatype 模型数据类型
|
||
* @param[in] in_index 模型数据索引数组的指针,为空时则依序储存模型数据数组
|
||
* @param[in] pack 输出模型数组索引是否从0开始,为假时索引值从1开始
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const array<T> &in_data,
|
||
mesh_data_type_e datatype, index_packed_e packed = Packed, const array<size_t> *in_index = nullptr)
|
||
{
|
||
if (in_index != nullptr)
|
||
{
|
||
save_gmsh_data(outfile, dataname, in_data.get(), in_data.size(), datatype, packed, in_index->get());
|
||
}
|
||
else save_gmsh_data(outfile, dataname, in_data.get(), in_data.size(), datatype, packed);
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief 保存Gmsh模型数据单元
|
||
*
|
||
* @param outfile 输出文件流
|
||
* @param[in] dataname 模型数据名称
|
||
* @param[in] in_data 模型数据数组
|
||
* @param[in] datatype 模型数据类型
|
||
* @param[in] in_index 模型数据索引数组的指针,为空时则依序储存模型数据数组
|
||
* @param[in] pack 输出模型数组索引是否从0开始,为假时索引值从1开始
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const std::vector<T> &in_data,
|
||
mesh_data_type_e datatype, index_packed_e packed = Packed, const std::vector<size_t> *in_index = nullptr)
|
||
{
|
||
if (in_index != nullptr)
|
||
{
|
||
save_gmsh_data(outfile, dataname, in_data.data(), in_data.size(), datatype, packed, in_index->data());
|
||
}
|
||
else save_gmsh_data(outfile, dataname, in_data.data(), in_data.size(), datatype, packed);
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief Save a Gmsh data block to a given file.
|
||
*
|
||
* @param[in] filename The filename of the file that in_data is going to be added into.
|
||
* @param[in] dataname Name of the data that is going to be saved.
|
||
* @param[in] in_data Pointer of the point3dc array of the input data.
|
||
* @param[in] d_size Number of the input data.
|
||
* @param[in] in_index Pointer of the int array of the input data's index. The size of in_index
|
||
* must be equal to in_data.
|
||
* @param[in] data_type The data type to be save. This enum could be equals to NODE_DATA
|
||
* or ELEMENT_DATA.
|
||
* @param[in] pack Indicates whether to set the starting index of data to zero.
|
||
* The data ordering will start with one if this option is false. The default value of
|
||
* this variable is true.
|
||
*
|
||
* @return status of the function
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const point3c<T> *in_data,
|
||
int d_size, mesh_data_type_e datatype, index_packed_e packed = Packed, const size_t *in_index = nullptr)
|
||
{
|
||
if (in_data == nullptr)
|
||
{
|
||
throw runtime_error("Null data pointer. From void gctl::save_gmsh_data(...)");
|
||
}
|
||
|
||
if (d_size <= 0)
|
||
{
|
||
throw runtime_error("Invalid array size. From void gctl::save_gmsh_data(...)");
|
||
}
|
||
|
||
// 将文件指针重置到文件尾
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(0, std::ios::end);
|
||
|
||
if (datatype == NodeData)
|
||
outfile<<"$NodeData"<<std::endl;
|
||
else if (datatype == ElemData || datatype == ElemData2D || datatype == ElemData3D)
|
||
outfile<<"$ElementData"<<std::endl;
|
||
|
||
int valid_size = 0;
|
||
for (int i = 0; i < d_size; i++)
|
||
{
|
||
if (in_data[i].valid()) valid_size++;
|
||
}
|
||
|
||
outfile<<1<<std::endl
|
||
<<"\"" << dataname << "\"" <<std::endl
|
||
<<1<<std::endl<<0.0<<std::endl
|
||
<<3<<std::endl<<0<<std::endl
|
||
<<3<<std::endl<<valid_size<<std::endl;
|
||
|
||
if (packed == Packed && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (in_data[j].valid())
|
||
{
|
||
outfile << in_index[j] << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< in_data[j].x << " " << in_data[j].y << " " << in_data[j].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else if (packed == NotPacked && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (in_data[j].valid())
|
||
{
|
||
outfile << in_index[j]+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< in_data[j].x << " " << in_data[j].y << " " << in_data[j].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else if (packed == Packed && in_index == nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (in_data[j].valid())
|
||
{
|
||
outfile << j << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< in_data[j].x << " " << in_data[j].y << " " << in_data[j].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (in_data[j].valid())
|
||
{
|
||
outfile << j+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14)
|
||
<< in_data[j].x << " " << in_data[j].y << " " << in_data[j].z << std::endl;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (datatype == NodeData)
|
||
outfile << "$EndNodeData" << std::endl;
|
||
else
|
||
outfile << "$EndElementData"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief 保存Gmsh模型数据单元
|
||
*
|
||
* @param outfile 输出文件流
|
||
* @param[in] dataname 模型数据名称
|
||
* @param[in] in_data 模型数据数组
|
||
* @param[in] datatype 模型数据类型
|
||
* @param[in] in_index 模型数据索引数组的指针,为空时则依序储存模型数据数组
|
||
* @param[in] pack 输出模型数组索引是否从0开始,为假时索引值从1开始
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const array<point3c<T>> &in_data,
|
||
mesh_data_type_e datatype, index_packed_e packed = Packed, const array<size_t> *in_index = nullptr)
|
||
{
|
||
if (in_index != nullptr)
|
||
{
|
||
save_gmsh_data(outfile, dataname, in_data.get(), in_data.size(), datatype, packed, in_index->get());
|
||
}
|
||
else save_gmsh_data(outfile, dataname, in_data.get(), in_data.size(), datatype, packed);
|
||
return;
|
||
}
|
||
|
||
/**
|
||
* @brief 保存Gmsh模型数据单元
|
||
*
|
||
* @param outfile 输出文件流
|
||
* @param[in] dataname 模型数据名称
|
||
* @param[in] in_data 模型数据数组
|
||
* @param[in] datatype 模型数据类型
|
||
* @param[in] in_index 模型数据索引数组的指针,为空时则依序储存模型数据数组
|
||
* @param[in] pack 输出模型数组索引是否从0开始,为假时索引值从1开始
|
||
*/
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const std::vector<point3c<T>> &in_data,
|
||
mesh_data_type_e datatype, index_packed_e packed = Packed, const std::vector<size_t> *in_index = nullptr)
|
||
{
|
||
if (in_index != nullptr)
|
||
{
|
||
save_gmsh_data(outfile, dataname, in_data.data(), in_data.size(), datatype, packed, in_index->data());
|
||
}
|
||
else save_gmsh_data(outfile, dataname, in_data.data(), in_data.size(), datatype, packed);
|
||
return;
|
||
}
|
||
|
||
#ifdef GCTL_EIGEN
|
||
|
||
template <typename T>
|
||
void save_gmsh_data(std::ofstream &outfile, std::string dataname, const Eigen::Matrix<T, Eigen::Dynamic, 1> &in_data,
|
||
mesh_data_type_e datatype, index_packed_e packed = Packed, const Eigen::Matrix<T, Eigen::Dynamic, 1> *in_index = nullptr)
|
||
{
|
||
size_t d_size = in_data.size();
|
||
if (d_size <= 0)
|
||
{
|
||
throw runtime_error("Invalid array size. From void gctl::save_gmsh_data(...)");
|
||
}
|
||
|
||
// 将文件指针重置到文件尾
|
||
outfile.clear(std::ios::goodbit);
|
||
outfile.seekp(0, std::ios::end);
|
||
|
||
if (datatype == NodeData)
|
||
outfile<<"$NodeData"<<std::endl;
|
||
else if (datatype == ElemData || datatype == ElemData2D || datatype == ElemData3D)
|
||
outfile<<"$ElementData"<<std::endl;
|
||
|
||
int valid_size = 0;
|
||
for (int i = 0; i < d_size; i++)
|
||
{
|
||
if (!std::isnan(in_data[i])) valid_size++;
|
||
}
|
||
|
||
outfile<<1<<std::endl
|
||
<<"\"" << dataname << "\"" <<std::endl
|
||
<<1<<std::endl<<0.0<<std::endl
|
||
<<3<<std::endl<<0<<std::endl
|
||
<<1<<std::endl<<valid_size<<std::endl;
|
||
|
||
if (packed == Packed && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << in_index->coeff(j) << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else if (packed == NotPacked && in_index != nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << in_index->coeff(j)+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else if (packed == Packed && in_index == nullptr)
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << j << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (int j = 0; j < d_size; j++)
|
||
{
|
||
if (!std::isnan(in_data[j]))
|
||
outfile << j+1 << " " << std::setiosflags(std::ios::scientific) << std::setprecision(14) << in_data[j] << std::endl;
|
||
}
|
||
}
|
||
|
||
if (datatype == NodeData)
|
||
outfile << "$EndNodeData" << std::endl;
|
||
else
|
||
outfile << "$EndElementData"<< std::endl;
|
||
return;
|
||
}
|
||
|
||
#endif // GCTL_EIGEN
|
||
|
||
};
|
||
|
||
#endif //_GCTL_GMSH_IO_H
|