9#ifndef EXECUTABLE_DIMENSION
10 #define EXECUTABLE_DIMENSION 3
59 GAUSS>::OpMixDivTimesScalar<SPACE_DIM>;
73 GAUSS>::OpBaseTimesVector<3, SPACE_DIM, 1>;
80 GAUSS>::OpMixDivTimesU<3, 1, SPACE_DIM>;
88 GAUSS>::OpBaseTimesScalar<1>;
119 GAUSS>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
122 GAUSS>::OpEssentialLhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
157auto save_range = [](moab::Interface &moab,
const std::string name,
161 CHKERR moab.add_entities(*out_meshset, r);
162 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
194 :
public boost::enable_shared_from_this<BlockedParameters> {
201 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &
mD);
205 return boost::shared_ptr<VectorDouble>(shared_from_this(),
214 return boost::shared_ptr<double>(shared_from_this(), &
heatCapacity);
219 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
220 std::string block_elastic_name, std::string block_thermal_name,
221 boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev);
225 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
226 std::string block_elastic_name, std::string block_thermal_name,
227 boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev) {
231 OpMatElasticBlocks(boost::shared_ptr<MatrixDouble>
m,
double bulk_modulus_K,
234 std::vector<const CubitMeshSets *> meshset_vec_ptr)
239 "Can not get data from block");
246 for (
auto &b : blockData) {
248 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
249 CHKERR getMatDPtr(matDPtr, b.bulkModulusK, b.shearModulusG);
254 CHKERR getMatDPtr(matDPtr, bulkModulusKDefault, shearModulusGDefault);
259 boost::shared_ptr<MatrixDouble> matDPtr;
263 double shearModulusG;
267 double bulkModulusKDefault;
268 double shearModulusGDefault;
269 std::vector<BlockData> blockData;
273 std::vector<const CubitMeshSets *> meshset_vec_ptr,
277 for (
auto m : meshset_vec_ptr) {
279 std::vector<double> block_data;
280 CHKERR m->getAttributes(block_data);
281 if (block_data.size() < 2) {
283 "Expected that block has two attributes");
285 auto get_block_ents = [&]() {
288 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
308 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
312 auto set_material_stiffness = [&]() {
332 set_material_stiffness();
337 double default_bulk_modulus_K =
339 double default_shear_modulus_G =
342 pipeline.push_back(
new OpMatElasticBlocks(
343 blockedParamsPtr->getDPtr(), default_bulk_modulus_K,
344 default_shear_modulus_G,
mField, sev,
349 (boost::format(
"%s(.*)") % block_elastic_name).str()
356 OpMatThermalBlocks(boost::shared_ptr<VectorDouble> expansion_ptr,
357 boost::shared_ptr<double> conductivity_ptr,
358 boost::shared_ptr<double> capacity_ptr,
360 std::vector<const CubitMeshSets *> meshset_vec_ptr)
362 expansionPtr(expansion_ptr), conductivityPtr(conductivity_ptr),
363 capacityPtr(capacity_ptr) {
365 "Can not get data from block");
372 for (
auto &b : blockData) {
374 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
375 *expansionPtr = b.expansion;
376 *conductivityPtr = b.conductivity;
377 *capacityPtr = b.capacity;
397 std::vector<BlockData> blockData;
401 std::vector<const CubitMeshSets *> meshset_vec_ptr,
405 for (
auto m : meshset_vec_ptr) {
407 std::vector<double> block_data;
408 CHKERR m->getAttributes(block_data);
409 if (block_data.size() < 3) {
411 "Expected that block has at least three attributes");
413 auto get_block_ents = [&]() {
416 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
420 auto get_expansion = [&]() {
422 if (block_data.size() > 3) {
423 expansion[1] = block_data[3];
425 if (
SPACE_DIM == 3 && block_data.size() > 4) {
426 expansion[2] = block_data[4];
431 auto coeff_exp_vec = get_expansion();
434 <<
m->getName() <<
": conductivity = " << block_data[0]
435 <<
" capacity = " << block_data[1]
436 <<
" expansion = " << coeff_exp_vec;
439 {block_data[0], block_data[1], coeff_exp_vec, get_block_ents()});
445 boost::shared_ptr<VectorDouble> expansionPtr;
446 boost::shared_ptr<double> conductivityPtr;
447 boost::shared_ptr<double> capacityPtr;
450 pipeline.push_back(
new OpMatThermalBlocks(
451 blockedParamsPtr->getCoeffExpansionPtr(),
452 blockedParamsPtr->getHeatConductivityPtr(),
453 blockedParamsPtr->getHeatCapacityPtr(),
mField, sev,
458 (boost::format(
"%s(.*)") % block_thermal_name).str()
483 auto get_command_line_parameters = [&]() {
544 <<
"Reference temperature " <<
ref_temp;
551 CHKERR get_command_line_parameters();
569 CHKERR simple->addDomainField(
"FLUX", flux_space, base, 1);
570 CHKERR simple->addBoundaryField(
"FLUX", flux_space, base, 1);
605 auto no_rule = [](int, int, int) {
return -1; };
608 field_eval_fe_ptr->getRuleHook = no_rule;
610 auto block_params = boost::make_shared<BlockedParameters>();
611 auto mDPtr = block_params->getDPtr();
612 auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
615 "MAT_THERMAL", block_params, Sev::verbose);
618 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
620 field_eval_fe_ptr->getOpPtrVector().push_back(
622 field_eval_fe_ptr->getOpPtrVector().push_back(
624 field_eval_fe_ptr->getOpPtrVector().push_back(
626 field_eval_fe_ptr->getOpPtrVector().push_back(
629 field_eval_fe_ptr->getOpPtrVector().push_back(
631 field_eval_fe_ptr->getOpPtrVector().push_back(
655 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
659 auto filter_flux_blocks = [&](
auto skin,
bool temp_bc =
false) {
660 auto remove_cubit_blocks = [&](
auto c) {
670 skin = subtract(skin, ents);
675 auto remove_named_blocks = [&](
auto n) {
680 (boost::format(
"%s(.*)") %
n).str()
688 skin = subtract(skin, ents);
694 "remove_cubit_blocks");
696 "remove_named_blocks");
699 "remove_cubit_blocks");
708 ParallelComm *pcomm =
710 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
711 PSTATUS_NOT, -1, &boundary_ents);
712 return boundary_ents;
716 auto remove_temp_bc_ents =
722 remove_temp_bc_ents);
724 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
727 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
740 remove_temp_bc_ents);
745 simple->getProblemName(),
"FLUX", remove_flux_ents);
747 simple->getProblemName(),
"TBC", remove_temp_bc_ents);
749 auto set_init_temp = [](boost::shared_ptr<FieldEntity> field_entity_ptr) {
750 field_entity_ptr->getEntFieldData()[0] =
init_temp;
757 simple->getProblemName(),
"U");
759 simple->getProblemName(),
"FLUX",
false);
776 auto boundary_marker =
777 bc_mng->getMergedBlocksMarker(vector<string>{
"HEATFLUX"});
787 auto block_params = boost::make_shared<BlockedParameters>();
788 auto mDPtr = block_params->getDPtr();
789 auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
790 auto heat_conductivity_ptr = block_params->getHeatConductivityPtr();
791 auto heat_capacity_ptr = block_params->getHeatCapacityPtr();
795 boost::make_shared<TimeScale>(
"",
false, [](
const double) {
return 1; });
796 auto def_time_scale = [time_scale](
const double time) {
797 return (!time_scale->argFileScale) ? time : 1;
799 auto def_file_name = [time_scale](
const std::string &&name) {
800 return (!time_scale->argFileScale) ? name :
"";
804 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
805 def_file_name(
"bodyforce_scale.txt"),
false, def_time_scale);
806 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
807 def_file_name(
"heatsource_scale.txt"),
false, def_time_scale);
808 auto time_temperature_scaling = boost::make_shared<TimeScale>(
809 def_file_name(
"temperature_bc_scale.txt"),
false, def_time_scale);
810 auto time_displacement_scaling = boost::make_shared<TimeScale>(
811 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
812 auto time_flux_scaling = boost::make_shared<TimeScale>(
813 def_file_name(
"flux_bc_scale.txt"),
false, def_time_scale);
814 auto time_force_scaling = boost::make_shared<TimeScale>(
815 def_file_name(
"force_bc_scale.txt"),
false, def_time_scale);
817 auto add_domain_rhs_ops = [&](
auto &pipeline) {
823 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
824 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
825 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
827 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
828 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
829 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
830 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
836 "FLUX", vec_temp_div_ptr));
844 pipeline.push_back(
new OpStressThermal(mat_strain_ptr, vec_temp_ptr, mDPtr,
850 [](
double,
double,
double)
constexpr {
return 1; }));
852 auto resistance = [heat_conductivity_ptr](
const double,
const double,
854 return (1. / (*heat_conductivity_ptr));
857 auto capacity = [heat_capacity_ptr](
const double,
const double,
859 return -(*heat_capacity_ptr);
864 pipeline.push_back(
new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance));
865 pipeline.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
866 pipeline.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
867 pipeline.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
871 pipeline,
mField,
"T", {time_scale, time_heatsource_scaling},
872 "HEAT_SOURCE", Sev::inform);
874 pipeline,
mField,
"U", {time_scale, time_bodyforce_scaling},
875 "BODY_FORCE", Sev::inform);
877 pipeline,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::inform);
882 auto add_domain_lhs_ops = [&](
auto &pipeline) {
888 pipeline.push_back(
new OpKCauchy(
"U",
"U", mDPtr));
890 "U",
"T", mDPtr, coeff_expansion_ptr));
892 auto resistance = [heat_conductivity_ptr](
const double,
const double,
894 return (1. / (*heat_conductivity_ptr));
896 auto capacity = [heat_capacity_ptr](
const double,
const double,
898 return -(*heat_capacity_ptr);
900 pipeline.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance));
902 new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
904 auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
905 op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
908 pipeline.push_back(op_capacity);
910 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
913 pipeline,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
918 auto add_boundary_rhs_ops = [&](
auto &pipeline) {
924 pipeline,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
932 pipeline,
mField,
"FLUX", {time_scale, time_temperature_scaling},
933 "TEMPERATURE", Sev::inform);
943 pipeline,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
947 using OpConvectionRhsBC =
948 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
949 using OpRadiationRhsBC =
950 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
951 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
953 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
954 pipeline,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
955 T::AddFluxToPipeline<OpRadiationRhsBC>::add(
956 pipeline,
mField,
"TBC", temp_bc_ptr,
"RADIATION", Sev::inform);
958 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
967 struct OpTBCTimesNormalFlux
972 OpTBCTimesNormalFlux(
const std::string
field_name,
973 boost::shared_ptr<MatrixDouble> vec,
974 boost::shared_ptr<Range> ents_ptr =
nullptr)
981 auto t_w = OP::getFTensor0IntegrationWeight();
985 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
989 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
991 const double alpha = t_w * (t_vec(
i) * t_normal(
i));
994 for (; rr != OP::nbRows; ++rr) {
995 OP::locF[rr] += alpha * t_row_base;
998 for (; rr < OP::nbRowBaseFunctions; ++rr)
1004 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1005 if (fe_type == MBTRI) {
1012 boost::shared_ptr<MatrixDouble> sourceVec;
1014 pipeline.push_back(
new OpTBCTimesNormalFlux(
"TBC", mat_flux_ptr));
1016 struct OpBaseNormalTimesTBC
1021 OpBaseNormalTimesTBC(
const std::string
field_name,
1022 boost::shared_ptr<VectorDouble> vec,
1023 boost::shared_ptr<Range> ents_ptr =
nullptr)
1030 auto t_w = OP::getFTensor0IntegrationWeight();
1034 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1038 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1040 const double alpha = t_w * t_vec;
1043 for (; rr != OP::nbRows; ++rr) {
1044 OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
1047 for (; rr < OP::nbRowBaseFunctions; ++rr)
1053 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1054 if (fe_type == MBTRI) {
1061 boost::shared_ptr<VectorDouble> sourceVec;
1064 pipeline.push_back(
new OpBaseNormalTimesTBC(
"FLUX", temp_bc_ptr));
1069 auto add_boundary_lhs_ops = [&](
auto &pipeline) {
1076 using OpConvectionLhsBC =
1077 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
1078 using OpRadiationLhsBC =
1079 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
1080 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
1082 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pipeline,
mField,
"TBC",
"TBC",
1083 "CONVECTION", Sev::verbose);
1084 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
1085 pipeline,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
1092 struct OpTBCTimesNormalFlux
1097 OpTBCTimesNormalFlux(
const std::string row_field_name,
1098 const std::string col_field_name,
1099 boost::shared_ptr<Range> ents_ptr =
nullptr)
1100 :
OP(row_field_name, col_field_name, OP::OPROWCOL, ents_ptr) {
1102 this->assembleTranspose =
true;
1103 this->onlyTranspose =
false;
1113 auto t_w = OP::getFTensor0IntegrationWeight();
1117 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1119 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1121 auto a_mat_ptr = &*OP::locMat.data().begin();
1123 for (; rr != OP::nbRows; rr++) {
1125 const double alpha = t_w * t_row_base;
1129 for (
int cc = 0; cc != OP::nbCols; cc++) {
1133 *a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
1139 for (; rr < OP::nbRowBaseFunctions; ++rr)
1144 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
1145 if (fe_type == MBTRI) {
1152 pipeline.push_back(
new OpTBCTimesNormalFlux(
"TBC",
"FLUX"));
1158 auto get_bc_hook_rhs = [&]() {
1160 mField, pipeline_mng->getDomainRhsFE(),
1161 {time_scale, time_displacement_scaling});
1164 auto get_bc_hook_lhs = [&]() {
1166 mField, pipeline_mng->getDomainLhsFE(),
1167 {time_scale, time_displacement_scaling});
1171 pipeline_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
1172 pipeline_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
1174 CHKERR add_domain_rhs_ops(pipeline_mng->getOpDomainRhsPipeline());
1175 CHKERR add_domain_lhs_ops(pipeline_mng->getOpDomainLhsPipeline());
1176 CHKERR add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
1177 CHKERR add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
1191 auto dm =
simple->getDM();
1192 auto solver = pipeline_mng->createTSIM();
1195 auto set_section_monitor = [&](
auto solver) {
1198 CHKERR TSGetSNES(solver, &snes);
1199 CHKERR SNESMonitorSet(snes,
1202 (
void *)(snes_ctx_ptr.get()),
nullptr);
1206 auto create_post_process_elements = [&]() {
1207 auto block_params = boost::make_shared<BlockedParameters>();
1208 auto mDPtr = block_params->getDPtr();
1209 auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
1210 auto u_ptr = boost::make_shared<MatrixDouble>();
1211 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
1212 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
1213 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
1214 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
1215 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
1217 auto push_domain_ops = [&](
auto &pp_fe) {
1219 auto &pip = pp_fe->getOpPtrVector();
1232 "U", mat_grad_ptr));
1235 pip.push_back(
new OpStressThermal(mat_strain_ptr, vec_temp_ptr, mDPtr,
1236 coeff_expansion_ptr, mat_stress_ptr));
1240 auto push_post_proc_ops = [&](
auto &pp_fe) {
1242 auto &pip = pp_fe->getOpPtrVector();
1249 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
1251 {{
"T", vec_temp_ptr}},
1253 {{
"U", u_ptr}, {
"FLUX", mat_flux_ptr}},
1257 {{
"STRAIN", mat_strain_ptr}, {
"STRESS", mat_stress_ptr}}
1265 auto domain_post_proc = [&]() {
1267 return boost::shared_ptr<PostProcEle>();
1268 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
1270 "push domain ops to domain element");
1272 "push post proc ops to domain element");
1276 auto skin_post_proc = [&]() {
1278 return boost::shared_ptr<SkinPostProcEle>();
1279 auto pp_fe = boost::make_shared<SkinPostProcEle>(
mField);
1284 "push domain ops to side element");
1285 pp_fe->getOpPtrVector().push_back(op_side);
1287 "push post proc ops to skin element");
1291 return std::make_pair(domain_post_proc(), skin_post_proc());
1294 auto monitor_ptr = boost::make_shared<FEMethod>();
1296 auto [domain_post_proc_fe, skin_post_proc_fe] =
1297 create_post_process_elements();
1299 auto set_time_monitor = [&](
auto dm,
auto solver) {
1301 monitor_ptr->preProcessHook = [&]() {
1307 domain_post_proc_fe,
1308 monitor_ptr->getCacheWeakPtr());
1309 CHKERR domain_post_proc_fe->writeFile(
1310 "out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
1316 monitor_ptr->getCacheWeakPtr());
1317 CHKERR skin_post_proc_fe->writeFile(
1319 boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
".h5m");
1327 ->evalFEAtThePoint3D(
1328 fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
1329 simple->getDomainFEName(), fieldEvalData,
1330 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
1334 ->evalFEAtThePoint2D(
1335 fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
1336 simple->getDomainFEName(), fieldEvalData,
1337 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
1344 CHKERR VecZeroEntries(eval_num_vec);
1345 if (tempFieldPtr->size()) {
1346 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
1348 CHKERR VecAssemblyBegin(eval_num_vec);
1349 CHKERR VecAssemblyEnd(eval_num_vec);
1352 CHKERR VecSum(eval_num_vec, &eval_num);
1353 if (!(
int)eval_num) {
1355 "atom test %d failed: did not find elements to evaluate "
1356 "the field, check the coordinates",
1361 if (tempFieldPtr->size()) {
1363 MOFEM_LOG(
"ThermoElasticSync", Sev::inform)
1364 <<
"Eval point T: " << t_temp;
1365 if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1366 if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
1368 "atom test %d failed: wrong temperature value",
1371 if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
1373 "atom test %d failed: wrong temperature value",
1378 if (fluxFieldPtr->size1()) {
1381 auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
1382 MOFEM_LOG(
"ThermoElasticSync", Sev::inform)
1383 <<
"Eval point FLUX magnitude: " << flux_mag;
1384 if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1385 if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
1387 "atom test %d failed: wrong flux value",
atom_test);
1389 if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
1391 "atom test %d failed: wrong flux value",
atom_test);
1395 if (dispFieldPtr->size1()) {
1398 auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
1399 MOFEM_LOG(
"ThermoElasticSync", Sev::inform)
1400 <<
"Eval point U magnitude: " << disp_mag;
1401 if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1402 if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
1404 "atom test %d failed: wrong displacement value",
1408 fabs(disp_mag - 0.00265) > 1e-5) {
1410 "atom test %d failed: wrong displacement value",
1415 if (strainFieldPtr->size1()) {
1419 auto t_strain_trace = t_strain(
i,
i);
1420 if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1421 if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
1423 "atom test %d failed: wrong strain value",
atom_test);
1426 fabs(t_strain_trace - 0.00522) > 1e-5) {
1428 "atom test %d failed: wrong strain value",
atom_test);
1432 if (stressFieldPtr->size1()) {
1435 auto von_mises_stress = std::sqrt(
1437 ((t_stress(0, 0) - t_stress(1, 1)) *
1438 (t_stress(0, 0) - t_stress(1, 1)) +
1439 (
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
1440 (t_stress(1, 1) - t_stress(2, 2))
1442 (
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
1443 (t_stress(2, 2) - t_stress(0, 0))
1445 6 * (t_stress(0, 1) * t_stress(0, 1) +
1446 (
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
1447 (
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
1448 MOFEM_LOG(
"ThermoElasticSync", Sev::inform)
1449 <<
"Eval point von Mises Stress: " << von_mises_stress;
1450 if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
1451 if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
1453 "atom test %d failed: wrong von Mises stress value",
1456 if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
1458 "atom test %d failed: wrong von Mises stress value",
1461 if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
1463 "atom test %d failed: wrong von Mises stress value",
1474 auto null = boost::shared_ptr<FEMethod>();
1480 auto set_fieldsplit_preconditioner = [&](
auto solver) {
1484 CHKERR TSGetSNES(solver, &snes);
1486 CHKERR SNESGetKSP(snes, &ksp);
1488 CHKERR KSPGetPC(ksp, &pc);
1489 PetscBool is_pcfs = PETSC_FALSE;
1490 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1493 if (is_pcfs == PETSC_TRUE) {
1494 auto bc_mng = mField.getInterface<
BcManager>();
1496 auto name_prb =
simple->getProblemName();
1499 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"U", 0,
1502 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"FLUX", 0, 0,
1505 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"T", 0, 0,
1508 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"TBC", 0, 0,
1511 CHKERR ISExpand(is_T, is_flux, &is_tmp);
1512 CHKERR ISExpand(is_TBC, is_tmp, &is_tmp2);
1513 CHKERR ISDestroy(&is_tmp);
1518 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_TFlux);
1519 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_u);
1527 CHKERR TSSetSolution(solver,
D);
1528 CHKERR TSSetFromOptions(solver);
1530 CHKERR set_section_monitor(solver);
1531 CHKERR set_fieldsplit_preconditioner(solver);
1532 CHKERR set_time_monitor(dm, solver);
1535 CHKERR TSSolve(solver, NULL);
1546 const char param_file[] =
"param_file.petsc";
1550 auto core_log = logging::core::get();
1564 DMType dm_name =
"DMMOFEM";
1569 moab::Core mb_instance;
1570 moab::Interface &moab = mb_instance;
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
Implementation of thermal convection bc.
Implementation of thermal radiation bc.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#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 ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ 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 MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm)
Get smart vector from DM.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasVector< double > VectorDouble
implementation of Data Operators for Forces and Sources
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *snes_ctx)
Sens monitor printing residual field by field.
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
static FTensor::Ddg< FTensor::PackPtr< T *, 1 >, Tensor_Dim01, Tensor_Dim23 > getFTensor4DdgFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 4 on first two and last indices from form data matrix.
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
static auto getFTensor2SymmetricFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
double young_modulus
Young modulus.
double poisson_ratio
Poisson ratio.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
constexpr auto field_name
static constexpr int approx_order
OpBaseImpl< PETSC, EdgeEleOp > OpBase
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
FTensor::Index< 'm', 3 > m
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
virtual moab::Interface & get_moab()=0
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.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Class (Function) to enforce essential constrains.
structure for User Loop Methods on finite elements
Field evaluator interface.
Definition of the heat flux bc data structure.
Section manager is used to create indexes and sections.
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.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Interface for managing meshsets containing materials and boundary conditions.
Natural boundary conditions.
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get value at integration points for scalar field.
Get field gradients at integration pts for scalar filed rank 0, i.e. vector field.
Get values at integration pts for tensor filed rank 1, i.e. vector field.
Enforce essential constrains on lhs.
Enforce essential constrains on rhs.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
VectorDouble coeffExpansion
auto getHeatCapacityPtr()
auto getCoeffExpansionPtr()
auto getHeatConductivityPtr()
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
MoFEMErrorCode getCommandLineParameters()
[Run problem]
MoFEMErrorCode runProblem()
[Run problem]
boost::shared_ptr< MatrixDouble > fluxFieldPtr
boost::shared_ptr< VectorDouble > tempFieldPtr
std::array< double, SPACE_DIM > fieldEvalCoords
boost::shared_ptr< MatrixDouble > stressFieldPtr
MoFEM::Interface & mField
ThermoElasticProblem(MoFEM::Interface &m_field)
MoFEMErrorCode addMatBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_elastic_name, std::string block_thermal_name, boost::shared_ptr< BlockedParameters > blockedParamsPtr, Sev sev)
boost::shared_ptr< MatrixDouble > dispGradPtr
MoFEMErrorCode setupProblem()
add fields
boost::shared_ptr< MatrixDouble > dispFieldPtr
MoFEMErrorCode bC()
[Set up problem]
MoFEMErrorCode OPs()
[Boundary condition]
boost::shared_ptr< MatrixDouble > strainFieldPtr
MoFEMErrorCode tsSolve()
[Push operators to pipeline]
FormsIntegrators< DomainEleOp >::Assembly< A >::OpBase AssemblyDomainEleOp
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux time base of temperature (FLUX x T) and transpose of it,...
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
static char help[]
[Solve]
PetscBool is_plane_strain
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradSymTensorGrad< 1, SPACE_DIM, SPACE_DIM, 0 > OpKCauchy
[Linear elastic problem]
#define EXECUTABLE_DIMENSION
double default_heat_capacity
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpCapacity
Integrate Lhs base of temperature times (heat capacity) times base of temperature (T x T)
double default_young_modulus
[Essential boundary conditions (Least square approach)]
double default_coeff_expansion
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 3, SPACE_DIM, 1 > OpHdivFlux
Integrating Rhs flux base (1/k) flux (FLUX)
PetscBool do_output_domain
double default_heat_conductivity
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 3, SPACE_DIM > OpHdivHdiv
[Linear elastic problem]
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
double default_poisson_ratio
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesSymTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForceCauchy