gctl/lib/io/gmsh_io.cpp
2025-01-10 16:34:55 +08:00

166 lines
5.2 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.
******************************************************/
#include "gmsh_io.h"
gctl::gmshio::gmshio()
{
in_packed = out_packed = Packed;
}
gctl::gmshio::gmshio(std::string filename, file_direction_e f_direct)
{
init_file(filename, f_direct);
}
gctl::gmshio::~gmshio()
{
if (gmsh_in.is_open()) gmsh_in.close();
if (gmsh_out.is_open()) gmsh_out.close();
if (!rgst_elem.empty()) destroy_vector(rgst_elem);
}
void gctl::gmshio::init_file(std::string filename, file_direction_e f_direct)
{
if (filename == "")
throw runtime_error("Empty filename. From gmshio::init_file(...)");
if (f_direct == Input)
{
open_infile(gmsh_in, filename, ".msh");
}
else if (f_direct == Output)
{
open_outfile(gmsh_out, filename, ".msh");
}
return;
}
void gctl::gmshio::reset_file(std::string filename, file_direction_e f_direct)
{
if (filename == "")
throw runtime_error("Empty filename. From gmshio::reset_file(...)");
if (f_direct == Input)
{
if (gmsh_in.is_open()) gmsh_in.close();
open_infile(gmsh_in, filename, ".msh");
}
else if (f_direct == Output)
{
if (gmsh_out.is_open()) gmsh_out.close();
open_outfile(gmsh_out, filename, ".msh");
}
return;
}
void gctl::gmshio::set_packed(index_packed_e is_packed, file_direction_e f_direct)
{
if (f_direct == Input)
{
in_packed = is_packed;
}
else if (f_direct == Output)
{
out_packed = is_packed;
}
return;
}
bool gctl::gmshio::initialized(file_direction_e f_direct)
{
if (f_direct == Input && gmsh_in.is_open()) return true;
if (f_direct == Output && gmsh_out.is_open()) return true;
throw domain_error("File stream not initialized. From gmshio::initialized(...)");
return false;
}
void gctl::gmshio::read_physical_groups(array<gmsh_physical_group> &phy_groups)
{
initialized(Input);
// 将文件指针重置到文件头
gmsh_in.clear(std::ios::goodbit);
gmsh_in.seekg(0, std::ios::beg);
size_t phys_num;
std::string tmp_str, tmp_str2;
std::stringstream tmp_ss;
while (getline(gmsh_in, tmp_str))
{
if (tmp_str == "$PhysicalNames")
{
getline(gmsh_in, tmp_str);
gctl::str2ss(tmp_str, tmp_ss);
tmp_ss >> phys_num;
phy_groups.resize(phys_num);
for (size_t i = 0; i < phys_num; i++)
{
getline(gmsh_in, tmp_str);
str2ss(tmp_str, tmp_ss);
tmp_ss >> phy_groups[i].dim_tag >> phy_groups[i].phys_tag >> tmp_str2;
// 去掉两端的双引号
replace_all(phy_groups[i].name, tmp_str2, "\"", "");
}
}
else continue;
}
return;
}
void gctl::gmshio::save_physical_groups(const array<gmsh_physical_group> &phy_groups)
{
initialized(Output);
// 将文件指针重置到文件尾
gmsh_out.clear(std::ios::goodbit);
gmsh_out.seekp(0, std::ios::end);
gmsh_out << "$PhysicalNames\n";
for (size_t i = 0; i < phy_groups.size(); i++)
{
gmsh_out << phy_groups[i].dim_tag << " " << phy_groups[i].phys_tag << " \"" << phy_groups[i].name << "\"\n";
}
gmsh_out << "$EndPhysicalNames\n";
return;
}
int gctl::gmshio::physical_name2tag(const array<gmsh_physical_group> &phy_groups, std::string name)
{
for (size_t i = 0; i < phy_groups.size(); i++)
{
if (phy_groups[i].name == name) return phy_groups[i].phys_tag;
}
throw std::runtime_error("[gctl::gmshio::physical_name2tag] Physical group name not found.");
return -1;
}