12#ifndef EXECUTABLE_DIMENSION
13 #define EXECUTABLE_DIMENSION 3
59 IntegrationType::GAUSS;
80 boost::function<
double(
const double,
const double,
const double)>;
109 return std::exp(-
b_iso * tau);
116 double JC_ref_temp = 0.;
117 double JC_melt_temp = 1650.;
119 return (
temp - JC_ref_temp) / (JC_melt_temp - JC_ref_temp);
146 double JC_ref_temp = 0.;
147 double JC_melt_temp = 1650.;
152 std::exp(
exp_D * T_hat + pow(T_hat, 2) *
exp_C) /
153 (JC_melt_temp - JC_ref_temp);
159template <
typename T,
int DIM>
166 if (
C1_k < std::numeric_limits<double>::epsilon()) {
170 t_alpha(
i,
j) =
C1_k * t_plastic_strain(
i,
j);
218const char *
const ICTypes[] = {
"uniform",
"gaussian",
"linear",
219 "ICType",
"IC_",
nullptr};
279 double y,
double z) {
288 double y,
double z) {
293 double y,
double z) {
return init_temp; };
311#include <HenckyOps.hpp>
312#include <PlasticOps.hpp>
313#include <PlasticNaturalBCs.hpp>
314#include <ThermoElasticOps.hpp>
315#include <FiniteThermalOps.hpp>
317#include <ThermalOps.hpp>
322#include <ThermalConvection.hpp>
323#include <ThermalRadiation.hpp>
326 #ifdef ENABLE_PYTHON_BINDING
327 #include <boost/python.hpp>
328 #include <boost/python/def.hpp>
329 #include <boost/python/numpy.hpp>
330namespace bp = boost::python;
331namespace np = boost::python::numpy;
340 #include <ContactOps.hpp>
352 std::string output_name,
int &counter = *(
new int(0))) {
355 auto create_post_process_elements = [&]() {
357 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
359 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
362 auto &pip = pp_fe->getOpPtrVector();
364 auto TAU_ptr = boost::make_shared<VectorDouble>();
366 auto T_ptr = boost::make_shared<VectorDouble>();
369 auto T_grad_ptr = boost::make_shared<MatrixDouble>();
372 auto U_ptr = boost::make_shared<MatrixDouble>();
374 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
378 auto EP_ptr = boost::make_shared<MatrixDouble>();
388 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
390 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
392 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}, {
"T_GRAD", T_grad_ptr}},
405 CHKERR push_vol_post_proc_ops(pp_fe);
410 CHKERR pp_fe->writeFile(
"out_" + std::to_string(counter) +
"_" +
411 output_name +
".h5m");
416 auto &post_proc_moab = pp_fe->getPostProcMesh();
417 auto file_name =
"out_" + std::to_string(counter) +
"_" + output_name +
420 <<
"Writing file " << file_name << std::endl;
421 CHKERR post_proc_moab.write_file(file_name.c_str(),
"VTK");
428 CHKERR create_post_process_elements();
434 Vec sol, std::string output_name) {
439 auto create_post_process_elements = [&]() {
441 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
443 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
446 auto &pip = pp_fe->getOpPtrVector();
448 auto TAU_ptr = boost::make_shared<VectorDouble>();
451 auto T_ptr = boost::make_shared<VectorDouble>();
454 auto U_ptr = boost::make_shared<MatrixDouble>();
457 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
459 "FLUX", FLUX_ptr, smart_sol));
461 auto EP_ptr = boost::make_shared<MatrixDouble>();
463 "EP", EP_ptr, smart_sol));
471 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
473 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
475 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}},
488 CHKERR push_vol_post_proc_ops(pp_fe);
491 CHKERR pp_fe->writeFile(
"out_" + output_name +
".h5m");
496 CHKERR create_post_process_elements();
502 const std::string &out_put_string,
503 const auto &out_put_quantity) {
509 for (
int i = 0;
i < size; ++
i) {
512 std::cout <<
"Proc " << rank <<
" " + out_put_string +
" "
513 << out_put_quantity << std::endl;
517 CHKERR PetscBarrier(NULL);
552 IT>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
562auto save_range = [](moab::Interface &moab,
const std::string name,
566 CHKERR moab.add_entities(*out_meshset, r);
567 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
572 std::string output_string =
"";
573 for (
auto el : vec) {
574 output_string += std::to_string(el) +
" ";
576 return output_string;
637 boost::weak_ptr<TSPrePostProc>
ptr;
647 int order_row,
int order_col,
651 constexpr int numNodes = 3;
652 constexpr int numEdges = 3;
654 auto &m_field = fe_raw_ptr->
mField;
655 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
656 auto fe_handle = fe_ptr->getFEEntityHandle();
658 auto set_base_quadrature = [&]() {
660 int rule = 2 * (order_data + 1);
670 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
671 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
672 &fe_ptr->gaussPts(0, 0), 1);
673 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
674 &fe_ptr->gaussPts(1, 0), 1);
676 &fe_ptr->gaussPts(2, 0), 1);
677 auto &data = fe_ptr->dataOnElement[
H1];
678 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
681 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
682 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
684 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
687 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
696 CHKERR set_base_quadrature();
698 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
700 fe_ptr->gaussPts.swap(ref_gauss_pts);
701 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
702 auto &data = fe_ptr->dataOnElement[
H1];
703 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3);
705 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
707 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
711 auto refine_quadrature = [&]() {
715 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
717 for (
int nn = 0; nn != numNodes; nn++)
718 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
720 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
724 Range ref_tri(tri, tri);
726 CHKERR m_field_ref.
get_moab().get_adjacencies(ref_tri, 1,
true, edges,
727 moab::Interface::UNION);
731 Range nodes_at_front;
732 for (
int nn = 0; nn != numNodes; nn++) {
734 CHKERR moab_ref.side_element(tri, 0, nn, ent);
735 nodes_at_front.insert(ent);
739 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
740 for (
int ee = 0; ee != numEdges; ee++) {
742 CHKERR moab_ref.side_element(tri, 1, ee, ent);
743 CHKERR moab_ref.add_entities(meshset, &ent, 1);
750 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(0),
758 CHKERR m_ref->addVerticesInTheMiddleOfEdges(ref_edges,
763 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
764 meshset, MBEDGE,
true);
766 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
767 meshset, MBTRI,
true);
770 Range output_ref_tris;
772 ->getEntitiesByTypeAndRefLevel(
779 MatrixDouble ref_coords(output_ref_tris.size(), 9,
false);
781 for (Range::iterator tit = output_ref_tris.begin();
782 tit != output_ref_tris.end(); tit++, tt++) {
785 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
786 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
789 auto &data = fe_ptr->dataOnElement[
H1];
790 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
791 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
794 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
795 double *tri_coords = &ref_coords(tt, 0);
798 auto det = t_normal.
l2();
799 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
800 for (
int dd = 0; dd != 2; dd++) {
801 ref_gauss_pts(dd, gg) = shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
802 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
803 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
806 << ref_gauss_pts(0, gg) <<
", " << ref_gauss_pts(1, gg);
807 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
813 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
815 std::bitset<numNodes> all_nodes;
816 for (
auto nn = 0; nn != numNodes; ++nn) {
826 CHKERR refine_quadrature();
842 friend PetscErrorCode ::MyTSResizeTransfer(TS, PetscInt, Vec[], Vec[],
852 std::vector<EntityHandle> &new_connectivity,
853 bool &do_refine,
Tag &th_spatial_coords);
856 Range &flipped_els,
Tag &th_spatial_coords,
857 std::vector<EntityHandle> &new_connectivity);
869 boost::make_shared<VectorDouble>();
871 boost::make_shared<MatrixDouble>();
873 boost::make_shared<MatrixDouble>();
875 boost::make_shared<MatrixDouble>();
877 boost::make_shared<MatrixDouble>();
879 boost::make_shared<MatrixDouble>();
881 boost::make_shared<VectorDouble>();
883 boost::make_shared<MatrixDouble>();
893 #ifdef ENABLE_PYTHON_BINDING
894 boost::shared_ptr<ContactOps::SDFPython> sdfPythonPtr;
898 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
901 std::string thermal_block_name, std::string thermoelastic_block_name,
902 std::string thermoplastic_block_name,
Pip &pip, std::string u,
903 std::string ep, std::string tau, std::string temperature) {
909 typename B::template OpGradTimesSymTensor<1, DIM, DIM>;
917 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
918 common_thermoelastic_ptr, common_thermoplastic_ptr] =
919 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
920 m_field, block_name, thermal_block_name, thermoelastic_block_name,
921 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
925 auto m_D_ptr = common_hencky_ptr->matDPtr;
928 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
930 tau, common_plastic_ptr->getPlasticTauDotPtr()));
932 temperature, common_thermoplastic_ptr->getTempPtr()));
934 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
935 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
936 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
940 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
941 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
942 common_thermoelastic_ptr->getCoeffExpansionPtr(),
943 common_thermoelastic_ptr->getRefTempPtr()));
946 if (common_hencky_ptr) {
948 u, common_hencky_ptr->getMatFirstPiolaStress()));
954 auto inelastic_heat_frac_ptr =
955 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
958 return (*inelastic_heat_frac_ptr);
964 temperature, common_hencky_ptr->getMatHenckyStress(),
969 typename P::template Assembly<A>::template OpCalculateConstraintsRhs<I>(
970 tau, common_plastic_ptr, m_D_ptr));
973 typename P::template Assembly<A>::template OpCalculatePlasticFlowRhs<
974 DIM,
I>(ep, common_plastic_ptr, m_D_ptr));
979 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
982 std::string thermal_block_name, std::string thermoelastic_block_name,
983 std::string thermoplastic_block_name,
Pip &pip, std::string u,
984 std::string ep, std::string tau, std::string temperature) {
992 using OpKPiola =
typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
993 using OpKCauchy =
typename B::template OpGradSymTensorGrad<1, DIM, DIM, 0>;
997 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
998 common_thermoelastic_ptr, common_thermoplastic_ptr] =
999 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
1000 m_field, block_name, thermal_block_name, thermoelastic_block_name,
1001 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
1005 auto m_D_ptr = common_hencky_ptr->matDPtr;
1008 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
1010 tau, common_plastic_ptr->getPlasticTauDotPtr()));
1011 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
1012 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1014 if (common_hencky_ptr) {
1015 pip.push_back(
new typename H::template OpHenckyTangent<DIM, I, 0>(
1016 u, common_hencky_ptr, m_D_ptr));
1017 pip.push_back(
new OpKPiola(u, u, common_hencky_ptr->getMatTangent()));
1019 new typename P::template Assembly<A>::
1020 template OpCalculatePlasticInternalForceLhs_LogStrain_dEP<DIM, I>(
1021 u, ep, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1023 pip.push_back(
new OpKCauchy(u, u, m_D_ptr));
1024 pip.push_back(
new typename P::template Assembly<A>::
1025 template OpCalculatePlasticInternalForceLhs_dEP<DIM, I>(
1026 u, ep, common_plastic_ptr, m_D_ptr));
1029 if (common_hencky_ptr) {
1031 new typename P::template Assembly<A>::
1032 template OpCalculateConstraintsLhs_LogStrain_dU<DIM, I>(
1033 tau, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1035 new typename P::template Assembly<A>::
1036 template OpCalculatePlasticFlowLhs_LogStrain_dU<DIM, I>(
1037 ep, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1039 pip.push_back(
new typename P::template Assembly<A>::
1040 template OpCalculateConstraintsLhs_dU<DIM, I>(
1041 tau, u, common_plastic_ptr, m_D_ptr));
1042 pip.push_back(
new typename P::template Assembly<A>::
1043 template OpCalculatePlasticFlowLhs_dU<DIM, I>(
1044 ep, u, common_plastic_ptr, m_D_ptr));
1047 pip.push_back(
new typename P::template Assembly<A>::
1048 template OpCalculatePlasticFlowLhs_dEP<DIM, I>(
1049 ep, ep, common_plastic_ptr, m_D_ptr));
1050 pip.push_back(
new typename P::template Assembly<A>::
1051 template OpCalculatePlasticFlowLhs_dTAU<DIM, I>(
1052 ep, tau, common_plastic_ptr, m_D_ptr));
1055 ep, temperature, common_thermoplastic_ptr));
1056 pip.push_back(
new typename P::template Assembly<A>::
1057 template OpCalculateConstraintsLhs_dEP<DIM, I>(
1058 tau, ep, common_plastic_ptr, m_D_ptr));
1060 new typename P::template Assembly<
1061 A>::template OpCalculateConstraintsLhs_dTAU<I>(tau, tau,
1062 common_plastic_ptr));
1065 pip.push_back(
new typename H::template OpCalculateHenckyThermalStressdT<
1067 u, temperature, common_hencky_ptr,
1068 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1070 auto inelastic_heat_frac_ptr =
1071 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1074 return (*inelastic_heat_frac_ptr);
1080 temperature, temperature, common_hencky_ptr, common_plastic_ptr,
1082 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1087 temperature, ep, common_hencky_ptr, common_plastic_ptr,
1093 temperature, u, common_hencky_ptr, common_plastic_ptr,
1097 tau, temperature, common_thermoplastic_ptr));
1102 template <
int DIM, IntegrationType I,
typename DomainEleOp>
1105 std::string thermal_block_name, std::string thermoelastic_block_name,
1106 std::string thermoplastic_block_name,
1107 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1108 std::string u, std::string ep, std::string tau, std::string temperature,
1112 bool with_rates =
true) {
1116 auto common_plastic_ptr = boost::make_shared<PlasticOps::CommonData>();
1117 auto common_thermal_ptr =
1118 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
1119 auto common_thermoelastic_ptr =
1120 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
1121 auto common_thermoplastic_ptr =
1122 boost::make_shared<ThermoPlasticOps::ThermoPlasticBlockedParameters>();
1124 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
1125 auto make_d_mat = []() {
1129 common_plastic_ptr->mDPtr = boost::make_shared<MatrixDouble>();
1130 common_plastic_ptr->mGradPtr = boost::make_shared<MatrixDouble>();
1131 common_plastic_ptr->mStrainPtr = boost::make_shared<MatrixDouble>();
1132 common_plastic_ptr->mStressPtr = boost::make_shared<MatrixDouble>();
1134 auto m_D_ptr = common_plastic_ptr->mDPtr;
1137 m_field, plastic_block_name, pip, m_D_ptr,
1138 common_plastic_ptr->getParamsPtr(),
scale, sev),
1139 "add mat block plastic ops");
1141 m_field, pip, thermal_block_name, common_thermal_ptr,
1146 "add mat block thermal ops");
1148 m_field, pip, thermoelastic_block_name,
1151 "add mat block thermal ops");
1153 m_field, pip, thermoplastic_block_name,
1154 common_thermoplastic_ptr, common_thermal_ptr, sev,
1156 "add mat block thermoplastic ops");
1157 auto common_hencky_ptr =
1158 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1159 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform,
scale);
1161 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1164 tau, common_plastic_ptr->getPlasticTauPtr()));
1166 ep, common_plastic_ptr->getPlasticStrainPtr()));
1168 u, common_plastic_ptr->mGradPtr));
1171 temperature, common_thermoplastic_ptr->getTempPtr()));
1173 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
1175 common_plastic_ptr->mGradPtr = common_hencky_ptr->matGradPtr;
1176 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1177 common_hencky_ptr->matLogCPlastic =
1178 common_plastic_ptr->getPlasticStrainPtr();
1179 common_plastic_ptr->mStrainPtr = common_hencky_ptr->getMatLogC();
1180 common_plastic_ptr->mStressPtr = common_hencky_ptr->getMatHenckyStress();
1184 pip.push_back(
new typename H::template OpCalculateEigenVals<DIM, I>(
1185 u, common_hencky_ptr));
1187 new typename H::template OpCalculateLogC<DIM, I>(u, common_hencky_ptr));
1188 pip.push_back(
new typename H::template OpCalculateLogC_dC<DIM, I>(
1189 u, common_hencky_ptr));
1193 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1194 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1195 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1196 common_thermoelastic_ptr->getRefTempPtr()));
1197 pip.push_back(
new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
1198 u, common_hencky_ptr));
1200 pip.push_back(
new typename P::template OpCalculatePlasticSurface<DIM, I>(
1201 u, common_plastic_ptr));
1203 pip.push_back(
new typename P::template OpCalculatePlasticHardening<DIM, I>(
1204 u, common_plastic_ptr, common_thermoplastic_ptr));
1206 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
1207 common_thermal_ptr, common_thermoelastic_ptr,
1208 common_thermoplastic_ptr);
1218 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Run step pre proc";
1220 auto &m_field = ptr->ExRawPtr->mField;
1224 CHKERR TSGetApplicationContext(ts, (
void **)&ctx);
1228 if (ctx->mesh_changed == PETSC_TRUE) {
1229 ptr->ExRawPtr->mechanicalBC();
1230 ptr->ExRawPtr->thermalBC();
1234 auto get_norm = [&](
auto x) {
1236 CHKERR VecNorm(x, NORM_2, &nrm);
1240 auto save_range = [](moab::Interface &moab,
const std::string name,
1244 CHKERR moab.add_entities(*out_meshset, r);
1245 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(),
1250 auto dm =
simple->getDM();
1254 CHKERR VecGhostUpdateBegin(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1255 CHKERR VecGhostUpdateEnd(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1259 Tag th_spatial_coords;
1260 std::multimap<double, EntityHandle> el_q_map;
1261 std::vector<EntityHandle> new_connectivity;
1263 bool do_refine =
false;
1265 auto check_element_quality = [&]() {
1269 Range virgin_entities;
1274 CHKERR ptr->ExRawPtr->getElementQuality(el_q_map, flipped_els,
1275 new_connectivity, do_refine,
1281 auto solve_equil_sub_problem = [&]() {
1283 if (el_q_map.size() == 0) {
1293 auto U_ptr = boost::make_shared<MatrixDouble>();
1294 auto EP_ptr = boost::make_shared<MatrixDouble>();
1295 auto TAU_ptr = boost::make_shared<VectorDouble>();
1296 auto T_ptr = boost::make_shared<VectorDouble>();
1300 auto post_proc = [&](
auto dm) {
1303 auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
1306 post_proc_fe->getOpPtrVector(), {H1, L2, HDIV});
1313 post_proc_fe->getOpPtrVector().push_back(
1318 post_proc_fe->getOpPtrVector().push_back(
1320 post_proc_fe->getOpPtrVector().push_back(
1322 post_proc_fe->getOpPtrVector().push_back(
1325 post_proc_fe->getOpPtrVector().push_back(
1327 new OpPPMap(post_proc_fe->getPostProcMesh(),
1328 post_proc_fe->getMapGaussPts(),
1346 CHKERR post_proc_fe->writeFile(
"out_equilibrate.h5m");
1351 auto solve_equilibrate_solution = [&]() {
1354 auto set_domain_rhs = [&](
auto &pip) {
1363 typename B::template OpGradTimesSymTensor<1,
SPACE_DIM,
1370 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1371 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1374 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1375 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1380 auto m_D_ptr = common_plastic_ptr->mDPtr;
1383 "T", common_thermoplastic_ptr->getTempPtr()));
1386 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1388 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1391 if (common_hencky_ptr) {
1393 "U", common_hencky_ptr->getMatFirstPiolaStress()));
1402 auto set_domain_lhs = [&](
auto &pip) {
1413 typename B::template OpGradTensorGrad<1, SPACE_DIM, SPACE_DIM, 1>;
1420 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1421 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1424 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1425 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1430 auto m_D_ptr = common_plastic_ptr->mDPtr;
1434 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1436 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1438 if (common_hencky_ptr) {
1441 new typename H::template OpHenckyTangent<SPACE_DIM, IT, 0>(
1442 "U", common_hencky_ptr, m_D_ptr));
1444 new OpKPiola(
"U",
"U", common_hencky_ptr->getMatTangent()));
1452 pip.push_back(
new OpKCauchy(
"U",
"U", m_D_ptr));
1472 auto dm_sub =
createDM(m_field.get_comm(),
"DMMOFEM");
1476 for (
auto f : {
"U",
"EP",
"TAU",
"T"}) {
1484 auto sub_dm = create_sub_dm(
simple->getDM());
1486 auto fe_rhs = boost::make_shared<DomainEle>(m_field);
1487 auto fe_lhs = boost::make_shared<DomainEle>(m_field);
1489 fe_rhs->getRuleHook = vol_rule;
1490 fe_lhs->getRuleHook = vol_rule;
1491 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
1492 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
1494 auto bc_mng = m_field.getInterface<
BcManager>();
1499 auto &bc_map = bc_mng->getBcMapByBlockName();
1500 for (
auto bc : bc_map)
1501 MOFEM_LOG(
"PLASTICITY",
Sev::verbose) <<
"Marker " << bc.first;
1503 auto time_scale = boost::make_shared<TimeScale>(
1504 "",
false, [](
const double) {
return 1; });
1505 auto def_time_scale = [time_scale](
const double time) {
1506 return (!time_scale->argFileScale) ? time : 1;
1508 auto def_file_name = [time_scale](
const std::string &&name) {
1509 return (!time_scale->argFileScale) ? name :
"";
1511 auto time_displacement_scaling = boost::make_shared<TimeScale>(
1512 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
1514 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1515 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1516 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1518 PetscReal current_time;
1519 TSGetTime(ts, ¤t_time);
1520 pre_proc_ptr->ts_t = current_time;
1523 auto get_bc_hook_rhs = [&]() {
1525 ptr->ExRawPtr->mField, pre_proc_ptr,
1526 {time_scale, time_displacement_scaling});
1529 auto get_bc_hook_lhs = [&]() {
1531 ptr->ExRawPtr->mField, pre_proc_ptr,
1532 {time_scale, time_displacement_scaling});
1536 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1537 pre_proc_ptr->preProcessHook = get_bc_hook_lhs();
1539 auto get_post_proc_hook_rhs = [&]() {
1542 ptr->ExRawPtr->mField, post_proc_rhs_ptr,
nullptr,
1545 ptr->ExRawPtr->mField, post_proc_rhs_ptr, 1.)();
1548 auto get_post_proc_hook_lhs = [&]() {
1550 ptr->ExRawPtr->mField, post_proc_lhs_ptr, 1.);
1552 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1553 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1556 snes_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_ptr);
1557 snes_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_ptr);
1558 snes_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs_ptr);
1559 snes_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs_ptr);
1561 auto null_fe = boost::shared_ptr<FEMethod>();
1580 CHKERR SNESSetDM(snes, sub_dm);
1581 CHKERR SNESSetFromOptions(snes);
1586 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1587 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1592 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);
1594 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1595 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1602 CHKERR solve_equilibrate_solution();
1606 <<
"Equilibrated solution after mapping";
1611 if (ctx->mesh_changed == PETSC_FALSE)
1612 CHKERR check_element_quality();
1613 ctx->mesh_changed = PETSC_FALSE;
1614 if (el_q_map.size() > 0 || do_refine) {
1617 ctx->el_q_map = el_q_map;
1618 ctx->flipped_els = flipped_els;
1619 ctx->new_connectivity = new_connectivity;
1620 ctx->th_spatial_coords = th_spatial_coords;
1621 ctx->mesh_changed = PETSC_TRUE;
1629 CHKERR PetscBarrier((PetscObject)ts);
1641 auto &m_field = ptr->ExRawPtr->mField;
1662 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1663 std::string thermoplastic_block_name,
1664 boost::shared_ptr<ThermoPlasticOps::ThermoPlasticBlockedParameters>
1666 boost::shared_ptr<ThermoElasticOps::BlockedThermalParameters>
1667 &blockedThermalParamsPtr,
1671 struct OpMatThermoPlasticBlocks :
public DomainEleOp {
1672 OpMatThermoPlasticBlocks(
1673 boost::shared_ptr<double> omega_0_ptr,
1674 boost::shared_ptr<double> omega_h_ptr,
1675 boost::shared_ptr<double> inelastic_heat_fraction_ptr,
1676 boost::shared_ptr<double> temp_0_ptr,
1678 boost::shared_ptr<double> heat_capacity,
1679 boost::shared_ptr<double> heat_conductivity_scaling,
1683 std::vector<const CubitMeshSets *> meshset_vec_ptr)
1685 omegaHPtr(omega_h_ptr),
1686 inelasticHeatFractionPtr(inelastic_heat_fraction_ptr),
1688 heatCapacityPtr(heat_capacity),
1689 heatConductivityScalingPtr(heat_conductivity_scaling),
1693 extractThermoPlasticBlockData(m_field, meshset_vec_ptr, sev),
1694 "Can not get data from block");
1701 auto scale_param = [
this](
auto parameter,
double scaling) {
1702 return parameter * scaling;
1705 for (
auto &b : blockData) {
1707 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
1708 *omega0Ptr = b.omega_0;
1709 *omegaHPtr = b.omega_h;
1710 *inelasticHeatFractionPtr = scale_param(
1711 b.inelastic_heat_fraction,
1712 inelasticHeatFractionScaling(
1714 *heatConductivityPtr / (*heatConductivityScalingPtr),
1715 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1716 *temp0Ptr = b.temp_0;
1723 *inelasticHeatFractionPtr =
1725 inelasticHeatFractionScaling(
1727 *heatConductivityPtr / (*heatConductivityScalingPtr),
1728 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1736 boost::shared_ptr<double> heatConductivityPtr;
1737 boost::shared_ptr<double> heatCapacityPtr;
1738 boost::shared_ptr<double> heatConductivityScalingPtr;
1739 boost::shared_ptr<double> heatCapacityScalingPtr;
1748 std::vector<BlockData> blockData;
1752 std::vector<const CubitMeshSets *> meshset_vec_ptr,
Sev sev) {
1755 for (
auto m : meshset_vec_ptr) {
1757 std::vector<double> block_data;
1758 CHKERR m->getAttributes(block_data);
1759 if (block_data.size() < 3) {
1761 "Expected that block has four attributes");
1763 auto get_block_ents = [&]() {
1766 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
1771 <<
m->getName() <<
": omega_0 = " << block_data[0]
1772 <<
" omega_h = " << block_data[1]
1773 <<
" inelastic_heat_fraction = " << block_data[2] <<
" temp_0 "
1776 blockData.push_back({block_data[0], block_data[1], block_data[2],
1777 block_data[3], get_block_ents()});
1783 boost::shared_ptr<double> omega0Ptr;
1784 boost::shared_ptr<double> omegaHPtr;
1785 boost::shared_ptr<double> inelasticHeatFractionPtr;
1786 boost::shared_ptr<double> temp0Ptr;
1789 pipeline.push_back(
new OpMatThermoPlasticBlocks(
1790 blockedParamsPtr->getOmega0Ptr(), blockedParamsPtr->getOmegaHPtr(),
1791 blockedParamsPtr->getInelasticHeatFractionPtr(),
1792 blockedParamsPtr->getTemp0Ptr(),
1793 blockedThermalParamsPtr->getHeatConductivityPtr(),
1794 blockedThermalParamsPtr->getHeatCapacityPtr(),
1795 blockedThermalParamsPtr->getHeatConductivityScalingPtr(),
1796 blockedThermalParamsPtr->getHeatCapacityScalingPtr(),
1797 inelastic_heat_fraction_scaling_func, m_field, sev,
1802 (boost::format(
"%s(.*)") % thermoplastic_block_name).str()
1815 std::vector<EntityHandle> &new_connectivity,
1816 bool &do_refine,
Tag &th_spatial_coords) {
1821 std::vector<double> coords(verts.size() * 3);
1823 auto t_x = getFTensor1FromPtr<3>(coords.data());
1825 auto save_tag = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
1828 auto field_data = ent_ptr->getEntFieldData();
1831 t_u = {field_data[0], field_data[1], 0.0};
1833 t_u = {field_data[0], field_data[1], field_data[2]};
1843 double def_coord[3] = {0.0, 0.0, 0.0};
1845 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
1846 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
1858 std::multimap<double, EntityHandle> candidate_el_q_map;
1859 double spatial_coords[9], material_coords[9];
1862 Range::iterator nit = all_els.begin();
1863 for (
int gg = 0; nit != all_els.end(); nit++, gg++) {
1870 double q = Tools::areaLengthQuality(spatial_coords);
1871 if (!std::isnormal(q))
1873 "Calculated quality of element is not "
1877 if (q < qual_tol && q > 0.)
1878 candidate_el_q_map.insert(std::pair<double, EntityHandle>(q, *nit));
1883 all_els, min_q, th_spatial_coords);
1885 <<
"Old minimum element quality: " << min_q;
1887 auto pair = candidate_el_q_map.begin();
1889 <<
"New minimum element quality: " << pair->first;
1891 for (
auto pair = candidate_el_q_map.begin(); pair != candidate_el_q_map.end();
1893 double quality = pair->first;
1895 element.insert(pair->second);
1896 if (!flipped_els.contains(element)) {
1903 double longest_edge_length = 0;
1904 std::vector<std::pair<double, EntityHandle>> edge_lengths;
1905 edge_lengths.reserve(edges.size());
1906 for (
auto edge : edges) {
1907 edge_lengths.emplace_back(
1910 if (!edge_lengths.empty()) {
1911 const auto it = std::max_element(
1912 edge_lengths.begin(), edge_lengths.end(),
1913 [](
const auto &
a,
const auto &b) { return a.first < b.first; });
1914 longest_edge_length = it->first;
1915 longest_edge = it->second;
1918 "Unable to calculate edge lengths to find longest edge.");
1922 <<
"Edge flip longest edge length: " << longest_edge_length
1923 <<
" for edge: " << longest_edge;
1931 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
1936 Range boundary_ents;
1937 ParallelComm *pcomm =
1939 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1940 PSTATUS_NOT, -1, &boundary_ents);
1941 return boundary_ents;
1947 <<
"Boundary entities: " << boundary_ents;
1950 Range flip_candidate_els;
1952 false, flip_candidate_els);
1956 Range neighbouring_el = subtract(flip_candidate_els, element);
1960 if (boundary_ents.contains(
Range(longest_edge, longest_edge))) {
1964 if (flipped_els.contains(neighbouring_el))
1968 if (neighbouring_el.size() != 1) {
1970 "Should be 1 neighbouring element to bad element for edge "
1971 "flip. Instead, there are %d",
1972 neighbouring_el.size());
1977 <<
"flip_candidate_els: " << flip_candidate_els;
1979 <<
"Neighbouring element: " << neighbouring_el;
1982 std::vector<EntityHandle> neighbouring_nodes;
1984 neighbouring_nodes,
true);
1986 std::vector<EntityHandle> element_nodes;
1988 element_nodes,
true);
1991 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
1993 double neighbour_qual = Tools::areaLengthQuality(spatial_coords);
1994 if (!std::isnormal(neighbour_qual))
1996 "Calculated quality of neighbouring element is not as "
2004 <<
"Element nodes before swap: "
2007 <<
"Neighbouring nodes before swap: "
2016 std::vector<EntityHandle> reversed_neighbouring_nodes =
2018 std::reverse(reversed_neighbouring_nodes.begin(),
2019 reversed_neighbouring_nodes.end());
2021 int num_matches = 0;
2022 std::vector<bool> mismatch_mask(element_nodes.size());
2023 int loop_counter = 0;
2024 while (num_matches != 2) {
2026 std::rotate(reversed_neighbouring_nodes.begin(),
2027 reversed_neighbouring_nodes.begin() + 1,
2028 reversed_neighbouring_nodes.end());
2030 std::transform(element_nodes.begin(), element_nodes.end(),
2031 reversed_neighbouring_nodes.begin(),
2032 mismatch_mask.begin(), std::equal_to<EntityHandle>());
2035 std::count(mismatch_mask.begin(), mismatch_mask.end(),
true);
2038 if (loop_counter > 3) {
2040 "Not found matching nodes for edge flipping");
2045 std::vector<EntityHandle> matched_elements(element_nodes.size());
2046 std::transform(element_nodes.begin(), element_nodes.end(),
2047 mismatch_mask.begin(), matched_elements.begin(),
2049 return match ? el : -1;
2053 matched_elements.erase(
2054 std::remove(matched_elements.begin(), matched_elements.end(), -1),
2055 matched_elements.end());
2058 std::vector<EntityHandle> mismatched_elements(element_nodes.size()),
2059 neighbouring_mismatched_elements(neighbouring_nodes.size());
2060 std::transform(element_nodes.begin(), element_nodes.end(),
2061 mismatch_mask.begin(), mismatched_elements.begin(),
2063 return match ? -1 : el;
2065 std::transform(reversed_neighbouring_nodes.begin(),
2066 reversed_neighbouring_nodes.end(), mismatch_mask.begin(),
2067 neighbouring_mismatched_elements.begin(),
2069 return match ? -1 : el;
2073 mismatched_elements.erase(std::remove(mismatched_elements.begin(),
2074 mismatched_elements.end(), -1),
2075 mismatched_elements.end());
2076 neighbouring_mismatched_elements.erase(
2077 std::remove(neighbouring_mismatched_elements.begin(),
2078 neighbouring_mismatched_elements.end(), -1),
2079 neighbouring_mismatched_elements.end());
2081 mismatched_elements.insert(mismatched_elements.end(),
2082 neighbouring_mismatched_elements.begin(),
2083 neighbouring_mismatched_elements.end());
2086 <<
"Reversed neighbouring nodes: "
2098 auto replace_correct_nodes = [](std::vector<EntityHandle> &ABC,
2099 std::vector<EntityHandle> &DBA,
2100 const std::vector<EntityHandle> &AB,
2101 const std::vector<EntityHandle> &CD) {
2103 std::vector<std::vector<EntityHandle>> results;
2105 for (
int i = 0;
i < 2; ++
i) {
2106 for (
int j = 0;
j < 2; ++
j) {
2108 if (std::find(ABC.begin(), ABC.end(), CD[
j]) == ABC.end()) {
2109 std::vector<EntityHandle> tmp = ABC;
2111 auto it = std::find(tmp.begin(), tmp.end(), AB[
i]);
2112 if (it != tmp.end()) {
2114 results.push_back(tmp);
2120 if (results.size() != 2) {
2122 "Failed to find two valid vertex replacements for edge "
2132 CHKERR replace_correct_nodes(element_nodes, neighbouring_nodes,
2133 matched_elements, mismatched_elements);
2136 <<
"Element nodes after swap: "
2139 <<
"Neighbouring nodes after swap: "
2144 th_spatial_coords, &element_nodes.front(), 3, spatial_coords);
2146 double new_qual = Tools::areaLengthQuality(spatial_coords);
2147 if (new_qual < 0.0 || !std::isfinite(new_qual))
2149 "Calculated quality of new element is not as expected: %f",
2153 auto check_normal_direction = [&](
double qual_val) {
2157 auto [new_area, t_new_normal] = Tools::triAreaAndNormal(spatial_coords);
2159 t_diff(
i) = t_new_normal(
i) - t_correct_normal(
i);
2160 if (qual_val > 1e-6 && t_diff(
i) * t_diff(
i) > 1e-6) {
2162 "Direction of element to be created is wrong orientation");
2167 CHKERR check_normal_direction(new_qual);
2171 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2173 double new_neighbour_qual = Tools::areaLengthQuality(spatial_coords);
2174 if (new_neighbour_qual < 0.0 || !std::isfinite(new_neighbour_qual))
2176 "Calculated quality of new neighbouring element is not "
2178 new_neighbour_qual);
2181 CHKERR check_normal_direction(new_neighbour_qual);
2185 if (std::min(new_qual, new_neighbour_qual) >
2186 (1. +
qual_thresh) * std::min(quality, neighbour_qual)) {
2188 <<
"Element quality improved from " << quality <<
" and "
2189 << neighbour_qual <<
" to " << new_qual <<
" and "
2190 << new_neighbour_qual <<
" for elements" << element <<
" and "
2194 flipped_els.merge(flip_candidate_els);
2196 std::pair<double, EntityHandle>(pair->first, pair->second));
2197 new_connectivity.insert(new_connectivity.end(), element_nodes.begin(),
2198 element_nodes.end());
2199 new_connectivity.insert(new_connectivity.end(),
2200 neighbouring_nodes.begin(),
2201 neighbouring_nodes.end());
2206 if (el_q_map.size() > 0) {
2207 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"Flipped elements: " << flipped_els;
2216 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2217 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2219 Range prev_ref_ents;
2224 for (
auto e : edges) {
2228 std::array<double, 6> ref_coords, spatial_coords;
2231 spatial_coords.data());
2232 auto get_length = [](
auto &
a) {
2236 p1(
i) = p1(
i) - p0(
i);
2239 auto ref_edge_length = get_length(ref_coords);
2240 auto spatial_edge_length = get_length(spatial_coords);
2241 auto change = spatial_edge_length / ref_edge_length;
2243 !prev_ref_ents.contains(
Range(e, e))) {
2259 auto make_edge_flip = [&](
auto edge,
auto adj_faces,
Range &new_tris) {
2266 CHKERR moab.get_connectivity(e, conn, num_nodes,
true);
2267 std::copy(conn, conn + num_nodes, conn_cpy);
2271 auto get_tri_normals = [&](
auto &conn) {
2272 std::array<double, 18> coords;
2273 CHKERR moab.get_coords(conn.data(), 6, coords.data());
2274 std::array<FTensor::Tensor1<double, 3>, 2> tri_normals;
2275 for (
int t = 0;
t != 2; ++
t) {
2281 auto test_flip = [&](
auto &&t_normals) {
2283 if (t_normals[0](
i) * t_normals[1](
i) <
2284 std::numeric_limits<float>::epsilon())
2289 std::array<EntityHandle, 6> adj_conn;
2290 CHKERR get_conn(adj_faces[0], &adj_conn[0]);
2291 CHKERR get_conn(adj_faces[1], &adj_conn[3]);
2292 std::array<EntityHandle, 2> edge_conn;
2293 CHKERR get_conn(edge, edge_conn.data());
2294 std::array<EntityHandle, 2> new_edge_conn;
2297 for (
int i = 0;
i != 6; ++
i) {
2298 if (adj_conn[
i] != edge_conn[0] && adj_conn[
i] != edge_conn[1]) {
2299 new_edge_conn[
j] = adj_conn[
i];
2304 auto &new_conn = adj_conn;
2305 for (
int t = 0;
t != 2; ++
t) {
2306 for (
int i = 0;
i != 3; ++
i) {
2309 (adj_conn[3 *
t +
i % 3] == edge_conn[0] &&
2310 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[1])
2314 (adj_conn[3 *
t +
i % 3] == edge_conn[1] &&
2315 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[0])
2318 new_conn[3 *
t + (
i + 1) % 3] = new_edge_conn[
t];
2324 if (test_flip(get_tri_normals(new_conn))) {
2325 for (
int t = 0;
t != 2; ++
t) {
2333 new_tris.insert(tri);
2336 if (rtri.size() != 1) {
2338 <<
"Multiple tries created during edge flip for edge " << edge
2339 <<
" adjacent faces " << std::endl
2342 "Multiple tries created during edge flip");
2345 new_tris.merge(rtri);
2351 moab::Interface::UNION);
2355 MOFEM_LOG(
"SELF", Sev::warning) <<
"Edge flip rejected for edge " << edge
2356 <<
" adjacent faces " << adj_faces;
2366 Skinner skin(&moab);
2368 CHKERR skin.find_skin(0, tris,
false, skin_edges);
2372 edges = subtract(edges, skin_edges);
2376 Range new_tris, flipped_tris, forbidden_tris;
2378 for (
auto edge : edges) {
2379 Range adjacent_tris;
2380 CHKERR moab.get_adjacencies(&edge, 1,
SPACE_DIM,
true, adjacent_tris);
2382 adjacent_tris = intersect(adjacent_tris, tris);
2383 adjacent_tris = subtract(adjacent_tris, forbidden_tris);
2384 if (adjacent_tris.size() == 2) {
2387 int side_number0, sense0, offset0;
2390 int side_number1, sense1, offset1;
2393 if (sense0 * sense1 > 0)
2396 "Cannot flip edge with same orientation in both adjacent faces");
2399 Range new_flipped_tris;
2400 CHKERR make_edge_flip(edge, adjacent_tris, new_flipped_tris);
2401 if (new_flipped_tris.size()) {
2402 flipped_tris.merge(adjacent_tris);
2403 forbidden_tris.merge(adjacent_tris);
2404 new_tris.merge(new_flipped_tris);
2408 "flipped_tris_" + std::to_string(flip_count) +
".vtk",
2411 moab,
"new_flipped_tris_" + std::to_string(flip_count) +
".vtk",
2423 Range not_flipped_tris = subtract(all_tris, flipped_tris);
2426 <<
"Flipped " << flip_count <<
" edges with two adjacent faces.";
2432 child_bit,
BitRefLevel().set(),
"edge_flips_before_refinement.vtk",
"VTK",
2442 Range &flipped_els,
Tag &th_spatial_coords,
2443 std::vector<EntityHandle> &new_connectivity) {
2446 ReadUtilIface *read_util;
2449 const int num_ele = el_q_map.size() * 2;
2450 int num_nod_per_ele;
2451 EntityType ent_type;
2454 num_nod_per_ele = 3;
2457 num_nod_per_ele = 4;
2462 auto new_conn = new_connectivity.begin();
2463 for (
auto e = 0; e != num_ele; ++e) {
2465 for (
int n = 0;
n < num_nod_per_ele; ++
n) {
2466 conn[
n] = *new_conn;
2473 if (adj_ele.size()) {
2474 if (adj_ele.size() != 1) {
2476 "Element duplication");
2478 new_ele = adj_ele.front();
2484 new_elements.insert(new_ele);
2488 <<
"New elements from edge flipping: " << new_elements;
2497 auto get_adj = [&](
auto ents) {
2502 moab::Interface::UNION),
2503 "Getting adjacencies of dimension " + std::to_string(d) +
" failed");
2508 Range non_flipped_range;
2512 non_flipped_range = subtract(non_flipped_range, flipped_els);
2513 auto flip_bit_ents = new_elements;
2514 flip_bit_ents.merge(non_flipped_range);
2515 auto adj = get_adj(new_elements);
2523 "new_elements_after_edge_flips.vtk",
"VTK",
"");
2533 Tag th_spatial_coords;
2534 double def_coord[3] = {0.0, 0.0, 0.0};
2536 auto refined_mesh = [&](
auto level) {
2543 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2544 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2548 for (
auto e : edges) {
2552 std::array<double, 6> ref_coords, spatial_coords;
2555 num_nodes, spatial_coords.data());
2556 auto get_length = [](
auto &
a) {
2560 p1(
i) = p1(
i) - p0(
i);
2563 auto ref_edge_length = get_length(ref_coords);
2564 auto spatial_edge_length = get_length(spatial_coords);
2565 auto change = spatial_edge_length / ref_edge_length;
2567 refine_edges.insert(e);
2571 if (refine_edges.size())
2574 Range prev_level_ents;
2578 Range prev_ref_ents;
2583 refine_edges.merge(intersect(prev_ref_ents, prev_level_ents));
2590 Range tris_to_refine;
2595 auto set_spatial_coords = [&]() {
2600 auto th_parent_handle =
2602 for (
auto v : new_vertices) {
2609 std::array<double, 6> spatial_coords;
2611 num_nodes, spatial_coords.data());
2612 for (
auto d = 0; d < 3; ++d) {
2613 spatial_coords[d] += spatial_coords[3 + d];
2615 for (
auto d = 0; d < 3; ++d) {
2616 spatial_coords[d] /= 2.0;
2619 spatial_coords.data());
2624 CHKERR set_spatial_coords();
2628 (
"A_refined_" + boost::lexical_cast<std::string>(level) +
".vtk")
2650 BitRefLevel().set(), 2,
"new_elements_after_edge_splits.vtk",
"VTK",
"");
2679 auto get_ents_by_dim = [&](
const auto dim) {
2692 auto get_base = [&]() {
2693 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
2694 if (domain_ents.empty())
2712 const auto base = get_base();
2749 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2753 auto filter_blocks = [&](
auto skin) {
2754 bool is_contact_block =
false;
2755 Range contact_range;
2759 (boost::format(
"%s(.*)") %
"CONTACT").str()
2768 <<
"Find contact block set: " <<
m->getName();
2769 auto meshset =
m->getMeshset();
2770 Range contact_meshset_range;
2772 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
2775 contact_meshset_range);
2776 contact_range.merge(contact_meshset_range);
2778 if (is_contact_block) {
2780 <<
"Nb entities in contact surface: " << contact_range.size();
2782 skin = intersect(skin, contact_range);
2788 Range boundary_ents;
2789 ParallelComm *pcomm =
2791 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2792 PSTATUS_NOT, -1, &boundary_ents);
2793 return boundary_ents;
2804 if (
qual_tol < std::numeric_limits<double>::epsilon() &&
2827 auto get_command_line_parameters = [&]() {
2841 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Minimum dt: " <<
min_dt;
2846 <<
"Minumum quality for edge flipping: " <<
qual_tol;
2851 <<
"Quality improvement threshold for edge flipping: " <<
qual_thresh;
2859 <<
"Number of refinement levels for edge splitting: "
2896 (PetscInt *)&
ic_type, PETSC_NULLPTR);
2920 PetscBool tau_order_is_set;
2923 PetscBool ep_order_is_set;
2926 PetscBool flux_order_is_set;
2928 &flux_order_is_set);
2929 PetscBool T_order_is_set;
2952 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Hardening " <<
H;
2953 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Viscous hardening " <<
visH;
2954 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation yield stress " <<
Qinf;
2955 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation exponent " <<
b_iso;
2956 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Kinematic hardening " <<
C1_k;
2961 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"zeta * dt " <<
zeta;
2975 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
2980 if (tau_order_is_set == PETSC_FALSE)
2982 if (ep_order_is_set == PETSC_FALSE)
2985 if (flux_order_is_set == PETSC_FALSE)
2987 if (T_order_is_set == PETSC_FALSE)
2990 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Approximation order " <<
order;
2992 <<
"Ep approximation order " <<
ep_order;
2994 <<
"Tau approximation order " <<
tau_order;
2996 <<
"FLUX approximation order " <<
flux_order;
3001 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Density " <<
rho;
3004 PetscBool is_scale = PETSC_TRUE;
3007 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Scaling used? " << is_scale;
3011 MOFEM_LOG(
"THERMOPLASTICITY", Sev::warning)
3012 <<
"Scaling does not yet work with radiation and convection BCs";
3017 if (heat_cap != 0.0 && thermal_cond != 0.0)
3018 return 1. / (thermal_cond * heat_cap);
3020 return 1. / thermal_cond;
3023 if (heat_cap != 0.0)
3024 return 1. / (thermal_cond * heat_cap);
3029 [&](
double young_modulus,
double thermal_cond,
double heat_cap) {
3030 if (heat_cap != 0.0)
3044 double thermal_cond,
3045 double heat_cap) {
return 1.0; };
3051 <<
"Thermal conductivity scale "
3055 <<
"Thermal capacity scale "
3058 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
3059 <<
"Inelastic heat fraction scale "
3073 CHKERR get_command_line_parameters();
3076 #ifdef ENABLE_PYTHON_BINDING
3077 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
3078 CHKERR sdfPythonPtr->sdfInit(
"sdf.py");
3079 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
3091 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order; };
3139 auto T_ptr = boost::make_shared<VectorDouble>();
3141 auto post_proc = [&](
auto dm) {
3144 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
3148 post_proc_fe->getOpPtrVector().push_back(
3154 auto TAU_ptr = boost::make_shared<VectorDouble>();
3155 auto EP_ptr = boost::make_shared<MatrixDouble>();
3157 post_proc_fe->getOpPtrVector().push_back(
3159 post_proc_fe->getOpPtrVector().push_back(
3162 post_proc_fe->getOpPtrVector().push_back(
3164 new OpPPMap(post_proc_fe->getPostProcMesh(),
3165 post_proc_fe->getMapGaussPts(),
3167 {{
"T", T_ptr}, {
"TAU", TAU_ptr}},
3179 post_proc_fe->getOpPtrVector().push_back(
3181 new OpPPMap(post_proc_fe->getPostProcMesh(),
3182 post_proc_fe->getMapGaussPts(),
3198 CHKERR post_proc_fe->writeFile(
"out_init.h5m");
3203 auto solve_init = [&]() {
3206 auto set_domain_rhs = [&](
auto &pip) {
3213 "T",
nullptr, T_ptr,
nullptr, boost::make_shared<double>(
init_temp),
3214 boost::make_shared<double>(
peak_temp)));
3217 auto TAU_ptr = boost::make_shared<VectorDouble>();
3218 auto EP_ptr = boost::make_shared<MatrixDouble>();
3221 auto min_tau = boost::make_shared<double>(1.0);
3222 auto max_tau = boost::make_shared<double>(2.0);
3224 nullptr, min_tau, max_tau));
3228 auto min_EP = boost::make_shared<double>(0.0);
3229 auto max_EP = boost::make_shared<double>(0.01);
3231 "EP",
nullptr, EP_ptr,
nullptr, min_EP, max_EP));
3273 auto set_domain_lhs = [&](
auto &pip) {
3280 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"T",
"T"));
3282 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"TAU",
"TAU"));
3328 auto dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
3332 for (
auto f : {
"T"}) {
3337 for (
auto f : {
"TAU",
"EP"}) {
3346 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3347 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3348 fe_rhs->getRuleHook = vol_rule;
3349 fe_lhs->getRuleHook = vol_rule;
3350 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3351 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3353 auto sub_dm = create_sub_dm(
simple->getDM());
3355 auto null_fe = boost::shared_ptr<FEMethod>();
3357 fe_lhs, null_fe, null_fe);
3362 CHKERR KSPSetDM(ksp, sub_dm);
3363 CHKERR KSPSetFromOptions(ksp);
3367 CHKERR KSPSolve(ksp, PETSC_NULLPTR,
D);
3369 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
3370 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
3379 MOFEM_LOG(
"THERMAL", Sev::inform) <<
"Set thermoelastic initial conditions";
3392 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
3395 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
3398 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
3401 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3402 "REMOVE_ALL",
"U", 0, 3,
true,
3406 for (
auto b : {
"FIX_X",
"REMOVE_X"})
3407 CHKERR bc_mng->removeBlockDOFsOnEntities(
3409 for (
auto b : {
"FIX_Y",
"REMOVE_Y"})
3410 CHKERR bc_mng->removeBlockDOFsOnEntities(
3412 for (
auto b : {
"FIX_Z",
"REMOVE_Z"})
3413 CHKERR bc_mng->removeBlockDOFsOnEntities(
3415 for (
auto b : {
"FIX_ALL",
"REMOVE_ALL"})
3416 CHKERR bc_mng->removeBlockDOFsOnEntities(
3418 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3419 "NO_CONTACT",
"SIGMA", 0, 3,
false,
3424 simple->getProblemName(),
"U");
3426 auto &bc_map = bc_mng->getBcMapByBlockName();
3427 for (
auto bc : bc_map)
3428 MOFEM_LOG(
"PLASTICITY", Sev::verbose) <<
"Marker " << bc.first;
3449 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
3453 auto filter_flux_blocks = [&](
auto skin,
bool temp_bc =
false) {
3454 auto remove_cubit_blocks = [&](
auto c) {
3464 skin = subtract(skin, ents);
3469 auto remove_named_blocks = [&](
auto n) {
3474 (boost::format(
"%s(.*)") %
n).str()
3482 skin = subtract(skin, ents);
3488 "remove_cubit_blocks");
3490 "remove_named_blocks");
3493 "remove_cubit_blocks");
3501 Range boundary_ents;
3502 ParallelComm *pcomm =
3504 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3505 PSTATUS_NOT, -1, &boundary_ents);
3506 return boundary_ents;
3510 auto remove_temp_bc_ents =
3516 remove_temp_bc_ents);
3518 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
3521 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3535 simple->getProblemName(),
"FLUX", remove_flux_ents);
3537 simple->getProblemName(),
"TBC", remove_temp_bc_ents);
3540 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"FLUX",
3543 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"TBC",
3544 remove_temp_bc_ents);
3556 simple->getProblemName(),
"FLUX",
false);
3569 auto boundary_marker =
3570 bc_mng->getMergedBlocksMarker(vector<string>{
"HEATFLUX"});
3572 auto integration_rule_bc = [](
int,
int,
int ao) {
return 2 * ao; };
3576 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
3577 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
3579 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
3580 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
3582 auto thermal_block_params =
3583 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
3584 auto heat_conductivity_ptr = thermal_block_params->getHeatConductivityPtr();
3585 auto heat_capacity_ptr = thermal_block_params->getHeatCapacityPtr();
3587 auto thermoelastic_block_params =
3588 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
3589 auto coeff_expansion_ptr = thermoelastic_block_params->getCoeffExpansionPtr();
3590 auto ref_temp_ptr = thermoelastic_block_params->getRefTempPtr();
3594 boost::make_shared<TimeScale>(
"",
false, [](
const double) {
return 1; });
3595 auto def_time_scale = [time_scale](
const double time) {
3596 return (!time_scale->argFileScale) ? time : 1;
3598 auto def_file_name = [time_scale](
const std::string &&name) {
3599 return (!time_scale->argFileScale) ? name :
"";
3603 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
3604 def_file_name(
"bodyforce_scale.txt"),
false, def_time_scale);
3605 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
3606 def_file_name(
"heatsource_scale.txt"),
false, def_time_scale);
3607 auto time_temperature_scaling = boost::make_shared<TimeScale>(
3608 def_file_name(
"temperature_bc_scale.txt"),
false, def_time_scale);
3609 auto time_displacement_scaling = boost::make_shared<TimeScale>(
3610 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
3611 auto time_flux_scaling = boost::make_shared<TimeScale>(
3612 def_file_name(
"flux_bc_scale.txt"),
false, def_time_scale);
3613 auto time_force_scaling = boost::make_shared<TimeScale>(
3614 def_file_name(
"force_bc_scale.txt"),
false, def_time_scale);
3616 auto add_boundary_ops_lhs = [&](
auto &pip) {
3619 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3626 pip,
mField,
"U", Sev::inform);
3630 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3633 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
3634 mField, pip,
simple->getDomainFEName(),
"SIGMA",
"U",
"", vol_rule);
3639 using OpConvectionLhsBC =
3640 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3641 using OpRadiationLhsBC =
3642 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3643 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3645 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pip,
mField,
"TBC",
"TBC",
3646 "CONVECTION", Sev::verbose);
3647 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
3648 pip,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
3655 struct OpTBCTimesNormalFlux
3660 OpTBCTimesNormalFlux(
const std::string row_field_name,
3661 const std::string col_field_name,
3662 boost::shared_ptr<Range> ents_ptr =
nullptr)
3663 :
OP(row_field_name, col_field_name,
OP::OPROWCOL, ents_ptr) {
3665 this->assembleTranspose =
true;
3666 this->onlyTranspose =
false;
3676 auto t_w = OP::getFTensor0IntegrationWeight();
3680 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3682 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3684 auto a_mat_ptr = &*OP::locMat.data().begin();
3686 for (; rr != OP::nbRows; rr++) {
3688 const double alpha = t_w * t_row_base;
3692 for (
int cc = 0; cc != OP::nbCols; cc++) {
3696 *a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
3702 for (; rr < OP::nbRowBaseFunctions; ++rr)
3707 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3708 if (fe_type == MBTRI) {
3715 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC",
"FLUX"));
3720 auto add_boundary_ops_rhs = [&](
auto &pip) {
3727 pip,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
3735 pip,
mField,
"FLUX", {time_scale, time_temperature_scaling},
3736 "TEMPERATURE", Sev::inform);
3746 pip,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
3750 using OpConvectionRhsBC =
3751 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3752 using OpRadiationRhsBC =
3753 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3754 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3756 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
3757 pip,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
3758 T::AddFluxToPipeline<OpRadiationRhsBC>::add(pip,
mField,
"TBC", temp_bc_ptr,
3759 "RADIATION", Sev::inform);
3761 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3770 struct OpTBCTimesNormalFlux
3775 OpTBCTimesNormalFlux(
const std::string
field_name,
3776 boost::shared_ptr<MatrixDouble> vec,
3777 boost::shared_ptr<Range> ents_ptr =
nullptr)
3784 auto t_w = OP::getFTensor0IntegrationWeight();
3788 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3790 auto t_vec = getFTensor1FromMat<SPACE_DIM, 1>(*sourceVec);
3792 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3794 const double alpha = t_w * (t_vec(
i) * t_normal(
i));
3797 for (; rr != OP::nbRows; ++rr) {
3798 OP::locF[rr] += alpha * t_row_base;
3801 for (; rr < OP::nbRowBaseFunctions; ++rr)
3807 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3808 if (fe_type == MBTRI) {
3815 boost::shared_ptr<MatrixDouble> sourceVec;
3817 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC", mat_flux_ptr));
3819 struct OpBaseNormalTimesTBC
3824 OpBaseNormalTimesTBC(
const std::string
field_name,
3825 boost::shared_ptr<VectorDouble> vec,
3826 boost::shared_ptr<Range> ents_ptr =
nullptr)
3833 auto t_w = OP::getFTensor0IntegrationWeight();
3837 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3841 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3843 const double alpha = t_w * t_vec;
3846 for (; rr != OP::nbRows; ++rr) {
3847 OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
3850 for (; rr < OP::nbRowBaseFunctions; ++rr)
3856 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3857 if (fe_type == MBTRI) {
3864 boost::shared_ptr<VectorDouble> sourceVec;
3867 pip.push_back(
new OpBaseNormalTimesTBC(
"FLUX", temp_bc_ptr));
3870 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3877 auto add_domain_ops_lhs = [&](
auto &pip) {
3880 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3883 mField, pip,
"MAT_THERMAL", thermal_block_params,
3897 auto get_inertia_and_mass_damping = [
this](
const double,
const double,
3901 return (
rho /
scale) * fe_domain_lhs->ts_aa +
3904 pip.push_back(
new OpMass(
"U",
"U", get_inertia_and_mass_damping));
3907 CHKERR opThermoPlasticFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
3908 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
3909 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
3911 auto hencky_common_data_ptr =
3912 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3913 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3914 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3915 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3917 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3919 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3921 return (1. / (*heat_conductivity_ptr));
3923 auto capacity = [heat_capacity_ptr](
const double,
const double,
3925 return -(*heat_capacity_ptr);
3928 pip.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance, mat_grad_ptr));
3930 new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
3932 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3937 new OpHdivU(
"FLUX",
"U", mat_flux_ptr, resistance, mat_grad_ptr));
3939 auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
3940 op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
3941 return fe_ptr->ts_a;
3943 pip.push_back(op_capacity);
3947 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3950 pip,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
3957 auto add_domain_ops_rhs = [&](
auto &pip) {
3960 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3963 mField, pip,
"MAT_THERMAL", thermal_block_params,
3970 auto hencky_common_data_ptr =
3971 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3972 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3973 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3974 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3975 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
3976 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
3978 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3979 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
3980 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3981 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
3986 "FLUX", vec_temp_div_ptr));
3990 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3992 return (1. / (*heat_conductivity_ptr));
3995 auto capacity = [heat_capacity_ptr](
const double,
const double,
3997 return -(*heat_capacity_ptr);
4003 new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
4004 pip.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
4005 pip.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
4006 pip.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
4010 {boost::make_shared<ScaledTimeScale>(
"body_force_hist.txt")},
4021 auto mat_acceleration = boost::make_shared<MatrixDouble>();
4023 "U", mat_acceleration));
4025 new OpInertiaForce(
"U", mat_acceleration, [](
double,
double,
double) {
4029 auto mat_velocity = boost::make_shared<MatrixDouble>();
4033 new OpInertiaForce(
"U", mat_velocity, [](
double,
double,
double) {
4039 CHKERR opThermoPlasticFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4040 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4041 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
4044 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4053 auto create_reaction_pipeline = [&](
auto &pip) {
4056 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
4057 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
4068 auto get_bc_hook_rhs = [&]() {
4070 mField, pip_mng->getDomainRhsFE(),
4071 {time_scale, time_displacement_scaling});
4074 auto get_bc_hook_lhs = [&]() {
4076 mField, pip_mng->getDomainLhsFE(),
4077 {time_scale, time_displacement_scaling});
4081 pip_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
4082 pip_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
4084 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
4085 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
4088 CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
4089 CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
4121 PetscInt snes_iter_counter = 0;
4143 PetscBool *resize,
void *ctx) {
4147 PetscFunctionReturn(0);
4151 Vec ts_vecsout[],
void *ctx) {
4155 if (
auto ptr = rctx->
ptr.lock()) {
4170 std::string improved_reasons =
"";
4172 Range edges_to_not_refine;
4178 improved_reasons +=
", Edge flipping";
4181 bool refined =
false;
4183 CHKERR TSGetStepNumber(ts, &step);
4184 CHKERR ptr->ExRawPtr->doEdgeSplits(refined, (step) ?
true :
false);
4186 improved_reasons +=
", Edge splitting";
4190 improved_reasons.erase(0, 2);
4192 if (improved_reasons !=
"")
4194 <<
"Improved mesh quality by: " << improved_reasons;
4208 "before_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4217 "before_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4220 "before_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4224 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"number of vectors to map = " << nv;
4226 for (PetscInt
i = 0;
i < nv; ++
i) {
4228 CHKERR VecNorm(ts_vecsin[
i], NORM_2, &nrm);
4230 <<
"Before remeshing: ts_vecsin[" <<
i <<
"] norm = " << nrm;
4252 intermediate_dm, &m_field,
"INTERMEDIATE_DM",
4256 CHKERR DMSetFromOptions(intermediate_dm);
4260 CHKERR DMSetUp(intermediate_dm);
4262 Vec vec_in[nv], vec_out[nv];
4263 for (PetscInt
i = 0;
i < nv; ++
i) {
4264 CHKERR DMCreateGlobalVector(intermediate_dm, &vec_in[
i]);
4265 CHKERR VecDuplicate(vec_in[
i], &vec_out[
i]);
4268 VecScatter scatter_to_intermediate;
4270 for (PetscInt
i = 0;
i < nv; ++
i) {
4271 CHKERR scatter_mng->vecScatterCreate(
4274 CHKERR VecScatterBegin(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4275 INSERT_VALUES, SCATTER_FORWARD);
4276 CHKERR VecScatterEnd(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4277 INSERT_VALUES, SCATTER_FORWARD);
4280 CHKERR VecScatterDestroy(&scatter_to_intermediate);
4288 auto ts_problem_name =
simple->getProblemName();
4295 PetscBarrier(
nullptr);
4304 CHKERR ptr->ExRawPtr->mechanicalBC();
4305 CHKERR ptr->ExRawPtr->thermalBC();
4307 VecScatter scatter_to_final;
4309 for (PetscInt
i = 0;
i < nv; ++
i) {
4310 CHKERR DMCreateGlobalVector(
simple->getDM(), &ts_vecsout[
i]);
4311 CHKERR scatter_mng->vecScatterCreate(
4314 CHKERR VecScatterBegin(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4315 INSERT_VALUES, SCATTER_REVERSE);
4316 CHKERR VecScatterEnd(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4317 INSERT_VALUES, SCATTER_REVERSE);
4318 CHKERR VecScatterDestroy(&scatter_to_final);
4321 for (PetscInt
i = 0;
i < nv; ++
i) {
4322 CHKERR VecDestroy(&vec_in[
i]);
4323 CHKERR VecDestroy(&vec_out[
i]);
4343 CHKERR bit_mng->lambdaBitRefLevel(set_all_bit);
4357 "after_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4366 "after_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4369 "after_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4381 CHKERR TSSetIJacobian(ts,
B,
B,
nullptr,
nullptr);
4384 for (PetscInt
i = 0;
i < nv; ++
i) {
4386 CHKERR VecNorm(ts_vecsout[
i], NORM_2, &nrm);
4388 <<
"After remeshing: ts_vecsout[" <<
i <<
"] norm = " << nrm;
4391 PetscFunctionReturn(0);
4405 auto set_section_monitor = [&](
auto solver) {
4408 CHKERR TSGetSNES(solver, &snes);
4409 CHKERR SNESMonitorSet(snes,
4412 (
void *)(snes_ctx_ptr.get()),
nullptr);
4416 auto create_post_process_elements = [&]() {
4417 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
4419 auto push_vol_ops = [
this](
auto &pip) {
4426 const double) {
return 1.; };
4428 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4429 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4430 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4431 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4432 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1., unity_2_args,
4433 unity_2_args, unity_3_args, Sev::inform);
4435 if (common_hencky_ptr) {
4436 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
4440 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
4441 common_thermoplastic_ptr);
4444 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
4447 auto &pip = pp_fe->getOpPtrVector();
4449 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
4452 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
4453 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4455 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4456 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4458 auto u_ptr = boost::make_shared<MatrixDouble>();
4469 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4471 {{
"ISOTROPIC_HARDENING",
4472 common_plastic_ptr->getPlasticIsoHardeningPtr()},
4474 common_plastic_ptr->getPlasticSurfacePtr()},
4475 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4476 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4479 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4481 {{
"GRAD", common_hencky_ptr->matGradPtr},
4482 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
4484 {{
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4485 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
4486 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
4487 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
4499 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4501 {{
"PLASTIC_SURFACE",
4502 common_plastic_ptr->getPlasticSurfacePtr()},
4503 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4504 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4507 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4511 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
4512 {
"STRESS", common_plastic_ptr->mStressPtr},
4513 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4514 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
4525 PetscBool post_proc_vol = PETSC_FALSE;
4526 PetscBool post_proc_skin = PETSC_TRUE;
4529 post_proc_vol = PETSC_TRUE;
4530 post_proc_skin = PETSC_FALSE;
4533 post_proc_vol = PETSC_FALSE;
4534 post_proc_skin = PETSC_TRUE;
4541 &post_proc_vol, PETSC_NULLPTR);
4543 &post_proc_skin, PETSC_NULLPTR);
4545 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4547 if (post_proc_vol == PETSC_FALSE)
4548 return boost::shared_ptr<PostProcEle>();
4549 auto pp_fe = boost::make_shared<PostProcEle>(mField);
4551 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
4552 "push_vol_post_proc_ops");
4556 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4557 &post_proc_skin]() {
4558 if (post_proc_skin == PETSC_FALSE)
4559 return boost::shared_ptr<SkinPostProcEle>();
4562 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
4565 pp_fe->getOpPtrVector().push_back(op_side);
4567 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
4568 "push_vol_post_proc_ops");
4572 return std::make_pair(vol_post_proc(), skin_post_proc());
4575 auto scatter_create = [&](
auto D,
auto coeff) {
4577 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
4578 ROW,
"U", coeff, coeff, is);
4580 CHKERR ISGetLocalSize(is, &loc_size);
4582 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
4584 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULLPTR, &scatter);
4589 boost::shared_ptr<SetPtsData> field_eval_data;
4590 boost::shared_ptr<MatrixDouble> u_field_ptr;
4592 std::array<double, 3> field_eval_coords = {0., 0., 0.};
4595 field_eval_coords.data(), &coords_dim,
4598 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
4599 scalar_field_ptrs = boost::make_shared<
4600 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
4601 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4602 vector_field_ptrs = boost::make_shared<
4603 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4604 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4605 sym_tensor_field_ptrs = boost::make_shared<
4606 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4607 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4608 tensor_field_ptrs = boost::make_shared<
4609 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4611 auto test_monitor_ptr = boost::make_shared<FEMethod>();
4617 field_eval_data,
simple->getDomainFEName());
4619 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4620 auto no_rule = [](
int,
int,
int) {
return -1; };
4621 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4622 field_eval_fe_ptr->getRuleHook = no_rule;
4625 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4631 const double) {
return 1.; };
4633 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4634 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4635 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4636 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4637 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4638 "TAU",
"T", 1., unity_2_args, unity_2_args, unity_3_args,
4641 auto u_field_ptr = boost::make_shared<MatrixDouble>();
4642 field_eval_fe_ptr->getOpPtrVector().push_back(
4644 auto T_field_ptr = boost::make_shared<VectorDouble>();
4645 field_eval_fe_ptr->getOpPtrVector().push_back(
4647 auto FLUX_field_ptr = boost::make_shared<MatrixDouble>();
4648 field_eval_fe_ptr->getOpPtrVector().push_back(
4651 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
4653 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4654 scalar_field_ptrs->insert(std::make_pair(
4655 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4656 scalar_field_ptrs->insert(std::make_pair(
4657 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4658 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4659 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4660 sym_tensor_field_ptrs->insert(std::make_pair(
4661 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4662 sym_tensor_field_ptrs->insert(std::make_pair(
4663 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4664 sym_tensor_field_ptrs->insert(std::make_pair(
4665 "HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()));
4666 sym_tensor_field_ptrs->insert(
4667 std::make_pair(
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()));
4668 tensor_field_ptrs->insert(
4669 std::make_pair(
"GRAD", common_hencky_ptr->matGradPtr));
4670 tensor_field_ptrs->insert(std::make_pair(
4671 "FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()));
4673 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4674 scalar_field_ptrs->insert(std::make_pair(
4675 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4676 scalar_field_ptrs->insert(std::make_pair(
4677 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4678 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4679 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4680 sym_tensor_field_ptrs->insert(
4681 std::make_pair(
"STRAIN", common_plastic_ptr->mStrainPtr));
4682 sym_tensor_field_ptrs->insert(
4683 std::make_pair(
"STRESS", common_plastic_ptr->mStressPtr));
4684 sym_tensor_field_ptrs->insert(std::make_pair(
4685 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4686 sym_tensor_field_ptrs->insert(std::make_pair(
4687 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4695 field_eval_data,
simple->getDomainFEName());
4697 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4698 auto no_rule = [](
int,
int,
int) {
return -1; };
4700 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4701 field_eval_fe_ptr->getRuleHook = no_rule;
4704 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4710 const double) {
return 1.; };
4712 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4713 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4714 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4715 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4716 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4717 "TAU",
"T", 1, unity_2_args, unity_2_args, unity_3_args,
4720 auto dispGradPtr = common_hencky_ptr->matGradPtr;
4721 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4723 auto coeff_expansion_ptr = common_thermoelastic_ptr->getCoeffExpansionPtr();
4724 auto ref_temp_ptr = common_thermoelastic_ptr->getRefTempPtr();
4726 field_eval_fe_ptr->getOpPtrVector().push_back(
4728 field_eval_fe_ptr->getOpPtrVector().push_back(
4730 field_eval_fe_ptr->getOpPtrVector().push_back(
4732 field_eval_fe_ptr->getOpPtrVector().push_back(
4735 plasticMultiplierFieldPtr = common_plastic_ptr->getPlasticTauPtr();
4736 plasticStrainFieldPtr = common_plastic_ptr->getPlasticStrainPtr();
4740 field_eval_fe_ptr->getOpPtrVector().push_back(
4741 new typename H::template OpCalculateHenckyThermoPlasticStress<
SPACE_DIM,
4743 "U", tempFieldPtr, common_hencky_ptr, coeff_expansion_ptr,
4746 field_eval_fe_ptr->getOpPtrVector().push_back(
4748 common_hencky_ptr->getMatFirstPiolaStress(), stressFieldPtr));
4749 field_eval_fe_ptr->getOpPtrVector().push_back(
4752 field_eval_fe_ptr->getOpPtrVector().push_back(
4753 new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
4754 "U", common_hencky_ptr));
4755 stressFieldPtr = common_hencky_ptr->getMatFirstPiolaStress();
4756 strainFieldPtr = common_hencky_ptr->getMatLogC();
4760 auto set_time_monitor = [&](
auto dm,
auto solver) {
4764 dm, create_post_process_elements(), reactionFe, uXScatter, uYScatter,
4765 uZScatter, field_eval_coords, field_eval_data, scalar_field_ptrs,
4766 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
4767 boost::shared_ptr<ForcesAndSourcesCore> null;
4769 monitor_ptr, null, null);
4772 test_monitor_ptr->preProcessHook = [&]() {
4776 ->evalFEAtThePoint<SPACE_DIM>(
4777 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
4778 simple->getDomainFEName(), field_eval_data,
4779 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
4782 auto eval_num_vec =
createVectorMPI(mField.get_comm(), PETSC_DECIDE, 1);
4783 CHKERR VecZeroEntries(eval_num_vec);
4784 if (tempFieldPtr->size()) {
4785 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
4787 CHKERR VecAssemblyBegin(eval_num_vec);
4788 CHKERR VecAssemblyEnd(eval_num_vec);
4791 CHKERR VecSum(eval_num_vec, &eval_num);
4792 if (!(
int)eval_num) {
4794 "atom test %d failed: did not find elements to evaluate "
4795 "the field, check the coordinates",
4799 if (tempFieldPtr->size()) {
4801 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4802 <<
"Eval point T magnitude: " << t_temp;
4803 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4804 if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
4806 "atom test %d failed: wrong temperature value",
4809 if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
4811 "atom test %d failed: wrong temperature value",
4814 if (
atom_test == 5 && fabs(t_temp - 1) > 1e-2) {
4816 "atom test %d failed: wrong temperature value",
4820 if (
atom_test == 8 && fabs(t_temp - 0.5) > 1e-12) {
4822 "atom test %d failed: wrong temperature value",
atom_test);
4825 if (fluxFieldPtr->size1()) {
4827 auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
4828 auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
4829 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4830 <<
"Eval point FLUX magnitude: " << flux_mag;
4831 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4832 if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
4834 "atom test %d failed: wrong flux value",
atom_test);
4836 if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
4838 "atom test %d failed: wrong flux value",
atom_test);
4840 if (
atom_test == 5 && fabs(flux_mag) > 1e-6) {
4842 "atom test %d failed: wrong flux value",
atom_test);
4846 if (dispFieldPtr->size1()) {
4848 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
4849 auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
4850 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4851 <<
"Eval point U magnitude: " << disp_mag;
4852 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4853 if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
4855 "atom test %d failed: wrong displacement value",
4859 fabs(disp_mag - 0.00265) > 1e-5) {
4861 "atom test %d failed: wrong displacement value",
4865 fabs(t_disp(0) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5 &&
4866 fabs(t_disp(1) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5) {
4868 "atom test %d failed: wrong displacement value",
4873 if (strainFieldPtr->size1()) {
4876 getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
4877 auto t_strain_trace = t_strain(
i,
i);
4878 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4879 if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
4881 "atom test %d failed: wrong strain value",
atom_test);
4884 fabs(t_strain_trace - 0.00522) > 1e-5) {
4886 "atom test %d failed: wrong strain value",
atom_test);
4888 if ((
atom_test == 5) && fabs(t_strain_trace - 0.2) > 1e-5) {
4890 "atom test %d failed: wrong strain value",
atom_test);
4894 if (stressFieldPtr->size1()) {
4895 double von_mises_stress;
4896 auto getVonMisesStress = [&](
auto t_stress) {
4898 von_mises_stress = std::sqrt(
4900 ((t_stress(0, 0) - t_stress(1, 1)) *
4901 (t_stress(0, 0) - t_stress(1, 1)) +
4902 (
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
4903 (t_stress(1, 1) - t_stress(2, 2))
4905 (
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
4906 (t_stress(2, 2) - t_stress(0, 0))
4908 6 * (t_stress(0, 1) * t_stress(0, 1) +
4909 (
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
4910 (
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
4915 getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
4916 CHKERR getVonMisesStress(t_stress);
4919 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
4920 CHKERR getVonMisesStress(t_stress);
4922 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4923 <<
"Eval point von Mises Stress: " << von_mises_stress;
4924 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4925 if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
4927 "atom test %d failed: wrong von Mises stress value",
4930 if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
4932 "atom test %d failed: wrong von Mises stress value",
4935 if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
4937 "atom test %d failed: wrong von Mises stress value",
4940 if (
atom_test == 5 && fabs(von_mises_stress) > 5e-2) {
4942 "atom test %d failed: wrong von Mises stress value",
4947 if (plasticMultiplierFieldPtr->size()) {
4948 auto t_plastic_multiplier =
4950 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4951 <<
"Eval point TAU magnitude: " << t_plastic_multiplier;
4952 if (
atom_test == 8 && fabs(t_plastic_multiplier - 1.5) > 1e-12) {
4954 "atom test %d failed: wrong plastic multiplier value",
4958 if (plasticStrainFieldPtr->size1()) {
4961 auto t_plastic_strain =
4962 getFTensor2SymmetricFromMat<SPACE_DIM>(*plasticStrainFieldPtr);
4963 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4964 <<
"Eval point EP(0,0) = " << t_plastic_strain(0, 0)
4965 <<
", EP(0,1) = " << t_plastic_strain(0, 1)
4966 <<
", EP(1,1) = " << t_plastic_strain(1, 1);
4968 if (fabs(t_plastic_strain(0, 0) - 0.005) > 1e-12) {
4970 "atom test %d failed: wrong EP(0,0) value",
atom_test);
4972 if (fabs(t_plastic_strain(0, 1) - 0.025) > 1e-12) {
4974 "atom test %d failed: wrong EP(0,1) value",
atom_test);
4976 if (fabs(t_plastic_strain(1, 1) - 0.015) > 1e-12) {
4978 "atom test %d failed: wrong EP(1,1) value",
atom_test);
4986 auto null = boost::shared_ptr<FEMethod>();
4988 test_monitor_ptr, null);
4994 auto set_schur_pc = [&](
auto solver,
4995 boost::shared_ptr<SetUpSchur> &schur_ptr) {
4998 auto name_prb =
simple->getProblemName();
5004 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5009 for (
auto f : {
"U",
"FLUX"}) {
5021 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5027 for (
auto f : {
"SIGMA",
"EP",
"TAU",
"T"}) {
5032 for (
auto f : {
"EP",
"TAU",
"T"}) {
5042 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
5051 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5057 {simple->getDomainFEName(),
5080 {simple->getBoundaryFEName(),
5082 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
5092 {dm_schur, dm_block}, block_mat_data,
5094 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5102 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5103 auto block_mat_data =
5106 {{simple->getDomainFEName(),
5132 {dm_schur, dm_block}, block_mat_data,
5134 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr}, false
5141 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
5144 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
5145 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
5151 CHKERR schur_ptr->setUp(solver);
5157 auto dm =
simple->getDM();
5160 uXScatter = scatter_create(
D, 0);
5161 uYScatter = scatter_create(
D, 1);
5163 uZScatter = scatter_create(
D, 2);
5165 auto create_solver = [pip_mng]() {
5167 return pip_mng->createTSIM();
5169 return pip_mng->createTSIM2();
5179 CHKERR VecLoad(solution_vector, viewer);
5180 CHKERR PetscViewerDestroy(&viewer);
5185 auto solver = create_solver();
5187 auto active_pre_lhs = []() {
5194 auto active_post_lhs = [&]() {
5196 auto get_iter = [&]() {
5201 "Can not get iter");
5205 auto iter = get_iter();
5208 std::array<int, 5> activity_data;
5209 std::fill(activity_data.begin(), activity_data.end(), 0);
5211 activity_data.data(), activity_data.size(), MPI_INT,
5212 MPI_SUM, mField.get_comm());
5214 int &active_points = activity_data[0];
5215 int &avtive_full_elems = activity_data[1];
5216 int &avtive_elems = activity_data[2];
5217 int &nb_points = activity_data[3];
5218 int &nb_elements = activity_data[4];
5222 double proc_nb_points =
5223 100 *
static_cast<double>(active_points) / nb_points;
5224 double proc_nb_active =
5225 100 *
static_cast<double>(avtive_elems) / nb_elements;
5226 double proc_nb_full_active = 100;
5228 proc_nb_full_active =
5229 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
5232 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
5234 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
5235 iter, nb_points, active_points, proc_nb_points,
5236 avtive_elems, proc_nb_active, avtive_full_elems,
5237 proc_nb_full_active, iter);
5244 auto add_active_dofs_elem = [&](
auto dm) {
5246 auto fe_pre_proc = boost::make_shared<FEMethod>();
5247 fe_pre_proc->preProcessHook = active_pre_lhs;
5248 auto fe_post_proc = boost::make_shared<FEMethod>();
5249 fe_post_proc->postProcessHook = active_post_lhs;
5251 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
5252 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
5256 auto set_essential_bc = [&](
auto dm,
auto solver) {
5260 auto pre_proc_ptr = boost::make_shared<FEMethod>();
5261 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
5262 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
5265 auto disp_time_scale = boost::make_shared<TimeScale>();
5267 auto get_bc_hook_rhs = [
this, pre_proc_ptr, disp_time_scale]() {
5269 {disp_time_scale},
false);
5272 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
5274 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
5277 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
5279 mField, post_proc_rhs_ptr, 1.)();
5282 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
5284 mField, post_proc_lhs_ptr, 1.);
5286 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
5289 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
5290 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
5291 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
5292 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
5293 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
5301 CHKERR TSSetSolution(solver,
D);
5303 CHKERR TS2SetSolution(solver,
D, DD);
5306 auto set_up_adapt = [&](
auto solver) {
5310 CHKERR TSGetAdapt(solver, &adapt);
5314 CHKERR set_section_monitor(solver);
5315 CHKERR set_time_monitor(dm, solver);
5316 CHKERR set_up_adapt(solver);
5317 CHKERR TSSetFromOptions(solver);
5324 CHKERR add_active_dofs_elem(dm);
5325 boost::shared_ptr<SetUpSchur> schur_ptr;
5326 CHKERR set_schur_pc(solver, schur_ptr);
5327 CHKERR set_essential_bc(dm, solver);
5329 auto my_ctx = boost::make_shared<MyTsCtx>();
5334 CHKERR TSGetSNES(solver, &snes);
5340 auto my_rhs = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec F,
void *ctx) {
5350 double time_increment;
5352 if (time_increment <
min_dt) {
5354 "Minimum time increment exceeded");
5358 int error = system(
"rm ./out_snes_residual_iter_*.h5m > /dev/null 2>&1");
5364 "Cannot get timestep from TS object");
5368 "Minimum timestep exceeded");
5372 auto post_proc = [&](
auto dm,
auto f_res,
auto sol,
auto sol_dot,
5381 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
5383 auto &pip = post_proc_fe->getOpPtrVector();
5389 auto disp_res_mat = boost::make_shared<MatrixDouble>();
5390 auto tau_res_vec = boost::make_shared<VectorDouble>();
5391 auto plastic_strain_res_mat = boost::make_shared<MatrixDouble>();
5392 auto flux_res_mat = boost::make_shared<MatrixDouble>();
5393 auto temp_res_vec = boost::make_shared<VectorDouble>();
5396 "U", disp_res_mat, smart_f_res));
5400 "EP", plastic_strain_res_mat, smart_f_res));
5408 auto disp_mat = boost::make_shared<MatrixDouble>();
5409 auto tau_vec = boost::make_shared<VectorDouble>();
5410 auto plastic_strain_mat = boost::make_shared<MatrixDouble>();
5411 auto flux_mat = boost::make_shared<MatrixDouble>();
5412 auto temp_vec = boost::make_shared<VectorDouble>();
5417 "EP", plastic_strain_mat));
5424 auto disp_dot_mat = boost::make_shared<MatrixDouble>();
5425 auto tau_dot_vec = boost::make_shared<VectorDouble>();
5426 auto plastic_strain_dot_mat = boost::make_shared<MatrixDouble>();
5427 auto flux_dot_mat = boost::make_shared<MatrixDouble>();
5428 auto temp_dot_vec = boost::make_shared<VectorDouble>();
5431 "U", disp_dot_mat, smart_sol_dot));
5435 "EP", plastic_strain_dot_mat, smart_sol_dot));
5443 auto make_d_mat = [&]() {
5447 auto push_vol_ops = [&](
auto &pip) {
5452 const double) {
return 1.; };
5454 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
5455 common_thermoelastic_ptr, common_thermoplastic_ptr] =
5458 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
5459 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1.,
5460 unity_2_args, unity_2_args, unity_3_args, Sev::inform);
5462 if (common_hencky_ptr) {
5463 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
5465 "Wrong pointer for grad");
5468 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
5469 common_thermoplastic_ptr);
5472 auto push_vol_post_proc_ops = [&](
auto &pp_fe,
auto &&p) {
5475 auto &pip = pp_fe->getOpPtrVector();
5477 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
5480 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
5481 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
5483 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
5484 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
5486 auto u_ptr = boost::make_shared<MatrixDouble>();
5497 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5499 {{
"RESIDUAL_TAU", tau_res_vec},
5500 {
"RESIDUAL_T", temp_res_vec},
5503 {
"RATE_TAU", tau_dot_vec},
5504 {
"RATE_T", temp_dot_vec},
5505 {
"ISOTROPIC_HARDENING",
5506 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5508 common_plastic_ptr->getPlasticSurfacePtr()},
5509 {
"PLASTIC_MULTIPLIER",
5510 common_plastic_ptr->getPlasticTauPtr()},
5512 common_plastic_ptr->getPlasticSurfacePtr()},
5513 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5515 {{
"RESIDUAL_U", disp_res_mat},
5516 {
"RATE_U", disp_dot_mat},
5518 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5520 {{
"GRAD", common_hencky_ptr->matGradPtr},
5522 common_hencky_ptr->getMatFirstPiolaStress()}},
5524 {{
"RESIDUAL_EP", plastic_strain_res_mat},
5525 {
"RATE_EP", plastic_strain_dot_mat},
5527 common_plastic_ptr->getPlasticStrainPtr()},
5528 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
5529 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
5530 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
5542 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5544 {{
"RESIDUAL_TAU", tau_res_vec},
5545 {
"RESIDUAL_T", temp_res_vec},
5548 {
"RATE_TAU", tau_dot_vec},
5549 {
"RATE_T", temp_dot_vec},
5550 {
"ISOTROPIC_HARDENING",
5551 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5553 common_plastic_ptr->getPlasticSurfacePtr()},
5554 {
"PLASTIC_MULTIPLIER",
5555 common_plastic_ptr->getPlasticTauPtr()},
5557 common_plastic_ptr->getPlasticSurfacePtr()},
5558 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5560 {{
"RESIDUAL_U", disp_res_mat},
5564 {
"RATE_U", disp_dot_mat},
5566 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5570 {{
"RESIDUAL_PLASTIC_STRAIN", plastic_strain_res_mat},
5571 {
"PLASTIC_STRAIN", plastic_strain_mat},
5572 {
"RATE_PLASTIC_STRAIN", plastic_strain_dot_mat},
5573 {
"STRAIN", common_plastic_ptr->mStrainPtr},
5574 {
"STRESS", common_plastic_ptr->mStressPtr},
5576 common_plastic_ptr->getPlasticStrainPtr()},
5577 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
5587 CHK_MOAB_THROW(push_vol_post_proc_ops(post_proc_fe, push_vol_ops(pip)),
5588 "push_vol_post_proc_ops");
5593 post_proc_fe->writeFile(out_name);
5604 "out_snes_residual_iter_" +
5609 PetscBool is_output_residual_fields = PETSC_FALSE;
5611 &is_output_residual_fields, PETSC_NULLPTR);
5613 if (is_output_residual_fields == PETSC_TRUE) {
5616 CHKERR TSSetIFunction(solver, PETSC_NULLPTR, my_rhs, my_ctx.get());
5619 CHKERR TSSetDM(solver, dm);
5621 auto ts_pre_post_proc = boost::make_shared<TSPrePostProc>();
5625 ptr->ExRawPtr =
this;
5626 std::multimap<double, EntityHandle> no_el_q_map;
5627 Range no_flipped_els;
5628 std::vector<EntityHandle> no_new_connectivity;
5629 Tag no_th_spatial_coords;
5632 &mField, PETSC_FALSE, no_el_q_map,
5633 no_flipped_els, no_new_connectivity, no_th_spatial_coords};
5634 PetscBool rollback =
5638 CHKERR TSSetApplicationContext(solver, (
void *)ctx);
5647 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
5648 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
5649 CHKERR ptr->tsSetUp(solver);
5651 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
5652 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
5653 CHKERR TSSolve(solver, PETSC_NULLPTR);
5654 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
5666 #ifdef ENABLE_PYTHON_BINDING
5673 const char param_file[] =
"param_file.petsc";
5677 auto core_log = logging::core::get();
5707 DMType dm_name =
"DMMOFEM";
5712 moab::Core mb_instance;
5713 moab::Interface &moab = mb_instance;
5733 char meshFileName[255];
5735 meshFileName, 255, PETSC_NULLPTR);
5757 #ifdef ENABLE_PYTHON_BINDING
5758 if (Py_FinalizeEx() < 0) {
5771 :
SetUpSchur(), mField(m_field), subDM(sub_dm),
5772 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5775 "Is expected that schur matrix is not "
5776 "allocated. This is "
5777 "possible only is PC is set up twice");
5801 CHKERR TSGetSNES(solver, &snes);
5803 CHKERR SNESGetKSP(snes, &ksp);
5804 CHKERR KSPSetFromOptions(ksp);
5807 CHKERR KSPGetPC(ksp, &pc);
5808 PetscBool is_pcfs = PETSC_FALSE;
5809 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
5813 "Is expected that schur matrix is not "
5814 "allocated. This is "
5815 "possible only is PC is set up twice");
5823 CHKERR TSGetDM(solver, &solver_dm);
5824 CHKERR DMSetMatType(solver_dm, MATSHELL);
5831 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t, PetscReal
a,
5832 Mat
A, Mat
B,
void *ctx) {
5835 CHKERR TSSetIJacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5837 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec utt,
5838 PetscReal
a, PetscReal aa, Mat
A, Mat
B,
5842 CHKERR TSSetI2Jacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5844 CHKERR KSPSetOperators(ksp,
A, P);
5846 auto set_ops = [&]() {
5852 pip_mng->getOpBoundaryLhsPipeline().push_front(
5856 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5861 pip_mng->getOpDomainLhsPipeline().push_front(
5865 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5871 double eps_stab = 1e-4;
5877 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
5880 pip_mng->getOpBoundaryLhsPipeline().push_front(
5882 pip_mng->getOpBoundaryLhsPipeline().push_back(
5883 new OpMassStab(
"SIGMA",
"SIGMA", [eps_stab](
double,
double,
double) {
5888 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5893 pip_mng->getOpDomainLhsPipeline().push_front(
5897 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5905 auto set_assemble_elems = [&]() {
5907 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
5908 schur_asmb_pre_proc->preProcessHook = [
this]() {
5911 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble Begin";
5914 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
5916 schur_asmb_post_proc->postProcessHook = [
this, schur_asmb_post_proc]() {
5918 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble End";
5921 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
5922 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
5929 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
5930 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
5934 auto set_pc = [&]() {
5937 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
5941 auto set_diagonal_pc = [&]() {
5944 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
5945 auto get_pc = [](
auto ksp) {
5947 CHKERR KSPGetPC(ksp, &pc_raw);
5952 CHKERR PetscFree(subksp);
5958 CHKERR set_assemble_elems();
5962 CHKERR set_diagonal_pc();
5965 pip_mng->getOpBoundaryLhsPipeline().push_front(
5967 pip_mng->getOpBoundaryLhsPipeline().push_back(
5970 pip_mng->getOpDomainLhsPipeline().push_back(
5979boost::shared_ptr<SetUpSchur>
5983 return boost::shared_ptr<SetUpSchur>(
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_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define BITREFLEVEL_SIZE
max number of refinements
#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()
FieldSpace
approximation spaces
@ 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_STD_EXCEPTION_THROW
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#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 ...
constexpr int order
Order displacement.
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSNESSetFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES residual evaluation function
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
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 DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMMoFEMSNESSetJacobian(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES Jacobian evaluation function
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
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.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
auto createDMMatrix(DM dm)
Get smart matrix from DM.
PetscErrorCode DMCreateGlobalVector_MoFEM(DM dm, Vec *g)
DMShellSetCreateGlobalVector.
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode)
set ghosted vector values on all existing mesh entities
PetscErrorCode DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
PetscErrorCode DMSetUp_MoFEM(DM dm)
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
MoFEMErrorCode lambdaBitRefLevel(boost::function< void(EntityHandle ent, BitRefLevel &bit)> fun) const
Process bit ref level by lambda function.
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
virtual MoFEMErrorCode modify_problem_mask_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set dof mask ref level for problem
virtual MoFEMErrorCode modify_problem_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set ref level for problem
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (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
const FTensor::Tensor2< T, Dim, Dim > Vec
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
auto type_from_handle(const EntityHandle h)
get type from entity handle
auto createKSP(MPI_Comm comm)
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 TsSetIJacobian(TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a, Mat A, Mat B, void *ctx)
Set function evaluating jacobian in TS solver.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
auto createSNES(MPI_Comm comm)
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
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 TsSetIFunction(TS ts, PetscReal t, Vec u, Vec u_t, Vec F, void *ctx)
Set IFunction for TS solver.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
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.
auto getDMSubData(DM dm)
Get sub problem data structure.
PetscErrorCode TsSetI2Jacobian(TS ts, PetscReal t, Vec u, Vec u_t, Vec u_tt, PetscReal a, PetscReal aa, Mat A, Mat B, void *ctx)
Calculation Jacobian for second order PDE in time.
boost::shared_ptr< BlockStructure > createBlockMatStructure(DM dm, SchurFEOpsFEandFields schur_fe_op_vec)
Create a Mat Diag Blocks object.
boost::shared_ptr< NestSchurData > createSchurNestedMatrixStruture(std::pair< SmartPetscObj< DM >, SmartPetscObj< DM > > dms, boost::shared_ptr< BlockStructure > block_mat_data_ptr, std::vector< std::string > fields_names, std::vector< boost::shared_ptr< Range > > field_ents, bool add_preconditioner_block)
Get the Schur Nest Mat Array object.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
MoFEMErrorCode DMMoFEMSetNestSchurData(DM dm, boost::shared_ptr< NestSchurData >)
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
auto createDMNestSchurMat(DM dm)
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
PetscErrorCode TSAdaptCreateMoFEM(TSAdapt adapt)
Craete MOFEM adapt.
OpSchurAssembleBase * createOpSchurAssembleBegin()
auto createDMBlockMat(DM dm)
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > Pip
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux times base of temperature (FLUX x T) and transpose of it,...
OpHdivHdivImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivHdiv
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)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
OpCalculateQdotQLhs_dU< SPACE_DIM, GAUSS, AssemblyDomainEleOp, IS_LARGE_STRAINS > OpHdivU
Integrate Lhs of flux term coupled to displacement field.
OpHdivFluxImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivFlux
MoFEMErrorCode addMatThermalBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, double default_heat_conductivity, double default_heat_capacity, double default_thermal_conductivity_scale, double default_thermal_capacity_scale, Sev sev, ScalerFunTwoArgs thermal_conductivity_scaling_func, ScalerFunTwoArgs heat_capacity_scaling_func)
MoFEMErrorCode addMatThermoElasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, double default_coeff_expansion, double default_ref_temp, Sev sev)
MoFEMErrorCode addMatThermoPlasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string thermoplastic_block_name, boost::shared_ptr< ThermoPlasticBlockedParameters > blockedParamsPtr, boost::shared_ptr< ThermoElasticOps::BlockedThermalParameters > &blockedThermalParamsPtr, Sev sev, ScalerFunThreeArgs inelastic_heat_fraction_scaling)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr IntegrationType I
constexpr AssemblyType A
[Define dimension]
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
constexpr auto field_name
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
OpBaseImpl< PETSC, EdgeEleOp > OpBase
constexpr double heat_conductivity
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, 1 > OpKPiola
[Only used for dynamics]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesSymTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForceCauchy
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradSymTensorGrad< 1, SPACE_DIM, SPACE_DIM, 0 > OpKCauchy
[Only used with Hooke equation (linear material model)]
FTensor::Index< 'm', 3 > m
void temp(int x, int y=10)
Rhs for testing EP mapping with initial conditions.
PipelineManager::ElementsAndOpsByDim< 2 >::DomainEleOnRange DomainEleOnRange
PipelineManager::ElementsAndOpsByDim< 2 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::DomainEleOnRange DomainEleOnRange
double getScale(const double time)
Get scaling at given time.
MoFEMErrorCode thermalBC()
[Mechanical boundary conditions]
boost::shared_ptr< VectorDouble > tempFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainLhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
boost::shared_ptr< DomainEle > reactionFe
MoFEMErrorCode edgeFlips(BitRefLevel parent_bit, BitRefLevel child_bit)
boost::shared_ptr< MatrixDouble > strainFieldPtr
MoFEMErrorCode doEdgeSplits(bool &refine, bool add_ents)
[Do Edge Flips]
boost::shared_ptr< MatrixDouble > dispGradPtr
FieldApproximationBase base
Choice of finite element basis functions
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
MoFEMErrorCode mechanicalBC()
[Initial conditions]
MoFEMErrorCode createCommonData()
friend struct TSPrePostProc
MoFEMErrorCode getElementQuality(std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, std::vector< EntityHandle > &new_connectivity, bool &do_refine, Tag &th_spatial_coords)
[Get element quality]
boost::shared_ptr< VectorDouble > plasticMultiplierFieldPtr
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
boost::shared_ptr< MatrixDouble > stressFieldPtr
MoFEM::Interface & mField
Reference to MoFEM interface.
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
boost::shared_ptr< MatrixDouble > fluxFieldPtr
MoFEMErrorCode setupProblem()
boost::shared_ptr< MatrixDouble > dispFieldPtr
boost::shared_ptr< MatrixDouble > plasticStrainFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainRhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
MoFEMErrorCode doEdgeFlips(std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, Tag &th_spatial_coords, std::vector< EntityHandle > &new_connectivity)
[Edge flips]
MoFEMErrorCode initialConditions()
[Create common data]
auto createCommonThermoPlasticOps(MoFEM::Interface &m_field, std::string plastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string u, std::string ep, std::string tau, std::string temperature, double scale, ScalerFunTwoArgs thermal_conductivity_scaling, ScalerFunTwoArgs heat_capacity_scaling, ScalerFunThreeArgs inelastic_heat_fraction_scaling, Sev sev, bool with_rates=true)
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
virtual int get_comm_size() const =0
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 on the left hand side diagonal.
Class (Function) to enforce essential constrains on the right hand side diagonal.
Class (Function) to calculate residual side diagonal.
Class (Function) to enforce essential constrains.
Structure for user loop methods on finite elements.
Field evaluator interface.
SetIntegrationPtsMethodData SetPtsData
structure to get information from mofem into EntitiesFieldData
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.
Mesh refinement interface.
MoFEMErrorCode addVerticesInTheMiddleOfEdges(const EntityHandle meshset, const BitRefLevel &bit, const bool recursive=false, int verb=QUIET, EntityHandle start_v=0)
make vertices in the middle of edges in meshset and add them to refinement levels defined by bit
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode updateAllMeshsetsByEntitiesChildren(const BitRefLevel &bit)
Update all blocksets, sidesets and node sets.
Natural boundary conditions.
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Calculate symmetric tensor field rates ant integratio pts.
Calculate symmetric tensor field values at integration pts.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Approximate field values for given petsc vector.
Specialization for double precision vector field values calculation.
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.
Set indices on entities on finite element.
Operator for symmetrizing tensor fields.
Unset indices on entities on finite element.
Template struct for dimension-specific finite element types.
PipelineManager interface.
MoFEM::VolumeElementForcesAndSourcesCore VolEle
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.
MoFEM::FaceElementForcesAndSourcesCore FaceEle
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
MoFEMErrorCode getOptions()
get options
intrusive_ptr for managing petsc objects
Force scale operator for reading two columns.
double getScale(const double time)
Get scaling at a given time.
TimeScale(std::string file_name="", bool error_if_file_not_given=false, ScalingFun def_scaling_fun=[](double time) { return time;})
TimeScale constructor.
MoFEM::Interface & mField
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
Volume finite element base.
boost::shared_ptr< MoFEM::TsCtx > dmts_ctx
PetscInt snes_iter_counter
static std::array< int, 5 > activityData
boost::weak_ptr< TSPrePostProc > ptr
MoFEM::Interface * m_field
std::vector< EntityHandle > new_connectivity
std::multimap< double, EntityHandle > el_q_map
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
SmartPetscObj< DM > subDM
field split sub dm
SmartPetscObj< AO > aoSchur
MoFEMErrorCode setUp(TS solver)
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
SetUpSchurImpl(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
virtual ~SetUpSchurImpl()
MoFEMErrorCode postProc()
MoFEM::Interface & mField
[Push operators to pipeline]
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
Create data structure for handling Schur complement.
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)
virtual MoFEMErrorCode setUp(TS solver)=0
MoFEMErrorCode mapFields(SmartPetscObj< DM > &intermediateDM, BitRefLevel parentBit, BitRefLevel childBit, PetscInt numVecs=1, Vec vecsToMapFrom[]=PETSC_NULLPTR, Vec vecsToMapTo[]=PETSC_NULLPTR)
MoFEMErrorCode reSetUp(std::vector< std::string > L2Fields, std::vector< int > L2Oders, std::vector< std::string > H1Fields, std::vector< int > H1Orders, std::vector< std::string > HdivFields, std::vector< int > HdivOrders, BitRefLevel bIt)
Set of functions called by PETSc solver used to refine and update mesh.
virtual ~TSPrePostProc()=default
static MoFEMErrorCode tsPreProc(TS ts)
Pre process time step.
static MoFEMErrorCode tsPostProc(TS ts)
Post process time step.
static MoFEMErrorCode tsPostProc(TS ts)
Post process time step.
static MoFEMErrorCode tsPreStage(TS ts)
static MoFEMErrorCode tsPreProc(TS ts)
Pre process time step.
MoFEMErrorCode tsSetUp(TS ts)
Used to setup TS solver.
constexpr AssemblyType AT
constexpr IntegrationType IT
double iso_hardening_dtemp(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
double young_modulus
Young modulus.
double default_heat_capacity_scale
constexpr AssemblyType AT
static boost::weak_ptr< TSPrePostProc > tsPrePostProc
double C1_k
Kinematic hardening.
int post_processing_counter
double exp_softening(double temp_hat)
double Qinf
Saturation yield stress.
constexpr IntegrationType IT
static char help[]
[Solve]
auto init_T
Initialisation function for temperature field.
double default_thermal_conductivity_scale
ScalerFunTwoArgs heat_capacity_scaling
double dH_thermal_dtemp(double H, double omega_h)
constexpr bool IS_LARGE_STRAINS
ScalerFunThreeArgs inelastic_heat_fraction_scaling
PetscBool is_distributed_mesh
#define EXECUTABLE_DIMENSION
PetscBool do_eval_field
Evaluate field.
PetscBool is_quasi_static
double dy_0_thermal_dtemp(double sigmaY, double omega_0)
boost::function< double(const double, const double, const double)> ScalerFunThreeArgs
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
boost::function< double(const double, const double)> ScalerFunTwoArgs
double iso_hardening(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
Example * thermoplastic_raw_ptr
PetscErrorCode MyTSResizeSetup(TS ts, PetscInt nstep, PetscReal time, Vec sol, PetscBool *resize, void *ctx)
BitRefLevel virgin_mesh_bit
static std::unordered_map< TS, ResizeCtx * > ts_to_rctx
PetscErrorCode MyTSResizeTransfer(TS, PetscInt, Vec[], Vec[], void *)
double Qinf_thermal(double Qinf, double omega_h, double temp_0, double temp)
BitRefLevel comp_mesh_bit
auto kinematic_hardening(FTensor::Tensor2_symmetric< T, DIM > &t_plastic_strain, double C1_k)
double default_heat_capacity
PetscBool set_timer
Set timer.
const char *const ICTypes[]
double temp_hat(double temp)
const bool is_large_strains
double edge_growth_thresh
auto postProcessHere(MoFEM::Interface &m_field, SmartPetscObj< DM > &dm, std::string output_name, int &counter= *(new int(0)))
int flux_order
Order of tau field.
MoFEMErrorCode TSIterationPreStage(TS ts, PetscReal stagetime)
double zeta
regularisation parameter
int T_order
Order of ep field.
ElementsAndOps< SPACE_DIM >::DomainEleOnRange DomainEleOnRange
BitRefLevel prev_mesh_bit
double y_0_thermal(double sigmaY, double omega_0, double temp_0, double temp)
double width
Width of Gaussian distribution.
double default_coeff_expansion
int tau_order
Order of tau field.
double iso_hardening_dtau(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
auto uniform_distribution
auto get_string_from_vector
auto printOnAllCores(MoFEM::Interface &m_field, const std::string &out_put_string, const auto &out_put_quantity)
MoFEMErrorCode SNESIterationMonitor(SNES snes, PetscInt its, PetscReal norm, void *ctx)
double omega_0
flow stress softening
double iso_hardening_exp(double tau, double b_iso)
auto postProcessPETScHere(MoFEM::Interface &m_field, SmartPetscObj< DM > &dm, Vec sol, std::string output_name)
double H_thermal(double H, double omega_h, double temp_0, double temp)
int order
Order displacement.
double b_iso
Saturation exponent.
auto Gaussian_distribution
int geom_order
Order if fixed.
double sigmaY
Yield stress.
ScalerFunTwoArgs thermal_conductivity_scaling
double default_heat_conductivity
auto kinematic_hardening_dplastic_strain(double C1_k)
double inelastic_heat_fraction
fraction of plastic dissipation converted to heat
int num_refinement_levels
double temp_0
reference temperature for thermal softening
static std::unordered_map< TS, MyTsCtx * > ts_to_ctx
int ep_order
Order of ep field.
double dQinf_thermal_dtemp(double Qinf, double omega_h)
constexpr FieldSpace CONTACT_SPACE
double omega_h
hardening softening
double young_modulus
Young modulus.
double C1_k
Kinematic hardening.
double Qinf
Saturation yield stress.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
PetscBool is_quasi_static
[Operators used for contact]
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
PetscBool set_timer
Set timer.
double zeta
Viscous hardening.
int tau_order
Order of tau files.
double b_iso
Saturation exponent.
PetscBool is_large_strains
Large strains.
int geom_order
Order if fixed.
double sigmaY
Yield stress.
int ep_order
Order of ep files.
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
#define FINITE_DEFORMATION_FLAG
constexpr bool IS_LARGE_STRAINS
double default_heat_capacity
double default_coeff_expansion
double default_heat_conductivity
constexpr int SPACE_DIM
[Define dimension]
constexpr AssemblyType A
[Define dimension]