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) {
1242 auto get_norm = [&](
auto x) {
1244 CHKERR VecNorm(x, NORM_2, &nrm);
1248 auto save_range = [](moab::Interface &moab,
const std::string name,
1252 CHKERR moab.add_entities(*out_meshset, r);
1253 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(),
1258 auto dm =
simple->getDM();
1262 CHKERR VecGhostUpdateBegin(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1263 CHKERR VecGhostUpdateEnd(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1267 Tag th_spatial_coords;
1268 std::multimap<double, EntityHandle> el_q_map;
1269 std::vector<EntityHandle> new_connectivity;
1271 bool do_refine =
false;
1273 auto check_element_quality = [&]() {
1277 Range virgin_entities;
1282 CHKERR ptr->ExRawPtr->getElementQuality(el_q_map, flipped_els,
1283 new_connectivity, do_refine,
1289 auto solve_equil_sub_problem = [&]() {
1291 if (el_q_map.size() == 0) {
1301 auto U_ptr = boost::make_shared<MatrixDouble>();
1302 auto EP_ptr = boost::make_shared<MatrixDouble>();
1303 auto TAU_ptr = boost::make_shared<VectorDouble>();
1304 auto T_ptr = boost::make_shared<VectorDouble>();
1308 auto post_proc = [&](
auto dm) {
1311 auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
1314 post_proc_fe->getOpPtrVector(), {H1, L2, HDIV});
1321 post_proc_fe->getOpPtrVector().push_back(
1326 post_proc_fe->getOpPtrVector().push_back(
1328 post_proc_fe->getOpPtrVector().push_back(
1330 post_proc_fe->getOpPtrVector().push_back(
1333 post_proc_fe->getOpPtrVector().push_back(
1335 new OpPPMap(post_proc_fe->getPostProcMesh(),
1336 post_proc_fe->getMapGaussPts(),
1354 CHKERR post_proc_fe->writeFile(
"out_equilibrate.h5m");
1359 auto solve_equilibrate_solution = [&]() {
1362 auto set_domain_rhs = [&](
auto &pip) {
1371 typename B::template OpGradTimesSymTensor<1,
SPACE_DIM,
1378 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1379 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1382 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1383 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1388 auto m_D_ptr = common_plastic_ptr->mDPtr;
1391 "T", common_thermoplastic_ptr->getTempPtr()));
1394 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1396 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1399 if (common_hencky_ptr) {
1401 "U", common_hencky_ptr->getMatFirstPiolaStress()));
1410 auto set_domain_lhs = [&](
auto &pip) {
1421 typename B::template OpGradTensorGrad<1, SPACE_DIM, SPACE_DIM, 1>;
1428 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1429 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1432 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1433 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1438 auto m_D_ptr = common_plastic_ptr->mDPtr;
1442 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1444 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1446 if (common_hencky_ptr) {
1449 new typename H::template OpHenckyTangent<SPACE_DIM, IT, 0>(
1450 "U", common_hencky_ptr, m_D_ptr));
1452 new OpKPiola(
"U",
"U", common_hencky_ptr->getMatTangent()));
1460 pip.push_back(
new OpKCauchy(
"U",
"U", m_D_ptr));
1480 auto dm_sub =
createDM(m_field.get_comm(),
"DMMOFEM");
1484 for (
auto f : {
"U",
"EP",
"TAU",
"T"}) {
1492 auto sub_dm = create_sub_dm(
simple->getDM());
1494 auto fe_rhs = boost::make_shared<DomainEle>(m_field);
1495 auto fe_lhs = boost::make_shared<DomainEle>(m_field);
1497 fe_rhs->getRuleHook = vol_rule;
1498 fe_lhs->getRuleHook = vol_rule;
1499 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
1500 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
1502 auto bc_mng = m_field.getInterface<
BcManager>();
1507 auto &bc_map = bc_mng->getBcMapByBlockName();
1508 for (
auto bc : bc_map)
1509 MOFEM_LOG(
"PLASTICITY",
Sev::verbose) <<
"Marker " << bc.first;
1511 auto time_scale = boost::make_shared<TimeScale>(
1512 "",
false, [](
const double) {
return 1; });
1513 auto def_time_scale = [time_scale](
const double time) {
1514 return (!time_scale->argFileScale) ? time : 1;
1516 auto def_file_name = [time_scale](
const std::string &&name) {
1517 return (!time_scale->argFileScale) ? name :
"";
1519 auto time_displacement_scaling = boost::make_shared<TimeScale>(
1520 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
1522 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1523 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1524 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1526 PetscReal current_time;
1527 TSGetTime(ts, ¤t_time);
1528 pre_proc_ptr->ts_t = current_time;
1531 auto get_bc_hook_rhs = [&]() {
1533 ptr->ExRawPtr->mField, pre_proc_ptr,
1534 {time_scale, time_displacement_scaling});
1537 auto get_bc_hook_lhs = [&]() {
1539 ptr->ExRawPtr->mField, pre_proc_ptr,
1540 {time_scale, time_displacement_scaling});
1544 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1545 pre_proc_ptr->preProcessHook = get_bc_hook_lhs();
1547 auto get_post_proc_hook_rhs = [&]() {
1550 ptr->ExRawPtr->mField, post_proc_rhs_ptr,
nullptr,
1553 ptr->ExRawPtr->mField, post_proc_rhs_ptr, 1.)();
1556 auto get_post_proc_hook_lhs = [&]() {
1558 ptr->ExRawPtr->mField, post_proc_lhs_ptr, 1.);
1560 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1561 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1564 snes_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_ptr);
1565 snes_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_ptr);
1566 snes_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs_ptr);
1567 snes_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs_ptr);
1569 auto null_fe = boost::shared_ptr<FEMethod>();
1588 CHKERR SNESSetDM(snes, sub_dm);
1589 CHKERR SNESSetFromOptions(snes);
1594 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1595 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1600 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);
1602 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1603 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1610 CHKERR solve_equilibrate_solution();
1614 <<
"Equilibrated solution after mapping";
1619 if (ctx->mesh_changed == PETSC_FALSE)
1620 CHKERR check_element_quality();
1621 ctx->mesh_changed = PETSC_FALSE;
1622 if (el_q_map.size() > 0 || do_refine) {
1625 ctx->el_q_map = el_q_map;
1626 ctx->flipped_els = flipped_els;
1627 ctx->new_connectivity = new_connectivity;
1628 ctx->th_spatial_coords = th_spatial_coords;
1629 ctx->mesh_changed = PETSC_TRUE;
1637 CHKERR PetscBarrier((PetscObject)ts);
1649 auto &m_field = ptr->ExRawPtr->mField;
1670 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1671 std::string thermoplastic_block_name,
1672 boost::shared_ptr<ThermoPlasticOps::ThermoPlasticBlockedParameters>
1674 boost::shared_ptr<ThermoElasticOps::BlockedThermalParameters>
1675 &blockedThermalParamsPtr,
1679 struct OpMatThermoPlasticBlocks :
public DomainEleOp {
1680 OpMatThermoPlasticBlocks(
1681 boost::shared_ptr<double> omega_0_ptr,
1682 boost::shared_ptr<double> omega_h_ptr,
1683 boost::shared_ptr<double> inelastic_heat_fraction_ptr,
1684 boost::shared_ptr<double> temp_0_ptr,
1686 boost::shared_ptr<double> heat_capacity,
1687 boost::shared_ptr<double> heat_conductivity_scaling,
1691 std::vector<const CubitMeshSets *> meshset_vec_ptr)
1693 omegaHPtr(omega_h_ptr),
1694 inelasticHeatFractionPtr(inelastic_heat_fraction_ptr),
1696 heatCapacityPtr(heat_capacity),
1697 heatConductivityScalingPtr(heat_conductivity_scaling),
1701 extractThermoPlasticBlockData(m_field, meshset_vec_ptr, sev),
1702 "Can not get data from block");
1709 auto scale_param = [
this](
auto parameter,
double scaling) {
1710 return parameter * scaling;
1713 for (
auto &b : blockData) {
1715 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
1716 *omega0Ptr = b.omega_0;
1717 *omegaHPtr = b.omega_h;
1718 *inelasticHeatFractionPtr = scale_param(
1719 b.inelastic_heat_fraction,
1720 inelasticHeatFractionScaling(
1722 *heatConductivityPtr / (*heatConductivityScalingPtr),
1723 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1724 *temp0Ptr = b.temp_0;
1731 *inelasticHeatFractionPtr =
1733 inelasticHeatFractionScaling(
1735 *heatConductivityPtr / (*heatConductivityScalingPtr),
1736 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1744 boost::shared_ptr<double> heatConductivityPtr;
1745 boost::shared_ptr<double> heatCapacityPtr;
1746 boost::shared_ptr<double> heatConductivityScalingPtr;
1747 boost::shared_ptr<double> heatCapacityScalingPtr;
1756 std::vector<BlockData> blockData;
1760 std::vector<const CubitMeshSets *> meshset_vec_ptr,
Sev sev) {
1763 for (
auto m : meshset_vec_ptr) {
1765 std::vector<double> block_data;
1766 CHKERR m->getAttributes(block_data);
1767 if (block_data.size() < 3) {
1769 "Expected that block has four attributes");
1771 auto get_block_ents = [&]() {
1774 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
1779 <<
m->getName() <<
": omega_0 = " << block_data[0]
1780 <<
" omega_h = " << block_data[1]
1781 <<
" inelastic_heat_fraction = " << block_data[2] <<
" temp_0 "
1784 blockData.push_back({block_data[0], block_data[1], block_data[2],
1785 block_data[3], get_block_ents()});
1791 boost::shared_ptr<double> omega0Ptr;
1792 boost::shared_ptr<double> omegaHPtr;
1793 boost::shared_ptr<double> inelasticHeatFractionPtr;
1794 boost::shared_ptr<double> temp0Ptr;
1797 pipeline.push_back(
new OpMatThermoPlasticBlocks(
1798 blockedParamsPtr->getOmega0Ptr(), blockedParamsPtr->getOmegaHPtr(),
1799 blockedParamsPtr->getInelasticHeatFractionPtr(),
1800 blockedParamsPtr->getTemp0Ptr(),
1801 blockedThermalParamsPtr->getHeatConductivityPtr(),
1802 blockedThermalParamsPtr->getHeatCapacityPtr(),
1803 blockedThermalParamsPtr->getHeatConductivityScalingPtr(),
1804 blockedThermalParamsPtr->getHeatCapacityScalingPtr(),
1805 inelastic_heat_fraction_scaling_func, m_field, sev,
1810 (boost::format(
"%s(.*)") % thermoplastic_block_name).str()
1823 std::vector<EntityHandle> &new_connectivity,
1824 bool &do_refine,
Tag &th_spatial_coords) {
1829 std::vector<double> coords(verts.size() * 3);
1831 auto t_x = getFTensor1FromPtr<3>(coords.data());
1833 auto save_tag = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
1836 auto field_data = ent_ptr->getEntFieldData();
1839 t_u = {field_data[0], field_data[1], 0.0};
1841 t_u = {field_data[0], field_data[1], field_data[2]};
1851 double def_coord[3] = {0.0, 0.0, 0.0};
1853 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
1854 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
1866 std::multimap<double, EntityHandle> candidate_el_q_map;
1867 double spatial_coords[9], material_coords[9];
1870 Range::iterator nit = all_els.begin();
1871 for (
int gg = 0; nit != all_els.end(); nit++, gg++) {
1878 double q = Tools::areaLengthQuality(spatial_coords);
1879 if (!std::isnormal(q))
1881 "Calculated quality of element is not "
1885 if (q < qual_tol && q > 0.)
1886 candidate_el_q_map.insert(std::pair<double, EntityHandle>(q, *nit));
1891 all_els, min_q, th_spatial_coords);
1893 <<
"Old minimum element quality: " << min_q;
1895 auto pair = candidate_el_q_map.begin();
1897 <<
"New minimum element quality: " << pair->first;
1899 for (
auto pair = candidate_el_q_map.begin(); pair != candidate_el_q_map.end();
1901 double quality = pair->first;
1903 element.insert(pair->second);
1904 if (!flipped_els.contains(element)) {
1911 double longest_edge_length = 0;
1912 std::vector<std::pair<double, EntityHandle>> edge_lengths;
1913 edge_lengths.reserve(edges.size());
1914 for (
auto edge : edges) {
1915 edge_lengths.emplace_back(
1918 if (!edge_lengths.empty()) {
1919 const auto it = std::max_element(
1920 edge_lengths.begin(), edge_lengths.end(),
1921 [](
const auto &
a,
const auto &b) { return a.first < b.first; });
1922 longest_edge_length = it->first;
1923 longest_edge = it->second;
1926 "Unable to calculate edge lengths to find longest edge.");
1930 <<
"Edge flip longest edge length: " << longest_edge_length
1931 <<
" for edge: " << longest_edge;
1933 auto get_skin = [&]() {
1939 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
1944 Range boundary_ents;
1945 ParallelComm *pcomm =
1947 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1948 PSTATUS_NOT, -1, &boundary_ents);
1949 return boundary_ents;
1952 Range boundary_ents = get_skin();
1955 <<
"Boundary entities: " << boundary_ents;
1958 Range flip_candidate_els;
1960 false, flip_candidate_els);
1964 Range neighbouring_el = subtract(flip_candidate_els, element);
1968 if (boundary_ents.contains(
Range(longest_edge, longest_edge))) {
1972 if (flipped_els.contains(neighbouring_el))
1976 if (neighbouring_el.size() != 1) {
1978 "Should be 1 neighbouring element to bad element for edge "
1979 "flip. Instead, there are %d",
1980 neighbouring_el.size());
1985 <<
"flip_candidate_els: " << flip_candidate_els;
1987 <<
"Neighbouring element: " << neighbouring_el;
1990 std::vector<EntityHandle> neighbouring_nodes;
1992 neighbouring_nodes,
true);
1994 std::vector<EntityHandle> element_nodes;
1996 element_nodes,
true);
1999 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2001 double neighbour_qual = Tools::areaLengthQuality(spatial_coords);
2002 if (!std::isnormal(neighbour_qual))
2004 "Calculated quality of neighbouring element is not as "
2012 <<
"Element nodes before swap: "
2015 <<
"Neighbouring nodes before swap: "
2024 std::vector<EntityHandle> reversed_neighbouring_nodes =
2026 std::reverse(reversed_neighbouring_nodes.begin(),
2027 reversed_neighbouring_nodes.end());
2029 int num_matches = 0;
2030 std::vector<bool> mismatch_mask(element_nodes.size());
2031 int loop_counter = 0;
2032 while (num_matches != 2) {
2034 std::rotate(reversed_neighbouring_nodes.begin(),
2035 reversed_neighbouring_nodes.begin() + 1,
2036 reversed_neighbouring_nodes.end());
2038 std::transform(element_nodes.begin(), element_nodes.end(),
2039 reversed_neighbouring_nodes.begin(),
2040 mismatch_mask.begin(), std::equal_to<EntityHandle>());
2043 std::count(mismatch_mask.begin(), mismatch_mask.end(),
true);
2046 if (loop_counter > 3) {
2048 "Not found matching nodes for edge flipping");
2053 std::vector<EntityHandle> matched_elements(element_nodes.size());
2054 std::transform(element_nodes.begin(), element_nodes.end(),
2055 mismatch_mask.begin(), matched_elements.begin(),
2057 return match ? el : -1;
2061 matched_elements.erase(
2062 std::remove(matched_elements.begin(), matched_elements.end(), -1),
2063 matched_elements.end());
2066 std::vector<EntityHandle> mismatched_elements(element_nodes.size()),
2067 neighbouring_mismatched_elements(neighbouring_nodes.size());
2068 std::transform(element_nodes.begin(), element_nodes.end(),
2069 mismatch_mask.begin(), mismatched_elements.begin(),
2071 return match ? -1 : el;
2073 std::transform(reversed_neighbouring_nodes.begin(),
2074 reversed_neighbouring_nodes.end(), mismatch_mask.begin(),
2075 neighbouring_mismatched_elements.begin(),
2077 return match ? -1 : el;
2081 mismatched_elements.erase(std::remove(mismatched_elements.begin(),
2082 mismatched_elements.end(), -1),
2083 mismatched_elements.end());
2084 neighbouring_mismatched_elements.erase(
2085 std::remove(neighbouring_mismatched_elements.begin(),
2086 neighbouring_mismatched_elements.end(), -1),
2087 neighbouring_mismatched_elements.end());
2089 mismatched_elements.insert(mismatched_elements.end(),
2090 neighbouring_mismatched_elements.begin(),
2091 neighbouring_mismatched_elements.end());
2094 <<
"Reversed neighbouring nodes: "
2106 auto replace_correct_nodes = [](std::vector<EntityHandle> &ABC,
2107 std::vector<EntityHandle> &DBA,
2108 const std::vector<EntityHandle> &AB,
2109 const std::vector<EntityHandle> &CD) {
2111 std::vector<std::vector<EntityHandle>> results;
2113 for (
int i = 0;
i < 2; ++
i) {
2114 for (
int j = 0;
j < 2; ++
j) {
2116 if (std::find(ABC.begin(), ABC.end(), CD[
j]) == ABC.end()) {
2117 std::vector<EntityHandle> tmp = ABC;
2119 auto it = std::find(tmp.begin(), tmp.end(), AB[
i]);
2120 if (it != tmp.end()) {
2122 results.push_back(tmp);
2128 if (results.size() != 2) {
2130 "Failed to find two valid vertex replacements for edge "
2140 CHKERR replace_correct_nodes(element_nodes, neighbouring_nodes,
2141 matched_elements, mismatched_elements);
2144 <<
"Element nodes after swap: "
2147 <<
"Neighbouring nodes after swap: "
2152 th_spatial_coords, &element_nodes.front(), 3, spatial_coords);
2154 double new_qual = Tools::areaLengthQuality(spatial_coords);
2155 if (new_qual < 0.0 || !std::isfinite(new_qual))
2157 "Calculated quality of new element is not as expected: %f",
2161 auto check_normal_direction = [&](
double qual_val) {
2165 auto [new_area, t_new_normal] = Tools::triAreaAndNormal(spatial_coords);
2167 t_diff(
i) = t_new_normal(
i) - t_correct_normal(
i);
2168 if (qual_val > 1e-6 && t_diff(
i) * t_diff(
i) > 1e-6) {
2170 "Direction of element to be created is wrong orientation");
2175 CHKERR check_normal_direction(new_qual);
2179 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2181 double new_neighbour_qual = Tools::areaLengthQuality(spatial_coords);
2182 if (new_neighbour_qual < 0.0 || !std::isfinite(new_neighbour_qual))
2184 "Calculated quality of new neighbouring element is not "
2186 new_neighbour_qual);
2189 CHKERR check_normal_direction(new_neighbour_qual);
2193 if (std::min(new_qual, new_neighbour_qual) >
2194 (1. +
qual_thresh) * std::min(quality, neighbour_qual)) {
2196 <<
"Element quality improved from " << quality <<
" and "
2197 << neighbour_qual <<
" to " << new_qual <<
" and "
2198 << new_neighbour_qual <<
" for elements" << element <<
" and "
2202 flipped_els.merge(flip_candidate_els);
2204 std::pair<double, EntityHandle>(pair->first, pair->second));
2205 new_connectivity.insert(new_connectivity.end(), element_nodes.begin(),
2206 element_nodes.end());
2207 new_connectivity.insert(new_connectivity.end(),
2208 neighbouring_nodes.begin(),
2209 neighbouring_nodes.end());
2214 if (el_q_map.size() > 0) {
2215 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"Flipped elements: " << flipped_els;
2224 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2225 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2227 Range prev_ref_ents;
2232 for (
auto e : edges) {
2236 std::array<double, 6> ref_coords, spatial_coords;
2239 spatial_coords.data());
2240 auto get_length = [](
auto &
a) {
2244 p1(
i) = p1(
i) - p0(
i);
2247 auto ref_edge_length = get_length(ref_coords);
2248 auto spatial_edge_length = get_length(spatial_coords);
2249 auto change = spatial_edge_length / ref_edge_length;
2251 !prev_ref_ents.contains(
Range(e, e))) {
2267 auto make_edge_flip = [&](
auto edge,
auto adj_faces,
Range &new_tris) {
2274 CHKERR moab.get_connectivity(e, conn, num_nodes,
true);
2275 std::copy(conn, conn + num_nodes, conn_cpy);
2279 auto get_tri_normals = [&](
auto &conn) {
2280 std::array<double, 18> coords;
2281 CHKERR moab.get_coords(conn.data(), 6, coords.data());
2282 std::array<FTensor::Tensor1<double, 3>, 2> tri_normals;
2283 for (
int t = 0;
t != 2; ++
t) {
2289 auto test_flip = [&](
auto &&t_normals) {
2291 if (t_normals[0](
i) * t_normals[1](
i) <
2292 std::numeric_limits<float>::epsilon())
2297 std::array<EntityHandle, 6> adj_conn;
2298 CHKERR get_conn(adj_faces[0], &adj_conn[0]);
2299 CHKERR get_conn(adj_faces[1], &adj_conn[3]);
2300 std::array<EntityHandle, 2> edge_conn;
2301 CHKERR get_conn(edge, edge_conn.data());
2302 std::array<EntityHandle, 2> new_edge_conn;
2305 for (
int i = 0;
i != 6; ++
i) {
2306 if (adj_conn[
i] != edge_conn[0] && adj_conn[
i] != edge_conn[1]) {
2307 new_edge_conn[
j] = adj_conn[
i];
2312 auto &new_conn = adj_conn;
2313 for (
int t = 0;
t != 2; ++
t) {
2314 for (
int i = 0;
i != 3; ++
i) {
2317 (adj_conn[3 *
t +
i % 3] == edge_conn[0] &&
2318 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[1])
2322 (adj_conn[3 *
t +
i % 3] == edge_conn[1] &&
2323 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[0])
2326 new_conn[3 *
t + (
i + 1) % 3] = new_edge_conn[
t];
2332 if (test_flip(get_tri_normals(new_conn))) {
2333 for (
int t = 0;
t != 2; ++
t) {
2341 new_tris.insert(tri);
2344 if (rtri.size() != 1) {
2346 <<
"Multiple tries created during edge flip for edge " << edge
2347 <<
" adjacent faces " << std::endl
2350 "Multiple tries created during edge flip");
2353 new_tris.merge(rtri);
2359 moab::Interface::UNION);
2363 MOFEM_LOG(
"SELF", Sev::warning) <<
"Edge flip rejected for edge " << edge
2364 <<
" adjacent faces " << adj_faces;
2374 Skinner skin(&moab);
2376 CHKERR skin.find_skin(0, tris,
false, skin_edges);
2380 edges = subtract(edges, skin_edges);
2384 Range new_tris, flipped_tris, forbidden_tris;
2386 for (
auto edge : edges) {
2387 Range adjacent_tris;
2388 CHKERR moab.get_adjacencies(&edge, 1,
SPACE_DIM,
true, adjacent_tris);
2390 adjacent_tris = intersect(adjacent_tris, tris);
2391 adjacent_tris = subtract(adjacent_tris, forbidden_tris);
2392 if (adjacent_tris.size() == 2) {
2395 int side_number0, sense0, offset0;
2398 int side_number1, sense1, offset1;
2401 if (sense0 * sense1 > 0)
2404 "Cannot flip edge with same orientation in both adjacent faces");
2407 Range new_flipped_tris;
2408 CHKERR make_edge_flip(edge, adjacent_tris, new_flipped_tris);
2409 if (new_flipped_tris.size()) {
2410 flipped_tris.merge(adjacent_tris);
2411 forbidden_tris.merge(adjacent_tris);
2412 new_tris.merge(new_flipped_tris);
2416 "flipped_tris_" + std::to_string(flip_count) +
".vtk",
2419 moab,
"new_flipped_tris_" + std::to_string(flip_count) +
".vtk",
2431 Range not_flipped_tris = subtract(all_tris, flipped_tris);
2434 <<
"Flipped " << flip_count <<
" edges with two adjacent faces.";
2440 child_bit,
BitRefLevel().set(),
"edge_flips_before_refinement.vtk",
"VTK",
2450 Range &flipped_els,
Tag &th_spatial_coords,
2451 std::vector<EntityHandle> &new_connectivity) {
2454 ReadUtilIface *read_util;
2457 const int num_ele = el_q_map.size() * 2;
2458 int num_nod_per_ele;
2459 EntityType ent_type;
2462 num_nod_per_ele = 3;
2465 num_nod_per_ele = 4;
2470 auto new_conn = new_connectivity.begin();
2471 for (
auto e = 0; e != num_ele; ++e) {
2473 for (
int n = 0;
n < num_nod_per_ele; ++
n) {
2474 conn[
n] = *new_conn;
2481 if (adj_ele.size()) {
2482 if (adj_ele.size() != 1) {
2484 "Element duplication");
2486 new_ele = adj_ele.front();
2492 new_elements.insert(new_ele);
2496 <<
"New elements from edge flipping: " << new_elements;
2505 auto get_adj = [&](
auto ents) {
2510 moab::Interface::UNION),
2511 "Getting adjacencies of dimension " + std::to_string(d) +
" failed");
2516 Range non_flipped_range;
2520 non_flipped_range = subtract(non_flipped_range, flipped_els);
2521 auto flip_bit_ents = new_elements;
2522 flip_bit_ents.merge(non_flipped_range);
2523 auto adj = get_adj(new_elements);
2531 "new_elements_after_edge_flips.vtk",
"VTK",
"");
2541 Tag th_spatial_coords;
2542 double def_coord[3] = {0.0, 0.0, 0.0};
2544 auto refined_mesh = [&](
auto level) {
2551 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2552 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2556 for (
auto e : edges) {
2560 std::array<double, 6> ref_coords, spatial_coords;
2563 num_nodes, spatial_coords.data());
2564 auto get_length = [](
auto &
a) {
2568 p1(
i) = p1(
i) - p0(
i);
2571 auto ref_edge_length = get_length(ref_coords);
2572 auto spatial_edge_length = get_length(spatial_coords);
2573 auto change = spatial_edge_length / ref_edge_length;
2575 refine_edges.insert(e);
2579 if (refine_edges.size())
2582 Range prev_level_ents;
2586 Range prev_ref_ents;
2591 refine_edges.merge(intersect(prev_ref_ents, prev_level_ents));
2598 Range tris_to_refine;
2603 auto set_spatial_coords = [&]() {
2608 auto th_parent_handle =
2610 for (
auto v : new_vertices) {
2617 std::array<double, 6> spatial_coords;
2619 num_nodes, spatial_coords.data());
2620 for (
auto d = 0; d < 3; ++d) {
2621 spatial_coords[d] += spatial_coords[3 + d];
2623 for (
auto d = 0; d < 3; ++d) {
2624 spatial_coords[d] /= 2.0;
2627 spatial_coords.data());
2632 CHKERR set_spatial_coords();
2636 (
"A_refined_" + boost::lexical_cast<std::string>(level) +
".vtk")
2658 BitRefLevel().set(), 2,
"new_elements_after_edge_splits.vtk",
"VTK",
"");
2687 auto get_ents_by_dim = [&](
const auto dim) {
2700 auto get_base = [&]() {
2701 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
2702 if (domain_ents.empty())
2720 const auto base = get_base();
2752 auto get_skin = [&]() {
2757 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2761 auto filter_blocks = [&](
auto skin) {
2762 bool is_contact_block =
false;
2763 Range contact_range;
2767 (boost::format(
"%s(.*)") %
"CONTACT").str()
2776 <<
"Find contact block set: " <<
m->getName();
2777 auto meshset =
m->getMeshset();
2778 Range contact_meshset_range;
2780 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
2783 contact_meshset_range);
2784 contact_range.merge(contact_meshset_range);
2786 if (is_contact_block) {
2788 <<
"Nb entities in contact surface: " << contact_range.size();
2790 skin = intersect(skin, contact_range);
2796 Range boundary_ents;
2797 ParallelComm *pcomm =
2799 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2800 PSTATUS_NOT, -1, &boundary_ents);
2801 return boundary_ents;
2812 if (
qual_tol < std::numeric_limits<double>::epsilon() &&
2835 auto get_command_line_parameters = [&]() {
2849 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Minimum dt: " <<
min_dt;
2854 <<
"Minumum quality for edge flipping: " <<
qual_tol;
2859 <<
"Quality improvement threshold for edge flipping: " <<
qual_thresh;
2867 <<
"Number of refinement levels for edge splitting: "
2904 (PetscInt *)&
ic_type, PETSC_NULLPTR);
2928 PetscBool tau_order_is_set;
2931 PetscBool ep_order_is_set;
2934 PetscBool flux_order_is_set;
2936 &flux_order_is_set);
2937 PetscBool T_order_is_set;
2960 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Hardening " <<
H;
2961 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Viscous hardening " <<
visH;
2962 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation yield stress " <<
Qinf;
2963 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation exponent " <<
b_iso;
2964 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Kinematic hardening " <<
C1_k;
2981 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
2986 if (tau_order_is_set == PETSC_FALSE)
2988 if (ep_order_is_set == PETSC_FALSE)
2991 if (flux_order_is_set == PETSC_FALSE)
2993 if (T_order_is_set == PETSC_FALSE)
2996 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Approximation order " <<
order;
2998 <<
"Ep approximation order " <<
ep_order;
3000 <<
"Tau approximation order " <<
tau_order;
3002 <<
"FLUX approximation order " <<
flux_order;
3007 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Density " <<
rho;
3010 PetscBool is_scale = PETSC_TRUE;
3013 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Scaling used? " << is_scale;
3017 MOFEM_LOG(
"THERMOPLASTICITY", Sev::warning)
3018 <<
"Scaling does not yet work with radiation and convection BCs";
3023 if (heat_cap != 0.0 && thermal_cond != 0.0)
3024 return 1. / (thermal_cond * heat_cap);
3026 return 1. / thermal_cond;
3029 if (heat_cap != 0.0)
3030 return 1. / (thermal_cond * heat_cap);
3035 [&](
double young_modulus,
double thermal_cond,
double heat_cap) {
3036 if (heat_cap != 0.0)
3050 double thermal_cond,
3051 double heat_cap) {
return 1.0; };
3057 <<
"Thermal conductivity scale "
3061 <<
"Thermal capacity scale "
3064 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
3065 <<
"Inelastic heat fraction scale "
3079 CHKERR get_command_line_parameters();
3082 #ifdef ENABLE_PYTHON_BINDING
3083 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
3084 CHKERR sdfPythonPtr->sdfInit(
"sdf.py");
3085 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
3097 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order; };
3145 auto T_ptr = boost::make_shared<VectorDouble>();
3147 auto post_proc = [&](
auto dm) {
3150 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
3154 post_proc_fe->getOpPtrVector().push_back(
3160 auto TAU_ptr = boost::make_shared<VectorDouble>();
3161 auto EP_ptr = boost::make_shared<MatrixDouble>();
3163 post_proc_fe->getOpPtrVector().push_back(
3165 post_proc_fe->getOpPtrVector().push_back(
3168 post_proc_fe->getOpPtrVector().push_back(
3170 new OpPPMap(post_proc_fe->getPostProcMesh(),
3171 post_proc_fe->getMapGaussPts(),
3173 {{
"T", T_ptr}, {
"TAU", TAU_ptr}},
3185 post_proc_fe->getOpPtrVector().push_back(
3187 new OpPPMap(post_proc_fe->getPostProcMesh(),
3188 post_proc_fe->getMapGaussPts(),
3204 CHKERR post_proc_fe->writeFile(
"out_init.h5m");
3209 auto solve_init = [&]() {
3212 auto set_domain_rhs = [&](
auto &pip) {
3219 "T",
nullptr, T_ptr,
nullptr, boost::make_shared<double>(
init_temp),
3220 boost::make_shared<double>(
peak_temp)));
3223 auto TAU_ptr = boost::make_shared<VectorDouble>();
3224 auto EP_ptr = boost::make_shared<MatrixDouble>();
3227 auto min_tau = boost::make_shared<double>(1.0);
3228 auto max_tau = boost::make_shared<double>(2.0);
3230 nullptr, min_tau, max_tau));
3234 auto min_EP = boost::make_shared<double>(0.0);
3235 auto max_EP = boost::make_shared<double>(0.01);
3237 "EP",
nullptr, EP_ptr,
nullptr, min_EP, max_EP));
3279 auto set_domain_lhs = [&](
auto &pip) {
3286 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"T",
"T"));
3288 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"TAU",
"TAU"));
3334 auto dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
3338 for (
auto f : {
"T"}) {
3343 for (
auto f : {
"TAU",
"EP"}) {
3352 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3353 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3354 fe_rhs->getRuleHook = vol_rule;
3355 fe_lhs->getRuleHook = vol_rule;
3356 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3357 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3359 auto sub_dm = create_sub_dm(
simple->getDM());
3361 auto null_fe = boost::shared_ptr<FEMethod>();
3363 fe_lhs, null_fe, null_fe);
3368 CHKERR KSPSetDM(ksp, sub_dm);
3369 CHKERR KSPSetFromOptions(ksp);
3373 CHKERR KSPSolve(ksp, PETSC_NULLPTR,
D);
3375 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
3376 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
3385 MOFEM_LOG(
"THERMAL", Sev::inform) <<
"Set thermoelastic initial conditions";
3398 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
3401 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
3404 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
3407 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3408 "REMOVE_ALL",
"U", 0, 3,
true,
3412 for (
auto b : {
"FIX_X",
"REMOVE_X"})
3413 CHKERR bc_mng->removeBlockDOFsOnEntities(
3415 for (
auto b : {
"FIX_Y",
"REMOVE_Y"})
3416 CHKERR bc_mng->removeBlockDOFsOnEntities(
3418 for (
auto b : {
"FIX_Z",
"REMOVE_Z"})
3419 CHKERR bc_mng->removeBlockDOFsOnEntities(
3421 for (
auto b : {
"FIX_ALL",
"REMOVE_ALL"})
3422 CHKERR bc_mng->removeBlockDOFsOnEntities(
3424 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3425 "NO_CONTACT",
"SIGMA", 0, 3,
false,
3430 simple->getProblemName(),
"U");
3432 auto &bc_map = bc_mng->getBcMapByBlockName();
3433 for (
auto bc : bc_map)
3434 MOFEM_LOG(
"PLASTICITY", Sev::verbose) <<
"Marker " << bc.first;
3450 auto get_skin = [&]() {
3457 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
3461 auto filter_flux_blocks = [&](
auto skin,
bool temp_bc =
false) {
3462 auto remove_cubit_blocks = [&](
auto c) {
3472 skin = subtract(skin, ents);
3477 auto remove_named_blocks = [&](
auto n) {
3482 (boost::format(
"%s(.*)") %
n).str()
3490 skin = subtract(skin, ents);
3496 "remove_cubit_blocks");
3498 "remove_named_blocks");
3501 "remove_cubit_blocks");
3509 Range boundary_ents;
3510 ParallelComm *pcomm =
3512 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3513 PSTATUS_NOT, -1, &boundary_ents);
3514 return boundary_ents;
3518 auto remove_temp_bc_ents =
3526 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
3529 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3543 simple->getProblemName(),
"FLUX", remove_flux_ents);
3545 simple->getProblemName(),
"TBC", remove_temp_bc_ents);
3548 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"FLUX",
3551 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"TBC",
3552 remove_temp_bc_ents);
3564 simple->getProblemName(),
"FLUX",
false);
3577 auto boundary_marker =
3578 bc_mng->getMergedBlocksMarker(vector<string>{
"HEATFLUX"});
3580 auto integration_rule_bc = [](
int,
int,
int ao) {
return 2 * ao; };
3584 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
3585 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
3587 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
3588 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
3590 auto thermal_block_params =
3591 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
3592 auto heat_conductivity_ptr = thermal_block_params->getHeatConductivityPtr();
3593 auto heat_capacity_ptr = thermal_block_params->getHeatCapacityPtr();
3595 auto thermoelastic_block_params =
3596 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
3597 auto coeff_expansion_ptr = thermoelastic_block_params->getCoeffExpansionPtr();
3598 auto ref_temp_ptr = thermoelastic_block_params->getRefTempPtr();
3602 boost::make_shared<TimeScale>(
"",
false, [](
const double) {
return 1; });
3603 auto def_time_scale = [time_scale](
const double time) {
3604 return (!time_scale->argFileScale) ? time : 1;
3606 auto def_file_name = [time_scale](
const std::string &&name) {
3607 return (!time_scale->argFileScale) ? name :
"";
3611 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
3612 def_file_name(
"bodyforce_scale.txt"),
false, def_time_scale);
3613 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
3614 def_file_name(
"heatsource_scale.txt"),
false, def_time_scale);
3615 auto time_temperature_scaling = boost::make_shared<TimeScale>(
3616 def_file_name(
"temperature_bc_scale.txt"),
false, def_time_scale);
3617 auto time_displacement_scaling = boost::make_shared<TimeScale>(
3618 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
3619 auto time_flux_scaling = boost::make_shared<TimeScale>(
3620 def_file_name(
"flux_bc_scale.txt"),
false, def_time_scale);
3621 auto time_force_scaling = boost::make_shared<TimeScale>(
3622 def_file_name(
"force_bc_scale.txt"),
false, def_time_scale);
3624 auto add_boundary_ops_lhs = [&](
auto &pip) {
3627 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3634 pip,
mField,
"U", Sev::inform);
3638 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3641 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
3642 mField, pip,
simple->getDomainFEName(),
"SIGMA",
"U",
"", vol_rule);
3647 using OpConvectionLhsBC =
3648 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3649 using OpRadiationLhsBC =
3650 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3651 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3653 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pip,
mField,
"TBC",
"TBC",
3654 "CONVECTION", Sev::verbose);
3655 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
3656 pip,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
3663 struct OpTBCTimesNormalFlux
3668 OpTBCTimesNormalFlux(
const std::string row_field_name,
3669 const std::string col_field_name,
3670 boost::shared_ptr<Range> ents_ptr =
nullptr)
3671 :
OP(row_field_name, col_field_name,
OP::OPROWCOL, ents_ptr) {
3673 this->assembleTranspose =
true;
3674 this->onlyTranspose =
false;
3684 auto t_w = OP::getFTensor0IntegrationWeight();
3688 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3690 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3692 auto a_mat_ptr = &*OP::locMat.data().begin();
3694 for (; rr != OP::nbRows; rr++) {
3696 const double alpha = t_w * t_row_base;
3700 for (
int cc = 0; cc != OP::nbCols; cc++) {
3704 *a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
3710 for (; rr < OP::nbRowBaseFunctions; ++rr)
3715 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3716 if (fe_type == MBTRI) {
3723 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC",
"FLUX"));
3728 auto add_boundary_ops_rhs = [&](
auto &pip) {
3735 pip,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
3743 pip,
mField,
"FLUX", {time_scale, time_temperature_scaling},
3744 "TEMPERATURE", Sev::inform);
3754 pip,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
3758 using OpConvectionRhsBC =
3759 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3760 using OpRadiationRhsBC =
3761 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3762 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3764 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
3765 pip,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
3766 T::AddFluxToPipeline<OpRadiationRhsBC>::add(pip,
mField,
"TBC", temp_bc_ptr,
3767 "RADIATION", Sev::inform);
3769 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3778 struct OpTBCTimesNormalFlux
3783 OpTBCTimesNormalFlux(
const std::string
field_name,
3784 boost::shared_ptr<MatrixDouble> vec,
3785 boost::shared_ptr<Range> ents_ptr =
nullptr)
3792 auto t_w = OP::getFTensor0IntegrationWeight();
3796 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3798 auto t_vec = getFTensor1FromMat<SPACE_DIM, 1>(*sourceVec);
3800 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3802 const double alpha = t_w * (t_vec(
i) * t_normal(
i));
3805 for (; rr != OP::nbRows; ++rr) {
3806 OP::locF[rr] += alpha * t_row_base;
3809 for (; rr < OP::nbRowBaseFunctions; ++rr)
3815 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3816 if (fe_type == MBTRI) {
3823 boost::shared_ptr<MatrixDouble> sourceVec;
3825 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC", mat_flux_ptr));
3827 struct OpBaseNormalTimesTBC
3832 OpBaseNormalTimesTBC(
const std::string
field_name,
3833 boost::shared_ptr<VectorDouble> vec,
3834 boost::shared_ptr<Range> ents_ptr =
nullptr)
3841 auto t_w = OP::getFTensor0IntegrationWeight();
3845 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3849 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3851 const double alpha = t_w * t_vec;
3854 for (; rr != OP::nbRows; ++rr) {
3855 OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
3858 for (; rr < OP::nbRowBaseFunctions; ++rr)
3864 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3865 if (fe_type == MBTRI) {
3872 boost::shared_ptr<VectorDouble> sourceVec;
3875 pip.push_back(
new OpBaseNormalTimesTBC(
"FLUX", temp_bc_ptr));
3878 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3885 auto add_domain_ops_lhs = [&](
auto &pip) {
3888 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3891 mField, pip,
"MAT_THERMAL", thermal_block_params,
3905 auto get_inertia_and_mass_damping = [
this](
const double,
const double,
3909 return (
rho /
scale) * fe_domain_lhs->ts_aa +
3912 pip.push_back(
new OpMass(
"U",
"U", get_inertia_and_mass_damping));
3915 CHKERR opThermoPlasticFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
3916 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
3917 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
3919 auto hencky_common_data_ptr =
3920 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3921 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3922 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3923 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3925 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3927 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3929 return (1. / (*heat_conductivity_ptr));
3931 auto capacity = [heat_capacity_ptr](
const double,
const double,
3933 return -(*heat_capacity_ptr);
3936 pip.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance, mat_grad_ptr));
3938 new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
3940 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3945 new OpHdivU(
"FLUX",
"U", mat_flux_ptr, resistance, mat_grad_ptr));
3947 auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
3948 op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
3949 return fe_ptr->ts_a;
3951 pip.push_back(op_capacity);
3955 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3958 pip,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
3965 auto add_domain_ops_rhs = [&](
auto &pip) {
3968 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3971 mField, pip,
"MAT_THERMAL", thermal_block_params,
3978 auto hencky_common_data_ptr =
3979 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3980 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3981 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3982 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3983 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
3984 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
3986 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3987 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
3988 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3989 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
3994 "FLUX", vec_temp_div_ptr));
3998 auto resistance = [heat_conductivity_ptr](
const double,
const double,
4000 return (1. / (*heat_conductivity_ptr));
4003 auto capacity = [heat_capacity_ptr](
const double,
const double,
4005 return -(*heat_capacity_ptr);
4011 new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
4012 pip.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
4013 pip.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
4014 pip.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
4018 {boost::make_shared<ScaledTimeScale>(
"body_force_hist.txt")},
4029 auto mat_acceleration = boost::make_shared<MatrixDouble>();
4031 "U", mat_acceleration));
4033 new OpInertiaForce(
"U", mat_acceleration, [](
double,
double,
double) {
4037 auto mat_velocity = boost::make_shared<MatrixDouble>();
4041 new OpInertiaForce(
"U", mat_velocity, [](
double,
double,
double) {
4047 CHKERR opThermoPlasticFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4048 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4049 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
4052 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4061 auto create_reaction_pipeline = [&](
auto &pip) {
4064 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
4065 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
4076 auto get_bc_hook_rhs = [&]() {
4078 mField, pip_mng->getDomainRhsFE(),
4079 {time_scale, time_displacement_scaling});
4082 auto get_bc_hook_lhs = [&]() {
4084 mField, pip_mng->getDomainLhsFE(),
4085 {time_scale, time_displacement_scaling});
4089 pip_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
4090 pip_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
4092 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
4093 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
4096 CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
4097 CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
4129 PetscInt snes_iter_counter = 0;
4151 PetscBool *resize,
void *ctx) {
4155 PetscFunctionReturn(0);
4159 Vec ts_vecsout[],
void *ctx) {
4163 if (
auto ptr = rctx->
ptr.lock()) {
4178 std::string improved_reasons =
"";
4180 Range edges_to_not_refine;
4186 improved_reasons +=
", Edge flipping";
4189 bool refined =
false;
4191 CHKERR TSGetStepNumber(ts, &step);
4192 CHKERR ptr->ExRawPtr->doEdgeSplits(refined, (step) ?
true :
false);
4194 improved_reasons +=
", Edge splitting";
4198 improved_reasons.erase(0, 2);
4200 if (improved_reasons !=
"")
4202 <<
"Improved mesh quality by: " << improved_reasons;
4216 "before_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4225 "before_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4228 "before_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4232 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"number of vectors to map = " << nv;
4234 for (PetscInt
i = 0;
i < nv; ++
i) {
4236 CHKERR VecNorm(ts_vecsin[
i], NORM_2, &nrm);
4238 <<
"Before remeshing: ts_vecsin[" <<
i <<
"] norm = " << nrm;
4260 intermediate_dm, &m_field,
"INTERMEDIATE_DM",
4264 CHKERR DMSetFromOptions(intermediate_dm);
4268 CHKERR DMSetUp(intermediate_dm);
4270 Vec vec_in[nv], vec_out[nv];
4271 for (PetscInt
i = 0;
i < nv; ++
i) {
4272 CHKERR DMCreateGlobalVector(intermediate_dm, &vec_in[
i]);
4273 CHKERR VecDuplicate(vec_in[
i], &vec_out[
i]);
4276 VecScatter scatter_to_intermediate;
4278 for (PetscInt
i = 0;
i < nv; ++
i) {
4279 CHKERR scatter_mng->vecScatterCreate(
4282 CHKERR VecScatterBegin(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4283 INSERT_VALUES, SCATTER_FORWARD);
4284 CHKERR VecScatterEnd(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4285 INSERT_VALUES, SCATTER_FORWARD);
4288 CHKERR VecScatterDestroy(&scatter_to_intermediate);
4296 auto ts_problem_name =
simple->getProblemName();
4303 PetscBarrier(
nullptr);
4312 CHKERR ptr->ExRawPtr->mechanicalBC(
4315 CHKERR ptr->ExRawPtr->thermalBC(
4319 VecScatter scatter_to_final;
4321 for (PetscInt
i = 0;
i < nv; ++
i) {
4322 CHKERR DMCreateGlobalVector(
simple->getDM(), &ts_vecsout[
i]);
4323 CHKERR scatter_mng->vecScatterCreate(
4326 CHKERR VecScatterBegin(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4327 INSERT_VALUES, SCATTER_REVERSE);
4328 CHKERR VecScatterEnd(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4329 INSERT_VALUES, SCATTER_REVERSE);
4330 CHKERR VecScatterDestroy(&scatter_to_final);
4333 for (PetscInt
i = 0;
i < nv; ++
i) {
4334 CHKERR VecDestroy(&vec_in[
i]);
4335 CHKERR VecDestroy(&vec_out[
i]);
4355 CHKERR bit_mng->lambdaBitRefLevel(set_all_bit);
4369 "after_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4378 "after_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4381 "after_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4393 CHKERR TSSetIJacobian(ts,
B,
B,
nullptr,
nullptr);
4396 for (PetscInt
i = 0;
i < nv; ++
i) {
4398 CHKERR VecNorm(ts_vecsout[
i], NORM_2, &nrm);
4400 <<
"After remeshing: ts_vecsout[" <<
i <<
"] norm = " << nrm;
4403 PetscFunctionReturn(0);
4417 auto set_section_monitor = [&](
auto solver) {
4420 CHKERR TSGetSNES(solver, &snes);
4421 CHKERR SNESMonitorSet(snes,
4424 (
void *)(snes_ctx_ptr.get()),
nullptr);
4428 auto create_post_process_elements = [&]() {
4429 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
4431 auto push_vol_ops = [
this](
auto &pip) {
4438 const double) {
return 1.; };
4440 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4441 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4442 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4443 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4444 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1., unity_2_args,
4445 unity_2_args, unity_3_args, Sev::inform);
4447 if (common_hencky_ptr) {
4448 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
4452 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
4453 common_thermoplastic_ptr);
4456 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
4459 auto &pip = pp_fe->getOpPtrVector();
4461 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
4464 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
4465 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4467 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4468 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4470 auto u_ptr = boost::make_shared<MatrixDouble>();
4481 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4483 {{
"ISOTROPIC_HARDENING",
4484 common_plastic_ptr->getPlasticIsoHardeningPtr()},
4486 common_plastic_ptr->getPlasticSurfacePtr()},
4487 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4488 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4491 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4493 {{
"GRAD", common_hencky_ptr->matGradPtr},
4494 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
4496 {{
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4497 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
4498 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
4499 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
4511 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4513 {{
"PLASTIC_SURFACE",
4514 common_plastic_ptr->getPlasticSurfacePtr()},
4515 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4516 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4519 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4523 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
4524 {
"STRESS", common_plastic_ptr->mStressPtr},
4525 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4526 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
4537 PetscBool post_proc_vol = PETSC_FALSE;
4538 PetscBool post_proc_skin = PETSC_TRUE;
4541 post_proc_vol = PETSC_TRUE;
4542 post_proc_skin = PETSC_FALSE;
4545 post_proc_vol = PETSC_FALSE;
4546 post_proc_skin = PETSC_TRUE;
4553 &post_proc_vol, PETSC_NULLPTR);
4555 &post_proc_skin, PETSC_NULLPTR);
4557 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4559 if (post_proc_vol == PETSC_FALSE)
4560 return boost::shared_ptr<PostProcEle>();
4561 auto pp_fe = boost::make_shared<PostProcEle>(mField);
4563 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
4564 "push_vol_post_proc_ops");
4568 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4569 &post_proc_skin]() {
4570 if (post_proc_skin == PETSC_FALSE)
4571 return boost::shared_ptr<SkinPostProcEle>();
4574 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
4577 pp_fe->getOpPtrVector().push_back(op_side);
4579 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
4580 "push_vol_post_proc_ops");
4584 return std::make_pair(vol_post_proc(), skin_post_proc());
4587 auto scatter_create = [&](
auto D,
auto coeff) {
4589 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
4590 ROW,
"U", coeff, coeff, is);
4592 CHKERR ISGetLocalSize(is, &loc_size);
4594 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
4596 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULLPTR, &scatter);
4601 boost::shared_ptr<SetPtsData> field_eval_data;
4602 boost::shared_ptr<MatrixDouble> u_field_ptr;
4604 std::array<double, 3> field_eval_coords = {0., 0., 0.};
4607 field_eval_coords.data(), &coords_dim,
4610 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
4611 scalar_field_ptrs = boost::make_shared<
4612 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
4613 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4614 vector_field_ptrs = boost::make_shared<
4615 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4616 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4617 sym_tensor_field_ptrs = boost::make_shared<
4618 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4619 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4620 tensor_field_ptrs = boost::make_shared<
4621 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4623 auto test_monitor_ptr = boost::make_shared<FEMethod>();
4629 field_eval_data,
simple->getDomainFEName());
4631 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4632 auto no_rule = [](
int,
int,
int) {
return -1; };
4633 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4634 field_eval_fe_ptr->getRuleHook = no_rule;
4637 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4643 const double) {
return 1.; };
4645 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4646 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4647 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4648 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4649 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4650 "TAU",
"T", 1., unity_2_args, unity_2_args, unity_3_args,
4653 auto u_field_ptr = boost::make_shared<MatrixDouble>();
4654 field_eval_fe_ptr->getOpPtrVector().push_back(
4656 auto T_field_ptr = boost::make_shared<VectorDouble>();
4657 field_eval_fe_ptr->getOpPtrVector().push_back(
4659 auto FLUX_field_ptr = boost::make_shared<MatrixDouble>();
4660 field_eval_fe_ptr->getOpPtrVector().push_back(
4663 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
4665 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4666 scalar_field_ptrs->insert(std::make_pair(
4667 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4668 scalar_field_ptrs->insert(std::make_pair(
4669 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4670 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4671 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4672 sym_tensor_field_ptrs->insert(std::make_pair(
4673 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4674 sym_tensor_field_ptrs->insert(std::make_pair(
4675 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4676 sym_tensor_field_ptrs->insert(std::make_pair(
4677 "HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()));
4678 sym_tensor_field_ptrs->insert(
4679 std::make_pair(
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()));
4680 tensor_field_ptrs->insert(
4681 std::make_pair(
"GRAD", common_hencky_ptr->matGradPtr));
4682 tensor_field_ptrs->insert(std::make_pair(
4683 "FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()));
4685 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4686 scalar_field_ptrs->insert(std::make_pair(
4687 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4688 scalar_field_ptrs->insert(std::make_pair(
4689 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4690 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4691 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4692 sym_tensor_field_ptrs->insert(
4693 std::make_pair(
"STRAIN", common_plastic_ptr->mStrainPtr));
4694 sym_tensor_field_ptrs->insert(
4695 std::make_pair(
"STRESS", common_plastic_ptr->mStressPtr));
4696 sym_tensor_field_ptrs->insert(std::make_pair(
4697 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4698 sym_tensor_field_ptrs->insert(std::make_pair(
4699 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4707 field_eval_data,
simple->getDomainFEName());
4709 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4710 auto no_rule = [](
int,
int,
int) {
return -1; };
4712 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4713 field_eval_fe_ptr->getRuleHook = no_rule;
4716 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4722 const double) {
return 1.; };
4724 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4725 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4726 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4727 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4728 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4729 "TAU",
"T", 1, unity_2_args, unity_2_args, unity_3_args,
4732 auto dispGradPtr = common_hencky_ptr->matGradPtr;
4733 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4735 auto coeff_expansion_ptr = common_thermoelastic_ptr->getCoeffExpansionPtr();
4736 auto ref_temp_ptr = common_thermoelastic_ptr->getRefTempPtr();
4738 field_eval_fe_ptr->getOpPtrVector().push_back(
4740 field_eval_fe_ptr->getOpPtrVector().push_back(
4742 field_eval_fe_ptr->getOpPtrVector().push_back(
4744 field_eval_fe_ptr->getOpPtrVector().push_back(
4747 plasticMultiplierFieldPtr = common_plastic_ptr->getPlasticTauPtr();
4748 plasticStrainFieldPtr = common_plastic_ptr->getPlasticStrainPtr();
4752 field_eval_fe_ptr->getOpPtrVector().push_back(
4753 new typename H::template OpCalculateHenckyThermoPlasticStress<
SPACE_DIM,
4755 "U", tempFieldPtr, common_hencky_ptr, coeff_expansion_ptr,
4758 field_eval_fe_ptr->getOpPtrVector().push_back(
4760 common_hencky_ptr->getMatFirstPiolaStress(), stressFieldPtr));
4761 field_eval_fe_ptr->getOpPtrVector().push_back(
4764 field_eval_fe_ptr->getOpPtrVector().push_back(
4765 new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
4766 "U", common_hencky_ptr));
4767 stressFieldPtr = common_hencky_ptr->getMatFirstPiolaStress();
4768 strainFieldPtr = common_hencky_ptr->getMatLogC();
4772 auto set_time_monitor = [&](
auto dm,
auto solver) {
4776 dm, create_post_process_elements(), reactionFe, uXScatter, uYScatter,
4777 uZScatter, field_eval_coords, field_eval_data, scalar_field_ptrs,
4778 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
4779 boost::shared_ptr<ForcesAndSourcesCore> null;
4781 monitor_ptr, null, null);
4784 test_monitor_ptr->preProcessHook = [&]() {
4788 ->evalFEAtThePoint<SPACE_DIM>(
4789 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
4790 simple->getDomainFEName(), field_eval_data,
4791 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
4794 auto eval_num_vec =
createVectorMPI(mField.get_comm(), PETSC_DECIDE, 1);
4795 CHKERR VecZeroEntries(eval_num_vec);
4796 if (tempFieldPtr->size()) {
4797 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
4799 CHKERR VecAssemblyBegin(eval_num_vec);
4800 CHKERR VecAssemblyEnd(eval_num_vec);
4803 CHKERR VecSum(eval_num_vec, &eval_num);
4804 if (!(
int)eval_num) {
4806 "atom test %d failed: did not find elements to evaluate "
4807 "the field, check the coordinates",
4811 if (tempFieldPtr->size()) {
4813 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4814 <<
"Eval point T magnitude: " << t_temp;
4815 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4816 if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
4818 "atom test %d failed: wrong temperature value",
4821 if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
4823 "atom test %d failed: wrong temperature value",
4826 if (
atom_test == 5 && fabs(t_temp - 1) > 1e-2) {
4828 "atom test %d failed: wrong temperature value",
4832 if (
atom_test == 8 && fabs(t_temp - 0.5) > 1e-12) {
4834 "atom test %d failed: wrong temperature value",
atom_test);
4837 if (fluxFieldPtr->size1()) {
4839 auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
4840 auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
4841 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4842 <<
"Eval point FLUX magnitude: " << flux_mag;
4843 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4844 if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
4846 "atom test %d failed: wrong flux value",
atom_test);
4848 if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
4850 "atom test %d failed: wrong flux value",
atom_test);
4852 if (
atom_test == 5 && fabs(flux_mag) > 1e-6) {
4854 "atom test %d failed: wrong flux value",
atom_test);
4858 if (dispFieldPtr->size1()) {
4860 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
4861 auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
4862 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4863 <<
"Eval point U magnitude: " << disp_mag;
4864 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4865 if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
4867 "atom test %d failed: wrong displacement value",
4871 fabs(disp_mag - 0.00265) > 1e-5) {
4873 "atom test %d failed: wrong displacement value",
4877 fabs(t_disp(0) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5 &&
4878 fabs(t_disp(1) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5) {
4880 "atom test %d failed: wrong displacement value",
4885 if (strainFieldPtr->size1()) {
4888 getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
4889 auto t_strain_trace = t_strain(
i,
i);
4890 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4891 if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
4893 "atom test %d failed: wrong strain value",
atom_test);
4896 fabs(t_strain_trace - 0.00522) > 1e-5) {
4898 "atom test %d failed: wrong strain value",
atom_test);
4900 if ((
atom_test == 5) && fabs(t_strain_trace - 0.2) > 1e-5) {
4902 "atom test %d failed: wrong strain value",
atom_test);
4906 if (stressFieldPtr->size1()) {
4907 double von_mises_stress;
4908 auto getVonMisesStress = [&](
auto t_stress) {
4910 von_mises_stress = std::sqrt(
4912 ((t_stress(0, 0) - t_stress(1, 1)) *
4913 (t_stress(0, 0) - t_stress(1, 1)) +
4914 (
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
4915 (t_stress(1, 1) - t_stress(2, 2))
4917 (
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
4918 (t_stress(2, 2) - t_stress(0, 0))
4920 6 * (t_stress(0, 1) * t_stress(0, 1) +
4921 (
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
4922 (
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
4927 getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
4928 CHKERR getVonMisesStress(t_stress);
4931 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
4932 CHKERR getVonMisesStress(t_stress);
4934 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4935 <<
"Eval point von Mises Stress: " << von_mises_stress;
4936 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4937 if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
4939 "atom test %d failed: wrong von Mises stress value",
4942 if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
4944 "atom test %d failed: wrong von Mises stress value",
4947 if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
4949 "atom test %d failed: wrong von Mises stress value",
4952 if (
atom_test == 5 && fabs(von_mises_stress) > 5e-2) {
4954 "atom test %d failed: wrong von Mises stress value",
4959 if (plasticMultiplierFieldPtr->size()) {
4960 auto t_plastic_multiplier =
4962 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4963 <<
"Eval point TAU magnitude: " << t_plastic_multiplier;
4964 if (
atom_test == 8 && fabs(t_plastic_multiplier - 1.5) > 1e-12) {
4966 "atom test %d failed: wrong plastic multiplier value",
4970 if (plasticStrainFieldPtr->size1()) {
4973 auto t_plastic_strain =
4974 getFTensor2SymmetricFromMat<SPACE_DIM>(*plasticStrainFieldPtr);
4975 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4976 <<
"Eval point EP(0,0) = " << t_plastic_strain(0, 0)
4977 <<
", EP(0,1) = " << t_plastic_strain(0, 1)
4978 <<
", EP(1,1) = " << t_plastic_strain(1, 1);
4980 if (fabs(t_plastic_strain(0, 0) - 0.005) > 1e-12) {
4982 "atom test %d failed: wrong EP(0,0) value",
atom_test);
4984 if (fabs(t_plastic_strain(0, 1) - 0.025) > 1e-12) {
4986 "atom test %d failed: wrong EP(0,1) value",
atom_test);
4988 if (fabs(t_plastic_strain(1, 1) - 0.015) > 1e-12) {
4990 "atom test %d failed: wrong EP(1,1) value",
atom_test);
4998 auto null = boost::shared_ptr<FEMethod>();
5000 test_monitor_ptr, null);
5006 auto set_schur_pc = [&](
auto solver,
5007 boost::shared_ptr<SetUpSchur> &schur_ptr) {
5010 auto name_prb =
simple->getProblemName();
5016 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5021 for (
auto f : {
"U",
"FLUX"}) {
5033 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5039 for (
auto f : {
"SIGMA",
"EP",
"TAU",
"T"}) {
5044 for (
auto f : {
"EP",
"TAU",
"T"}) {
5054 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
5063 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5069 {simple->getDomainFEName(),
5092 {simple->getBoundaryFEName(),
5094 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
5104 {dm_schur, dm_block}, block_mat_data,
5106 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5114 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5115 auto block_mat_data =
5118 {{simple->getDomainFEName(),
5144 {dm_schur, dm_block}, block_mat_data,
5146 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr}, false
5153 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
5156 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
5157 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
5163 CHKERR schur_ptr->setUp(solver);
5169 auto dm =
simple->getDM();
5172 uXScatter = scatter_create(
D, 0);
5173 uYScatter = scatter_create(
D, 1);
5175 uZScatter = scatter_create(
D, 2);
5177 auto create_solver = [pip_mng]() {
5179 return pip_mng->createTSIM();
5181 return pip_mng->createTSIM2();
5191 CHKERR VecLoad(solution_vector, viewer);
5192 CHKERR PetscViewerDestroy(&viewer);
5197 auto solver = create_solver();
5199 auto active_pre_lhs = []() {
5206 auto active_post_lhs = [&]() {
5208 auto get_iter = [&]() {
5213 "Can not get iter");
5217 auto iter = get_iter();
5220 std::array<int, 5> activity_data;
5221 std::fill(activity_data.begin(), activity_data.end(), 0);
5223 activity_data.data(), activity_data.size(), MPI_INT,
5224 MPI_SUM, mField.get_comm());
5226 int &active_points = activity_data[0];
5227 int &avtive_full_elems = activity_data[1];
5228 int &avtive_elems = activity_data[2];
5229 int &nb_points = activity_data[3];
5230 int &nb_elements = activity_data[4];
5234 double proc_nb_points =
5235 100 *
static_cast<double>(active_points) / nb_points;
5236 double proc_nb_active =
5237 100 *
static_cast<double>(avtive_elems) / nb_elements;
5238 double proc_nb_full_active = 100;
5240 proc_nb_full_active =
5241 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
5244 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
5246 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
5247 iter, nb_points, active_points, proc_nb_points,
5248 avtive_elems, proc_nb_active, avtive_full_elems,
5249 proc_nb_full_active, iter);
5256 auto add_active_dofs_elem = [&](
auto dm) {
5258 auto fe_pre_proc = boost::make_shared<FEMethod>();
5259 fe_pre_proc->preProcessHook = active_pre_lhs;
5260 auto fe_post_proc = boost::make_shared<FEMethod>();
5261 fe_post_proc->postProcessHook = active_post_lhs;
5263 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
5264 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
5268 auto set_essential_bc = [&](
auto dm,
auto solver) {
5272 auto pre_proc_ptr = boost::make_shared<FEMethod>();
5273 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
5274 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
5277 auto disp_time_scale = boost::make_shared<TimeScale>();
5279 auto get_bc_hook_rhs = [
this, pre_proc_ptr, disp_time_scale]() {
5281 {disp_time_scale},
false);
5284 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
5286 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
5289 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
5291 mField, post_proc_rhs_ptr, 1.)();
5294 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
5296 mField, post_proc_lhs_ptr, 1.);
5298 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
5301 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
5302 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
5303 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
5304 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
5305 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
5313 CHKERR TSSetSolution(solver,
D);
5315 CHKERR TS2SetSolution(solver,
D, DD);
5318 auto set_up_adapt = [&](
auto solver) {
5322 CHKERR TSGetAdapt(solver, &adapt);
5326 CHKERR set_section_monitor(solver);
5327 CHKERR set_time_monitor(dm, solver);
5328 CHKERR set_up_adapt(solver);
5329 CHKERR TSSetFromOptions(solver);
5338 CHKERR add_active_dofs_elem(dm);
5339 boost::shared_ptr<SetUpSchur> schur_ptr;
5340 CHKERR set_schur_pc(solver, schur_ptr);
5341 CHKERR set_essential_bc(dm, solver);
5343 auto my_ctx = boost::make_shared<MyTsCtx>();
5348 CHKERR TSGetSNES(solver, &snes);
5354 auto my_rhs = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec F,
void *ctx) {
5364 double time_increment;
5366 if (time_increment <
min_dt) {
5368 "Minimum time increment exceeded");
5372 int error = system(
"rm ./out_snes_residual_iter_*.h5m > /dev/null 2>&1");
5378 "Cannot get timestep from TS object");
5382 "Minimum timestep exceeded");
5386 auto post_proc = [&](
auto dm,
auto f_res,
auto sol,
auto sol_dot,
5395 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
5397 auto &pip = post_proc_fe->getOpPtrVector();
5403 auto disp_res_mat = boost::make_shared<MatrixDouble>();
5404 auto tau_res_vec = boost::make_shared<VectorDouble>();
5405 auto plastic_strain_res_mat = boost::make_shared<MatrixDouble>();
5406 auto flux_res_mat = boost::make_shared<MatrixDouble>();
5407 auto temp_res_vec = boost::make_shared<VectorDouble>();
5410 "U", disp_res_mat, smart_f_res));
5414 "EP", plastic_strain_res_mat, smart_f_res));
5422 auto disp_mat = boost::make_shared<MatrixDouble>();
5423 auto tau_vec = boost::make_shared<VectorDouble>();
5424 auto plastic_strain_mat = boost::make_shared<MatrixDouble>();
5425 auto flux_mat = boost::make_shared<MatrixDouble>();
5426 auto temp_vec = boost::make_shared<VectorDouble>();
5431 "EP", plastic_strain_mat));
5438 auto disp_dot_mat = boost::make_shared<MatrixDouble>();
5439 auto tau_dot_vec = boost::make_shared<VectorDouble>();
5440 auto plastic_strain_dot_mat = boost::make_shared<MatrixDouble>();
5441 auto flux_dot_mat = boost::make_shared<MatrixDouble>();
5442 auto temp_dot_vec = boost::make_shared<VectorDouble>();
5445 "U", disp_dot_mat, smart_sol_dot));
5449 "EP", plastic_strain_dot_mat, smart_sol_dot));
5457 auto make_d_mat = [&]() {
5461 auto push_vol_ops = [&](
auto &pip) {
5466 const double) {
return 1.; };
5468 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
5469 common_thermoelastic_ptr, common_thermoplastic_ptr] =
5472 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
5473 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1.,
5474 unity_2_args, unity_2_args, unity_3_args, Sev::inform);
5476 if (common_hencky_ptr) {
5477 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
5479 "Wrong pointer for grad");
5482 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
5483 common_thermoplastic_ptr);
5486 auto push_vol_post_proc_ops = [&](
auto &pp_fe,
auto &&p) {
5489 auto &pip = pp_fe->getOpPtrVector();
5491 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
5494 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
5495 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
5497 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
5498 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
5500 auto u_ptr = boost::make_shared<MatrixDouble>();
5511 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5513 {{
"RESIDUAL_TAU", tau_res_vec},
5514 {
"RESIDUAL_T", temp_res_vec},
5517 {
"RATE_TAU", tau_dot_vec},
5518 {
"RATE_T", temp_dot_vec},
5519 {
"ISOTROPIC_HARDENING",
5520 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5522 common_plastic_ptr->getPlasticSurfacePtr()},
5523 {
"PLASTIC_MULTIPLIER",
5524 common_plastic_ptr->getPlasticTauPtr()},
5526 common_plastic_ptr->getPlasticSurfacePtr()},
5527 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5529 {{
"RESIDUAL_U", disp_res_mat},
5530 {
"RATE_U", disp_dot_mat},
5532 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5534 {{
"GRAD", common_hencky_ptr->matGradPtr},
5536 common_hencky_ptr->getMatFirstPiolaStress()}},
5538 {{
"RESIDUAL_EP", plastic_strain_res_mat},
5539 {
"RATE_EP", plastic_strain_dot_mat},
5541 common_plastic_ptr->getPlasticStrainPtr()},
5542 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
5543 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
5544 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
5556 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5558 {{
"RESIDUAL_TAU", tau_res_vec},
5559 {
"RESIDUAL_T", temp_res_vec},
5562 {
"RATE_TAU", tau_dot_vec},
5563 {
"RATE_T", temp_dot_vec},
5564 {
"ISOTROPIC_HARDENING",
5565 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5567 common_plastic_ptr->getPlasticSurfacePtr()},
5568 {
"PLASTIC_MULTIPLIER",
5569 common_plastic_ptr->getPlasticTauPtr()},
5571 common_plastic_ptr->getPlasticSurfacePtr()},
5572 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5574 {{
"RESIDUAL_U", disp_res_mat},
5578 {
"RATE_U", disp_dot_mat},
5580 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5584 {{
"RESIDUAL_PLASTIC_STRAIN", plastic_strain_res_mat},
5585 {
"PLASTIC_STRAIN", plastic_strain_mat},
5586 {
"RATE_PLASTIC_STRAIN", plastic_strain_dot_mat},
5587 {
"STRAIN", common_plastic_ptr->mStrainPtr},
5588 {
"STRESS", common_plastic_ptr->mStressPtr},
5590 common_plastic_ptr->getPlasticStrainPtr()},
5591 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
5601 CHK_MOAB_THROW(push_vol_post_proc_ops(post_proc_fe, push_vol_ops(pip)),
5602 "push_vol_post_proc_ops");
5607 post_proc_fe->writeFile(out_name);
5618 "out_snes_residual_iter_" +
5623 PetscBool is_output_residual_fields = PETSC_FALSE;
5625 &is_output_residual_fields, PETSC_NULLPTR);
5627 if (is_output_residual_fields == PETSC_TRUE) {
5630 CHKERR TSSetIFunction(solver, PETSC_NULLPTR, my_rhs, my_ctx.get());
5633 CHKERR TSSetDM(solver, dm);
5635 auto ts_pre_post_proc = boost::make_shared<TSPrePostProc>();
5639 ptr->ExRawPtr =
this;
5640 std::multimap<double, EntityHandle> no_el_q_map;
5641 Range no_flipped_els;
5642 std::vector<EntityHandle> no_new_connectivity;
5643 Tag no_th_spatial_coords;
5646 &mField, PETSC_FALSE, no_el_q_map,
5647 no_flipped_els, no_new_connectivity, no_th_spatial_coords};
5648 PetscBool rollback =
5652 CHKERR TSSetApplicationContext(solver, (
void *)ctx);
5661 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
5662 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
5663 CHKERR ptr->tsSetUp(solver);
5665 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
5666 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
5667 CHKERR TSSolve(solver, PETSC_NULLPTR);
5668 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
5680 #ifdef ENABLE_PYTHON_BINDING
5687 const char param_file[] =
"param_file.petsc";
5691 auto core_log = logging::core::get();
5721 DMType dm_name =
"DMMOFEM";
5726 moab::Core mb_instance;
5727 moab::Interface &moab = mb_instance;
5747 char meshFileName[255];
5749 meshFileName, 255, PETSC_NULLPTR);
5771 #ifdef ENABLE_PYTHON_BINDING
5772 if (Py_FinalizeEx() < 0) {
5785 :
SetUpSchur(), mField(m_field), subDM(sub_dm),
5786 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5789 "Is expected that schur matrix is not "
5790 "allocated. This is "
5791 "possible only is PC is set up twice");
5815 CHKERR TSGetSNES(solver, &snes);
5817 CHKERR SNESGetKSP(snes, &ksp);
5818 CHKERR KSPSetFromOptions(ksp);
5821 CHKERR KSPGetPC(ksp, &pc);
5822 PetscBool is_pcfs = PETSC_FALSE;
5823 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
5827 "Is expected that schur matrix is not "
5828 "allocated. This is "
5829 "possible only is PC is set up twice");
5837 CHKERR TSGetDM(solver, &solver_dm);
5838 CHKERR DMSetMatType(solver_dm, MATSHELL);
5845 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t, PetscReal
a,
5846 Mat
A, Mat
B,
void *ctx) {
5849 CHKERR TSSetIJacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5851 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec utt,
5852 PetscReal
a, PetscReal aa, Mat
A, Mat
B,
5856 CHKERR TSSetI2Jacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5858 CHKERR KSPSetOperators(ksp,
A, P);
5860 auto set_ops = [&]() {
5866 pip_mng->getOpBoundaryLhsPipeline().push_front(
5870 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5875 pip_mng->getOpDomainLhsPipeline().push_front(
5879 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5885 double eps_stab = 1e-4;
5891 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
5894 pip_mng->getOpBoundaryLhsPipeline().push_front(
5896 pip_mng->getOpBoundaryLhsPipeline().push_back(
5897 new OpMassStab(
"SIGMA",
"SIGMA", [eps_stab](
double,
double,
double) {
5902 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5907 pip_mng->getOpDomainLhsPipeline().push_front(
5911 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5919 auto set_assemble_elems = [&]() {
5921 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
5922 schur_asmb_pre_proc->preProcessHook = [
this]() {
5925 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble Begin";
5928 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
5930 schur_asmb_post_proc->postProcessHook = [
this, schur_asmb_post_proc]() {
5932 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble End";
5935 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
5936 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
5943 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
5944 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
5948 auto set_pc = [&]() {
5951 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
5955 auto set_diagonal_pc = [&]() {
5958 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
5959 auto get_pc = [](
auto ksp) {
5961 CHKERR KSPGetPC(ksp, &pc_raw);
5966 CHKERR PetscFree(subksp);
5972 CHKERR set_assemble_elems();
5976 CHKERR set_diagonal_pc();
5979 pip_mng->getOpBoundaryLhsPipeline().push_front(
5981 pip_mng->getOpBoundaryLhsPipeline().push_back(
5984 pip_mng->getOpDomainLhsPipeline().push_back(
5993boost::shared_ptr<SetUpSchur>
5997 return boost::shared_ptr<SetUpSchur>(
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
#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 ...
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
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.
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 createCommonData()
MoFEMErrorCode mechanicalBC(BitRefLevel bit, BitRefLevel mask)
[Initial conditions]
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)
MoFEMErrorCode thermalBC(BitRefLevel bit, BitRefLevel mask)
[Mechanical boundary conditions]
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.
PetscBool is_quasi_static
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.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
int ep_order
Order of ep files.
constexpr FieldSpace CONTACT_SPACE
#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]