23 #ifndef EXECUTABLE_DIMENSION
24 #define EXECUTABLE_DIMENSION 2
32 using namespace MoFEM;
50 GAUSS>::OpGradSymTensorGrad<1, SPACE_DIM, SPACE_DIM, 0>;
64 GAUSS>::OpGradTensorGrad<1, SPACE_DIM, SPACE_DIM, 1>;
95 GAUSS>::OpMixDivTimesScalar<SPACE_DIM>;
154 GAUSS>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
157 GAUSS>::OpEssentialLhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
174 CHKERR moab.add_entities(*out_meshset,
r);
175 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
202 :
public boost::enable_shared_from_this<BlockedParameters> {
207 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &mD);
211 return boost::shared_ptr<double>(shared_from_this(), &fluidConductivity);
216 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
217 std::string block_elastic_name, std::string block_thermal_name,
218 boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev);
222 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
223 std::string block_elastic_name, std::string block_thermal_name,
224 boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev) {
228 OpMatElasticBlocks(boost::shared_ptr<MatrixDouble>
m,
double bulk_modulus_K,
231 std::vector<const CubitMeshSets *> meshset_vec_ptr)
236 "Can not get data from block");
243 for (
auto &b : blockData) {
245 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
246 CHKERR getMatDPtr(matDPtr, b.bulkModulusK, b.shearModulusG);
251 CHKERR getMatDPtr(matDPtr, bulkModulusKDefault, shearModulusGDefault);
256 boost::shared_ptr<MatrixDouble> matDPtr;
260 double shearModulusG;
264 double bulkModulusKDefault;
265 double shearModulusGDefault;
266 std::vector<BlockData> blockData;
270 std::vector<const CubitMeshSets *> meshset_vec_ptr,
274 for (
auto m : meshset_vec_ptr) {
276 std::vector<double> block_data;
277 CHKERR m->getAttributes(block_data);
278 if (block_data.size() < 2) {
280 "Expected that block has two attributes");
282 auto get_block_ents = [&]() {
285 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
305 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
309 auto set_material_stiffness = [&]() {
319 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mat_D_ptr);
328 set_material_stiffness();
333 double default_bulk_modulus_K =
335 double default_shear_modulus_G =
338 pipeline.push_back(
new OpMatElasticBlocks(
339 blockedParamsPtr->getDPtr(), default_bulk_modulus_K,
340 default_bulk_modulus_K, mField, sev,
345 (boost::format(
"%s(.*)") % block_elastic_name).str()
352 OpMatFluidBlocks(boost::shared_ptr<double> conductivity_ptr,
354 std::vector<const CubitMeshSets *> meshset_vec_ptr)
356 conductivityPtr(conductivity_ptr) {
358 "Can not get data from block");
365 for (
auto &b : blockData) {
367 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
368 *conductivityPtr = b.conductivity;
384 std::vector<BlockData> blockData;
388 std::vector<const CubitMeshSets *> meshset_vec_ptr,
392 for (
auto m : meshset_vec_ptr) {
394 std::vector<double> block_data;
395 CHKERR m->getAttributes(block_data);
396 if (block_data.size() < 1) {
398 "Expected that block has two attributes");
400 auto get_block_ents = [&]() {
403 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
408 <<
m->getName() <<
": conductivity = " << block_data[0];
410 blockData.push_back({block_data[0], get_block_ents()});
416 boost::shared_ptr<double> expansionPtr;
417 boost::shared_ptr<double> conductivityPtr;
418 boost::shared_ptr<double> capacityPtr;
421 pipeline.push_back(
new OpMatFluidBlocks(
422 blockedParamsPtr->getConductivityPtr(), mField, sev,
427 (boost::format(
"%s(.*)") % block_thermal_name).str()
440 CHKERR createCommonData();
479 auto get_command_line_parameters = [&]() {
500 fieldEvalCoords.data(), &coords_dim,
506 CHKERR get_command_line_parameters();
523 simple->getProblemName(),
"U");
525 simple->getProblemName(),
"FLUX",
false);
527 auto get_skin = [&]() {
529 CHKERR mField.get_moab().get_entities_by_dimension(0,
SPACE_DIM, body_ents);
530 Skinner skin(&mField.get_moab());
532 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
536 auto filter_flux_blocks = [&](
auto skin) {
537 auto remove_cubit_blocks = [&](
auto c) {
545 CHKERR mField.get_moab().get_entities_by_dimension(
547 skin = subtract(skin, ents);
552 auto remove_named_blocks = [&](
auto n) {
557 (boost::format(
"%s(.*)") %
n).str()
563 CHKERR mField.get_moab().get_entities_by_dimension(
565 skin = subtract(skin, ents);
571 "remove_cubit_blocks");
573 "remove_cubit_blocks");
580 auto filter_true_skin = [&](
auto skin) {
582 ParallelComm *pcomm =
584 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
585 PSTATUS_NOT, -1, &boundary_ents);
586 return boundary_ents;
589 auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
594 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
601 (boost::format(
"flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
607 simple->getProblemName(),
"FLUX", remove_flux_ents);
620 auto boundary_marker =
621 bc_mng->getMergedBlocksMarker(vector<string>{
"FLUIDFLUX"});
623 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
624 auto dot_u_grad_ptr = boost::make_shared<MatrixDouble>();
625 auto trace_dot_u_grad_ptr = boost::make_shared<VectorDouble>();
626 auto h_ptr = boost::make_shared<VectorDouble>();
627 auto dot_h_ptr = boost::make_shared<VectorDouble>();
628 auto flux_ptr = boost::make_shared<MatrixDouble>();
629 auto div_flux_ptr = boost::make_shared<VectorDouble>();
630 auto strain_ptr = boost::make_shared<MatrixDouble>();
631 auto stress_ptr = boost::make_shared<MatrixDouble>();
633 auto time_scale = boost::make_shared<TimeScale>();
635 auto block_params = boost::make_shared<BlockedParameters>();
636 auto mDPtr = block_params->getDPtr();
637 auto conductivity_ptr = block_params->getConductivityPtr();
648 auto add_domain_base_ops = [&](
auto &pip) {
659 "U", dot_u_grad_ptr));
661 trace_dot_u_grad_ptr));
667 "FLUX", div_flux_ptr));
672 auto add_domain_ops_lhs_mechanical = [&](
auto &pip) {
674 pip.push_back(
new OpKCauchy(
"U",
"U", mDPtr));
677 [](
const double,
const double,
const double) {
return -9.81; },
true,
682 auto add_domain_ops_rhs_mechanical = [&](
auto &pip) {
686 pip, mField,
"U", {time_scale},
"BODY_FORCE", Sev::inform);
690 "U", strain_ptr, stress_ptr, mDPtr));
698 auto add_domain_ops_lhs_seepage = [&](
auto &pip,
auto &fe) {
700 auto resistance = [conductivity_ptr](
const double,
const double,
702 return (1. / *(conductivity_ptr));
705 auto unity = []() constexpr {
return -1; };
706 pip.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance));
707 pip.push_back(
new OpHdivQ(
"FLUX",
"H", unity,
true));
709 "H",
"U", [](
double,
double,
double) constexpr {
return -1; },
false,
711 op_base_div_u->feScalingFun = [](
const FEMethod *fe_ptr) {
714 pip.push_back(op_base_div_u);
719 auto add_domain_ops_rhs_seepage = [&](
auto &pip) {
722 return (1. / (*conductivity_ptr));
726 pip.push_back(
new OpHdivFlux(
"FLUX", flux_ptr, resistance));
727 pip.push_back(
new OpHDivH(
"FLUX", h_ptr, minus_one));
728 pip.push_back(
new OpBaseDotH(
"H", trace_dot_u_grad_ptr, minus_one));
729 pip.push_back(
new OpBaseDivFlux(
"H", div_flux_ptr, minus_one));
734 auto add_boundary_rhs_ops = [&](
auto &pip) {
739 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
742 pipeline_mng->getOpBoundaryRhsPipeline(), mField,
"U", {time_scale},
743 "FORCE", Sev::inform);
746 pipeline_mng->getOpBoundaryRhsPipeline(), mField,
"FLUX", {time_scale},
747 "PRESSURE", Sev::inform);
751 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
756 mField, pip,
simple->getProblemName(),
"FLUX", mat_flux_ptr,
762 auto add_boundary_lhs_ops = [&](
auto &pip) {
769 mField, pip,
simple->getProblemName(),
"FLUX");
775 CHKERR add_domain_base_ops(pipeline_mng->getOpDomainLhsPipeline());
776 CHKERR add_domain_ops_lhs_mechanical(pipeline_mng->getOpDomainLhsPipeline());
777 CHKERR add_domain_ops_lhs_seepage(pipeline_mng->getOpDomainLhsPipeline(),
778 pipeline_mng->getDomainLhsFE());
781 CHKERR add_domain_base_ops(pipeline_mng->getOpDomainRhsPipeline());
782 CHKERR add_domain_ops_rhs_mechanical(pipeline_mng->getOpDomainRhsPipeline());
783 CHKERR add_domain_ops_rhs_seepage(pipeline_mng->getOpDomainRhsPipeline());
785 CHKERR add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
786 CHKERR add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
799 auto dm =
simple->getDM();
800 auto solver = pipeline_mng->createTSIM();
803 auto set_section_monitor = [&](
auto solver) {
806 CHKERR TSGetSNES(solver, &snes);
807 CHKERR SNESMonitorSet(snes,
810 (
void *)(snes_ctx_ptr.get()),
nullptr);
814 auto create_post_process_element = [&]() {
815 auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
817 auto block_params = boost::make_shared<BlockedParameters>();
818 auto mDPtr = block_params->getDPtr();
820 "MAT_FLUID", block_params, Sev::verbose);
822 post_proc_fe->getOpPtrVector(), {H1, HDIV});
824 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
825 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
826 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
828 auto h_ptr = boost::make_shared<VectorDouble>();
829 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
831 post_proc_fe->getOpPtrVector().push_back(
833 post_proc_fe->getOpPtrVector().push_back(
836 auto u_ptr = boost::make_shared<MatrixDouble>();
837 post_proc_fe->getOpPtrVector().push_back(
839 post_proc_fe->getOpPtrVector().push_back(
842 post_proc_fe->getOpPtrVector().push_back(
844 post_proc_fe->getOpPtrVector().push_back(
846 "U", mat_strain_ptr, mat_stress_ptr, mDPtr));
850 post_proc_fe->getOpPtrVector().push_back(
854 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
858 {{
"U", u_ptr}, {
"FLUX", mat_flux_ptr}},
862 {{
"STRAIN", mat_strain_ptr}, {
"STRESS", mat_stress_ptr}}
871 auto create_creaction_fe = [&]() {
872 auto fe_ptr = boost::make_shared<DomainEle>(mField);
873 fe_ptr->getRuleHook = [](
int,
int,
int o) {
return 2 * o; };
875 auto &pip = fe_ptr->getOpPtrVector();
877 auto block_params = boost::make_shared<BlockedParameters>();
878 auto mDPtr = block_params->getDPtr();
883 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
884 auto strain_ptr = boost::make_shared<MatrixDouble>();
885 auto stress_ptr = boost::make_shared<MatrixDouble>();
893 "U", strain_ptr, stress_ptr, mDPtr));
896 fe_ptr->postProcessHook =
902 auto monitor_ptr = boost::make_shared<FEMethod>();
903 auto post_proc_fe = create_post_process_element();
905 auto rections_fe = create_creaction_fe();
907 auto set_time_monitor = [&](
auto dm,
auto solver) {
909 monitor_ptr->preProcessHook = [&]() {
914 monitor_ptr->getCacheWeakPtr());
915 CHKERR post_proc_fe->writeFile(
916 "out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
919 rections_fe->f = res;
922 monitor_ptr->getCacheWeakPtr());
925 CHKERR VecNorm(res, NORM_2, &nrm);
927 <<
"Residual norm " << nrm <<
" at time step "
928 << monitor_ptr->ts_step;
932 auto scalar_field_ptr = boost::make_shared<VectorDouble>();
933 auto vector_field_ptr = boost::make_shared<MatrixDouble>();
934 auto tensor_field_ptr = boost::make_shared<MatrixDouble>();
937 ->getData<DomainEle>();
941 field_eval_data,
simple->getDomainFEName());
944 field_eval_data,
simple->getDomainFEName());
947 field_eval_data->setEvalPoints(fieldEvalCoords.data(), 1);
948 auto no_rule = [](
int,
int,
int) {
return -1; };
950 auto field_eval_ptr = field_eval_data->feMethodPtr.lock();
951 field_eval_ptr->getRuleHook = no_rule;
953 auto u_grad_ptr = boost::make_shared<MatrixDouble>();
954 auto strain_ptr = boost::make_shared<MatrixDouble>();
955 auto stress_ptr = boost::make_shared<MatrixDouble>();
956 auto h_ptr = boost::make_shared<VectorDouble>();
958 auto block_params = boost::make_shared<BlockedParameters>();
959 auto mDPtr = block_params->getDPtr();
961 "MAT_FLUID", block_params, Sev::noisy);
963 field_eval_ptr->getOpPtrVector(), {H1, HDIV});
964 field_eval_ptr->getOpPtrVector().push_back(
967 field_eval_ptr->getOpPtrVector().push_back(
969 field_eval_ptr->getOpPtrVector().push_back(
971 field_eval_ptr->getOpPtrVector().push_back(
973 "U", strain_ptr, stress_ptr, mDPtr));
977 ->evalFEAtThePoint3D(
978 fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
979 simple->getDomainFEName(), field_eval_data,
980 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
984 ->evalFEAtThePoint2D(
985 fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
986 simple->getDomainFEName(), field_eval_data,
987 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
992 <<
"Eval point hydrostatic hight: " << *h_ptr;
994 <<
"Eval point skeleton stress pressure: " << *stress_ptr;
1000 auto null = boost::shared_ptr<FEMethod>();
1006 auto set_fieldsplit_preconditioner = [&](
auto solver) {
1010 CHKERR TSGetSNES(solver, &snes);
1012 CHKERR SNESGetKSP(snes, &ksp);
1014 CHKERR KSPGetPC(ksp, &pc);
1015 PetscBool is_pcfs = PETSC_FALSE;
1016 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
1019 if (is_pcfs == PETSC_TRUE) {
1020 auto bc_mng = mField.getInterface<
BcManager>();
1022 auto name_prb =
simple->getProblemName();
1025 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"U", 0,
1028 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"FLUX", 0, 0,
1031 CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"H", 0, 0,
1034 CHKERR ISExpand(is_H, is_flux, &is_tmp);
1037 auto is_all_bc = bc_mng->getBlockIS(name_prb,
"FLUIDFLUX",
"FLUX", 0, 0);
1039 CHKERR ISGetSize(is_all_bc, &is_all_bc_size);
1041 <<
"Field split block size " << is_all_bc_size;
1042 if (is_all_bc_size) {
1044 CHKERR ISDifference(is_Flux, is_all_bc, &is_tmp2);
1046 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL,
1052 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_Flux);
1053 CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_u);
1059 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1060 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1061 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1062 auto time_scale = boost::make_shared<TimeScale>();
1064 auto get_bc_hook_rhs = [
this, pre_proc_ptr, time_scale]() {
1066 {time_scale},
false);
1070 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
1073 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
1075 mField, post_proc_rhs_ptr, 1.)();
1078 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
1080 post_proc_lhs_ptr, 1.);
1083 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1084 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1085 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1088 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
1089 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
1090 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
1091 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
1094 CHKERR TSSetSolution(solver,
D);
1095 CHKERR TSSetFromOptions(solver);
1097 CHKERR set_section_monitor(solver);
1098 CHKERR set_fieldsplit_preconditioner(solver);
1099 CHKERR set_time_monitor(dm, solver);
1102 CHKERR TSSolve(solver, NULL);
1113 const char param_file[] =
"param_file.petsc";
1117 auto core_log = logging::core::get();
1119 LogManager::createSink(LogManager::getStrmWorld(),
"Seepage"));
1120 LogManager::setLog(
"Seepage");
1123 LogManager::createSink(LogManager::getStrmSync(),
"SeepageSync"));
1124 LogManager::setLog(
"SeepageSync");
1130 DMType dm_name =
"DMMOFEM";