v0.16.0
Loading...
Searching...
No Matches
Functions | Variables
mesh_tag_transfer.cpp File Reference

extract mesh tag tool to extract a mesh tag and write to new mesh file. Can be used to extract a component of an existing vector tag. More...

#include <MoFEM.hpp>

Go to the source code of this file.

Functions

int main (int argc, char *argv[])
 

Variables

static char help [] = "...\n\n"
 

Detailed Description

extract mesh tag tool to extract a mesh tag and write to new mesh file. Can be used to extract a component of an existing vector tag.

NOTE: Only supports extracting one component from tags defined on tetrahedral entities and creates new tag on same entities. Can be extended to support other entity types as needed.

Definition in file mesh_tag_transfer.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 16 of file mesh_tag_transfer.cpp.

16 {
17 MoFEM::Core::Initialize(&argc, &argv, (char *)0, help);
18
19 try {
20
21 moab::Core mb_instance;
22 moab::Interface &moab = mb_instance;
23
24 char mesh_file_name[255] = "mesh.h5m";
25 char mesh_out_file[255] = "out.h5m";
26 char tag_name[255] = "new_tag";
27 char extract_tag_name[255] = "old_tag_name";
28 int extract_component = 0;
29
30 PetscBool flg_extract_tag_name = PETSC_FALSE;
31 int atom_test = 0;
32
33 PetscBool flg_file = PETSC_FALSE;
34 PetscBool flg_analytical = PETSC_FALSE;
35
36 PetscOptionsBegin(PETSC_COMM_WORLD, "", "none", "none");
37 CHKERR PetscOptionsString("-file_name", "mesh file name", "", "mesh.h5m",
38 mesh_file_name, 255, &flg_file);
39 CHKERR PetscOptionsString("-create_tag_name", "name of tag to create", "",
40 "", tag_name, 255, PETSC_NULLPTR);
41 CHKERR PetscOptionsString("-extract_tag_name",
42 "name of tag to extract from", "", "",
43 extract_tag_name, 255, &flg_extract_tag_name);
44 CHKERR PetscOptionsInt("-component_to_extract",
45 "component of vector tag to extract (0-based index)",
46 "", extract_component, &extract_component,
47 PETSC_NULLPTR);
48 CHKERR PetscOptionsString("-output_file", "output mesh file name", "",
49 "out.h5m", mesh_out_file, 255, PETSC_NULLPTR);
50 CHKERR PetscOptionsInt("-atom_test", "flag to create tag for test", "",
51 atom_test, &atom_test, PETSC_NULLPTR);
52 CHKERR PetscOptionsBool("-use_analytical_tag",
53 "bool to use coded analytical function", "",
54 flg_analytical, &flg_analytical, PETSC_NULLPTR);
55 PetscOptionsEnd();
56
57 const char *option;
58 option = "";
59 CHKERR moab.load_file(mesh_file_name, 0, option);
60
61 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab, MYPCOMM_INDEX);
62 if (pcomm == NULL)
63 pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
64
65 // Create MoFEM database
66 MoFEM::Core core(moab);
67
68 Range ents;
69 std::vector<double> new_tag_values;
70 // default entity type is tets, can be updated as needed
71 EntityType entity_type = MBTET;
72
73 if (atom_test || flg_analytical)
74 entity_type = MBVERTEX;
75
76 if (flg_extract_tag_name) {
77 // Tag extraction only supported on tets for now, can be extended to other entity types as needed
78 CHKERR moab.get_entities_by_type(0, entity_type, ents);
79 // find existing tag to extract value from
80 Tag extract_tag;
81 auto rval = moab.tag_get_handle(extract_tag_name, extract_tag);
82 if (rval != MB_SUCCESS) {
83 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
84 "Failed to get handle for tag '%s'", extract_tag_name);
85 }
86
87 int extract_tag_len;
88 CHKERR moab.tag_get_length(extract_tag, extract_tag_len);
89 MOFEM_LOG("WORLD", Sev::inform)
90 << "Extracting component " << extract_component << " from tag '"
91 << extract_tag_name << "' with length " << extract_tag_len;
92
93 std::vector<double> extract_values(extract_tag_len * ents.size(), 0.0);
94 CHKERR moab.tag_get_data(extract_tag, ents, &extract_values[0]);
95
96 MOFEM_LOG("WORLD", Sev::inform)
97 << "Extracted " << extract_values.size() << " values from tag '"
98 << extract_tag_name << "'";
99
100 // extract specified component into new tag values
101 for (size_t i = 0; i < ents.size(); ++i) {
102 int idx = extract_component; // Assuming 1 component
103 if (idx < extract_tag_len) {
104 new_tag_values.push_back(extract_values[i * extract_tag_len + idx]);
105 } else {
106 SETERRQ(
107 PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
108 "Component index to extract is out of bounds for the tag length");
109 }
110 }
111 MOFEM_LOG("WORLD", Sev::inform) << "Extracted component values for "
112 << new_tag_values.size() << " entities";
113 } else {
114 MOFEM_LOG("WORLD", Sev::warning) << "No tag specified for extraction.";
115 std::vector<double> test_data;
116 if (atom_test) {
117 // Atom test assigns values based on vector index
118 CHKERR moab.get_entities_by_type(0, entity_type, ents);
119
120 std::vector<double> test_data;
121 if (atom_test == 1) {
122 for (size_t i = 0; i < ents.size(); ++i) {
123 // assign index 0-5 for each
124 for (int idx = 0; idx < 5; ++idx) {
125 test_data.push_back(idx);
126 }
127 }
128 } else {
129 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
130 "atom test '%i' does not exist for setting a tag", atom_test);
131 }
132
133 for (const auto &val : test_data) {
134 new_tag_values.push_back(val);
135 }
136 } else if (flg_analytical) {
137 // create new tag for youngs modulus and set value based on analytical function
139 const std::vector<double> &x,
140 const std::vector<double> &y,
141 const std::vector<double> &z, int) {
142 std::vector<double> youngs_modulus;
143 youngs_modulus.reserve(x.size());
144
145 for (double xi : x) {
146 double E0 = 1000.0;
147 double local = E0 * std::exp(xi);
148 youngs_modulus.push_back(local);
149 }
150
151 return youngs_modulus;
152 };
153
154 std::vector<double> coords(3 * ents.size(), 0.0);
155 CHKERR moab.get_coords(ents, &coords[0]);
156
157 for (size_t i = 0; i < ents.size(); ++i) {
158 double x = coords[3 * i + 0];
159 double y = coords[3 * i + 1];
160 double z = coords[3 * i + 2];
161
162 double val = analytical_elastic(0.0, 0.0, {x}, {y}, {z}, 0)[0];
163 test_data.push_back(val);
164 }
165
166 for (const auto &val : test_data) {
167 new_tag_values.push_back(val);
168 }
169 } else {
170 MOFEM_LOG("WORLD", Sev::warning) << "No tag has been created.";
171 }
172 }
173
174 // print the range of new tag values for verification
175 auto minmax =
176 std::minmax_element(new_tag_values.begin(), new_tag_values.end());
177 MOFEM_LOG("WORLD", Sev::inform)
178 << "New tag '" << tag_name << "' value range: [" << *minmax.first
179 << ", " << *minmax.second << "]";
180
181 // Create new tag and set value
182 std::vector<double> def_val;
183
184 if (atom_test == 1) {
185 def_val = {0.0, 0.0, 0.0, 0.0, 0.0};
186 } else {
187 def_val = {0.0};
188 }
189
190 Tag new_tag;
191 CHKERR moab.tag_get_handle(tag_name, def_val.size(), MB_TYPE_DOUBLE, new_tag,
192 MB_TAG_CREAT | MB_TAG_DENSE, &def_val);
193
194 CHKERR moab.tag_set_data(new_tag, ents, &new_tag_values[0]);
195
196 // write output mesh with new tag
197 CHKERR moab.write_file(mesh_out_file, "MOAB", "PARALLEL=WRITE_PART");
198 CHKERR moab.write_file("out.vtk", "vtk");
199
200 // check results
201 if (atom_test == 1) {
202 std::vector<double> check_values(new_tag_values.size(), 0.0);
203 CHKERR moab.tag_get_data(new_tag, ents, &check_values[0]);
204 MOFEM_LOG("WORLD", Sev::inform)
205 << "check_values size: " << check_values.size()
206 << ", new_tag_values size: " << new_tag_values.size();
207
208 for (size_t i = 0; i < new_tag_values.size(); ++i) {
209 if (std::abs(check_values[i] - new_tag_values[i]) > 1e-6) {
210 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
211 "Atom test failed: Value mismatch at index %zu: expected %f, "
212 "got %f",
213 i, new_tag_values[i], check_values[i]);
214 }
215 }
216 } else if (atom_test == 2) {
217 // For index test, check that extracted values match the expected component index
218 // instead of new_tag_values use expected values based on component index
219 std::vector<double> expected_values(new_tag_values.size(), 0.0);
220 CHKERR moab.tag_get_data(new_tag, ents, &expected_values[0]);
221 MOFEM_LOG("WORLD", Sev::inform)
222 << "check_values size: " << expected_values.size()
223 << ", new_tag_values size: " << new_tag_values.size();
224
225 for (size_t i = 0; i < expected_values.size(); ++i) {
226 if (std::abs(expected_values[i] - extract_component) > 1e-6) {
227 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
228 "Tag extraction test failed: Value mismatch at index %zu: "
229 "expected %i, got %f",
230 i, extract_component, expected_values[i]);
231 }
232 }
233 } else if (atom_test > 0) {
234 SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY,
235 "atom test %i does not exist", atom_test);
236 }
237 }
239
241
242 return 0;
243}
#define CATCH_ERRORS
Catch errors.
#define MYPCOMM_INDEX
default communicator number PCOMM
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
static char help[]
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
analytical_elastic(delta_t, t, x, y, z, block_name)
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
int atom_test
Atom test.
Definition plastic.cpp:122

Variable Documentation

◆ help

char help[] = "...\n\n"
static

Definition at line 14 of file mesh_tag_transfer.cpp.