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};
259 double y,
double z) {
268 double y,
double z) {
273 double y,
double z) {
return init_temp; };
291#include <HenckyOps.hpp>
292#include <PlasticOps.hpp>
293#include <PlasticNaturalBCs.hpp>
294#include <ThermoElasticOps.hpp>
295#include <FiniteThermalOps.hpp>
297#include <ThermalOps.hpp>
302#include <ThermalConvection.hpp>
303#include <ThermalRadiation.hpp>
306 #ifdef ENABLE_PYTHON_BINDING
307 #include <boost/python.hpp>
308 #include <boost/python/def.hpp>
309 #include <boost/python/numpy.hpp>
310namespace bp = boost::python;
311namespace np = boost::python::numpy;
320 #include <ContactOps.hpp>
332 std::string output_name,
int &counter = *(
new int(0))) {
335 auto create_post_process_elements = [&]() {
337 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
339 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
342 auto &pip = pp_fe->getOpPtrVector();
344 auto TAU_ptr = boost::make_shared<VectorDouble>();
346 auto T_ptr = boost::make_shared<VectorDouble>();
349 auto T_grad_ptr = boost::make_shared<MatrixDouble>();
352 auto U_ptr = boost::make_shared<MatrixDouble>();
354 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
358 auto EP_ptr = boost::make_shared<MatrixDouble>();
368 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
370 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
372 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}, {
"T_GRAD", T_grad_ptr}},
385 CHKERR push_vol_post_proc_ops(pp_fe);
390 CHKERR pp_fe->writeFile(
"out_" + std::to_string(counter) +
"_" +
391 output_name +
".h5m");
396 auto &post_proc_moab = pp_fe->getPostProcMesh();
397 auto file_name =
"out_" + std::to_string(counter) +
"_" + output_name +
400 <<
"Writing file " << file_name << std::endl;
401 CHKERR post_proc_moab.write_file(file_name.c_str(),
"VTK");
408 CHKERR create_post_process_elements();
414 Vec sol, std::string output_name) {
419 auto create_post_process_elements = [&]() {
422 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
423 auto &pip = pp_fe->getOpPtrVector();
425 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
428 auto &pip = pp_fe->getOpPtrVector();
430 auto TAU_ptr = boost::make_shared<VectorDouble>();
433 auto T_ptr = boost::make_shared<VectorDouble>();
436 auto U_ptr = boost::make_shared<MatrixDouble>();
439 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
441 "FLUX", FLUX_ptr, smart_sol));
443 auto EP_ptr = boost::make_shared<MatrixDouble>();
445 "EP", EP_ptr, smart_sol));
453 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
455 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
457 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}},
470 CHKERR push_vol_post_proc_ops(pp_fe);
473 CHKERR pp_fe->writeFile(
"out_" + output_name +
".h5m");
478 CHKERR create_post_process_elements();
484 const std::string &out_put_string,
485 const auto &out_put_quantity) {
491 for (
int i = 0;
i < size; ++
i) {
494 std::cout <<
"Proc " << rank <<
" " + out_put_string +
" "
495 << out_put_quantity << std::endl;
499 CHKERR PetscBarrier(NULL);
534 IT>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
544auto save_range = [](moab::Interface &moab,
const std::string name,
548 CHKERR moab.add_entities(*out_meshset, r);
549 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
620 int order_row,
int order_col,
624 constexpr int numNodes = 3;
625 constexpr int numEdges = 3;
627 auto &m_field = fe_raw_ptr->
mField;
628 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
629 auto fe_handle = fe_ptr->getFEEntityHandle();
631 auto set_base_quadrature = [&]() {
633 int rule = 2 * (order_data + 1);
643 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
644 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
645 &fe_ptr->gaussPts(0, 0), 1);
646 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
647 &fe_ptr->gaussPts(1, 0), 1);
649 &fe_ptr->gaussPts(2, 0), 1);
650 auto &data = fe_ptr->dataOnElement[
H1];
651 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
654 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
655 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
657 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
660 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
669 CHKERR set_base_quadrature();
671 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
673 fe_ptr->gaussPts.swap(ref_gauss_pts);
674 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
675 auto &data = fe_ptr->dataOnElement[
H1];
676 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3);
678 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
680 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
684 auto refine_quadrature = [&]() {
688 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
690 for (
int nn = 0; nn != numNodes; nn++)
691 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
693 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
697 Range ref_tri(tri, tri);
699 CHKERR m_field_ref.
get_moab().get_adjacencies(ref_tri, 1,
true, edges,
700 moab::Interface::UNION);
704 Range nodes_at_front;
705 for (
int nn = 0; nn != numNodes; nn++) {
707 CHKERR moab_ref.side_element(tri, 0, nn, ent);
708 nodes_at_front.insert(ent);
712 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
713 for (
int ee = 0; ee != numEdges; ee++) {
715 CHKERR moab_ref.side_element(tri, 1, ee, ent);
716 CHKERR moab_ref.add_entities(meshset, &ent, 1);
723 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(0),
731 CHKERR m_ref->addVerticesInTheMiddleOfEdges(ref_edges,
736 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
737 meshset, MBEDGE,
true);
739 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
740 meshset, MBTRI,
true);
743 Range output_ref_tris;
745 ->getEntitiesByTypeAndRefLevel(
752 MatrixDouble ref_coords(output_ref_tris.size(), 9,
false);
754 for (Range::iterator tit = output_ref_tris.begin();
755 tit != output_ref_tris.end(); tit++, tt++) {
758 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
759 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
762 auto &data = fe_ptr->dataOnElement[
H1];
763 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
764 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
767 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
768 double *tri_coords = &ref_coords(tt, 0);
771 auto det = t_normal.
l2();
772 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
773 for (
int dd = 0; dd != 2; dd++) {
774 ref_gauss_pts(dd, gg) = shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
775 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
776 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
779 << ref_gauss_pts(0, gg) <<
", " << ref_gauss_pts(1, gg);
780 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
786 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
788 std::bitset<numNodes> all_nodes;
789 for (
auto nn = 0; nn != numNodes; ++nn) {
799 CHKERR refine_quadrature();
828 boost::make_shared<VectorDouble>();
830 boost::make_shared<MatrixDouble>();
832 boost::make_shared<MatrixDouble>();
834 boost::make_shared<MatrixDouble>();
836 boost::make_shared<MatrixDouble>();
838 boost::make_shared<MatrixDouble>();
840 boost::make_shared<VectorDouble>();
842 boost::make_shared<MatrixDouble>();
852 #ifdef ENABLE_PYTHON_BINDING
853 boost::shared_ptr<ContactOps::SDFPython> sdfPythonPtr;
857 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
860 std::string thermal_block_name, std::string thermoelastic_block_name,
861 std::string thermoplastic_block_name,
Pip &pip, std::string u,
862 std::string ep, std::string tau, std::string temperature) {
868 typename B::template OpGradTimesSymTensor<1, DIM, DIM>;
876 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
877 common_thermoelastic_ptr, common_thermoplastic_ptr] =
878 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
879 m_field, block_name, thermal_block_name, thermoelastic_block_name,
880 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
884 auto m_D_ptr = common_hencky_ptr->matDPtr;
887 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
889 tau, common_plastic_ptr->getPlasticTauDotPtr()));
891 temperature, common_thermoplastic_ptr->getTempPtr()));
893 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
894 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
895 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
899 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
900 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
901 common_thermoelastic_ptr->getCoeffExpansionPtr(),
902 common_thermoelastic_ptr->getRefTempPtr()));
905 if (common_hencky_ptr) {
907 u, common_hencky_ptr->getMatFirstPiolaStress()));
913 auto inelastic_heat_frac_ptr =
914 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
917 return (*inelastic_heat_frac_ptr);
923 temperature, common_hencky_ptr->getMatHenckyStress(),
928 typename P::template Assembly<A>::template OpCalculateConstraintsRhs<I>(
929 tau, common_plastic_ptr, m_D_ptr));
932 typename P::template Assembly<A>::template OpCalculatePlasticFlowRhs<
933 DIM,
I>(ep, common_plastic_ptr, m_D_ptr));
938 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
941 std::string thermal_block_name, std::string thermoelastic_block_name,
942 std::string thermoplastic_block_name,
Pip &pip, std::string u,
943 std::string ep, std::string tau, std::string temperature) {
951 using OpKPiola =
typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
952 using OpKCauchy =
typename B::template OpGradSymTensorGrad<1, DIM, DIM, 0>;
956 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
957 common_thermoelastic_ptr, common_thermoplastic_ptr] =
958 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
959 m_field, block_name, thermal_block_name, thermoelastic_block_name,
960 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
964 auto m_D_ptr = common_hencky_ptr->matDPtr;
967 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
969 tau, common_plastic_ptr->getPlasticTauDotPtr()));
970 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
971 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
973 if (common_hencky_ptr) {
974 pip.push_back(
new typename H::template OpHenckyTangent<DIM, I, 0>(
975 u, common_hencky_ptr, m_D_ptr));
976 pip.push_back(
new OpKPiola(u, u, common_hencky_ptr->getMatTangent()));
978 new typename P::template Assembly<A>::
979 template OpCalculatePlasticInternalForceLhs_LogStrain_dEP<DIM, I>(
980 u, ep, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
982 pip.push_back(
new OpKCauchy(u, u, m_D_ptr));
983 pip.push_back(
new typename P::template Assembly<A>::
984 template OpCalculatePlasticInternalForceLhs_dEP<DIM, I>(
985 u, ep, common_plastic_ptr, m_D_ptr));
988 if (common_hencky_ptr) {
990 new typename P::template Assembly<A>::
991 template OpCalculateConstraintsLhs_LogStrain_dU<DIM, I>(
992 tau, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
994 new typename P::template Assembly<A>::
995 template OpCalculatePlasticFlowLhs_LogStrain_dU<DIM, I>(
996 ep, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
998 pip.push_back(
new typename P::template Assembly<A>::
999 template OpCalculateConstraintsLhs_dU<DIM, I>(
1000 tau, u, common_plastic_ptr, m_D_ptr));
1001 pip.push_back(
new typename P::template Assembly<A>::
1002 template OpCalculatePlasticFlowLhs_dU<DIM, I>(
1003 ep, u, common_plastic_ptr, m_D_ptr));
1006 pip.push_back(
new typename P::template Assembly<A>::
1007 template OpCalculatePlasticFlowLhs_dEP<DIM, I>(
1008 ep, ep, common_plastic_ptr, m_D_ptr));
1009 pip.push_back(
new typename P::template Assembly<A>::
1010 template OpCalculatePlasticFlowLhs_dTAU<DIM, I>(
1011 ep, tau, common_plastic_ptr, m_D_ptr));
1014 ep, temperature, common_thermoplastic_ptr));
1015 pip.push_back(
new typename P::template Assembly<A>::
1016 template OpCalculateConstraintsLhs_dEP<DIM, I>(
1017 tau, ep, common_plastic_ptr, m_D_ptr));
1019 new typename P::template Assembly<
1020 A>::template OpCalculateConstraintsLhs_dTAU<I>(tau, tau,
1021 common_plastic_ptr));
1024 pip.push_back(
new typename H::template OpCalculateHenckyThermalStressdT<
1026 u, temperature, common_hencky_ptr,
1027 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1029 auto inelastic_heat_frac_ptr =
1030 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1033 return (*inelastic_heat_frac_ptr);
1039 temperature, temperature, common_hencky_ptr, common_plastic_ptr,
1041 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1046 temperature, ep, common_hencky_ptr, common_plastic_ptr,
1052 temperature, u, common_hencky_ptr, common_plastic_ptr,
1056 tau, temperature, common_thermoplastic_ptr));
1061 template <
int DIM, IntegrationType I,
typename DomainEleOp>
1064 std::string thermal_block_name, std::string thermoelastic_block_name,
1065 std::string thermoplastic_block_name,
1066 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1067 std::string u, std::string ep, std::string tau, std::string temperature,
1071 bool with_rates =
true) {
1075 auto common_plastic_ptr = boost::make_shared<PlasticOps::CommonData>();
1076 auto common_thermal_ptr =
1077 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
1078 auto common_thermoelastic_ptr =
1079 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
1080 auto common_thermoplastic_ptr =
1081 boost::make_shared<ThermoPlasticOps::ThermoPlasticBlockedParameters>();
1083 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
1084 auto make_d_mat = []() {
1088 common_plastic_ptr->mDPtr = boost::make_shared<MatrixDouble>();
1089 common_plastic_ptr->mGradPtr = boost::make_shared<MatrixDouble>();
1090 common_plastic_ptr->mStrainPtr = boost::make_shared<MatrixDouble>();
1091 common_plastic_ptr->mStressPtr = boost::make_shared<MatrixDouble>();
1093 auto m_D_ptr = common_plastic_ptr->mDPtr;
1096 m_field, plastic_block_name, pip, m_D_ptr,
1097 common_plastic_ptr->getParamsPtr(),
scale, sev),
1098 "add mat block plastic ops");
1100 m_field, pip, thermal_block_name, common_thermal_ptr,
1105 "add mat block thermal ops");
1107 m_field, pip, thermoelastic_block_name,
1110 "add mat block thermal ops");
1112 m_field, pip, thermoplastic_block_name,
1113 common_thermoplastic_ptr, common_thermal_ptr, sev,
1115 "add mat block thermoplastic ops");
1116 auto common_hencky_ptr =
1117 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1118 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform,
scale);
1120 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1123 tau, common_plastic_ptr->getPlasticTauPtr()));
1125 ep, common_plastic_ptr->getPlasticStrainPtr()));
1127 u, common_plastic_ptr->mGradPtr));
1130 temperature, common_thermoplastic_ptr->getTempPtr()));
1132 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
1134 common_plastic_ptr->mGradPtr = common_hencky_ptr->matGradPtr;
1135 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1136 common_hencky_ptr->matLogCPlastic =
1137 common_plastic_ptr->getPlasticStrainPtr();
1138 common_plastic_ptr->mStrainPtr = common_hencky_ptr->getMatLogC();
1139 common_plastic_ptr->mStressPtr = common_hencky_ptr->getMatHenckyStress();
1143 pip.push_back(
new typename H::template OpCalculateEigenVals<DIM, I>(
1144 u, common_hencky_ptr));
1146 new typename H::template OpCalculateLogC<DIM, I>(u, common_hencky_ptr));
1147 pip.push_back(
new typename H::template OpCalculateLogC_dC<DIM, I>(
1148 u, common_hencky_ptr));
1152 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1153 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1154 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1155 common_thermoelastic_ptr->getRefTempPtr()));
1156 pip.push_back(
new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
1157 u, common_hencky_ptr));
1159 pip.push_back(
new typename P::template OpCalculatePlasticSurface<DIM, I>(
1160 u, common_plastic_ptr));
1162 pip.push_back(
new typename P::template OpCalculatePlasticHardening<DIM, I>(
1163 u, common_plastic_ptr, common_thermoplastic_ptr));
1165 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
1166 common_thermal_ptr, common_thermoelastic_ptr,
1167 common_thermoplastic_ptr);
1177 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Run step pre proc";
1179 auto &m_field = ptr->ExRawPtr->mField;
1181 auto &moab = m_field.get_moab();
1184 auto get_norm = [&](
auto x) {
1186 CHKERR VecNorm(x, NORM_2, &nrm);
1190 auto save_range = [](moab::Interface &moab,
const std::string name,
1194 CHKERR moab.add_entities(*out_meshset, r);
1195 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(),
1200 auto dm =
simple->getDM();
1204 CHKERR VecGhostUpdateBegin(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1205 CHKERR VecGhostUpdateEnd(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1209 Range new_elements, all_old_els, flipped_els, adj_edges;
1215 auto improve_element_quality = [&]() {
1223 double spatial_coords[9], material_coords[9];
1224 Tag th_spatial_coords;
1225 std::multimap<double, EntityHandle> el_q_map, el_J_increased_map,
1228 auto get_element_quality_measures = [&]() {
1232 CHKERR moab.get_entities_by_type(0, MBVERTEX, verts);
1233 std::vector<double> coords(verts.size() * 3);
1234 CHKERR moab.get_coords(verts, coords.data());
1235 auto t_x = getFTensor1FromPtr<3>(coords.data());
1237 auto save_tag = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
1240 auto field_data = ent_ptr->getEntFieldData();
1243 t_u = {field_data[0], field_data[1], 0.0};
1245 t_u = {field_data[0], field_data[1], field_data[2]};
1253 m_field.getInterface<
FieldBlas>()->fieldLambdaOnEntities(save_tag,
"U",
1255 double def_coord[3] = {0.0, 0.0, 0.0};
1256 CHKERR moab.tag_get_handle(
"SpatialCoord", 3, MB_TYPE_DOUBLE,
1258 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
1259 CHKERR moab.tag_set_data(th_spatial_coords, verts, coords.data());
1265 Range::iterator nit = all_els.begin();
1266 for (
int gg = 0; nit != all_els.end(); nit++, gg++) {
1267 CHKERR m_field.get_moab().get_connectivity(*nit, conn, num_nodes,
1270 CHKERR moab.get_coords(conn, num_nodes, material_coords);
1271 CHKERR moab.tag_get_data(th_spatial_coords, conn, num_nodes,
1275 Tools::triArea(spatial_coords) / Tools::triArea(material_coords);
1278 <<
"Element: " << *nit <<
" Jacobian: " <<
J;
1280 double q = Tools::areaLengthQuality(spatial_coords);
1281 if (!std::isnormal(q))
1284 if (
J < 0.1 && q < qual_tol && q > 0) {
1285 el_J_decreased_map.insert(std::pair<double, EntityHandle>(
J, *nit));
1286 }
else if (
J > 3.0 && q < qual_tol && q > 0) {
1287 el_J_increased_map.insert(std::pair<double, EntityHandle>(
J, *nit));
1288 }
else if (q < qual_tol && q > 0) {
1289 el_q_map.insert(std::pair<double, EntityHandle>(q, *nit));
1294 CHKERR m_field.getInterface<
Tools>()->minElQuality<SPACE_DIM>(
1295 all_els, min_q, th_spatial_coords);
1297 <<
"Old minimum element quality: " << min_q;
1299 auto pair = el_q_map.begin();
1301 <<
"New minimum element quality: " << pair->first;
1308 CHKERR get_element_quality_measures();
1310 std::vector<EntityHandle> new_connectivity;
1312 auto get_string_from_vector = [](
auto vec) {
1313 std::string output_string =
"";
1314 for (
auto el : vec) {
1315 output_string += std::to_string(el) +
" ";
1317 return output_string;
1320 std::string improved_reasons =
"";
1356 auto perform_edge_flip = [&]() {
1359 for (
auto pair = el_q_map.begin(); pair != el_q_map.end(); ++pair) {
1360 double quality = pair->first;
1362 element.insert(pair->second);
1363 if (!flipped_els.contains(element)) {
1366 CHKERR m_field.get_moab().get_adjacencies(element, 1,
false, edges);
1371 double longest_edge_length = 0;
1372 for (
auto edge : edges) {
1373 edge_length = m_field.getInterface<
Tools>()->getEdgeLength(edge);
1374 if (edge_length > longest_edge_length) {
1375 longest_edge_length = edge_length;
1376 longest_edge = edge;
1381 <<
"Edge flip longest edge length: " << longest_edge_length
1382 <<
" for edge: " << longest_edge;
1384 auto get_skin = [&]() {
1388 Skinner skin(&m_field.get_moab());
1390 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
1395 Range boundary_ents;
1396 ParallelComm *pcomm =
1397 ParallelComm::get_pcomm(&m_field.get_moab(),
MYPCOMM_INDEX);
1398 CHKERR pcomm->filter_pstatus(skin,
1399 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1400 PSTATUS_NOT, -1, &boundary_ents);
1401 return boundary_ents;
1404 Range boundary_ents = get_skin();
1407 <<
"Boundary entities: " << boundary_ents;
1409 if (boundary_ents.contains(
Range(longest_edge, longest_edge)))
1413 Range flip_candidate_els;
1414 CHKERR m_field.get_moab().get_adjacencies(
1415 &longest_edge, 1,
SPACE_DIM,
false, flip_candidate_els);
1419 flip_candidate_els);
1421 Range neighbouring_el = subtract(flip_candidate_els, element);
1423 ->filterEntitiesByRefLevel(
1427 if (neighbouring_el.size() != 1) {
1430 "Should be 1 neighbouring element to bad element for edge "
1431 "flip. Instead, there are %d",
1432 neighbouring_el.size());
1437 <<
"flip_candidate_els: " << flip_candidate_els;
1439 <<
"Neighbouring element: " << neighbouring_el;
1441 if (flipped_els.contains(neighbouring_el))
1445 std::vector<EntityHandle> neighbouring_nodes;
1446 CHKERR m_field.get_moab().get_connectivity(
1447 &neighbouring_el.front(), 1, neighbouring_nodes,
true);
1449 std::vector<EntityHandle> element_nodes;
1450 CHKERR m_field.get_moab().get_connectivity(&element.front(), 1,
1451 element_nodes,
true);
1453 CHKERR moab.tag_get_data(th_spatial_coords,
1454 &neighbouring_nodes.front(), 3,
1457 double neighbour_qual = Tools::areaLengthQuality(spatial_coords);
1458 if (!std::isnormal(neighbour_qual))
1459 neighbour_qual = -2;
1465 <<
"Element nodes before swap: "
1466 << get_string_from_vector(element_nodes);
1468 <<
"Neighbouring nodes before swap: "
1469 << get_string_from_vector(neighbouring_nodes);
1473 std::vector<EntityHandle> reversed_neighbouring_nodes =
1475 std::reverse(reversed_neighbouring_nodes.begin(),
1476 reversed_neighbouring_nodes.end());
1478 int num_matches = 0;
1479 std::vector<bool> mismatch_mask(element_nodes.size());
1480 int loop_counter = 0;
1481 while (num_matches != 2) {
1483 std::rotate(reversed_neighbouring_nodes.begin(),
1484 reversed_neighbouring_nodes.begin() + 1,
1485 reversed_neighbouring_nodes.end());
1487 std::transform(element_nodes.begin(), element_nodes.end(),
1488 reversed_neighbouring_nodes.begin(),
1489 mismatch_mask.begin(),
1490 std::equal_to<EntityHandle>());
1493 std::count(mismatch_mask.begin(), mismatch_mask.end(),
true);
1496 if (loop_counter > 3) {
1498 "Not found matching nodes for edge flipping");
1503 std::vector<EntityHandle> matched_elements(element_nodes.size());
1504 std::transform(element_nodes.begin(), element_nodes.end(),
1505 mismatch_mask.begin(), matched_elements.begin(),
1512 matched_elements.erase(std::remove(matched_elements.begin(),
1513 matched_elements.end(), -1),
1514 matched_elements.end());
1517 std::vector<EntityHandle> mismatched_elements(element_nodes.size()),
1518 neighbouring_mismatched_elements(neighbouring_nodes.size());
1519 std::transform(element_nodes.begin(), element_nodes.end(),
1520 mismatch_mask.begin(), mismatched_elements.begin(),
1526 reversed_neighbouring_nodes.begin(),
1527 reversed_neighbouring_nodes.end(), mismatch_mask.begin(),
1528 neighbouring_mismatched_elements.begin(),
1530 return match ? -1 : el;
1534 mismatched_elements.erase(std::remove(mismatched_elements.begin(),
1535 mismatched_elements.end(),
1537 mismatched_elements.end());
1538 neighbouring_mismatched_elements.erase(
1539 std::remove(neighbouring_mismatched_elements.begin(),
1540 neighbouring_mismatched_elements.end(), -1),
1541 neighbouring_mismatched_elements.end());
1543 mismatched_elements.insert(mismatched_elements.end(),
1544 neighbouring_mismatched_elements.begin(),
1545 neighbouring_mismatched_elements.end());
1548 <<
"Reversed neighbouring nodes: "
1549 << get_string_from_vector(reversed_neighbouring_nodes);
1552 <<
"mismatch mask: " << get_string_from_vector(mismatch_mask);
1555 <<
"Old nodes are: "
1556 << get_string_from_vector(matched_elements);
1559 <<
"New nodes are: "
1560 << get_string_from_vector(mismatched_elements);
1562 auto replace_correct_nodes =
1563 [](std::vector<EntityHandle> &ABC,
1564 std::vector<EntityHandle> &DBA,
1565 const std::vector<EntityHandle> &AB,
1566 const std::vector<EntityHandle> &CD) {
1568 std::vector<std::vector<EntityHandle>> results;
1570 for (
int i = 0;
i < 2; ++
i) {
1571 for (
int j = 0;
j < 2; ++
j) {
1573 if (std::find(ABC.begin(), ABC.end(), CD[
j]) ==
1575 std::vector<EntityHandle> tmp = ABC;
1577 auto it = std::find(tmp.begin(), tmp.end(), AB[
i]);
1578 if (it != tmp.end()) {
1580 results.push_back(tmp);
1586 if (results.size() != 2) {
1589 "Failed to find two valid vertex replacements for edge "
1599 CHKERR replace_correct_nodes(element_nodes, neighbouring_nodes,
1600 matched_elements, mismatched_elements);
1603 <<
"Element nodes after swap: "
1604 << get_string_from_vector(element_nodes);
1606 <<
"Neighbouring nodes after swap: "
1607 << get_string_from_vector(neighbouring_nodes);
1610 CHKERR moab.tag_get_data(th_spatial_coords, &element_nodes.front(),
1613 double new_qual = Tools::areaLengthQuality(spatial_coords);
1614 if (!std::isnormal(new_qual))
1618 auto check_normal_direction = [&]() {
1621 auto t_correct_normal =
1623 auto [new_area, t_new_normal] =
1624 Tools::triAreaAndNormal(spatial_coords);
1626 t_diff(
i) = t_new_normal(
i) - t_correct_normal(
i);
1627 if (t_diff(
i) * t_diff(
i) > 1e-6) {
1630 "Direction of element to be created is wrong orientation");
1635 CHKERR check_normal_direction();
1638 CHKERR moab.tag_get_data(th_spatial_coords,
1639 &neighbouring_nodes.front(), 3,
1642 double new_neighbour_qual =
1643 Tools::areaLengthQuality(spatial_coords);
1644 if (!std::isnormal(new_neighbour_qual))
1645 new_neighbour_qual = -2;
1648 CHKERR check_normal_direction();
1652 if (std::min(new_qual, new_neighbour_qual) >
1653 std::min(quality, neighbour_qual)) {
1655 <<
"Element quality improved from " << quality <<
" and "
1656 << neighbour_qual <<
" to " << new_qual <<
" and "
1657 << new_neighbour_qual <<
" for elements" << element <<
" and "
1661 flipped_els.merge(flip_candidate_els);
1662 new_connectivity.insert(new_connectivity.end(),
1663 element_nodes.begin(),
1664 element_nodes.end());
1665 new_connectivity.insert(new_connectivity.end(),
1666 neighbouring_nodes.begin(),
1667 neighbouring_nodes.end());
1672 improved_reasons +=
", Edge flipping";
1678 CHKERR perform_edge_flip();
1681 <<
"Flipped elements: " << flipped_els;
1683 <<
"New connectivity: " << get_string_from_vector(new_connectivity);
1687 CHKERR moab.get_entities_by_type(0, MBTRI, all_old_els,
true);
1696 <<
"Elements added to old_mesh: " << all_old_els;
1698 Range old_mesh_range;
1700 old_mesh_bitreflevel,
BitRefLevel().set(), old_mesh_range, 1);
1702 <<
"Old mesh range: " << old_mesh_range;
1705 (boost::format(
"old_mesh.vtk")).str(), old_mesh_range);
1717 Range remaining_els_after_flip = subtract(all_old_els, flipped_els);
1722 <<
"Non-flipped elements: " << remaining_els_after_flip;
1724 ReadUtilIface *read_util;
1725 CHKERR m_field.get_moab().query_interface(read_util);
1727 const int num_ele = flipped_els.size();
1728 int num_nod_per_ele;
1729 EntityType ent_type;
1732 num_nod_per_ele = 3;
1735 num_nod_per_ele = 4;
1742 if (flipped_els.size() > 0) {
1744 auto new_conn = new_connectivity.begin();
1745 for (
auto e = 0; e != num_ele; ++e) {
1747 for (
int n = 0;
n < num_nod_per_ele; ++
n) {
1748 conn[
n] = *new_conn;
1753 CHKERR m_field.get_moab().get_adjacencies(conn, num_nod_per_ele,
1755 if (adj_ele.size()) {
1756 if (adj_ele.size() != 1) {
1758 "Element duplication");
1760 new_ele = adj_ele.front();
1763 CHKERR m_field.get_moab().create_element(ent_type, conn,
1764 num_nod_per_ele, new_ele);
1766 new_elements.insert(new_ele);
1783 <<
"New elements: " << new_elements;
1804 <<
"New elements from before: " << remaining_els_after_flip;
1806 Range new_elements_nodes_vertices;
1807 new_elements_nodes_vertices.merge(new_elements);
1808 new_elements_nodes_vertices.merge(remaining_els_after_flip);
1810 Range new_edges_range;
1811 CHKERR moab.get_adjacencies(new_elements_nodes_vertices, 1,
true,
1812 new_edges_range, moab::Interface::UNION);
1813 Range new_vertices_range;
1814 CHKERR moab.get_adjacencies(new_elements_nodes_vertices, 0,
true,
1815 new_vertices_range, moab::Interface::UNION);
1817 new_elements_nodes_vertices.merge(new_edges_range);
1818 new_elements_nodes_vertices.merge(new_vertices_range);
1821 <<
"New mesh after flip: " << new_elements_nodes_vertices;
1824 new_elements_nodes_vertices, new_mesh_bitreflevel,
false);
1827 Range new_mesh_range;
1829 new_mesh_bitreflevel,
BitRefLevel().set(), new_mesh_range, 1);
1831 <<
"New mesh range: " << new_mesh_range;
1833 (boost::format(
"new_mesh.vtk")).str(),
1838 improved_reasons.erase(0, 2);
1841 <<
"Improved mesh quality by: " << improved_reasons;
1849 auto solve_equil_sub_problem = [&]() {
1851 if (flipped_els.size() == 0) {
1861 auto U_ptr = boost::make_shared<MatrixDouble>();
1862 auto EP_ptr = boost::make_shared<MatrixDouble>();
1863 auto TAU_ptr = boost::make_shared<VectorDouble>();
1864 auto T_ptr = boost::make_shared<VectorDouble>();
1868 auto post_proc = [&](
auto dm) {
1871 auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
1874 post_proc_fe->getOpPtrVector(), {H1, L2, HDIV},
"GEOMETRY");
1881 post_proc_fe->getOpPtrVector().push_back(
1886 post_proc_fe->getOpPtrVector().push_back(
1888 post_proc_fe->getOpPtrVector().push_back(
1890 post_proc_fe->getOpPtrVector().push_back(
1893 post_proc_fe->getOpPtrVector().push_back(
1895 new OpPPMap(post_proc_fe->getPostProcMesh(),
1896 post_proc_fe->getMapGaussPts(),
1914 CHKERR post_proc_fe->writeFile(
"out_equilibrate.h5m");
1919 auto solve_equilibrate_solution = [&]() {
1922 auto set_domain_rhs = [&](
auto &pip) {
1931 typename B::template OpGradTimesSymTensor<1,
SPACE_DIM,
1938 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1939 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1942 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1943 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1948 auto m_D_ptr = common_plastic_ptr->mDPtr;
1951 "T", common_thermoplastic_ptr->getTempPtr()));
1954 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1956 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1959 if (common_hencky_ptr) {
1961 "U", common_hencky_ptr->getMatFirstPiolaStress()));
1970 auto set_domain_lhs = [&](
auto &pip) {
1981 typename B::template OpGradTensorGrad<1, SPACE_DIM, SPACE_DIM, 1>;
1988 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1989 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1992 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1993 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1998 auto m_D_ptr = common_plastic_ptr->mDPtr;
2002 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
2004 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
2006 if (common_hencky_ptr) {
2009 new typename H::template OpHenckyTangent<SPACE_DIM, IT, 0>(
2010 "U", common_hencky_ptr, m_D_ptr));
2012 new OpKPiola(
"U",
"U", common_hencky_ptr->getMatTangent()));
2020 pip.push_back(
new OpKCauchy(
"U",
"U", m_D_ptr));
2040 auto dm_sub =
createDM(m_field.get_comm(),
"DMMOFEM");
2044 for (
auto f : {
"U",
"EP",
"TAU",
"T"}) {
2052 auto sub_dm = create_sub_dm(
simple->getDM());
2054 auto fe_rhs = boost::make_shared<DomainEle>(m_field);
2055 auto fe_lhs = boost::make_shared<DomainEle>(m_field);
2057 fe_rhs->getRuleHook = vol_rule;
2058 fe_lhs->getRuleHook = vol_rule;
2059 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
2060 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
2062 auto bc_mng = m_field.getInterface<
BcManager>();
2067 auto &bc_map = bc_mng->getBcMapByBlockName();
2068 for (
auto bc : bc_map)
2069 MOFEM_LOG(
"PLASTICITY",
Sev::verbose) <<
"Marker " << bc.first;
2071 auto time_scale = boost::make_shared<TimeScale>(
2072 "",
false, [](
const double) {
return 1; });
2073 auto def_time_scale = [time_scale](
const double time) {
2074 return (!time_scale->argFileScale) ? time : 1;
2076 auto def_file_name = [time_scale](
const std::string &&name) {
2077 return (!time_scale->argFileScale) ? name :
"";
2079 auto time_displacement_scaling = boost::make_shared<TimeScale>(
2080 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
2082 auto pre_proc_ptr = boost::make_shared<FEMethod>();
2083 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
2084 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
2086 PetscReal current_time;
2087 TSGetTime(ts, ¤t_time);
2088 pre_proc_ptr->ts_t = current_time;
2091 auto get_bc_hook_rhs = [&]() {
2093 ptr->ExRawPtr->mField, pre_proc_ptr,
2094 {time_scale, time_displacement_scaling});
2097 auto get_bc_hook_lhs = [&]() {
2099 ptr->ExRawPtr->mField, pre_proc_ptr,
2100 {time_scale, time_displacement_scaling});
2104 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
2105 pre_proc_ptr->preProcessHook = get_bc_hook_lhs();
2107 auto get_post_proc_hook_rhs = [&]() {
2110 ptr->ExRawPtr->mField, post_proc_rhs_ptr,
nullptr,
2113 ptr->ExRawPtr->mField, post_proc_rhs_ptr, 1.)();
2116 auto get_post_proc_hook_lhs = [&]() {
2118 ptr->ExRawPtr->mField, post_proc_lhs_ptr, 1.);
2120 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
2121 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
2124 snes_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_ptr);
2125 snes_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_ptr);
2126 snes_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs_ptr);
2127 snes_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs_ptr);
2129 auto null_fe = boost::shared_ptr<FEMethod>();
2148 CHKERR SNESSetDM(snes, sub_dm);
2149 CHKERR SNESSetFromOptions(snes);
2154 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
2155 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
2160 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);
2162 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
2163 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
2170 CHKERR solve_equilibrate_solution();
2174 <<
"Equilibrated solution after mapping";
2179 CHKERR improve_element_quality();
2180 if (flipped_els.size() > 0) {
2183 CHKERR TSGetApplicationContext(ts, (
void **)&ctx);
2197 CHKERR PetscBarrier((PetscObject)ts);
2209 auto &m_field = ptr->ExRawPtr->mField;
2230 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
2231 std::string thermoplastic_block_name,
2232 boost::shared_ptr<ThermoPlasticOps::ThermoPlasticBlockedParameters>
2234 boost::shared_ptr<ThermoElasticOps::BlockedThermalParameters>
2235 &blockedThermalParamsPtr,
2239 struct OpMatThermoPlasticBlocks :
public DomainEleOp {
2240 OpMatThermoPlasticBlocks(
2241 boost::shared_ptr<double> omega_0_ptr,
2242 boost::shared_ptr<double> omega_h_ptr,
2243 boost::shared_ptr<double> inelastic_heat_fraction_ptr,
2244 boost::shared_ptr<double> temp_0_ptr,
2246 boost::shared_ptr<double> heat_capacity,
2247 boost::shared_ptr<double> heat_conductivity_scaling,
2251 std::vector<const CubitMeshSets *> meshset_vec_ptr)
2253 omegaHPtr(omega_h_ptr),
2254 inelasticHeatFractionPtr(inelastic_heat_fraction_ptr),
2256 heatCapacityPtr(heat_capacity),
2257 heatConductivityScalingPtr(heat_conductivity_scaling),
2261 extractThermoPlasticBlockData(m_field, meshset_vec_ptr, sev),
2262 "Can not get data from block");
2269 auto scale_param = [
this](
auto parameter,
double scaling) {
2270 return parameter * scaling;
2273 for (
auto &b : blockData) {
2275 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
2276 *omega0Ptr = b.omega_0;
2277 *omegaHPtr = b.omega_h;
2278 *inelasticHeatFractionPtr = scale_param(
2279 b.inelastic_heat_fraction,
2280 inelasticHeatFractionScaling(
2282 *heatConductivityPtr / (*heatConductivityScalingPtr),
2283 *heatCapacityPtr / (*heatCapacityScalingPtr)));
2284 *temp0Ptr = b.temp_0;
2291 *inelasticHeatFractionPtr =
2293 inelasticHeatFractionScaling(
2295 *heatConductivityPtr / (*heatConductivityScalingPtr),
2296 *heatCapacityPtr / (*heatCapacityScalingPtr)));
2304 boost::shared_ptr<double> heatConductivityPtr;
2305 boost::shared_ptr<double> heatCapacityPtr;
2306 boost::shared_ptr<double> heatConductivityScalingPtr;
2307 boost::shared_ptr<double> heatCapacityScalingPtr;
2316 std::vector<BlockData> blockData;
2320 std::vector<const CubitMeshSets *> meshset_vec_ptr,
Sev sev) {
2323 for (
auto m : meshset_vec_ptr) {
2325 std::vector<double> block_data;
2326 CHKERR m->getAttributes(block_data);
2327 if (block_data.size() < 3) {
2329 "Expected that block has four attributes");
2331 auto get_block_ents = [&]() {
2334 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
2339 <<
m->getName() <<
": omega_0 = " << block_data[0]
2340 <<
" omega_h = " << block_data[1]
2341 <<
" inelastic_heat_fraction = " << block_data[2] <<
" temp_0 "
2344 blockData.push_back({block_data[0], block_data[1], block_data[2],
2345 block_data[3], get_block_ents()});
2351 boost::shared_ptr<double> omega0Ptr;
2352 boost::shared_ptr<double> omegaHPtr;
2353 boost::shared_ptr<double> inelasticHeatFractionPtr;
2354 boost::shared_ptr<double> temp0Ptr;
2357 pipeline.push_back(
new OpMatThermoPlasticBlocks(
2358 blockedParamsPtr->getOmega0Ptr(), blockedParamsPtr->getOmegaHPtr(),
2359 blockedParamsPtr->getInelasticHeatFractionPtr(),
2360 blockedParamsPtr->getTemp0Ptr(),
2361 blockedThermalParamsPtr->getHeatConductivityPtr(),
2362 blockedThermalParamsPtr->getHeatCapacityPtr(),
2363 blockedThermalParamsPtr->getHeatConductivityScalingPtr(),
2364 blockedThermalParamsPtr->getHeatCapacityScalingPtr(),
2365 inelastic_heat_fraction_scaling_func, m_field, sev,
2370 (boost::format(
"%s(.*)") % thermoplastic_block_name).str()
2402 auto get_ents_by_dim = [&](
const auto dim) {
2415 auto get_base = [&]() {
2416 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
2417 if (domain_ents.empty())
2435 const auto base = get_base();
2467 auto get_skin = [&]() {
2472 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2476 auto filter_blocks = [&](
auto skin) {
2477 bool is_contact_block =
false;
2478 Range contact_range;
2482 (boost::format(
"%s(.*)") %
"CONTACT").str()
2491 <<
"Find contact block set: " <<
m->getName();
2492 auto meshset =
m->getMeshset();
2493 Range contact_meshset_range;
2495 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
2498 contact_meshset_range);
2499 contact_range.merge(contact_meshset_range);
2501 if (is_contact_block) {
2503 <<
"Nb entities in contact surface: " << contact_range.size();
2505 skin = intersect(skin, contact_range);
2511 Range boundary_ents;
2512 ParallelComm *pcomm =
2514 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2515 PSTATUS_NOT, -1, &boundary_ents);
2516 return boundary_ents;
2530 auto project_ho_geometry = [&]() {
2534 PetscBool project_geometry = PETSC_TRUE;
2536 &project_geometry, PETSC_NULLPTR);
2537 if (project_geometry) {
2538 CHKERR project_ho_geometry();
2549 auto get_command_line_parameters = [&]() {
2563 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Minimum dt: " <<
min_dt;
2568 <<
"Minumum quality for edge flipping: " <<
qual_tol;
2604 (PetscInt *)&
ic_type, PETSC_NULLPTR);
2628 PetscBool tau_order_is_set;
2631 PetscBool ep_order_is_set;
2634 PetscBool flux_order_is_set;
2636 &flux_order_is_set);
2637 PetscBool T_order_is_set;
2660 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Hardening " <<
H;
2661 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Viscous hardening " <<
visH;
2662 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation yield stress " <<
Qinf;
2663 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation exponent " <<
b_iso;
2664 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Kinematic hardening " <<
C1_k;
2669 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"zeta * dt " <<
zeta;
2683 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
2688 if (tau_order_is_set == PETSC_FALSE)
2690 if (ep_order_is_set == PETSC_FALSE)
2693 if (flux_order_is_set == PETSC_FALSE)
2695 if (T_order_is_set == PETSC_FALSE)
2698 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Approximation order " <<
order;
2700 <<
"Ep approximation order " <<
ep_order;
2702 <<
"Tau approximation order " <<
tau_order;
2704 <<
"FLUX approximation order " <<
flux_order;
2707 <<
"Geometry approximation order " <<
geom_order;
2709 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Density " <<
rho;
2712 PetscBool is_scale = PETSC_TRUE;
2715 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Scaling used? " << is_scale;
2719 MOFEM_LOG(
"THERMOPLASTICITY", Sev::warning)
2720 <<
"Scaling does not yet work with radiation and convection BCs";
2725 if (heat_cap != 0.0 && thermal_cond != 0.0)
2726 return 1. / (thermal_cond * heat_cap);
2728 return 1. / thermal_cond;
2731 if (heat_cap != 0.0)
2732 return 1. / (thermal_cond * heat_cap);
2737 [&](
double young_modulus,
double thermal_cond,
double heat_cap) {
2738 if (heat_cap != 0.0)
2752 double thermal_cond,
2753 double heat_cap) {
return 1.0; };
2759 <<
"Thermal conductivity scale "
2763 <<
"Thermal capacity scale "
2766 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
2767 <<
"Inelastic heat fraction scale "
2781 CHKERR get_command_line_parameters();
2784 #ifdef ENABLE_PYTHON_BINDING
2785 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
2786 CHKERR sdfPythonPtr->sdfInit(
"sdf.py");
2787 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
2799 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order; };
2847 auto T_ptr = boost::make_shared<VectorDouble>();
2849 auto post_proc = [&](
auto dm) {
2852 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
2856 post_proc_fe->getOpPtrVector().push_back(
2862 auto TAU_ptr = boost::make_shared<VectorDouble>();
2863 auto EP_ptr = boost::make_shared<MatrixDouble>();
2865 post_proc_fe->getOpPtrVector().push_back(
2867 post_proc_fe->getOpPtrVector().push_back(
2870 post_proc_fe->getOpPtrVector().push_back(
2872 new OpPPMap(post_proc_fe->getPostProcMesh(),
2873 post_proc_fe->getMapGaussPts(),
2875 {{
"T", T_ptr}, {
"TAU", TAU_ptr}},
2887 post_proc_fe->getOpPtrVector().push_back(
2889 new OpPPMap(post_proc_fe->getPostProcMesh(),
2890 post_proc_fe->getMapGaussPts(),
2906 CHKERR post_proc_fe->writeFile(
"out_init.h5m");
2911 auto solve_init = [&]() {
2914 auto set_domain_rhs = [&](
auto &pip) {
2922 "T",
nullptr, T_ptr,
nullptr, boost::make_shared<double>(
init_temp),
2923 boost::make_shared<double>(
peak_temp)));
2926 auto TAU_ptr = boost::make_shared<VectorDouble>();
2927 auto EP_ptr = boost::make_shared<MatrixDouble>();
2930 auto min_tau = boost::make_shared<double>(1.0);
2931 auto max_tau = boost::make_shared<double>(2.0);
2933 nullptr, min_tau, max_tau));
2937 auto min_EP = boost::make_shared<double>(0.0);
2938 auto max_EP = boost::make_shared<double>(0.01);
2940 "EP",
nullptr, EP_ptr,
nullptr, min_EP, max_EP));
2982 auto set_domain_lhs = [&](
auto &pip) {
2990 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"T",
"T"));
2992 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"TAU",
"TAU"));
3038 auto dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
3042 for (
auto f : {
"T"}) {
3047 for (
auto f : {
"TAU",
"EP"}) {
3056 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3057 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3058 fe_rhs->getRuleHook = vol_rule;
3059 fe_lhs->getRuleHook = vol_rule;
3060 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3061 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3063 auto sub_dm = create_sub_dm(
simple->getDM());
3065 auto null_fe = boost::shared_ptr<FEMethod>();
3067 fe_lhs, null_fe, null_fe);
3072 CHKERR KSPSetDM(ksp, sub_dm);
3073 CHKERR KSPSetFromOptions(ksp);
3077 CHKERR KSPSolve(ksp, PETSC_NULLPTR,
D);
3079 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
3080 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
3089 MOFEM_LOG(
"THERMAL", Sev::inform) <<
"Set thermoelastic initial conditions";
3102 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
3105 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
3108 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
3111 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3112 "REMOVE_ALL",
"U", 0, 3,
true,
3116 for (
auto b : {
"FIX_X",
"REMOVE_X"})
3117 CHKERR bc_mng->removeBlockDOFsOnEntities(
3119 for (
auto b : {
"FIX_Y",
"REMOVE_Y"})
3120 CHKERR bc_mng->removeBlockDOFsOnEntities(
3122 for (
auto b : {
"FIX_Z",
"REMOVE_Z"})
3123 CHKERR bc_mng->removeBlockDOFsOnEntities(
3125 for (
auto b : {
"FIX_ALL",
"REMOVE_ALL"})
3126 CHKERR bc_mng->removeBlockDOFsOnEntities(
3128 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3129 "NO_CONTACT",
"SIGMA", 0, 3,
false,
3134 simple->getProblemName(),
"U");
3136 auto &bc_map = bc_mng->getBcMapByBlockName();
3137 for (
auto bc : bc_map)
3138 MOFEM_LOG(
"PLASTICITY", Sev::verbose) <<
"Marker " << bc.first;
3154 auto get_skin = [&]() {
3159 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
3163 auto filter_flux_blocks = [&](
auto skin,
bool temp_bc =
false) {
3164 auto remove_cubit_blocks = [&](
auto c) {
3174 skin = subtract(skin, ents);
3179 auto remove_named_blocks = [&](
auto n) {
3184 (boost::format(
"%s(.*)") %
n).str()
3192 skin = subtract(skin, ents);
3198 "remove_cubit_blocks");
3200 "remove_named_blocks");
3203 "remove_cubit_blocks");
3211 Range boundary_ents;
3212 ParallelComm *pcomm =
3214 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3215 PSTATUS_NOT, -1, &boundary_ents);
3216 return boundary_ents;
3220 auto remove_temp_bc_ents =
3226 remove_temp_bc_ents);
3228 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
3231 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3245 simple->getProblemName(),
"FLUX", remove_flux_ents);
3247 simple->getProblemName(),
"TBC", remove_temp_bc_ents);
3250 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"FLUX",
3253 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"TBC",
3254 remove_temp_bc_ents);
3266 simple->getProblemName(),
"FLUX",
false);
3279 auto boundary_marker =
3280 bc_mng->getMergedBlocksMarker(vector<string>{
"HEATFLUX"});
3282 auto integration_rule_bc = [](
int,
int,
int ao) {
return 2 * ao; };
3286 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
3287 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
3289 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
3290 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
3292 auto thermal_block_params =
3293 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
3294 auto heat_conductivity_ptr = thermal_block_params->getHeatConductivityPtr();
3295 auto heat_capacity_ptr = thermal_block_params->getHeatCapacityPtr();
3297 auto thermoelastic_block_params =
3298 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
3299 auto coeff_expansion_ptr = thermoelastic_block_params->getCoeffExpansionPtr();
3300 auto ref_temp_ptr = thermoelastic_block_params->getRefTempPtr();
3304 boost::make_shared<TimeScale>(
"",
false, [](
const double) {
return 1; });
3305 auto def_time_scale = [time_scale](
const double time) {
3306 return (!time_scale->argFileScale) ? time : 1;
3308 auto def_file_name = [time_scale](
const std::string &&name) {
3309 return (!time_scale->argFileScale) ? name :
"";
3313 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
3314 def_file_name(
"bodyforce_scale.txt"),
false, def_time_scale);
3315 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
3316 def_file_name(
"heatsource_scale.txt"),
false, def_time_scale);
3317 auto time_temperature_scaling = boost::make_shared<TimeScale>(
3318 def_file_name(
"temperature_bc_scale.txt"),
false, def_time_scale);
3319 auto time_displacement_scaling = boost::make_shared<TimeScale>(
3320 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
3321 auto time_flux_scaling = boost::make_shared<TimeScale>(
3322 def_file_name(
"flux_bc_scale.txt"),
false, def_time_scale);
3323 auto time_force_scaling = boost::make_shared<TimeScale>(
3324 def_file_name(
"force_bc_scale.txt"),
false, def_time_scale);
3326 auto add_boundary_ops_lhs = [&](
auto &pip) {
3329 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3337 pip,
mField,
"U", Sev::inform);
3341 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3344 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
3345 mField, pip,
simple->getDomainFEName(),
"SIGMA",
"U",
"GEOMETRY",
3351 using OpConvectionLhsBC =
3352 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3353 using OpRadiationLhsBC =
3354 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3355 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3357 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pip,
mField,
"TBC",
"TBC",
3358 "CONVECTION", Sev::verbose);
3359 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
3360 pip,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
3367 struct OpTBCTimesNormalFlux
3372 OpTBCTimesNormalFlux(
const std::string row_field_name,
3373 const std::string col_field_name,
3374 boost::shared_ptr<Range> ents_ptr =
nullptr)
3375 :
OP(row_field_name, col_field_name,
OP::OPROWCOL, ents_ptr) {
3377 this->assembleTranspose =
true;
3378 this->onlyTranspose =
false;
3388 auto t_w = OP::getFTensor0IntegrationWeight();
3392 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3394 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3396 auto a_mat_ptr = &*OP::locMat.data().begin();
3398 for (; rr != OP::nbRows; rr++) {
3400 const double alpha = t_w * t_row_base;
3404 for (
int cc = 0; cc != OP::nbCols; cc++) {
3408 *a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
3414 for (; rr < OP::nbRowBaseFunctions; ++rr)
3419 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3420 if (fe_type == MBTRI) {
3427 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC",
"FLUX"));
3432 auto add_boundary_ops_rhs = [&](
auto &pip) {
3440 pip,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
3448 pip,
mField,
"FLUX", {time_scale, time_temperature_scaling},
3449 "TEMPERATURE", Sev::inform);
3459 pip,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
3463 using OpConvectionRhsBC =
3464 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3465 using OpRadiationRhsBC =
3466 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3467 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3469 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
3470 pip,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
3471 T::AddFluxToPipeline<OpRadiationRhsBC>::add(pip,
mField,
"TBC", temp_bc_ptr,
3472 "RADIATION", Sev::inform);
3474 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3483 struct OpTBCTimesNormalFlux
3488 OpTBCTimesNormalFlux(
const std::string
field_name,
3489 boost::shared_ptr<MatrixDouble> vec,
3490 boost::shared_ptr<Range> ents_ptr =
nullptr)
3497 auto t_w = OP::getFTensor0IntegrationWeight();
3501 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3503 auto t_vec = getFTensor1FromMat<SPACE_DIM, 1>(*sourceVec);
3505 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3507 const double alpha = t_w * (t_vec(
i) * t_normal(
i));
3510 for (; rr != OP::nbRows; ++rr) {
3511 OP::locF[rr] += alpha * t_row_base;
3514 for (; rr < OP::nbRowBaseFunctions; ++rr)
3520 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3521 if (fe_type == MBTRI) {
3528 boost::shared_ptr<MatrixDouble> sourceVec;
3530 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC", mat_flux_ptr));
3532 struct OpBaseNormalTimesTBC
3537 OpBaseNormalTimesTBC(
const std::string
field_name,
3538 boost::shared_ptr<VectorDouble> vec,
3539 boost::shared_ptr<Range> ents_ptr =
nullptr)
3546 auto t_w = OP::getFTensor0IntegrationWeight();
3550 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3554 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3556 const double alpha = t_w * t_vec;
3559 for (; rr != OP::nbRows; ++rr) {
3560 OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
3563 for (; rr < OP::nbRowBaseFunctions; ++rr)
3569 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3570 if (fe_type == MBTRI) {
3577 boost::shared_ptr<VectorDouble> sourceVec;
3580 pip.push_back(
new OpBaseNormalTimesTBC(
"FLUX", temp_bc_ptr));
3583 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3590 auto add_domain_ops_lhs = [&](
auto &pip) {
3593 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3596 mField, pip,
"MAT_THERMAL", thermal_block_params,
3611 auto get_inertia_and_mass_damping = [
this](
const double,
const double,
3615 return (
rho /
scale) * fe_domain_lhs->ts_aa +
3618 pip.push_back(
new OpMass(
"U",
"U", get_inertia_and_mass_damping));
3621 CHKERR opThermoPlasticFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
3622 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
3623 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
3625 auto hencky_common_data_ptr =
3626 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3627 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3628 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3629 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3631 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3633 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3635 return (1. / (*heat_conductivity_ptr));
3637 auto capacity = [heat_capacity_ptr](
const double,
const double,
3639 return -(*heat_capacity_ptr);
3642 pip.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance, mat_grad_ptr));
3644 new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
3646 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3651 new OpHdivU(
"FLUX",
"U", mat_flux_ptr, resistance, mat_grad_ptr));
3653 auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
3654 op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
3655 return fe_ptr->ts_a;
3657 pip.push_back(op_capacity);
3661 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3664 pip,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
3671 auto add_domain_ops_rhs = [&](
auto &pip) {
3674 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3677 mField, pip,
"MAT_THERMAL", thermal_block_params,
3685 auto hencky_common_data_ptr =
3686 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3687 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3688 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3689 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3690 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
3691 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
3693 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
3694 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
3695 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3696 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
3701 "FLUX", vec_temp_div_ptr));
3705 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3707 return (1. / (*heat_conductivity_ptr));
3710 auto capacity = [heat_capacity_ptr](
const double,
const double,
3712 return -(*heat_capacity_ptr);
3718 new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
3719 pip.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
3720 pip.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
3721 pip.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
3725 {boost::make_shared<ScaledTimeScale>(
"body_force_hist.txt")},
3736 auto mat_acceleration = boost::make_shared<MatrixDouble>();
3738 "U", mat_acceleration));
3740 new OpInertiaForce(
"U", mat_acceleration, [](
double,
double,
double) {
3744 auto mat_velocity = boost::make_shared<MatrixDouble>();
3748 new OpInertiaForce(
"U", mat_velocity, [](
double,
double,
double) {
3754 CHKERR opThermoPlasticFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
3755 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
3756 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
3759 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
3768 auto create_reaction_pipeline = [&](
auto &pip) {
3772 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
3773 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
3784 auto get_bc_hook_rhs = [&]() {
3786 mField, pip_mng->getDomainRhsFE(),
3787 {time_scale, time_displacement_scaling});
3790 auto get_bc_hook_lhs = [&]() {
3792 mField, pip_mng->getDomainLhsFE(),
3793 {time_scale, time_displacement_scaling});
3797 pip_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
3798 pip_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
3800 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
3801 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
3804 CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
3805 CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
3837 PetscInt snes_iter_counter = 0;
3859 PetscBool *resize,
void *ctx) {
3863 PetscFunctionReturn(0);
3867 Vec ts_vecsout[],
void *ctx) {
3871 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"number of vectors to map = " << nv;
3873 for (PetscInt
i = 0;
i < nv; ++
i) {
3875 CHKERR VecNorm(ts_vecsin[
i], NORM_2, &nrm);
3877 <<
"Before remeshing: ts_vecsin[" <<
i <<
"] norm = " << nrm;
3904 CHKERR DMSetFromOptions(intermediate_dm);
3908 CHKERR DMSetUp(intermediate_dm);
3910 Vec vec_in[nv], vec_out[nv];
3911 for (PetscInt
i = 0;
i < nv; ++
i) {
3912 CHKERR DMCreateGlobalVector(intermediate_dm, &vec_in[
i]);
3913 CHKERR VecDuplicate(vec_in[
i], &vec_out[
i]);
3916 VecScatter scatter_to_intermediate;
3918 for (PetscInt
i = 0;
i < nv; ++
i) {
3919 CHKERR scatter_mng->vecScatterCreate(
3922 CHKERR VecScatterBegin(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
3923 INSERT_VALUES, SCATTER_FORWARD);
3924 CHKERR VecScatterEnd(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
3925 INSERT_VALUES, SCATTER_FORWARD);
3928 CHKERR VecScatterDestroy(&scatter_to_intermediate);
3933 constexpr bool do_fake_mapping =
false;
3934 if (do_fake_mapping) {
3938 CHKERR VecCopy(vec_in[0], vec_out[0]);
3941 CHKERR DMSetType(sub_dm,
"DMMOFEM");
3947 MOFEM_LOG(
"REMESHING", Sev::inform) <<
"Created sub DpoM";
3949 for (
auto f : {
"T",
"TAU",
"EP"}) {
3963 auto fe_method = boost::make_shared<DomainEle>(m_field);
3976 auto ts_problem_name =
simple->getProblemName();
3993 <<
"Writing debug VTK files for remeshing verification";
4009 VecScatter scatter_to_final;
4011 for (PetscInt
i = 0;
i < nv; ++
i) {
4012 CHKERR DMCreateGlobalVector(
simple->getDM(), &ts_vecsout[
i]);
4013 CHKERR scatter_mng->vecScatterCreate(
4016 CHKERR VecScatterBegin(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4017 INSERT_VALUES, SCATTER_REVERSE);
4018 CHKERR VecScatterEnd(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4019 INSERT_VALUES, SCATTER_REVERSE);
4020 CHKERR VecScatterDestroy(&scatter_to_final);
4023 for (PetscInt
i = 0;
i < nv; ++
i) {
4024 CHKERR VecDestroy(&vec_in[
i]);
4025 CHKERR VecDestroy(&vec_out[
i]);
4034 CHKERR bit_mng->addBitRefLevel(flipped_ents,
4038 CHKERR bit_mng->shiftRightBitRef(1, shift_mask);
4046 CHKERR TSSetIJacobian(ts,
B,
B,
nullptr,
nullptr);
4050 for (PetscInt
i = 0;
i < nv; ++
i) {
4052 CHKERR VecNorm(ts_vecsout[
i], NORM_2, &nrm);
4054 <<
"After remeshing: ts_vecsout[" <<
i <<
"] norm = " << nrm;
4057 PetscFunctionReturn(0);
4071 auto set_section_monitor = [&](
auto solver) {
4074 CHKERR TSGetSNES(solver, &snes);
4075 CHKERR SNESMonitorSet(snes,
4078 (
void *)(snes_ctx_ptr.get()),
nullptr);
4082 auto create_post_process_elements = [&]() {
4083 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
4085 auto push_vol_ops = [
this](
auto &pip) {
4093 const double) {
return 1.; };
4095 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4096 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4097 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4098 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4099 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1., unity_2_args,
4100 unity_2_args, unity_3_args, Sev::inform);
4102 if (common_hencky_ptr) {
4103 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
4107 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
4108 common_thermoplastic_ptr);
4111 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
4114 auto &pip = pp_fe->getOpPtrVector();
4116 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
4119 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
4120 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4122 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4123 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4125 auto u_ptr = boost::make_shared<MatrixDouble>();
4130 auto x_ptr = boost::make_shared<MatrixDouble>();
4140 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4142 {{
"ISOTROPIC_HARDENING",
4143 common_plastic_ptr->getPlasticIsoHardeningPtr()},
4145 common_plastic_ptr->getPlasticSurfacePtr()},
4146 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4147 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4150 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()},
4151 {
"GEOMETRY", x_ptr}},
4153 {{
"GRAD", common_hencky_ptr->matGradPtr},
4154 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
4156 {{
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4157 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
4158 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
4159 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
4171 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4173 {{
"PLASTIC_SURFACE",
4174 common_plastic_ptr->getPlasticSurfacePtr()},
4175 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4176 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4179 {
"GEOMETRY", x_ptr},
4180 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4184 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
4185 {
"STRESS", common_plastic_ptr->mStressPtr},
4186 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4187 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
4198 PetscBool post_proc_vol = PETSC_FALSE;
4199 PetscBool post_proc_skin = PETSC_TRUE;
4202 post_proc_vol = PETSC_TRUE;
4203 post_proc_skin = PETSC_FALSE;
4206 post_proc_vol = PETSC_FALSE;
4207 post_proc_skin = PETSC_TRUE;
4214 &post_proc_vol, PETSC_NULLPTR);
4216 &post_proc_skin, PETSC_NULLPTR);
4218 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4220 if (post_proc_vol == PETSC_FALSE)
4221 return boost::shared_ptr<PostProcEle>();
4222 auto pp_fe = boost::make_shared<PostProcEle>(mField);
4224 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
4225 "push_vol_post_proc_ops");
4229 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4230 &post_proc_skin]() {
4231 if (post_proc_skin == PETSC_FALSE)
4232 return boost::shared_ptr<SkinPostProcEle>();
4235 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
4238 pp_fe->getOpPtrVector().push_back(op_side);
4240 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
4241 "push_vol_post_proc_ops");
4245 return std::make_pair(vol_post_proc(), skin_post_proc());
4248 auto scatter_create = [&](
auto D,
auto coeff) {
4250 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
4251 ROW,
"U", coeff, coeff, is);
4253 CHKERR ISGetLocalSize(is, &loc_size);
4255 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
4257 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULLPTR, &scatter);
4262 boost::shared_ptr<SetPtsData> field_eval_data;
4263 boost::shared_ptr<MatrixDouble> u_field_ptr;
4265 std::array<double, 3> field_eval_coords = {0., 0., 0.};
4268 field_eval_coords.data(), &coords_dim,
4271 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
4272 scalar_field_ptrs = boost::make_shared<
4273 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
4274 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4275 vector_field_ptrs = boost::make_shared<
4276 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4277 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4278 sym_tensor_field_ptrs = boost::make_shared<
4279 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4280 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4281 tensor_field_ptrs = boost::make_shared<
4282 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4284 auto test_monitor_ptr = boost::make_shared<FEMethod>();
4290 field_eval_data,
simple->getDomainFEName());
4292 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4293 auto no_rule = [](
int,
int,
int) {
return -1; };
4294 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4295 field_eval_fe_ptr->getRuleHook = no_rule;
4298 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV},
"GEOMETRY");
4304 const double) {
return 1.; };
4306 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4307 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4308 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4309 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4310 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4311 "TAU",
"T", 1., unity_2_args, unity_2_args, unity_3_args,
4314 auto u_field_ptr = boost::make_shared<MatrixDouble>();
4315 field_eval_fe_ptr->getOpPtrVector().push_back(
4317 auto T_field_ptr = boost::make_shared<VectorDouble>();
4318 field_eval_fe_ptr->getOpPtrVector().push_back(
4320 auto FLUX_field_ptr = boost::make_shared<MatrixDouble>();
4321 field_eval_fe_ptr->getOpPtrVector().push_back(
4324 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
4326 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4327 scalar_field_ptrs->insert(std::make_pair(
4328 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4329 scalar_field_ptrs->insert(std::make_pair(
4330 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4331 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4332 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4333 sym_tensor_field_ptrs->insert(std::make_pair(
4334 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4335 sym_tensor_field_ptrs->insert(std::make_pair(
4336 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4337 sym_tensor_field_ptrs->insert(std::make_pair(
4338 "HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()));
4339 sym_tensor_field_ptrs->insert(
4340 std::make_pair(
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()));
4341 tensor_field_ptrs->insert(
4342 std::make_pair(
"GRAD", common_hencky_ptr->matGradPtr));
4343 tensor_field_ptrs->insert(std::make_pair(
4344 "FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()));
4346 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4347 scalar_field_ptrs->insert(std::make_pair(
4348 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4349 scalar_field_ptrs->insert(std::make_pair(
4350 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4351 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4352 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4353 sym_tensor_field_ptrs->insert(
4354 std::make_pair(
"STRAIN", common_plastic_ptr->mStrainPtr));
4355 sym_tensor_field_ptrs->insert(
4356 std::make_pair(
"STRESS", common_plastic_ptr->mStressPtr));
4357 sym_tensor_field_ptrs->insert(std::make_pair(
4358 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4359 sym_tensor_field_ptrs->insert(std::make_pair(
4360 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4368 field_eval_data,
simple->getDomainFEName());
4370 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4371 auto no_rule = [](
int,
int,
int) {
return -1; };
4373 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
4374 field_eval_fe_ptr->getRuleHook = no_rule;
4377 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4383 const double) {
return 1.; };
4385 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4386 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4387 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4388 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4389 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4390 "TAU",
"T", 1, unity_2_args, unity_2_args, unity_3_args,
4393 auto dispGradPtr = common_hencky_ptr->matGradPtr;
4394 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4396 auto coeff_expansion_ptr = common_thermoelastic_ptr->getCoeffExpansionPtr();
4397 auto ref_temp_ptr = common_thermoelastic_ptr->getRefTempPtr();
4399 field_eval_fe_ptr->getOpPtrVector().push_back(
4401 field_eval_fe_ptr->getOpPtrVector().push_back(
4403 field_eval_fe_ptr->getOpPtrVector().push_back(
4405 field_eval_fe_ptr->getOpPtrVector().push_back(
4408 plasticMultiplierFieldPtr = common_plastic_ptr->getPlasticTauPtr();
4409 plasticStrainFieldPtr = common_plastic_ptr->getPlasticStrainPtr();
4413 field_eval_fe_ptr->getOpPtrVector().push_back(
4414 new typename H::template OpCalculateHenckyThermoPlasticStress<
SPACE_DIM,
4416 "U", tempFieldPtr, common_hencky_ptr, coeff_expansion_ptr,
4419 field_eval_fe_ptr->getOpPtrVector().push_back(
4421 common_hencky_ptr->getMatFirstPiolaStress(), stressFieldPtr));
4422 field_eval_fe_ptr->getOpPtrVector().push_back(
4425 field_eval_fe_ptr->getOpPtrVector().push_back(
4426 new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
4427 "U", common_hencky_ptr));
4428 stressFieldPtr = common_hencky_ptr->getMatFirstPiolaStress();
4429 strainFieldPtr = common_hencky_ptr->getMatLogC();
4433 auto set_time_monitor = [&](
auto dm,
auto solver) {
4437 dm, create_post_process_elements(), reactionFe, uXScatter, uYScatter,
4438 uZScatter, field_eval_coords, field_eval_data, scalar_field_ptrs,
4439 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
4440 boost::shared_ptr<ForcesAndSourcesCore> null;
4442 monitor_ptr, null, null);
4445 test_monitor_ptr->preProcessHook = [&]() {
4449 ->evalFEAtThePoint<SPACE_DIM>(
4450 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
4451 simple->getDomainFEName(), field_eval_data,
4452 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
4455 auto eval_num_vec =
createVectorMPI(mField.get_comm(), PETSC_DECIDE, 1);
4456 CHKERR VecZeroEntries(eval_num_vec);
4457 if (tempFieldPtr->size()) {
4458 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
4460 CHKERR VecAssemblyBegin(eval_num_vec);
4461 CHKERR VecAssemblyEnd(eval_num_vec);
4464 CHKERR VecSum(eval_num_vec, &eval_num);
4465 if (!(
int)eval_num) {
4467 "atom test %d failed: did not find elements to evaluate "
4468 "the field, check the coordinates",
4472 if (tempFieldPtr->size()) {
4474 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4475 <<
"Eval point T magnitude: " << t_temp;
4476 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4477 if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
4479 "atom test %d failed: wrong temperature value",
4482 if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
4484 "atom test %d failed: wrong temperature value",
4487 if (
atom_test == 5 && fabs(t_temp - 1) > 1e-2) {
4489 "atom test %d failed: wrong temperature value",
4493 if (
atom_test == 8 && fabs(t_temp - 0.5) > 1e-12) {
4495 "atom test %d failed: wrong temperature value",
atom_test);
4498 if (fluxFieldPtr->size1()) {
4500 auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
4501 auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
4502 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4503 <<
"Eval point FLUX magnitude: " << flux_mag;
4504 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4505 if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
4507 "atom test %d failed: wrong flux value",
atom_test);
4509 if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
4511 "atom test %d failed: wrong flux value",
atom_test);
4513 if (
atom_test == 5 && fabs(flux_mag) > 1e-6) {
4515 "atom test %d failed: wrong flux value",
atom_test);
4519 if (dispFieldPtr->size1()) {
4521 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
4522 auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
4523 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4524 <<
"Eval point U magnitude: " << disp_mag;
4525 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4526 if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
4528 "atom test %d failed: wrong displacement value",
4532 fabs(disp_mag - 0.00265) > 1e-5) {
4534 "atom test %d failed: wrong displacement value",
4538 fabs(t_disp(0) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5 &&
4539 fabs(t_disp(1) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5) {
4541 "atom test %d failed: wrong displacement value",
4546 if (strainFieldPtr->size1()) {
4549 getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
4550 auto t_strain_trace = t_strain(
i,
i);
4551 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4552 if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
4554 "atom test %d failed: wrong strain value",
atom_test);
4557 fabs(t_strain_trace - 0.00522) > 1e-5) {
4559 "atom test %d failed: wrong strain value",
atom_test);
4561 if ((
atom_test == 5) && fabs(t_strain_trace - 0.2) > 1e-5) {
4563 "atom test %d failed: wrong strain value",
atom_test);
4567 if (stressFieldPtr->size1()) {
4568 double von_mises_stress;
4569 auto getVonMisesStress = [&](
auto t_stress) {
4571 von_mises_stress = std::sqrt(
4573 ((t_stress(0, 0) - t_stress(1, 1)) *
4574 (t_stress(0, 0) - t_stress(1, 1)) +
4575 (
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
4576 (t_stress(1, 1) - t_stress(2, 2))
4578 (
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
4579 (t_stress(2, 2) - t_stress(0, 0))
4581 6 * (t_stress(0, 1) * t_stress(0, 1) +
4582 (
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
4583 (
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
4588 getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
4589 CHKERR getVonMisesStress(t_stress);
4592 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
4593 CHKERR getVonMisesStress(t_stress);
4595 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4596 <<
"Eval point von Mises Stress: " << von_mises_stress;
4597 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4598 if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
4600 "atom test %d failed: wrong von Mises stress value",
4603 if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
4605 "atom test %d failed: wrong von Mises stress value",
4608 if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
4610 "atom test %d failed: wrong von Mises stress value",
4613 if (
atom_test == 5 && fabs(von_mises_stress) > 5e-2) {
4615 "atom test %d failed: wrong von Mises stress value",
4620 if (plasticMultiplierFieldPtr->size()) {
4621 auto t_plastic_multiplier =
4623 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4624 <<
"Eval point TAU magnitude: " << t_plastic_multiplier;
4625 if (
atom_test == 8 && fabs(t_plastic_multiplier - 1.5) > 1e-12) {
4627 "atom test %d failed: wrong plastic multiplier value",
4631 if (plasticStrainFieldPtr->size1()) {
4634 auto t_plastic_strain =
4635 getFTensor2SymmetricFromMat<SPACE_DIM>(*plasticStrainFieldPtr);
4636 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4637 <<
"Eval point EP(0,0) = " << t_plastic_strain(0, 0)
4638 <<
", EP(0,1) = " << t_plastic_strain(0, 1)
4639 <<
", EP(1,1) = " << t_plastic_strain(1, 1);
4641 if (fabs(t_plastic_strain(0, 0) - 0.005) > 1e-12) {
4643 "atom test %d failed: wrong EP(0,0) value",
atom_test);
4645 if (fabs(t_plastic_strain(0, 1) - 0.025) > 1e-12) {
4647 "atom test %d failed: wrong EP(0,1) value",
atom_test);
4649 if (fabs(t_plastic_strain(1, 1) - 0.015) > 1e-12) {
4651 "atom test %d failed: wrong EP(1,1) value",
atom_test);
4659 auto null = boost::shared_ptr<FEMethod>();
4661 test_monitor_ptr, null);
4667 auto set_schur_pc = [&](
auto solver,
4668 boost::shared_ptr<SetUpSchur> &schur_ptr) {
4671 auto name_prb =
simple->getProblemName();
4677 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
4682 for (
auto f : {
"U",
"FLUX"}) {
4694 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
4700 for (
auto f : {
"SIGMA",
"EP",
"TAU",
"T"}) {
4705 for (
auto f : {
"EP",
"TAU",
"T"}) {
4715 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
4724 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
4730 {simple->getDomainFEName(),
4753 {simple->getBoundaryFEName(),
4755 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
4765 {dm_schur, dm_block}, block_mat_data,
4767 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
4775 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
4776 auto block_mat_data =
4779 {{simple->getDomainFEName(),
4805 {dm_schur, dm_block}, block_mat_data,
4807 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr}, false
4814 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
4817 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
4818 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
4824 CHKERR schur_ptr->setUp(solver);
4830 auto dm =
simple->getDM();
4833 uXScatter = scatter_create(
D, 0);
4834 uYScatter = scatter_create(
D, 1);
4836 uZScatter = scatter_create(
D, 2);
4838 auto create_solver = [pip_mng]() {
4840 return pip_mng->createTSIM();
4842 return pip_mng->createTSIM2();
4852 CHKERR VecLoad(solution_vector, viewer);
4853 CHKERR PetscViewerDestroy(&viewer);
4858 auto solver = create_solver();
4860 auto active_pre_lhs = []() {
4867 auto active_post_lhs = [&]() {
4869 auto get_iter = [&]() {
4874 "Can not get iter");
4878 auto iter = get_iter();
4881 std::array<int, 5> activity_data;
4882 std::fill(activity_data.begin(), activity_data.end(), 0);
4884 activity_data.data(), activity_data.size(), MPI_INT,
4885 MPI_SUM, mField.get_comm());
4887 int &active_points = activity_data[0];
4888 int &avtive_full_elems = activity_data[1];
4889 int &avtive_elems = activity_data[2];
4890 int &nb_points = activity_data[3];
4891 int &nb_elements = activity_data[4];
4895 double proc_nb_points =
4896 100 *
static_cast<double>(active_points) / nb_points;
4897 double proc_nb_active =
4898 100 *
static_cast<double>(avtive_elems) / nb_elements;
4899 double proc_nb_full_active = 100;
4901 proc_nb_full_active =
4902 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
4905 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
4907 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
4908 iter, nb_points, active_points, proc_nb_points,
4909 avtive_elems, proc_nb_active, avtive_full_elems,
4910 proc_nb_full_active, iter);
4917 auto add_active_dofs_elem = [&](
auto dm) {
4919 auto fe_pre_proc = boost::make_shared<FEMethod>();
4920 fe_pre_proc->preProcessHook = active_pre_lhs;
4921 auto fe_post_proc = boost::make_shared<FEMethod>();
4922 fe_post_proc->postProcessHook = active_post_lhs;
4924 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
4925 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
4929 auto set_essential_bc = [&](
auto dm,
auto solver) {
4933 auto pre_proc_ptr = boost::make_shared<FEMethod>();
4934 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
4935 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
4938 auto disp_time_scale = boost::make_shared<TimeScale>();
4940 auto get_bc_hook_rhs = [
this, pre_proc_ptr, disp_time_scale]() {
4942 {disp_time_scale},
false);
4945 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
4947 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
4950 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
4952 mField, post_proc_rhs_ptr, 1.)();
4955 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
4957 mField, post_proc_lhs_ptr, 1.);
4959 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
4962 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
4963 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
4964 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
4965 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
4966 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
4974 CHKERR TSSetSolution(solver,
D);
4976 CHKERR TS2SetSolution(solver,
D, DD);
4979 auto set_up_adapt = [&](
auto solver) {
4983 CHKERR TSGetAdapt(solver, &adapt);
4987 CHKERR set_section_monitor(solver);
4988 CHKERR set_time_monitor(dm, solver);
4989 CHKERR set_up_adapt(solver);
4990 CHKERR TSSetFromOptions(solver);
4997 CHKERR add_active_dofs_elem(dm);
4998 boost::shared_ptr<SetUpSchur> schur_ptr;
4999 CHKERR set_schur_pc(solver, schur_ptr);
5000 CHKERR set_essential_bc(dm, solver);
5002 auto my_ctx = boost::make_shared<MyTsCtx>();
5007 CHKERR TSGetSNES(solver, &snes);
5013 auto my_rhs = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec F,
void *ctx) {
5023 double time_increment;
5025 if (time_increment <
min_dt) {
5027 "Minimum time increment exceeded");
5031 int error = system(
"rm ./out_snes_residual_iter_*.h5m > /dev/null 2>&1");
5037 "Cannot get timestep from TS object");
5041 "Minimum timestep exceeded");
5045 auto post_proc = [&](
auto dm,
auto f_res,
auto sol,
auto sol_dot,
5054 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
5056 auto &pip = post_proc_fe->getOpPtrVector();
5063 auto disp_res_mat = boost::make_shared<MatrixDouble>();
5064 auto tau_res_vec = boost::make_shared<VectorDouble>();
5065 auto plastic_strain_res_mat = boost::make_shared<MatrixDouble>();
5066 auto flux_res_mat = boost::make_shared<MatrixDouble>();
5067 auto temp_res_vec = boost::make_shared<VectorDouble>();
5070 "U", disp_res_mat, smart_f_res));
5074 "EP", plastic_strain_res_mat, smart_f_res));
5082 auto disp_mat = boost::make_shared<MatrixDouble>();
5083 auto tau_vec = boost::make_shared<VectorDouble>();
5084 auto plastic_strain_mat = boost::make_shared<MatrixDouble>();
5085 auto flux_mat = boost::make_shared<MatrixDouble>();
5086 auto temp_vec = boost::make_shared<VectorDouble>();
5091 "EP", plastic_strain_mat));
5098 auto disp_dot_mat = boost::make_shared<MatrixDouble>();
5099 auto tau_dot_vec = boost::make_shared<VectorDouble>();
5100 auto plastic_strain_dot_mat = boost::make_shared<MatrixDouble>();
5101 auto flux_dot_mat = boost::make_shared<MatrixDouble>();
5102 auto temp_dot_vec = boost::make_shared<VectorDouble>();
5105 "U", disp_dot_mat, smart_sol_dot));
5109 "EP", plastic_strain_dot_mat, smart_sol_dot));
5117 auto make_d_mat = [&]() {
5121 auto push_vol_ops = [&](
auto &pip) {
5126 const double) {
return 1.; };
5128 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
5129 common_thermoelastic_ptr, common_thermoplastic_ptr] =
5132 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
5133 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1.,
5134 unity_2_args, unity_2_args, unity_3_args, Sev::inform);
5136 if (common_hencky_ptr) {
5137 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
5139 "Wrong pointer for grad");
5142 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
5143 common_thermoplastic_ptr);
5146 auto push_vol_post_proc_ops = [&](
auto &pp_fe,
auto &&p) {
5149 auto &pip = pp_fe->getOpPtrVector();
5151 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
5154 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
5155 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
5157 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
5158 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
5160 auto u_ptr = boost::make_shared<MatrixDouble>();
5165 auto x_ptr = boost::make_shared<MatrixDouble>();
5175 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5177 {{
"RESIDUAL_TAU", tau_res_vec},
5178 {
"RESIDUAL_T", temp_res_vec},
5181 {
"RATE_TAU", tau_dot_vec},
5182 {
"RATE_T", temp_dot_vec},
5183 {
"ISOTROPIC_HARDENING",
5184 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5186 common_plastic_ptr->getPlasticSurfacePtr()},
5187 {
"PLASTIC_MULTIPLIER",
5188 common_plastic_ptr->getPlasticTauPtr()},
5190 common_plastic_ptr->getPlasticSurfacePtr()},
5191 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5193 {{
"RESIDUAL_U", disp_res_mat},
5194 {
"RATE_U", disp_dot_mat},
5196 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()},
5197 {
"GEOMETRY", x_ptr}},
5199 {{
"GRAD", common_hencky_ptr->matGradPtr},
5201 common_hencky_ptr->getMatFirstPiolaStress()}},
5203 {{
"RESIDUAL_EP", plastic_strain_res_mat},
5204 {
"RATE_EP", plastic_strain_dot_mat},
5206 common_plastic_ptr->getPlasticStrainPtr()},
5207 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
5208 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
5209 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
5221 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5223 {{
"RESIDUAL_TAU", tau_res_vec},
5224 {
"RESIDUAL_T", temp_res_vec},
5227 {
"RATE_TAU", tau_dot_vec},
5228 {
"RATE_T", temp_dot_vec},
5229 {
"ISOTROPIC_HARDENING",
5230 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5232 common_plastic_ptr->getPlasticSurfacePtr()},
5233 {
"PLASTIC_MULTIPLIER",
5234 common_plastic_ptr->getPlasticTauPtr()},
5236 common_plastic_ptr->getPlasticSurfacePtr()},
5237 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5239 {{
"RESIDUAL_U", disp_res_mat},
5243 {
"RATE_U", disp_dot_mat},
5245 {
"GEOMETRY", x_ptr},
5246 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5250 {{
"RESIDUAL_PLASTIC_STRAIN", plastic_strain_res_mat},
5251 {
"PLASTIC_STRAIN", plastic_strain_mat},
5252 {
"RATE_PLASTIC_STRAIN", plastic_strain_dot_mat},
5253 {
"STRAIN", common_plastic_ptr->mStrainPtr},
5254 {
"STRESS", common_plastic_ptr->mStressPtr},
5256 common_plastic_ptr->getPlasticStrainPtr()},
5257 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
5267 CHK_MOAB_THROW(push_vol_post_proc_ops(post_proc_fe, push_vol_ops(pip)),
5268 "push_vol_post_proc_ops");
5273 post_proc_fe->writeFile(out_name);
5284 "out_snes_residual_iter_" +
5289 PetscBool is_output_residual_fields = PETSC_FALSE;
5291 &is_output_residual_fields, PETSC_NULLPTR);
5293 if (is_output_residual_fields == PETSC_TRUE) {
5296 CHKERR TSSetIFunction(solver, PETSC_NULLPTR, my_rhs, my_ctx.get());
5299 CHKERR TSSetDM(solver, dm);
5301 auto ts_pre_post_proc = boost::make_shared<TSPrePostProc>();
5305 ptr->ExRawPtr =
this;
5307 Range no_all_old_els, no_new_els, no_flipped_els;
5309 no_new_els, no_flipped_els};
5310 PetscBool rollback =
5314 CHKERR TSSetApplicationContext(solver, (
void *)ctx);
5323 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
5324 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
5325 CHKERR ptr->tsSetUp(solver);
5327 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
5328 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
5329 CHKERR TSSolve(solver, PETSC_NULLPTR);
5330 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
5342 #ifdef ENABLE_PYTHON_BINDING
5349 const char param_file[] =
"param_file.petsc";
5353 auto core_log = logging::core::get();
5383 DMType dm_name =
"DMMOFEM";
5388 moab::Core mb_instance;
5389 moab::Interface &moab = mb_instance;
5405 char meshFileName[255];
5407 meshFileName, 255, PETSC_NULLPTR);
5422 #ifdef ENABLE_PYTHON_BINDING
5423 if (Py_FinalizeEx() < 0) {
5436 :
SetUpSchur(), mField(m_field), subDM(sub_dm),
5437 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5440 "Is expected that schur matrix is not "
5441 "allocated. This is "
5442 "possible only is PC is set up twice");
5466 CHKERR TSGetSNES(solver, &snes);
5468 CHKERR SNESGetKSP(snes, &ksp);
5469 CHKERR KSPSetFromOptions(ksp);
5472 CHKERR KSPGetPC(ksp, &pc);
5473 PetscBool is_pcfs = PETSC_FALSE;
5474 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
5478 "Is expected that schur matrix is not "
5479 "allocated. This is "
5480 "possible only is PC is set up twice");
5488 CHKERR TSGetDM(solver, &solver_dm);
5489 CHKERR DMSetMatType(solver_dm, MATSHELL);
5496 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t, PetscReal
a,
5497 Mat
A, Mat
B,
void *ctx) {
5500 CHKERR TSSetIJacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5502 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec utt,
5503 PetscReal
a, PetscReal aa, Mat
A, Mat
B,
5507 CHKERR TSSetI2Jacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5509 CHKERR KSPSetOperators(ksp,
A, P);
5511 auto set_ops = [&]() {
5517 pip_mng->getOpBoundaryLhsPipeline().push_front(
5521 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5526 pip_mng->getOpDomainLhsPipeline().push_front(
5530 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5536 double eps_stab = 1e-4;
5542 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
5545 pip_mng->getOpBoundaryLhsPipeline().push_front(
5547 pip_mng->getOpBoundaryLhsPipeline().push_back(
5548 new OpMassStab(
"SIGMA",
"SIGMA", [eps_stab](
double,
double,
double) {
5553 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5558 pip_mng->getOpDomainLhsPipeline().push_front(
5562 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5570 auto set_assemble_elems = [&]() {
5572 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
5573 schur_asmb_pre_proc->preProcessHook = [
this]() {
5576 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble Begin";
5579 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
5581 schur_asmb_post_proc->postProcessHook = [
this, schur_asmb_post_proc]() {
5583 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble End";
5586 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
5587 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
5594 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
5595 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
5599 auto set_pc = [&]() {
5602 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
5606 auto set_diagonal_pc = [&]() {
5609 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
5610 auto get_pc = [](
auto ksp) {
5612 CHKERR KSPGetPC(ksp, &pc_raw);
5617 CHKERR PetscFree(subksp);
5623 CHKERR set_assemble_elems();
5627 CHKERR set_diagonal_pc();
5630 pip_mng->getOpBoundaryLhsPipeline().push_front(
5632 pip_mng->getOpBoundaryLhsPipeline().push_back(
5635 pip_mng->getOpDomainLhsPipeline().push_back(
5644boost::shared_ptr<SetUpSchur>
5648 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 ...
constexpr int order
Order displacement.
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, 1 > OpInertiaForce
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSNESSetFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES residual evaluation function
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMMoFEMSNESSetJacobian(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set SNES Jacobian evaluation function
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMMoFEMKSPSetComputeRHS(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set KSP right hand side evaluation function
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm)
Get smart vector from DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
auto createDMMatrix(DM dm)
Get smart matrix from DM.
PetscErrorCode DMCreateGlobalVector_MoFEM(DM dm, Vec *g)
DMShellSetCreateGlobalVector.
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode)
set ghosted vector values on all existing mesh entities
PetscErrorCode DMSubDMSetUp_MoFEM(DM subdm)
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.
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.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
MoFEMErrorCode 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
FTensor::Index< 'J', 3 > J
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux times base of temperature (FLUX x T) and transpose of it,...
OpHdivHdivImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivHdiv
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpCapacity
Integrate Lhs base of temperature times (heat capacity) times base of temperature (T x T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
OpCalculateQdotQLhs_dU< SPACE_DIM, GAUSS, AssemblyDomainEleOp, IS_LARGE_STRAINS > OpHdivU
Integrate Lhs of flux term coupled to displacement field.
OpHdivFluxImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivFlux
MoFEMErrorCode addMatThermalBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, double default_heat_conductivity, double default_heat_capacity, double default_thermal_conductivity_scale, double default_thermal_capacity_scale, Sev sev, ScalerFunTwoArgs thermal_conductivity_scaling_func, ScalerFunTwoArgs heat_capacity_scaling_func)
MoFEMErrorCode addMatThermoElasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, double default_coeff_expansion, double default_ref_temp, Sev sev)
MoFEMErrorCode addMatThermoPlasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string thermoplastic_block_name, boost::shared_ptr< ThermoPlasticBlockedParameters > blockedParamsPtr, boost::shared_ptr< ThermoElasticOps::BlockedThermalParameters > &blockedThermalParamsPtr, Sev sev, ScalerFunThreeArgs inelastic_heat_fraction_scaling)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr IntegrationType I
constexpr AssemblyType A
[Define dimension]
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
constexpr auto field_name
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
OpBaseImpl< PETSC, EdgeEleOp > OpBase
constexpr double heat_conductivity
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, 1 > OpKPiola
[Only used for dynamics]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesSymTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForceCauchy
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradSymTensorGrad< 1, SPACE_DIM, SPACE_DIM, 0 > OpKCauchy
[Only used with Hooke equation (linear material model)]
FTensor::Index< 'm', 3 > m
void temp(int x, int y=10)
Rhs for testing EP mapping with initial conditions.
PipelineManager::ElementsAndOpsByDim< 2 >::DomainEleOnRange DomainEleOnRange
PipelineManager::ElementsAndOpsByDim< 2 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::DomainEleOnRange DomainEleOnRange
double getScale(const double time)
Get scaling at given time.
MoFEMErrorCode thermalBC()
[Mechanical boundary conditions]
boost::shared_ptr< VectorDouble > tempFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainLhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
boost::shared_ptr< DomainEle > reactionFe
boost::shared_ptr< MatrixDouble > strainFieldPtr
boost::shared_ptr< MatrixDouble > dispGradPtr
FieldApproximationBase base
Choice of finite element basis functions
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
MoFEMErrorCode mechanicalBC()
[Initial conditions]
MoFEMErrorCode createCommonData()
friend struct TSPrePostProc
boost::shared_ptr< VectorDouble > plasticMultiplierFieldPtr
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
boost::shared_ptr< MatrixDouble > stressFieldPtr
MoFEM::Interface & mField
Reference to MoFEM interface.
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
boost::shared_ptr< MatrixDouble > fluxFieldPtr
MoFEMErrorCode setupProblem()
boost::shared_ptr< MatrixDouble > dispFieldPtr
boost::shared_ptr< MatrixDouble > plasticStrainFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainRhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
MoFEMErrorCode 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.
Interface for managing meshsets containing materials and boundary conditions.
Natural boundary conditions.
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get 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.
Projection of edge entities with one mid-node on hierarchical basis.
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
MoFEM::Interface * m_field
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
SetEnrichedIntegration(boost::shared_ptr< Range > new_els)
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 reSetUp(std::vector< std::string > fIelds, std::vector< int > oRders, BitRefLevel bIt)
MoFEMErrorCode mapFields(SmartPetscObj< DM > &intermediateDM, Range elsToRemove=Range(), Range elsToAdd=Range(), Range elsToFlip=Range(), PetscInt numVecs=1, Vec vecsToMapFrom[]=PETSC_NULLPTR, Vec vecsToMapTo[]=PETSC_NULLPTR)
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)
static std::unordered_map< TS, ResizeCtx * > ts_to_rctx
double Qinf_thermal(double Qinf, double omega_h, double temp_0, double temp)
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
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
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 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)
PetscErrorCode MyTSResizeTransfer(TS ts, PetscInt nv, Vec ts_vecsin[], Vec ts_vecsout[], void *ctx)
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
double temp_0
reference temperature for thermal softening
static std::unordered_map< TS, MyTsCtx * > ts_to_ctx
int ep_order
Order of ep field.
double dQinf_thermal_dtemp(double Qinf, double omega_h)
constexpr FieldSpace CONTACT_SPACE
double omega_h
hardening softening
double young_modulus
Young modulus.
double C1_k
Kinematic hardening.
double Qinf
Saturation yield stress.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
PetscBool is_quasi_static
[Operators used for contact]
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
PetscBool set_timer
Set timer.
double zeta
Viscous hardening.
int tau_order
Order of tau files.
double b_iso
Saturation exponent.
PetscBool is_large_strains
Large strains.
int geom_order
Order if fixed.
double sigmaY
Yield stress.
int ep_order
Order of ep files.
constexpr FieldSpace CONTACT_SPACE
[Specialisation for assembly]
#define FINITE_DEFORMATION_FLAG
constexpr bool IS_LARGE_STRAINS
double default_heat_capacity
double default_coeff_expansion
double default_heat_conductivity
constexpr int SPACE_DIM
[Define dimension]
constexpr AssemblyType A
[Define dimension]