21 {
23
24 try {
25
26 moab::Core mb_instance;
27 moab::Interface &moab = mb_instance;
28
29
32
33 char mesh_source_file[255] = "source.h5m";
34 char mesh_target_file[255] = "target.h5m";
35 char mesh_out_file[255] = "out.h5m";
36 char iterp_tag_name[255] = "INTERNAL_STRESS";
37 char output_tag_name[255] = "";
38
39 int interp_order = 1;
40 PetscBool hybrid_interp = PETSC_TRUE;
41 PetscBool src_tag_nodes_to_elem_avg = PETSC_FALSE;
42 PetscBool src_tag_nodes_to_elem_set = PETSC_FALSE;
44
45 double toler = 5.e-10;
46
47 PetscOptionsBegin(m_field.
get_comm(),
"",
"mesh data transfer tool",
48 "none");
49 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
50 "source.h5m", mesh_source_file, 255,
51 PETSC_NULLPTR);
52 CHKERR PetscOptionsString(
"-target_file",
"target mesh file name",
"",
53 "target.h5m", mesh_target_file, 255,
54 PETSC_NULLPTR);
55 CHKERR PetscOptionsString(
"-output_file",
"output mesh file name",
"",
56 "out.h5m", mesh_out_file, 255, PETSC_NULLPTR);
57 CHKERR PetscOptionsString(
"-interp_tag",
"interpolation tag name",
"",
58 "INTERNAL_STRESS", iterp_tag_name, 255,
59 PETSC_NULLPTR);
60 CHKERR PetscOptionsString(
"-output_tag",
"output tag name",
61 "", "", output_tag_name, 255, PETSC_NULLPTR);
62 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
63 &interp_order, PETSC_NULLPTR);
64 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
65 hybrid_interp, &hybrid_interp, PETSC_NULLPTR);
67 "-src_nodes_to_elem", "0: use source nodes directly; 1: average nodes to elements; omitted: use source elements",
68 "", src_tag_nodes_to_elem_avg, &src_tag_nodes_to_elem_avg,
69 &src_tag_nodes_to_elem_set);
70 CHKERR PetscOptionsInt(
"-atom_test",
"atom test number",
"", 0, &
atom_test,
71 PETSC_NULLPTR);
72
73 PetscOptionsEnd();
74
77
78 Coupler::Method method;
79 switch (interp_order) {
80 case 0:
81 method = Coupler::CONSTANT;
82 break;
83 case 1:
84 method = Coupler::LINEAR_FE;
85 break;
86 default:
88 "Unsupported interpolation order");
89 }
90
91 const bool src_tag_nodes =
92 src_tag_nodes_to_elem_set && !src_tag_nodes_to_elem_avg;
93 if (src_tag_nodes && interp_order != 1) {
95 "-src_nodes_to_elem 0 requires -interp_order 1; use "
96 "-src_nodes_to_elem 1 to average nodal data for elemental output");
97 }
98
99 std::vector<std::string> mesh_files(2);
100 mesh_files[0] = string(mesh_source_file);
101 mesh_files[1] = string(mesh_target_file);
102
103 int nprocs, rank;
104 ierr = MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
106 ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
108
109 std::string read_opts, write_opts;
110 read_opts = "PARALLEL=READ_PART;PARTITION=PARALLEL_PARTITION;PARTITION_"
111 "DISTRIBUTE;PARALLEL_RESOLVE_SHARED_ENTS";
112 if (nprocs > 1)
113 read_opts += ";PARALLEL_GHOSTS=3.0.1";
114 write_opts = (nprocs > 1) ? "PARALLEL=WRITE_PART" : "";
115
116 std::vector<boost::shared_ptr<ParallelComm>> pcs(mesh_files.size());
117 std::vector<EntityHandle> roots(mesh_files.size());
118
119 for (
unsigned int i = 0;
i < mesh_files.size();
i++) {
120 pcs[
i] = boost::make_shared<ParallelComm>(&moab, MPI_COMM_WORLD);
121 int index = pcs[
i]->get_id();
122 std::string newread_opts;
123 std::ostringstream extra_opt;
124 extra_opt << ";PARALLEL_COMM=" << index;
125 newread_opts = read_opts + extra_opt.str();
126
127 CHKERR moab.create_meshset(MESHSET_SET, roots[
i]);
128
129 CHKERR moab.load_file(mesh_files[
i].c_str(), &roots[
i],
130 newread_opts.c_str());
131 }
132
133 Range src_elems, targ_elems, targ_verts;
134 CHKERR pcs[0]->get_part_entities(src_elems, 3);
135
137 CHKERR moab.tag_get_handle(iterp_tag_name, interp_tag);
138
139 int interp_tag_len;
140 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
141
142 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
144 "Unsupported interpolation tag length: %d", interp_tag_len);
145 }
146
147 Tag output_tag = interp_tag;
148 if (output_tag_name[0]) {
149 std::vector<double> def_val(interp_tag_len, 0.0);
150 auto rval = moab.tag_get_handle(output_tag_name, interp_tag_len,
151 MB_TYPE_DOUBLE, output_tag,
152 MB_TAG_CREAT | MB_TAG_DENSE,
153 def_val.data());
154 if (
rval == MB_ALREADY_ALLOCATED) {
156 "Output tag '%s' has a conflicting default; use another name",
157 output_tag_name);
158 }
160 }
161
162 if (src_tag_nodes_to_elem_avg) {
163 for (auto &elem : src_elems) {
165 CHKERR moab.get_connectivity(&elem, 1, adj_verts,
true);
166
167 std::vector<double> adj_vert_data(adj_verts.size() * interp_tag_len, 0.0);
168 std::vector<double> elem_data(interp_tag_len, 0.0);
169 CHKERR moab.tag_get_data(interp_tag, adj_verts, adj_vert_data.data());
170
171
172 for (int itag = 0; itag < interp_tag_len; ++itag) {
173 for (size_t ivert = 0; ivert != adj_verts.size(); ++ivert)
174 elem_data[itag] += adj_vert_data[ivert * interp_tag_len + itag];
175 elem_data[itag] /= adj_verts.size();
176 }
177 CHKERR moab.tag_set_data(interp_tag, &elem, 1, elem_data.data());
178 }
179 }
180
181 Coupler mbc(&moab, pcs[0].get(), src_elems, 0, true);
182
183 std::vector<double> vpos;
184 int num_pts = 0;
185
187
188
189 CHKERR pcs[1]->get_part_entities(targ_elems, 3);
190 if (interp_order == 0) {
191 targ_verts = targ_elems;
192 } else {
193 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
194 moab::Interface::UNION);
195 }
196
197
198 CHKERR pcs[1]->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
199 targ_verts = subtract(targ_verts, tmp_verts);
200
201
202 num_pts = (
int)targ_verts.size();
203 vpos.resize(3 * targ_verts.size());
204 CHKERR moab.get_coords(targ_verts, &vpos[0]);
205
206
207 boost::shared_ptr<TupleList> tl_ptr;
208 tl_ptr = boost::make_shared<TupleList>();
209 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
false);
210
211
212 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
213 std::vector<double> &vpos,
214 Range &missing_verts) {
216 int missing_pts_num = 0;
218 auto vit = targ_verts.begin();
219 for (; vit != targ_verts.end();
i++) {
220 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
221 missing_verts.insert(*vit);
222 vit = targ_verts.erase(vit);
223 missing_pts_num++;
224 } else {
225 vit++;
226 }
227 }
228
229 int missing_pts_num_global = 0;
230 MPI_Allreduce(&missing_pts_num, &missing_pts_num_global, 1, MPI_INT,
232 if (missing_pts_num_global) {
234 << missing_pts_num_global
235 << " points in target mesh were not located in source mesh. ";
236 }
237
238 if (missing_pts_num) {
239 num_pts = (
int)targ_verts.size();
240 vpos.resize(3 * targ_verts.size());
241 CHKERR moab.get_coords(targ_verts, &vpos[0]);
242 tl_ptr->reset();
243 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
244 false);
245 }
247 };
248
250 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
251
253 if (src_tag_nodes) {
254 CHKERR moab.get_connectivity(src_elems, src_entities,
true);
255 } else {
256 src_entities = src_elems;
257 }
258 std::vector<double> source_data(interp_tag_len * src_entities.size(), 0.0);
259 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
260
261 CHKERR moab.tag_get_data(interp_tag, src_entities, source_data.data());
262
263 Tag scalar_tag, adj_count_tag;
264 double def_scl = 0;
265 string scalar_tag_name = string(iterp_tag_name) + "_COMP";
266 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
267 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
268 &def_scl);
269
270 string adj_count_tag_name = "ADJ_COUNT";
271 double def_adj = 0;
272 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
273 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
274 &def_adj);
275
276
277
278 auto create_scalar_tags = [&](
const Range &src_elems,
279 const std::vector<double> &source_data,
280 int itag) {
282
283 std::vector<double> source_data_scalar(src_entities.size());
284 for (
size_t i = 0;
i != src_entities.size(); ++
i)
285 source_data_scalar[
i] = source_data[
i * interp_tag_len + itag];
286
287 CHKERR moab.tag_set_data(scalar_tag, src_entities,
288 source_data_scalar.data());
289
290 if (!src_tag_nodes && interp_order == 1) {
291
293 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
294
295 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
296 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
297
298 for (auto &tet : src_elems) {
299 double tet_data = 0;
300 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
301
303 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
304
305 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
306 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
307
308 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
309 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
310 &adj_vert_count[0]);
311
312 for (int ivert = 0; ivert < adj_verts.size(); ivert++) {
313 adj_vert_data[ivert] += tet_data;
314 adj_vert_count[ivert] += 1;
315 }
316
317 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
318 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
319 &adj_vert_count[0]);
320 }
321
322
323 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
324 pcs[0]->reduce_tags(tags, tags, MPI_SUM, src_verts);
325
326 std::vector<double> src_vert_data(src_verts.size(), 0.0);
327 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
328
329 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
330 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
331 &src_vert_adj_count[0]);
332
333 for (int ivert = 0; ivert < src_verts.size(); ivert++) {
334 src_vert_data[ivert] /= src_vert_adj_count[ivert];
335 }
336 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
337 }
339 };
340
341 for (int itag = 0; itag < interp_tag_len; itag++) {
342
343 CHKERR create_scalar_tags(src_elems, source_data, itag);
344
345 std::vector<double> target_data_scalar(num_pts, 0.0);
346 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
347 tl_ptr.get());
348
349 for (int ielem = 0; ielem < num_pts; ielem++) {
350 target_data[itag + ielem * interp_tag_len] = target_data_scalar[ielem];
351 }
352 }
353
354
355 CHKERR moab.tag_set_data(output_tag, targ_verts, &target_data[0]);
356
357 if (missing_verts.size() && (interp_order == 1) && hybrid_interp) {
358 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Using hybrid interpolation for "
359 "missing points in the target mesh.";
360 Range missing_adj_elems;
361 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
362 moab::Interface::UNION);
363
364 int num_adj_elems = (
int)missing_adj_elems.size();
365 std::vector<double> vpos_adj_elems;
366
367 vpos_adj_elems.resize(3 * missing_adj_elems.size());
368 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
369
370
371 tl_ptr->reset();
372 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
373 tl_ptr.get(), false);
374
376 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
377 vpos_adj_elems, missing_tets);
378 if (missing_tets.size()) {
380 << missing_tets.size()
381 << "points in target mesh were not located in source mesh. ";
382 }
383
384 std::vector<double> target_data_adj_elems(interp_tag_len * num_adj_elems,
385 0.0);
386
387 for (int itag = 0; itag < interp_tag_len; itag++) {
388 CHKERR create_scalar_tags(src_elems, source_data, itag);
389
390 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
391 CHKERR mbc.interpolate(method, scalar_tag_name,
392 &target_data_adj_elems_scalar[0], tl_ptr.get());
393
394 for (int ielem = 0; ielem < num_adj_elems; ielem++) {
395 target_data_adj_elems[itag + ielem * interp_tag_len] =
396 target_data_adj_elems_scalar[ielem];
397 }
398 }
399
400 CHKERR moab.tag_set_data(output_tag, missing_adj_elems,
401 &target_data_adj_elems[0]);
402
403
404 for (auto &vert : missing_verts) {
406 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
407 moab::Interface::UNION);
408
409 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
410 0.0);
411 CHKERR moab.tag_get_data(output_tag, adj_elems, &adj_elems_data[0]);
412
413 std::vector<double> vert_data(interp_tag_len, 0.0);
414 for (int itag = 0; itag < interp_tag_len; itag++) {
415 for (
int i = 0;
i < adj_elems.size();
i++) {
416 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
417 }
418 vert_data[itag] /= adj_elems.size();
419 }
420 CHKERR moab.tag_set_data(output_tag, &vert, 1, &vert_data[0]);
421 }
422 }
423
424 CHKERR moab.tag_delete(scalar_tag);
425 CHKERR moab.tag_delete(adj_count_tag);
426
428
429
430 if (interp_order == 1) {
431
432
433
434
435 std::vector<Tag> tags;
436 tags.push_back(output_tag);
437 pcs[1]->reduce_tags(tags, tags, MPI_SUM, targ_verts);
438
439 for (auto &tet : targ_elems) {
441 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
442
443 std::vector<double> adj_vert_data(adj_verts.size() * interp_tag_len,
444 0.0);
445 CHKERR moab.tag_get_data(output_tag, adj_verts, &adj_vert_data[0]);
446
447 std::vector<double> tet_data(interp_tag_len, 0.0);
448 for (int itag = 0; itag < interp_tag_len; itag++) {
449 for (
int i = 0;
i < adj_verts.size();
i++) {
450 tet_data[itag] += adj_vert_data[
i * interp_tag_len + itag];
451 }
452 tet_data[itag] /= adj_verts.size();
453 }
454 CHKERR moab.tag_set_data(output_tag, &tet, 1, &tet_data[0]);
455 }
456 }
457
458 std::vector<double> data_integ(interp_tag_len, 0.0);
459 for (auto &tet : targ_elems) {
460
461 std::vector<double> tet_data(interp_tag_len, 0.0);
462 CHKERR moab.tag_get_data(output_tag, &tet, 1, &tet_data[0]);
463
464 const EntityHandle *vert_conn;
465 int vert_num;
466 CHKERR moab.get_connectivity(tet, vert_conn, vert_num,
true);
467 std::vector<double> vpos(3 * vert_num);
468 CHKERR moab.get_coords(vert_conn, vert_num, &vpos[0]);
470
471 for (int itag = 0; itag < interp_tag_len; itag++) {
472 data_integ[itag] += tet_data[itag] * vol;
473 }
474 }
475
476 std::vector<double> global_data_integ(interp_tag_len, 0.0);
477 MPI_Allreduce(&data_integ[0], &global_data_integ[0], interp_tag_len,
478 MPI_DOUBLE, MPI_SUM, m_field.
get_comm());
479
480 std::string
temp =
"Integrated stress for sslv116 test: ";
481 for (
int i = 0;
i < 9; ++
i) {
482 std::stringstream ss;
483 ss << std::scientific << std::setprecision(3) << global_data_integ[
i];
484 temp += ss.str() +
" ";
485 }
487
488 double non_zero_val = 1.655e12;
489 double non_zero_tol = 5.1e-2;
490 if (interp_order == 1) {
491 non_zero_tol = 1e-3;
492 }
493 std::vector<int> non_zero_inds(3);
494 std::vector<int> zero_inds(6);
496 non_zero_inds = {0, 4, 8};
497 zero_inds = {1, 2, 3, 5, 6, 7};
498 } else {
499 non_zero_inds = {0, 1, 2};
500 zero_inds = {3, 4, 5, 6, 7, 8};
501 }
502 bool non_zero_check =
503 all_of(begin(non_zero_inds), end(non_zero_inds), [&](
int i) {
504 return abs(global_data_integ[
i] - non_zero_val) / non_zero_val <
505 non_zero_tol;
506 });
507 bool zero_check = all_of(begin(zero_inds), end(zero_inds), [&](
int i) {
508 return abs(global_data_integ[
i]) < 1e-12;
509 });
510 if (!non_zero_check || !zero_check) {
512 "Wrong value of the integrated stress");
513 }
517 }
518
520
521 part_sets.insert(roots[1]);
522 std::string new_write_opts;
523 std::ostringstream extra_opt;
524 if (nprocs > 1) {
525 int index = pcs[1]->get_id();
526 extra_opt << ";PARALLEL_COMM=" << index;
527 }
528 new_write_opts = write_opts + extra_opt.str();
529 CHKERR moab.write_file(mesh_out_file, NULL, new_write_opts.c_str(),
530 part_sets);
531 if (0 == rank) {
532 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Wrote file " << mesh_out_file;
533 }
534 }
536
538
539 return 0;
540}
#define CATCH_ERRORS
Catch errors.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
void temp(int x, int y=10)
virtual MPI_Comm & get_comm() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.