96 {
97
98 const string default_options = "-ksp_type gmres \n"
99 "-pc_type lu \n"
100 "-pc_factor_mat_solver_type mumps \n"
101 "-mat_mumps_icntl_20 0 \n"
102 "-ksp_monitor \n"
103 "-snes_type newtonls \n"
104 "-snes_linesearch_type basic \n"
105 "-snes_atol 1e-8 \n"
106 "-snes_rtol 1e-8 \n"
107 "-snes_monitor \n"
108 "-ts_monitor \n"
109 "-ts_type beuler \n";
110
111 string param_file = "param_file.petsc";
112 if (!static_cast<bool>(ifstream(param_file))) {
113 std::ofstream
file(param_file.c_str(), std::ios::ate);
114 if (
file.is_open()) {
115 file << default_options;
117 }
118 }
119
121 auto core_log = logging::core::get();
122 core_log->add_sink(
126
127 core_log->add_sink(
131
132 try {
133
134 PetscBool flg_block_config, flg_file;
135 char mesh_file_name[255];
136 char block_config_file[255];
137 PetscInt test_nb = 0;
139 PetscBool is_partitioned = PETSC_FALSE;
140 PetscBool is_calculating_frequency = PETSC_FALSE;
141 PetscBool is_post_proc_volume = PETSC_TRUE;
142
143
144 enum bases { LEGENDRE, LOBATTO, BERNSTEIN_BEZIER, JACOBI, LASBASETOP };
145 const char *list_bases[] = {"legendre", "lobatto", "bernstein_bezier",
146 "jacobi"};
147 PetscInt choice_base_value = LOBATTO;
148
149
150 PetscOptionsBegin(PETSC_COMM_WORLD, "", "Elastic Config", "none");
151 CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"mesh.h5m",
152 mesh_file_name, 255, &flg_file);
153
154 CHKERR PetscOptionsInt(
"-my_order",
"default approximation order",
"",
156
157 CHKERR PetscOptionsEList(
"-base",
"approximation base",
"", list_bases,
158 LASBASETOP, list_bases[choice_base_value],
159 &choice_base_value, PETSC_NULLPTR);
160
161 CHKERR PetscOptionsInt(
"-is_atom_test",
"ctest number",
"", test_nb,
162 &test_nb, PETSC_NULLPTR);
163
164 CHKERR PetscOptionsBool(
"-my_is_partitioned",
165 "set if mesh is partitioned (this result that each "
166 "process keeps only one part of the mesh)",
167 "", is_partitioned, &is_partitioned, PETSC_NULLPTR);
168
169 CHKERR PetscOptionsString(
"-my_block_config",
"elastic configure file name",
170 "", "block_conf.in", block_config_file, 255,
171 &flg_block_config);
172
174 "-my_is_calculating_frequency", "set if frequency will be calculated",
175 "", is_calculating_frequency, &is_calculating_frequency, PETSC_NULLPTR);
176
177 CHKERR PetscOptionsBool(
"-my_is_post_proc_volume",
178 "if true post proc volume", "", is_post_proc_volume,
179 &is_post_proc_volume, PETSC_NULLPTR);
180
181 PetscOptionsEnd();
182
183
184 if (flg_file != PETSC_TRUE) {
185 SETERRQ(PETSC_COMM_SELF, 1, "*** ERROR -my_file (MESH FILE NEEDED)");
186 }
187
188
189 moab::Core mb_instance;
190 moab::Interface &moab = mb_instance;
191
192
193
194
195
196 MPI_Comm moab_comm_world;
197 MPI_Comm_dup(PETSC_COMM_WORLD, &moab_comm_world);
198 ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
199 if (pcomm == NULL)
200 pcomm = new ParallelComm(&moab, moab_comm_world);
201
202
203 if (is_partitioned == PETSC_TRUE) {
204
205
206 const char *option;
207 option = "PARALLEL=READ_PART;"
208 "PARALLEL_RESOLVE_SHARED_ENTS;"
209 "PARTITION=PARALLEL_PARTITION;";
210 CHKERR moab.load_file(mesh_file_name, 0, option);
211 } else {
212
213
214
215
216 const char *option;
217 option = "";
218 CHKERR moab.load_file(mesh_file_name, 0, option);
219 }
220
221
224
225
231
232 bool mesh_has_tets = false;
233 bool mesh_has_prisms = false;
234 int nb_tets = 0;
235 int nb_hexs = 0;
236 int nb_prisms = 0;
237
238 CHKERR moab.get_number_entities_by_type(0, MBTET, nb_tets,
true);
239 CHKERR moab.get_number_entities_by_type(0, MBHEX, nb_hexs,
true);
240 CHKERR moab.get_number_entities_by_type(0, MBPRISM, nb_prisms,
true);
241
242 mesh_has_tets = (nb_tets + nb_hexs) > 0;
243 mesh_has_prisms = nb_prisms > 0;
244
245
246
248 bit_level0.set(0);
250 0, 3, bit_level0);
251
252
253
254
255
257 if (
bit->getName().compare(0, 3,
"ROD") == 0) {
259 0, 1, bit_level0);
260 }
261 }
262
263
265 switch (choice_base_value) {
266 case LEGENDRE:
268 break;
269 case LOBATTO:
271 break;
272 case BERNSTEIN_BEZIER:
274 break;
275 case JACOBI:
277 break;
278 default:
280 };
283
284
287
288
289
290
291
294
295
297 CHKERR m_field.
get_moab().get_entities_by_type(0, MBEDGE, all_edges,
true);
298
299
300 Range edges_in_simple_rod;
302 if (
bit->getName().compare(0, 3,
"ROD") == 0) {
305 MBEDGE, edges, true);
306 edges_in_simple_rod.merge(edges);
307 }
308 }
309
311 "DISPLACEMENT");
312
313
315
316
317 Range edges_to_set_order;
318 edges_to_set_order = subtract(all_edges, edges_in_simple_rod);
319
320
321
322
330
333 else
335
336
337
338 auto setting_second_order_geometry = [&m_field]() {
340
344 moab::Interface::UNION);
345
346
347
348
349
350
351
352
353
354
355
358
360 };
361 CHKERR setting_second_order_geometry();
362
363
364
365 std::map<int, BlockOptionData> block_data;
366 auto setting_blocks_data_and_order_from_config_file =
367 [&m_field, &moab, &block_data, flg_block_config, block_config_file,
368 order](boost::shared_ptr<std::map<int, BlockData>> &block_sets_ptr) {
370 if (flg_block_config) {
371 ifstream ini_file(block_config_file);
372 po::variables_map vm;
373 po::options_description config_file_options;
375 it)) {
376 std::ostringstream str_order;
377 str_order << "block_" << it->getMeshsetId()
378 << ".displacement_order";
379 config_file_options.add_options()(
380 str_order.str().c_str(),
381 po::value<int>(&block_data[it->getMeshsetId()].oRder)
382 ->default_value(
order));
383
384 std::ostringstream str_cond;
385 str_cond << "block_" << it->getMeshsetId() << ".young_modulus";
386 config_file_options.add_options()(
387 str_cond.str().c_str(),
388 po::value<double>(&block_data[it->getMeshsetId()].yOung)
389 ->default_value(-1));
390
391 std::ostringstream str_capa;
392 str_capa << "block_" << it->getMeshsetId() << ".poisson_ratio";
393 config_file_options.add_options()(
394 str_capa.str().c_str(),
395 po::value<double>(&block_data[it->getMeshsetId()].pOisson)
396 ->default_value(-2));
397
398 std::ostringstream str_init_temp;
399 str_init_temp << "block_" << it->getMeshsetId()
400 << ".initial_temperature";
401 config_file_options.add_options()(
402 str_init_temp.str().c_str(),
403 po::value<double>(&block_data[it->getMeshsetId()].initTemp)
404 ->default_value(0));
405 }
406 po::parsed_options parsed =
407 parse_config_file(ini_file, config_file_options, true);
408 store(parsed, vm);
409 po::notify(vm);
411 it)) {
412 if (block_data[it->getMeshsetId()].oRder == -1)
413 continue;
414 if (block_data[it->getMeshsetId()].oRder ==
order)
415 continue;
416 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Set block %d order to %d",
417 it->getMeshsetId(),
418 block_data[it->getMeshsetId()].oRder);
420 CHKERR moab.get_entities_by_handle(it->getMeshset(), block_ents,
421 true);
422 Range ents_to_set_order;
423 CHKERR moab.get_adjacencies(block_ents, 3,
false,
424 ents_to_set_order,
425 moab::Interface::UNION);
426 ents_to_set_order = ents_to_set_order.subset_by_dimension(3);
427 CHKERR moab.get_adjacencies(block_ents, 2,
false,
428 ents_to_set_order,
429 moab::Interface::UNION);
430 CHKERR moab.get_adjacencies(block_ents, 1,
false,
431 ents_to_set_order,
432 moab::Interface::UNION);
434 ents_to_set_order);
435
437 ents_to_set_order, "DISPLACEMENT",
438 block_data[it->getMeshsetId()].oRder);
439 }
440 std::vector<std::string> additional_parameters;
441 additional_parameters =
442 collect_unrecognized(parsed.options, po::include_positional);
443 for (std::vector<std::string>::iterator vit =
444 additional_parameters.begin();
445 vit != additional_parameters.end(); vit++) {
446 MOFEM_LOG_C(
"ELASTIC", Sev::warning,
"Unrecognized option %s",
447 vit->c_str());
448 }
449 }
450
451
452
455 const int id = it->getMeshsetId();
456 auto &bd = (*block_sets_ptr)[id];
457 if (block_data[id].yOung > 0)
458 bd.E = block_data[id].yOung;
459 if (block_data[id].pOisson >= -1)
460 bd.PoissonRatio = block_data[id].pOisson;
461 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Block %d",
id);
462 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"\tYoung modulus %3.4g", bd.E);
463 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"\tPoisson ratio %3.4g",
464 bd.PoissonRatio);
465 }
466
468 };
469
470
471
472 boost::shared_ptr<std::map<int, HookeElement::BlockData>> block_sets_ptr =
473 boost::make_shared<std::map<int, HookeElement::BlockData>>();
474 CHKERR HookeElement::setBlocks(m_field, block_sets_ptr);
475 CHKERR setting_blocks_data_and_order_from_config_file(block_sets_ptr);
476
477 boost::shared_ptr<std::map<int, MassBlockData>> mass_block_sets_ptr =
478 boost::make_shared<std::map<int, MassBlockData>>();
480
481 auto fe_lhs_ptr =
482 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
483 auto fe_rhs_ptr =
484 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
485 fe_lhs_ptr->getRuleHook =
VolRule();
486 fe_rhs_ptr->getRuleHook =
VolRule();
487
489 "MESH_NODE_POSITIONS");
491 "MESH_NODE_POSITIONS");
492
493 boost::shared_ptr<ForcesAndSourcesCore> prism_fe_lhs_ptr(
495 boost::shared_ptr<ForcesAndSourcesCore> prism_fe_rhs_ptr(
497
498 CHKERR HookeElement::addElasticElement(m_field, block_sets_ptr,
"ELASTIC",
499 "DISPLACEMENT",
500 "MESH_NODE_POSITIONS", false);
501
502 auto add_skin_element_for_post_processing = [&]() {
504 Range elastic_element_ents;
506 "ELASTIC", 3, elastic_element_ents);
509 CHKERR skin.find_skin(0, elastic_element_ents,
false, skin_faces);
511 if (is_partitioned) {
512 CHKERR pcomm->filter_pstatus(skin_faces,
513 PSTATUS_SHARED | PSTATUS_MULTISHARED,
514 PSTATUS_NOT, -1, &proc_skin);
515 } else {
516 proc_skin = skin_faces;
517 }
520 "DISPLACEMENT");
522 "DISPLACEMENT");
524 "DISPLACEMENT");
526
527
528
529
531 "TEMP");
532 }
534 "POST_PROC_SKIN", "MESH_NODE_POSITIONS");
536 "POST_PROC_SKIN");
538 };
539 CHKERR add_skin_element_for_post_processing();
540
541 auto data_at_pts = boost::make_shared<HookeElement::DataAtIntegrationPts>();
542 if (mesh_has_tets) {
543 CHKERR HookeElement::setOperators(fe_lhs_ptr, fe_rhs_ptr, block_sets_ptr,
544 "DISPLACEMENT", "MESH_NODE_POSITIONS",
545 false, true, MBTET, data_at_pts);
546 }
547 if (mesh_has_prisms) {
548 CHKERR HookeElement::setOperators(
549 prism_fe_lhs_ptr, prism_fe_rhs_ptr, block_sets_ptr, "DISPLACEMENT",
550 "MESH_NODE_POSITIONS", false, true, MBPRISM, data_at_pts);
551 }
552
553 if (test_nb == 4) {
554
555 auto thermal_strain =
558 constexpr double alpha = 1;
562 t_thermal_strain(
i,
j) = alpha * t_coords(2) *
t_kd(
i,
j);
563 return t_thermal_strain;
564 };
565
566 fe_rhs_ptr->getOpPtrVector().push_back(
567 new HookeElement::OpAnalyticalInternalStrain_dx<0>(
568 "DISPLACEMENT", data_at_pts, thermal_strain));
569 }
570
571 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_mass_ptr(
573
574 for (auto &sit : *block_sets_ptr) {
575 for (auto &mit : *mass_block_sets_ptr) {
576 fe_mass_ptr->getOpPtrVector().push_back(
577 new HookeElement::OpCalculateMassMatrix("DISPLACEMENT",
578 "DISPLACEMENT", sit.second,
579 mit.second, data_at_pts));
580 }
581 }
582
583
584
586 "MESH_NODE_POSITIONS");
587
588
589
590 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ptr(
592 boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ptr(
594
596 fe_spring_rhs_ptr, "DISPLACEMENT",
597 "MESH_NODE_POSITIONS");
598
599
600
602 "MESH_NODE_POSITIONS");
603
604
605
606
607
608
609 boost::shared_ptr<EdgeEle> fe_simple_rod_lhs_ptr(
new EdgeEle(m_field));
610 boost::shared_ptr<EdgeEle> fe_simple_rod_rhs_ptr(
new EdgeEle(m_field));
611
612
614 m_field, fe_simple_rod_lhs_ptr, fe_simple_rod_rhs_ptr, "DISPLACEMENT",
615 "MESH_NODE_POSITIONS");
616
617
618
621 "DISPLACEMENT");
623 "DISPLACEMENT");
625 "DISPLACEMENT");
627 "MESH_NODE_POSITIONS");
628
632 CHKERR m_field.
get_moab().get_entities_by_dimension(it->meshset, 3, tets,
633 true);
635 }
637
638
639
643
644
645
647
648
649 fluid_pressure_fe.addNeumannFluidPressureBCElements("DISPLACEMENT");
650
651
653
655 bool add_temp_field = false;
657 if (block_data[it->getMeshsetId()].initTemp != 0) {
658 add_temp_field = true;
659 break;
660 }
661 }
662 if (add_temp_field) {
665
668 }
669 }
671 CHKERR thermal_stress_elem.addThermalStressElement(
672 "ELASTIC", "DISPLACEMENT", "TEMP");
673 }
674
675
677
678
679
681 "MESH_NODE_POSITIONS");
685 if (block_data[it->getMeshsetId()].initTemp != 0) {
687 "Set block %d temperature to %3.2g\n", it->getMeshsetId(),
688 block_data[it->getMeshsetId()].initTemp);
690 CHKERR moab.get_entities_by_handle(it->meshset, block_ents,
true);
692 CHKERR moab.get_connectivity(block_ents, vertices,
true);
694 block_data[it->getMeshsetId()].initTemp, MBVERTEX, vertices,
695 "TEMP");
696 }
697 }
698 }
699
700
701
703
705
706
708
709
710 auto dm =
createDM(PETSC_COMM_WORLD,
"MOFEM");
712 CHKERR DMSetFromOptions(dm);
714
724
725
726
733 CHKERR MatSetOption(Aij, MAT_SPD, PETSC_TRUE);
734
735
737 if (is_calculating_frequency == PETSC_TRUE) {
739 CHKERR MatSetOption(Mij, MAT_SPD, PETSC_TRUE);
740
741 }
742
743
744 fe_spring_lhs_ptr->ksp_B = Aij;
745 fe_spring_rhs_ptr->ksp_f =
F;
746
747
748 fe_simple_rod_lhs_ptr->ksp_B = Aij;
749 fe_simple_rod_rhs_ptr->ksp_f =
F;
750
751
753 CHKERR VecGhostUpdateBegin(
F, INSERT_VALUES, SCATTER_FORWARD);
754 CHKERR VecGhostUpdateEnd(
F, INSERT_VALUES, SCATTER_FORWARD);
756 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
757 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
759 CHKERR MatZeroEntries(Aij);
760
761
762
763
764
765
766
767
768
769
770
771 auto dirichlet_bc_ptr = boost::make_shared<DirichletDisplacementBc>(
772 m_field,
"DISPLACEMENT", Aij, D0,
F);
773
774
775
776 dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
777 dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
778
779
780 CHKERR VecZeroEntries(D0);
781 CHKERR VecGhostUpdateBegin(D0, INSERT_VALUES, SCATTER_FORWARD);
782 CHKERR VecGhostUpdateEnd(D0, INSERT_VALUES, SCATTER_FORWARD);
784
785
786
788
789
790 CHKERR VecGhostUpdateBegin(D0, INSERT_VALUES, SCATTER_FORWARD);
791 CHKERR VecGhostUpdateEnd(D0, INSERT_VALUES, SCATTER_FORWARD);
793
794
795
796
797
798
799
800 fe_rhs_ptr->snes_f =
F;
801 prism_fe_rhs_ptr->snes_f =
F;
802 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Assemble external force vector ...";
805 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
806
807 fe_lhs_ptr->snes_B = Aij;
808 prism_fe_lhs_ptr->snes_B = Aij;
809 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Calculate stiffness matrix ...";
812 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
813
814
817
818
821
822 if (is_calculating_frequency == PETSC_TRUE) {
823
824 fe_mass_ptr->snes_B = Mij;
825 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Calculate mass matrix ...";
827 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
828 }
829
830
831
832
833
834
835 boost::ptr_map<std::string, NeumannForcesSurface> neumann_forces;
838
839 {
840 boost::ptr_map<std::string, NeumannForcesSurface>::iterator mit =
841 neumann_forces.begin();
842 for (; mit != neumann_forces.end(); mit++) {
844 &mit->second->getLoopFe());
845 }
846 }
847
848 boost::ptr_map<std::string, NodalForce> nodal_forces;
850 "DISPLACEMENT");
851
852 {
853 boost::ptr_map<std::string, NodalForce>::iterator fit =
854 nodal_forces.begin();
855 for (; fit != nodal_forces.end(); fit++) {
857 &fit->second->getLoopFe());
858 }
859 }
860
861 boost::ptr_map<std::string, EdgeForce> edge_forces;
863 "DISPLACEMENT");
864 {
865 auto fit = edge_forces.begin();
866 for (; fit != edge_forces.end(); fit++) {
867 auto &fe = fit->second->getLoopFe();
869 }
870 }
871
875 CHKERR body_forces_methods.addBlock(
"DISPLACEMENT",
F,
876 it->getMeshsetId());
877 }
879 &body_forces_methods.getLoopFe());
880
882 fluid_pressure_fe.getLoopFe().getOpPtrVector(), {},
883 "MESH_NODE_POSITIONS");
884 CHKERR fluid_pressure_fe.setNeumannFluidPressureFiniteElementOperators(
885 "DISPLACEMENT",
F,
false,
true);
886
888 &fluid_pressure_fe.getLoopFe());
889
891
892
893 PetscViewerPushFormat(
894 PETSC_VIEWER_STDOUT_SELF,
895 PETSC_VIEWER_ASCII_MATLAB);
896
897
898
899
900
901
902 if (is_calculating_frequency == PETSC_TRUE) {
903 CHKERR MatAssemblyBegin(Mij, MAT_FINAL_ASSEMBLY);
904 CHKERR MatAssemblyEnd(Mij, MAT_FINAL_ASSEMBLY);
905 }
906
907
908
909
910 CHKERR MatSetOption(Aij, MAT_SPD, PETSC_TRUE);
911 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
912 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
916
917
918 auto solver =
createKSP(PETSC_COMM_WORLD);
919 CHKERR KSPSetDM(solver, dm);
920 CHKERR KSPSetFromOptions(solver);
921 CHKERR KSPSetOperators(solver, Aij, Aij);
922
923
924 {
925
926 PetscBool same = PETSC_FALSE;
927 PC pc;
928 CHKERR KSPGetPC(solver, &pc);
929 PetscObjectTypeCompare((PetscObject)pc, PCMG, &same);
930 if (same) {
933 CHKERR PCSetFromOptions(pc);
934 } else {
935
936 CHKERR KSPSetDMActive(solver, PETSC_FALSE);
937 }
938 }
939 CHKERR KSPSetInitialGuessKnoll(solver, PETSC_FALSE);
940 CHKERR KSPSetInitialGuessNonzero(solver, PETSC_TRUE);
941
943
945
946 auto set_post_proc_skin = [&](auto &post_proc_skin) {
949 "MESH_NODE_POSITIONS");
950 auto disp_ptr = boost::make_shared<MatrixDouble>();
951 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
952 post_proc_skin.getOpPtrVector().push_back(
954 post_proc_skin.getOpPtrVector().push_back(
956 mesh_pos_ptr));
957
958 auto side_loop =
960 m_field, "ELASTIC", 3);
962 "MESH_NODE_POSITIONS");
963 side_loop->getOpPtrVector().push_back(
965 data_at_pts->hMat));
966 side_loop->getOpPtrVector().push_back(
968 data_at_pts->HMat));
969 post_proc_skin.getOpPtrVector().push_back(side_loop);
970
973 {"DISPLACEMENT", disp_ptr},
974 {"MESH_NODE_POSITIONS", mesh_pos_ptr}};
976 {"DISPLACEMENT_GRAD", data_at_pts->hMat}};
978 auto temp_ptr = boost::make_shared<VectorDouble>();
979 auto temp_grad_ptr = boost::make_shared<MatrixDouble>();
980 post_proc_skin.getOpPtrVector().push_back(
982 post_proc_skin.getOpPtrVector().push_back(
984 scalar_map["TEMP"] = temp_ptr;
985 vector_map["TEMP_GRAD"] = temp_grad_ptr;
986 }
987 post_proc_skin.getOpPtrVector().push_back(
988 new HookeElement::OpPostProcHookeElement<
990 "DISPLACEMENT", data_at_pts, *block_sets_ptr,
991 post_proc_skin.getPostProcMesh(),
992 post_proc_skin.getMapGaussPts(), true, true));
993 post_proc_skin.getOpPtrVector().push_back(
new OpPPMap(
994 post_proc_skin.getPostProcMesh(), post_proc_skin.getMapGaussPts(),
995 scalar_map, vector_map, tensor_map, {}));
997 };
998
999 auto set_post_proc_tets = [&](auto &post_proc) {
1001
1003 "MESH_NODE_POSITIONS");
1004 auto disp_ptr = boost::make_shared<MatrixDouble>();
1005 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
1006 auto disp_grad_ptr = boost::make_shared<MatrixDouble>();
1007 post_proc.getOpPtrVector().push_back(
1009 post_proc.getOpPtrVector().push_back(
1011 mesh_pos_ptr));
1012 post_proc.getOpPtrVector().push_back(
1014 disp_grad_ptr));
1017 {"DISPLACEMENT", disp_ptr},
1018 {"MESH_NODE_POSITIONS", mesh_pos_ptr}};
1020 {"DISPLACEMENT_GRAD", disp_grad_ptr}};
1022 auto temp_ptr = boost::make_shared<VectorDouble>();
1023 auto temp_grad_ptr = boost::make_shared<MatrixDouble>();
1024 post_proc.getOpPtrVector().push_back(
1026 post_proc.getOpPtrVector().push_back(
1028 scalar_map["TEMP"] = temp_ptr;
1029 vector_map["TEMP_GRAD"] = temp_grad_ptr;
1030 }
1031
1033 m_field, post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
1034 post_proc.getPostProcElements(), "DISPLACEMENT", disp_grad_ptr,
1035 block_sets_ptr.get()));
1036 post_proc.getOpPtrVector().push_back(
new OpPPMap(
1037 post_proc.getPostProcMesh(), post_proc.getMapGaussPts(), scalar_map,
1038 vector_map, tensor_map, {}));
1040 };
1041
1042 auto set_post_proc_edge = [&](auto &post_proc_edge) {
1044 auto disp_ptr = boost::make_shared<MatrixDouble>();
1045 post_proc_edge.getOpPtrVector().push_back(
1047 post_proc_edge.getOpPtrVector().push_back(
new OpPPMap(
1048 post_proc_edge.getPostProcMesh(), post_proc_edge.getMapGaussPts(), {},
1049 {{"DISPLACEMENT", disp_ptr}}, {}, {}));
1051 };
1052
1053 auto set_post_proc_prisms = [&](auto &prism_post_proc) {
1055 boost::shared_ptr<MatrixDouble> inv_jac_ptr(
new MatrixDouble);
1056 prism_post_proc.getOpPtrVector().push_back(
1058 prism_post_proc.getOpPtrVector().push_back(
1060 auto disp_ptr = boost::make_shared<MatrixDouble>();
1061 auto mesh_pos_ptr = boost::make_shared<MatrixDouble>();
1062 auto disp_grad_ptr = boost::make_shared<MatrixDouble>();
1063 prism_post_proc.getOpPtrVector().push_back(
1065 prism_post_proc.getOpPtrVector().push_back(
1067 mesh_pos_ptr));
1068 prism_post_proc.getOpPtrVector().push_back(
1070 disp_grad_ptr));
1072 m_field, prism_post_proc.getPostProcMesh(),
1073 prism_post_proc.getMapGaussPts(),
1074 prism_post_proc.getPostProcElements(), "DISPLACEMENT",
1075 disp_grad_ptr, block_sets_ptr.get()));
1076 prism_post_proc.getOpPtrVector().push_back(
new OpPPMap(
1077 prism_post_proc.getPostProcMesh(),
1078 prism_post_proc.getMapGaussPts(), {},
1079 {{"DISPLACEMENT", disp_ptr},
1080 {"MESH_NODE_POSITIONS", mesh_pos_ptr}},
1081 {{"DISPLACEMENT_GRAD", disp_grad_ptr}}, {}));
1083 };
1084
1086 m_field);
1089 m_field);
1091 m_field);
1092
1093 auto is_prism = [](
FEMethod *fe_ptr) {
1094 return fe_ptr->numeredEntFiniteElementPtr->getEntType() == MBPRISM;
1095 };
1096 prism_post_proc.exeTestHook = is_prism;
1097 post_proc.exeTestHook = [is_prism](
FEMethod *fe_ptr) {
1098 return !is_prism(fe_ptr);
1099 };
1100
1101 CHKERR set_post_proc_skin(post_proc_skin);
1102 CHKERR set_post_proc_tets(post_proc);
1103 CHKERR set_post_proc_prisms(prism_post_proc);
1104 CHKERR set_post_proc_edge(post_proc_edge);
1105
1106 PetscBool field_eval_flag = PETSC_FALSE;
1107 std::array<double, 3> field_eval_coords;
1108 boost::shared_ptr<FieldEvaluatorInterface::SetPtsData> field_eval_data;
1109 PetscInt coords_dim = 3;
1111 field_eval_coords.data(), &coords_dim,
1112 &field_eval_flag);
1113
1114 auto scalar_field_ptr = boost::make_shared<VectorDouble>();
1115 auto vector_field_ptr = boost::make_shared<MatrixDouble>();
1116 auto tensor_field_ptr = boost::make_shared<MatrixDouble>();
1117
1118 if (field_eval_flag) {
1120 ->getData<VolumeElementForcesAndSourcesCore>();
1122 field_eval_data, "ELASTIC");
1123
1124 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1125 auto no_rule = [](
int,
int,
int) {
return -1; };
1126
1127 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
1128 field_eval_fe_ptr->getRuleHook = no_rule;
1129
1131 field_eval_fe_ptr->getOpPtrVector().push_back(
1133 }
1134 field_eval_fe_ptr->getOpPtrVector().push_back(
1136 field_eval_fe_ptr->getOpPtrVector().push_back(
1138 }
1139
1140
1142
1143
1145 CHKERR VecDuplicate(
F, &F_thermal);
1146
1147
1148
1149 CHKERR thermal_stress_elem.setThermalStressRhsOperators(
1150 "DISPLACEMENT", "TEMP", F_thermal);
1151
1154
1155
1156
1157
1158
1159
1160
1161
1163
1164
1165
1167 sit)) {
1168 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Process step %d",
1169 sit->get_step_number());
1170
1172 sit->get_step_number());
1173
1174 CHKERR VecZeroEntries(F_thermal);
1175 CHKERR VecGhostUpdateBegin(F_thermal, INSERT_VALUES, SCATTER_FORWARD);
1176 CHKERR VecGhostUpdateEnd(F_thermal, INSERT_VALUES, SCATTER_FORWARD);
1177
1178
1179
1180
1181
1182
1184 dm, "ELASTIC", &thermal_stress_elem.getLoopThermalStressRhs());
1185
1186
1187 CHKERR VecAssemblyBegin(F_thermal);
1188 CHKERR VecAssemblyEnd(F_thermal);
1189
1190 CHKERR VecGhostUpdateBegin(F_thermal, ADD_VALUES, SCATTER_REVERSE);
1191 CHKERR VecGhostUpdateEnd(F_thermal, ADD_VALUES, SCATTER_REVERSE);
1192
1193
1194 PetscReal nrm_F;
1195 CHKERR VecNorm(
F, NORM_2, &nrm_F);
1196
1197 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"norm2 F = %6.4e", nrm_F);
1198 PetscReal nrm_F_thermal;
1199 CHKERR VecNorm(F_thermal, NORM_2, &nrm_F_thermal);
1200 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"norm2 F_thermal = %6.4e",
1201 nrm_F_thermal);
1202
1203 CHKERR VecScale(F_thermal, -1);
1204
1205 CHKERR VecAXPY(F_thermal, 1,
F);
1206
1207
1208 dirichlet_bc_ptr->snes_x =
D;
1209 dirichlet_bc_ptr->snes_f = F_thermal;
1211
1212
1213 CHKERR KSPSolve(solver, F_thermal,
D);
1214
1216 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1217 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1218
1219
1221
1222
1224
1225 if (field_eval_flag) {
1227 ->evalFEAtThePoint<3>(
1228 field_eval_coords.data(), 1e-12, "ELASTIC_PROB", "ELASTIC",
1231 if (scalar_field_ptr->size()) {
1234 << "Eval point TEMP: " << t_temp;
1235 }
1236 if (vector_field_ptr->size1()) {
1238 auto t_disp = getFTensor1FromMat<3>(*vector_field_ptr);
1240 << "Eval point DISPLACEMENT magnitude: "
1241 << sqrt(t_disp(
i) * t_disp(
i));
1242 }
1243 if (tensor_field_ptr->size1()) {
1245 auto t_disp_grad = getFTensor2FromMat<3, 3>(*tensor_field_ptr);
1247 <<
"Eval point DISPLACEMENT_GRAD trace: " << t_disp_grad(
i,
i);
1248 }
1249
1251 }
1252
1253
1254 if (is_post_proc_volume == PETSC_TRUE) {
1255 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Write output file ...";
1257 std::ostringstream o1;
1258 o1 << "out_" << sit->step_number << ".h5m";
1259 if (!test_nb)
1260 CHKERR post_proc.writeFile(o1.str().c_str());
1261 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done ...";
1262 }
1263
1264 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Write output file skin ...";
1266 &post_proc_skin);
1267 std::ostringstream o1_skin;
1268 o1_skin << "out_skin_" << sit->step_number << ".h5m";
1269 if (!test_nb)
1270 CHKERR post_proc_skin.writeFile(o1_skin.str().c_str());
1271 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done ...";
1272 }
1273 } else {
1274
1275
1276 CHKERR VecZeroEntries(F_thermal);
1277 CHKERR VecGhostUpdateBegin(F_thermal, INSERT_VALUES, SCATTER_FORWARD);
1278 CHKERR VecGhostUpdateEnd(F_thermal, INSERT_VALUES, SCATTER_FORWARD);
1279
1280
1282 dm, "ELASTIC", &thermal_stress_elem.getLoopThermalStressRhs());
1283
1284
1285 CHKERR VecAssemblyBegin(F_thermal);
1286 CHKERR VecAssemblyEnd(F_thermal);
1287
1288
1289 CHKERR VecGhostUpdateBegin(F_thermal, ADD_VALUES, SCATTER_REVERSE);
1290 CHKERR VecGhostUpdateEnd(F_thermal, ADD_VALUES, SCATTER_REVERSE);
1291
1292
1293 PetscReal nrm_F;
1294 CHKERR VecNorm(
F, NORM_2, &nrm_F);
1295
1296 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"norm2 F = %6.4e", nrm_F);
1297 PetscReal nrm_F_thermal;
1298 CHKERR VecNorm(F_thermal, NORM_2, &nrm_F_thermal);
1299
1300 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"norm2 F_thermal = %6.4e",
1301 nrm_F_thermal);
1302
1303
1304 CHKERR VecScale(F_thermal, -1);
1305 CHKERR VecAXPY(F_thermal, 1,
F);
1306
1307
1308 dirichlet_bc_ptr->snes_x =
D;
1309 dirichlet_bc_ptr->snes_f = F_thermal;
1311
1312
1313 CHKERR KSPSolve(solver, F_thermal,
D);
1315
1316
1317 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1318 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1320
1321
1322 if (is_post_proc_volume == PETSC_TRUE) {
1323 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Write output file ...";
1325
1326 if (!test_nb)
1327 CHKERR post_proc.writeFile(
"out.h5m");
1328 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
1329 }
1330
1331 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Write output file skin ...";
1333 if (!test_nb)
1334 CHKERR post_proc_skin.writeFile(
"out_skin.h5m");
1335 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
1336 }
1337
1338
1339 CHKERR VecDestroy(&F_thermal);
1340 } else {
1341
1342
1343
1345
1346
1347
1348
1349
1351
1352 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1353 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1354
1356
1357 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Post-process start ...";
1358 if (is_post_proc_volume == PETSC_TRUE) {
1360 }
1364 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
1365
1366
1367 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"Write output file ...";
1368 if (mesh_has_tets) {
1369 if (is_post_proc_volume == PETSC_TRUE) {
1370 if (!test_nb)
1371 CHKERR post_proc.writeFile(
"out.h5m");
1372 }
1373 if (!test_nb)
1374 CHKERR post_proc_skin.writeFile(
"out_skin.h5m");
1375 }
1376 if (mesh_has_prisms) {
1377 if (!test_nb)
1378 CHKERR prism_post_proc.writeFile(
"prism_out.h5m");
1379 }
1380 if (!edges_in_simple_rod.empty())
1381 if (!test_nb)
1382 CHKERR post_proc_edge.writeFile(
"out_edge.h5m");
1383 MOFEM_LOG(
"ELASTIC", Sev::inform) <<
"done";
1384 }
1385
1386 if (is_calculating_frequency == PETSC_TRUE) {
1387
1389 VecDuplicate(
D, &u1);
1391 double mode_mass;
1392 CHKERR VecDot(u1,
D, &mode_mass);
1393 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Mode mass %6.4e\n", mode_mass);
1394
1396 VecDuplicate(
D, &v1);
1398
1399 double mode_stiffness;
1400 CHKERR VecDot(v1,
D, &mode_stiffness);
1401 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Mode stiffness %6.4e\n",
1402 mode_stiffness);
1403
1404 double frequency;
1405 double pi = 3.14159265359;
1406 frequency = std::sqrt(mode_stiffness / mode_mass) / (2 * pi);
1407 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Frequency %6.4e", frequency);
1408 }
1409
1410
1411 auto calculate_strain_energy = [&]() {
1413
1415 CHKERR HookeElement::calculateEnergy(dm, block_sets_ptr,
"DISPLACEMENT",
1416 "MESH_NODE_POSITIONS", false, true,
1417 v_energy);
1418
1419
1420 double energy;
1421 CHKERR VecSum(v_energy, &energy);
1422 MOFEM_LOG_C(
"ELASTIC", Sev::inform,
"Elastic energy %6.4e", energy);
1423
1424 switch (test_nb) {
1425 case 1:
1426 if (fabs(energy - 17.129) > 1e-3)
1428 "atom test diverged!");
1429 break;
1430 case 2:
1431 if (fabs(energy - 5.6475e-03) > 1e-4)
1433 "atom test diverged!");
1434 break;
1435 case 3:
1436 if (fabs(energy - 7.4679e-03) > 1e-4)
1438 "atom test diverged!");
1439 break;
1440 case 4:
1441 if (fabs(energy - 2.4992e+00) > 1e-3)
1443 "atom test diverged!");
1444 break;
1445
1446 case 8: {
1447 double min;
1448 CHKERR VecMin(
D, PETSC_NULLPTR, &min);
1449 constexpr double expected_val = 0.10001;
1450 if (fabs(min + expected_val) > 1e-10)
1452 "atom test diverged! %3.4e != %3.4e", min, expected_val);
1453 } break;
1454 case 9: {
1455 if (fabs(energy - 4.7416e-04) > 1e-8)
1457 "atom test diverged!");
1458 }
1459 default:
1460 break;
1461 }
1462
1464 };
1465 CHKERR calculate_strain_energy();
1466
1467 MPI_Comm_free(&moab_comm_world);
1468 }
1470
1472
1473 return 0;
1474}
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ AINSWORTH_BERNSTEIN_BEZIER_BASE
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ BODYFORCESSET
block name is "BODY_FORCES"
@ MAT_ELASTICSET
block name is "MAT_ELASTIC"
@ MOFEM_ATOM_TEST_INVALID
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMCreateMatrix_MoFEM(DM dm, Mat *M)
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
MoFEMErrorCode DMRegister_MGViaApproxOrders(const char sname[])
Register DM for Multi-Grid via approximation orders.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMCreateGlobalVector_MoFEM(DM dm, Vec *g)
DMShellSetCreateGlobalVector.
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode get_finite_element_entities_by_dimension(const std::string name, int dim, Range &ents) const =0
get entities in the finite element by dimension
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual bool check_field(const std::string &name) const =0
check if field is in database
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
MoFEMErrorCode printForceSet() const
Print meshsets with force boundary conditions.
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
MoFEMErrorCode printMaterialsSet() const
Print meshsets with material properties.
MoFEMErrorCode printDisplacementSet() const
Print meshsets with displacement boundary conditions.
#define _IT_CUBITMESHSETS_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
virtual MoFEMErrorCode load_series_data(const std::string &serie_name, const int step_number)
virtual bool check_series(const std::string &name) const
check if series is in database
#define _IT_SERIES_STEPS_BY_NAME_FOR_LOOP_(RECORDER, NAME, IT)
loop over recorded series step
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
const FTensor::Tensor2< T, Dim, Dim > Vec
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
auto createKSP(MPI_Comm comm)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > createPCMGSetUpViaApproxOrdersCtx(DM dm, Mat A, bool use_shell_mat)
createPCMGSetUpViaApproxOrdersCtx
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
MoFEMErrorCode PCMGSetUpViaApproxOrders(PC pc, boost::shared_ptr< PCMGSetUpViaApproxOrdersCtx > ctx, int verb)
Function build MG structure.
SmartPetscObj< Mat > matDuplicate(Mat mat, MatDuplicateOption op)
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
Core broken-mesh post-processor adapted to the fat-prism element.
MoFEMErrorCode setBlocks()
Add operators pushing bases from local to physical configuration.
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() 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.
Structure for user loop methods on finite elements.
Field evaluator interface.
Log manager is used to build and partition problems.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Interface for managing meshsets containing materials and boundary conditions.
Calculate inverse of jacobian for face element.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for MatrixDouble vector field values calculation.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
std::map< std::string, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
Transform local reference derivatives of shape functions to global derivatives.
Projection of edge entities with one mid-node on hierarchical basis.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.
Operator post-procesing stresses for Hook isotropic material.
Implentation of thermal stress element.
Set integration rule to volume elements.