12#ifndef EXECUTABLE_DIMENSION
13 #define EXECUTABLE_DIMENSION 3
55 IntegrationType::GAUSS;
75 boost::function<
double(
const double,
const double,
const double)>;
79inline double triangleAreaLengthQuality(
const double *coords) {
80 std::array<std::array<int, 2>, 3> edge_nodes = {
81 std::array<int, 2>{0, 1}, std::array<int, 2>{1, 2},
82 std::array<int, 2>{2, 0}};
86 "calculate triangle normal");
90 std::sqrt(normal[0] * normal[0] + normal[1] * normal[1] +
91 normal[2] * normal[2]);
93 double sum_edge_length_sq = 0;
94 for (
const auto &edge : edge_nodes) {
95 for (
int dd = 0; dd != 3; ++dd) {
96 const double diff = coords[3 * edge[0] + dd] - coords[3 * edge[1] + dd];
97 sum_edge_length_sq += diff * diff;
101 if (sum_edge_length_sq <= std::numeric_limits<double>::epsilon()) {
105 return 4. * std::sqrt(3.) * area / sum_edge_length_sq;
108inline MoFEMErrorCode getTriangleAreaAndNormal(
const double *coords,
110 std::array<double, 3> &normal) {
113 area = 0.5 * std::sqrt(normal[0] * normal[0] + normal[1] * normal[1] +
114 normal[2] * normal[2]);
120 boost::function<
double(
double,
double)>
f =
121 [](
double a,
double b) ->
double {
return std::min(
a, b); }) {
127 for (
auto tri : tris) {
128 CHKERR moab.get_connectivity(tri, conn, num_nodes,
true);
130 CHKERR moab.tag_get_data(
th, conn, num_nodes, coords);
132 CHKERR moab.get_coords(conn, num_nodes, coords);
134 double q = triangleAreaLengthQuality(coords);
135 if (!std::isnormal(q))
137 min_quality =
f(q, min_quality);
171 return std::exp(-
b_iso * tau);
178 double JC_ref_temp = 0.;
179 double JC_melt_temp = 1650.;
181 return (
temp - JC_ref_temp) / (JC_melt_temp - JC_ref_temp);
208 double JC_ref_temp = 0.;
209 double JC_melt_temp = 1650.;
214 std::exp(
exp_D * T_hat + pow(T_hat, 2) *
exp_C) /
215 (JC_melt_temp - JC_ref_temp);
221template <
typename T,
int DIM>
228 if (
C1_k < std::numeric_limits<double>::epsilon()) {
232 t_alpha(
i,
j) =
C1_k * t_plastic_strain(
i,
j);
280const char *
const ICTypes[] = {
"uniform",
"gaussian",
"linear",
281 "ICType",
"IC_",
nullptr};
341 double y,
double z) {
350 double y,
double z) {
355 double y,
double z) {
return init_temp; };
373#include <HenckyOps.hpp>
374#include <PlasticOps.hpp>
375#include <PlasticNaturalBCs.hpp>
376#include <ThermoElasticOps.hpp>
377#include <FiniteThermalOps.hpp>
379#include <ThermalOps.hpp>
384#include <ThermalConvection.hpp>
385#include <ThermalRadiation.hpp>
388 #ifdef ENABLE_PYTHON_BINDING
389 #include <boost/python.hpp>
390 #include <boost/python/def.hpp>
391 #include <boost/python/numpy.hpp>
392namespace bp = boost::python;
393namespace np = boost::python::numpy;
402 #include <ContactOps.hpp>
414 std::string output_name,
int &counter = *(
new int(0))) {
417 auto create_post_process_elements = [&]() {
419 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
421 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
424 auto &pip = pp_fe->getOpPtrVector();
426 auto TAU_ptr = boost::make_shared<VectorDouble>();
428 auto T_ptr = boost::make_shared<VectorDouble>();
431 auto T_grad_ptr = boost::make_shared<MatrixDouble>();
434 auto U_ptr = boost::make_shared<MatrixDouble>();
436 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
440 auto EP_ptr = boost::make_shared<MatrixDouble>();
450 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
452 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
454 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}, {
"T_GRAD", T_grad_ptr}},
467 CHKERR push_vol_post_proc_ops(pp_fe);
472 CHKERR pp_fe->writeFile(
"out_" + std::to_string(counter) +
"_" +
473 output_name +
".h5m");
478 auto &post_proc_moab = pp_fe->getPostProcMesh();
479 auto file_name =
"out_" + std::to_string(counter) +
"_" + output_name +
482 <<
"Writing file " << file_name << std::endl;
483 CHKERR post_proc_moab.write_file(file_name.c_str(),
"VTK");
490 CHKERR create_post_process_elements();
496 Vec sol, std::string output_name) {
501 auto create_post_process_elements = [&]() {
503 auto pp_fe = boost::make_shared<PostProcEle>(m_field);
505 auto push_vol_post_proc_ops = [&](
auto &pp_fe) {
508 auto &pip = pp_fe->getOpPtrVector();
510 auto TAU_ptr = boost::make_shared<VectorDouble>();
513 auto T_ptr = boost::make_shared<VectorDouble>();
516 auto U_ptr = boost::make_shared<MatrixDouble>();
519 auto FLUX_ptr = boost::make_shared<MatrixDouble>();
521 "FLUX", FLUX_ptr, smart_sol));
523 auto EP_ptr = boost::make_shared<MatrixDouble>();
525 "EP", EP_ptr, smart_sol));
533 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
535 {{
"TAU", TAU_ptr}, {
"T", T_ptr}},
537 {{
"U", U_ptr}, {
"FLUX", FLUX_ptr}},
550 CHKERR push_vol_post_proc_ops(pp_fe);
553 CHKERR pp_fe->writeFile(
"out_" + output_name +
".h5m");
558 CHKERR create_post_process_elements();
564 const std::string &out_put_string,
565 const auto &out_put_quantity) {
571 for (
int i = 0;
i < size; ++
i) {
574 std::cout <<
"Proc " << rank <<
" " + out_put_string +
" "
575 << out_put_quantity << std::endl;
579 CHKERR PetscBarrier(NULL);
614 IT>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
624auto save_range = [](moab::Interface &moab,
const std::string name,
628 CHKERR moab.add_entities(*out_meshset, r);
629 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
634 std::string output_string =
"";
635 for (
auto el : vec) {
636 output_string += std::to_string(el) +
" ";
638 return output_string;
699 boost::weak_ptr<TSPrePostProc>
ptr;
709 int order_row,
int order_col,
713 constexpr int numNodes = 3;
714 constexpr int numEdges = 3;
716 auto &m_field = fe_raw_ptr->
mField;
717 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
718 auto fe_handle = fe_ptr->getFEEntityHandle();
720 auto set_base_quadrature = [&]() {
722 int rule = 2 * (order_data + 1);
732 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
733 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
734 &fe_ptr->gaussPts(0, 0), 1);
735 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
736 &fe_ptr->gaussPts(1, 0), 1);
738 &fe_ptr->gaussPts(2, 0), 1);
739 auto &data = fe_ptr->dataOnElement[
H1];
740 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
743 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
744 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
746 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
749 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
758 CHKERR set_base_quadrature();
760 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
762 fe_ptr->gaussPts.swap(ref_gauss_pts);
763 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
764 auto &data = fe_ptr->dataOnElement[
H1];
765 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3);
767 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
769 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
773 auto refine_quadrature = [&]() {
777 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
779 for (
int nn = 0; nn != numNodes; nn++)
780 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
782 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
786 Range ref_tri(tri, tri);
788 CHKERR m_field_ref.
get_moab().get_adjacencies(ref_tri, 1,
true, edges,
789 moab::Interface::UNION);
793 Range nodes_at_front;
794 for (
int nn = 0; nn != numNodes; nn++) {
796 CHKERR moab_ref.side_element(tri, 0, nn, ent);
797 nodes_at_front.insert(ent);
801 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
802 for (
int ee = 0; ee != numEdges; ee++) {
804 CHKERR moab_ref.side_element(tri, 1, ee, ent);
805 CHKERR moab_ref.add_entities(meshset, &ent, 1);
812 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(0),
820 CHKERR m_ref->addVerticesInTheMiddleOfEdges(ref_edges,
824 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
825 meshset, MBEDGE,
true);
827 ->updateMeshsetByEntitiesChildren(meshset,
BitRefLevel().set(1),
828 meshset, MBTRI,
true);
831 Range output_ref_tris;
833 ->getEntitiesByTypeAndRefLevel(
840 MatrixDouble ref_coords(output_ref_tris.size(), 9,
false);
842 for (Range::iterator tit = output_ref_tris.begin();
843 tit != output_ref_tris.end(); tit++, tt++) {
846 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
847 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
850 auto &data = fe_ptr->dataOnElement[
H1];
851 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
852 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
855 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
856 double *tri_coords = &ref_coords(tt, 0);
859 auto det = t_normal.
l2();
860 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
861 for (
int dd = 0; dd != 2; dd++) {
862 ref_gauss_pts(dd, gg) = shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
863 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
864 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
867 << ref_gauss_pts(0, gg) <<
", " << ref_gauss_pts(1, gg);
868 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
874 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
876 std::bitset<numNodes> all_nodes;
877 for (
auto nn = 0; nn != numNodes; ++nn) {
887 CHKERR refine_quadrature();
903 friend PetscErrorCode ::MyTSResizeTransfer(TS, PetscInt, Vec[], Vec[],
913 std::vector<EntityHandle> &new_connectivity,
914 bool &do_refine,
Tag &th_spatial_coords);
917 Range &flipped_els,
Tag &th_spatial_coords,
918 std::vector<EntityHandle> &new_connectivity);
930 boost::make_shared<VectorDouble>();
932 boost::make_shared<MatrixDouble>();
934 boost::make_shared<MatrixDouble>();
936 boost::make_shared<MatrixDouble>();
938 boost::make_shared<MatrixDouble>();
940 boost::make_shared<MatrixDouble>();
942 boost::make_shared<VectorDouble>();
944 boost::make_shared<MatrixDouble>();
954 #ifdef ENABLE_PYTHON_BINDING
955 boost::shared_ptr<ContactOps::SDFPython> sdfPythonPtr;
959 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
962 std::string thermal_block_name, std::string thermoelastic_block_name,
963 std::string thermoplastic_block_name,
Pip &pip, std::string u,
964 std::string ep, std::string tau, std::string temperature) {
970 typename B::template OpGradTimesSymTensor<1, DIM, DIM>;
978 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
979 common_thermoelastic_ptr, common_thermoplastic_ptr] =
980 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
981 m_field, block_name, thermal_block_name, thermoelastic_block_name,
982 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
986 auto m_D_ptr = common_hencky_ptr->matDPtr;
989 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
991 tau, common_plastic_ptr->getPlasticTauDotPtr()));
993 temperature, common_thermoplastic_ptr->getTempPtr()));
995 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
996 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
997 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1001 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1002 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1003 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1004 common_thermoelastic_ptr->getRefTempPtr()));
1007 if (common_hencky_ptr) {
1009 u, common_hencky_ptr->getMatFirstPiolaStress()));
1015 auto inelastic_heat_frac_ptr =
1016 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1019 return (*inelastic_heat_frac_ptr);
1025 temperature, common_hencky_ptr->getMatHenckyStress(),
1030 typename P::template Assembly<A>::template OpCalculateConstraintsRhs<I>(
1031 tau, common_plastic_ptr, m_D_ptr));
1034 typename P::template Assembly<A>::template OpCalculatePlasticFlowRhs<
1035 DIM,
I>(ep, common_plastic_ptr, m_D_ptr));
1040 template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
1043 std::string thermal_block_name, std::string thermoelastic_block_name,
1044 std::string thermoplastic_block_name,
Pip &pip, std::string u,
1045 std::string ep, std::string tau, std::string temperature) {
1053 using OpKPiola =
typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
1054 using OpKCauchy =
typename B::template OpGradSymTensorGrad<1, DIM, DIM, 0>;
1058 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1059 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1060 createCommonThermoPlasticOps<DIM, I, DomainEleOp>(
1061 m_field, block_name, thermal_block_name, thermoelastic_block_name,
1062 thermoplastic_block_name, pip, u, ep, tau, temperature,
scale,
1066 auto m_D_ptr = common_hencky_ptr->matDPtr;
1069 ep, common_plastic_ptr->getPlasticStrainDotPtr()));
1071 tau, common_plastic_ptr->getPlasticTauDotPtr()));
1072 pip.push_back(
new typename P::template OpCalculatePlasticity<DIM, I>(
1073 u, common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1075 if (common_hencky_ptr) {
1076 pip.push_back(
new typename H::template OpHenckyTangent<DIM, I, 0>(
1077 u, common_hencky_ptr, m_D_ptr));
1078 pip.push_back(
new OpKPiola(u, u, common_hencky_ptr->getMatTangent()));
1080 new typename P::template Assembly<A>::
1081 template OpCalculatePlasticInternalForceLhs_LogStrain_dEP<DIM, I>(
1082 u, ep, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1084 pip.push_back(
new OpKCauchy(u, u, m_D_ptr));
1085 pip.push_back(
new typename P::template Assembly<A>::
1086 template OpCalculatePlasticInternalForceLhs_dEP<DIM, I>(
1087 u, ep, common_plastic_ptr, m_D_ptr));
1090 if (common_hencky_ptr) {
1092 new typename P::template Assembly<A>::
1093 template OpCalculateConstraintsLhs_LogStrain_dU<DIM, I>(
1094 tau, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1096 new typename P::template Assembly<A>::
1097 template OpCalculatePlasticFlowLhs_LogStrain_dU<DIM, I>(
1098 ep, u, common_plastic_ptr, common_hencky_ptr, m_D_ptr));
1100 pip.push_back(
new typename P::template Assembly<A>::
1101 template OpCalculateConstraintsLhs_dU<DIM, I>(
1102 tau, u, common_plastic_ptr, m_D_ptr));
1103 pip.push_back(
new typename P::template Assembly<A>::
1104 template OpCalculatePlasticFlowLhs_dU<DIM, I>(
1105 ep, u, common_plastic_ptr, m_D_ptr));
1108 pip.push_back(
new typename P::template Assembly<A>::
1109 template OpCalculatePlasticFlowLhs_dEP<DIM, I>(
1110 ep, ep, common_plastic_ptr, m_D_ptr));
1111 pip.push_back(
new typename P::template Assembly<A>::
1112 template OpCalculatePlasticFlowLhs_dTAU<DIM, I>(
1113 ep, tau, common_plastic_ptr, m_D_ptr));
1116 ep, temperature, common_thermoplastic_ptr));
1117 pip.push_back(
new typename P::template Assembly<A>::
1118 template OpCalculateConstraintsLhs_dEP<DIM, I>(
1119 tau, ep, common_plastic_ptr, m_D_ptr));
1121 new typename P::template Assembly<
1122 A>::template OpCalculateConstraintsLhs_dTAU<I>(tau, tau,
1123 common_plastic_ptr));
1126 pip.push_back(
new typename H::template OpCalculateHenckyThermalStressdT<
1128 u, temperature, common_hencky_ptr,
1129 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1131 auto inelastic_heat_frac_ptr =
1132 common_thermoplastic_ptr->getInelasticHeatFractionPtr();
1135 return (*inelastic_heat_frac_ptr);
1141 temperature, temperature, common_hencky_ptr, common_plastic_ptr,
1143 common_thermoelastic_ptr->getCoeffExpansionPtr()));
1148 temperature, ep, common_hencky_ptr, common_plastic_ptr,
1154 temperature, u, common_hencky_ptr, common_plastic_ptr,
1158 tau, temperature, common_thermoplastic_ptr));
1163 template <
int DIM, IntegrationType I,
typename DomainEleOp>
1166 std::string thermal_block_name, std::string thermoelastic_block_name,
1167 std::string thermoplastic_block_name,
1168 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1169 std::string u, std::string ep, std::string tau, std::string temperature,
1173 bool with_rates =
true) {
1177 auto common_plastic_ptr = boost::make_shared<PlasticOps::CommonData>();
1178 auto common_thermal_ptr =
1179 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
1180 auto common_thermoelastic_ptr =
1181 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
1182 auto common_thermoplastic_ptr =
1183 boost::make_shared<ThermoPlasticOps::ThermoPlasticBlockedParameters>();
1185 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
1186 auto make_d_mat = []() {
1190 common_plastic_ptr->mDPtr = boost::make_shared<MatrixDouble>();
1191 common_plastic_ptr->mGradPtr = boost::make_shared<MatrixDouble>();
1192 common_plastic_ptr->mStrainPtr = boost::make_shared<MatrixDouble>();
1193 common_plastic_ptr->mStressPtr = boost::make_shared<MatrixDouble>();
1195 auto m_D_ptr = common_plastic_ptr->mDPtr;
1198 m_field, plastic_block_name, pip, m_D_ptr,
1199 common_plastic_ptr->getParamsPtr(),
scale, sev),
1200 "add mat block plastic ops");
1202 m_field, pip, thermal_block_name, common_thermal_ptr,
1207 "add mat block thermal ops");
1209 m_field, pip, thermoelastic_block_name,
1212 "add mat block thermal ops");
1214 m_field, pip, thermoplastic_block_name,
1215 common_thermoplastic_ptr, common_thermal_ptr, sev,
1217 "add mat block thermoplastic ops");
1218 auto common_hencky_ptr =
1219 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
1220 mField, pip,
"U",
"MAT_ELASTIC", Sev::inform,
scale);
1222 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1225 tau, common_plastic_ptr->getPlasticTauPtr()));
1227 ep, common_plastic_ptr->getPlasticStrainPtr()));
1229 u, common_plastic_ptr->mGradPtr));
1232 temperature, common_thermoplastic_ptr->getTempPtr()));
1234 "FLUX", common_thermoplastic_ptr->getHeatFluxPtr()));
1236 common_plastic_ptr->mGradPtr = common_hencky_ptr->matGradPtr;
1237 common_plastic_ptr->mDPtr = common_hencky_ptr->matDPtr;
1238 common_hencky_ptr->matLogCPlastic =
1239 common_plastic_ptr->getPlasticStrainPtr();
1240 common_plastic_ptr->mStrainPtr = common_hencky_ptr->getMatLogC();
1241 common_plastic_ptr->mStressPtr = common_hencky_ptr->getMatHenckyStress();
1245 pip.push_back(
new typename H::template OpCalculateEigenVals<DIM, I>(
1246 u, common_hencky_ptr));
1248 new typename H::template OpCalculateLogC<DIM, I>(u, common_hencky_ptr));
1249 pip.push_back(
new typename H::template OpCalculateLogC_dC<DIM, I>(
1250 u, common_hencky_ptr));
1254 typename H::template OpCalculateHenckyThermoPlasticStress<DIM, I, 0>(
1255 u, common_thermoplastic_ptr->getTempPtr(), common_hencky_ptr,
1256 common_thermoelastic_ptr->getCoeffExpansionPtr(),
1257 common_thermoelastic_ptr->getRefTempPtr()));
1258 pip.push_back(
new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
1259 u, common_hencky_ptr));
1261 pip.push_back(
new typename P::template OpCalculatePlasticSurface<DIM, I>(
1262 u, common_plastic_ptr));
1264 pip.push_back(
new typename P::template OpCalculatePlasticHardening<DIM, I>(
1265 u, common_plastic_ptr, common_thermoplastic_ptr));
1267 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
1268 common_thermal_ptr, common_thermoelastic_ptr,
1269 common_thermoplastic_ptr);
1279 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Run step pre proc";
1281 auto &m_field = ptr->ExRawPtr->mField;
1285 CHKERR TSGetApplicationContext(ts, (
void **)&ctx);
1289 if (ctx->mesh_changed == PETSC_TRUE) {
1303 auto get_norm = [&](
auto x) {
1305 CHKERR VecNorm(x, NORM_2, &nrm);
1309 auto save_range = [](moab::Interface &moab,
const std::string name,
1313 CHKERR moab.add_entities(*out_meshset, r);
1314 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(),
1319 auto dm =
simple->getDM();
1323 CHKERR VecGhostUpdateBegin(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1324 CHKERR VecGhostUpdateEnd(d_vector, INSERT_VALUES, SCATTER_FORWARD);
1328 Tag th_spatial_coords;
1329 std::multimap<double, EntityHandle> el_q_map;
1330 std::vector<EntityHandle> new_connectivity;
1332 bool do_refine =
false;
1334 auto check_element_quality = [&]() {
1338 Range virgin_entities;
1343 CHKERR ptr->ExRawPtr->getElementQuality(el_q_map, flipped_els,
1344 new_connectivity, do_refine,
1350 auto solve_equil_sub_problem = [&]() {
1352 if (el_q_map.size() == 0) {
1362 auto U_ptr = boost::make_shared<MatrixDouble>();
1363 auto EP_ptr = boost::make_shared<MatrixDouble>();
1364 auto TAU_ptr = boost::make_shared<VectorDouble>();
1365 auto T_ptr = boost::make_shared<VectorDouble>();
1369 auto post_proc = [&](
auto dm) {
1372 auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
1375 post_proc_fe->getOpPtrVector(), {H1, L2, HDIV});
1382 post_proc_fe->getOpPtrVector().push_back(
1387 post_proc_fe->getOpPtrVector().push_back(
1389 post_proc_fe->getOpPtrVector().push_back(
1391 post_proc_fe->getOpPtrVector().push_back(
1394 post_proc_fe->getOpPtrVector().push_back(
1396 new OpPPMap(post_proc_fe->getPostProcMesh(),
1397 post_proc_fe->getMapGaussPts(),
1415 CHKERR post_proc_fe->writeFile(
"out_equilibrate.h5m");
1420 auto solve_equilibrate_solution = [&]() {
1423 auto set_domain_rhs = [&](
auto &pip) {
1432 typename B::template OpGradTimesSymTensor<1,
SPACE_DIM,
1439 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1440 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1443 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1444 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1449 auto m_D_ptr = common_plastic_ptr->mDPtr;
1452 "T", common_thermoplastic_ptr->getTempPtr()));
1455 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1457 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1460 if (common_hencky_ptr) {
1462 "U", common_hencky_ptr->getMatFirstPiolaStress()));
1471 auto set_domain_lhs = [&](
auto &pip) {
1482 typename B::template OpGradTensorGrad<1, SPACE_DIM, SPACE_DIM, 1>;
1489 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
1490 common_thermoelastic_ptr, common_thermoplastic_ptr] =
1493 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
1494 "MAT_THERMOELASTIC",
"MAT_THERMOPLASTIC", pip,
"U",
"EP",
1499 auto m_D_ptr = common_plastic_ptr->mDPtr;
1503 typename P::template OpCalculatePlasticityWithoutRates<
SPACE_DIM,
1505 "U", common_plastic_ptr, m_D_ptr, common_thermoplastic_ptr));
1507 if (common_hencky_ptr) {
1510 new typename H::template OpHenckyTangent<SPACE_DIM, IT, 0>(
1511 "U", common_hencky_ptr, m_D_ptr));
1513 new OpKPiola(
"U",
"U", common_hencky_ptr->getMatTangent()));
1521 pip.push_back(
new OpKCauchy(
"U",
"U", m_D_ptr));
1541 auto dm_sub =
createDM(m_field.get_comm(),
"DMMOFEM");
1545 for (
auto f : {
"U",
"EP",
"TAU",
"T"}) {
1553 auto sub_dm = create_sub_dm(
simple->getDM());
1555 auto fe_rhs = boost::make_shared<DomainEle>(m_field);
1556 auto fe_lhs = boost::make_shared<DomainEle>(m_field);
1560 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
1561 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
1563 auto bc_mng = m_field.getInterface<
BcManager>();
1568 auto &bc_map = bc_mng->getBcMapByBlockName();
1569 for (
auto bc : bc_map)
1570 MOFEM_LOG(
"PLASTICITY",
Sev::verbose) <<
"Marker " << bc.first;
1572 auto time_scale = boost::make_shared<TimeScale>(
1573 "",
false, [](
const double) {
return 1; });
1574 auto def_time_scale = [time_scale](
const double time) {
1575 return (!time_scale->argFileScale) ? time : 1;
1577 auto def_file_name = [time_scale](
const std::string &&name) {
1578 return (!time_scale->argFileScale) ? name :
"";
1580 auto time_displacement_scaling = boost::make_shared<TimeScale>(
1581 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
1583 auto pre_proc_ptr = boost::make_shared<FEMethod>();
1584 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
1585 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
1587 PetscReal current_time;
1588 TSGetTime(ts, ¤t_time);
1589 pre_proc_ptr->ts_t = current_time;
1592 auto get_bc_hook_rhs = [&]() {
1594 ptr->ExRawPtr->mField, pre_proc_ptr,
1595 {time_scale, time_displacement_scaling});
1598 auto get_bc_hook_lhs = [&]() {
1600 ptr->ExRawPtr->mField, pre_proc_ptr,
1601 {time_scale, time_displacement_scaling});
1605 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
1606 pre_proc_ptr->preProcessHook = get_bc_hook_lhs();
1608 auto get_post_proc_hook_rhs = [&]() {
1611 ptr->ExRawPtr->mField, post_proc_rhs_ptr,
nullptr,
1614 ptr->ExRawPtr->mField, post_proc_rhs_ptr, 1.)();
1617 auto get_post_proc_hook_lhs = [&]() {
1619 ptr->ExRawPtr->mField, post_proc_lhs_ptr, 1.);
1621 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
1622 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
1625 snes_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_ptr);
1626 snes_ctx_ptr->getPreProcSetOperators().push_front(pre_proc_ptr);
1627 snes_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs_ptr);
1628 snes_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs_ptr);
1630 auto null_fe = boost::shared_ptr<FEMethod>();
1649 CHKERR SNESSetDM(snes, sub_dm);
1650 CHKERR SNESSetFromOptions(snes);
1655 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1656 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1661 CHKERR SNESSolve(snes, PETSC_NULLPTR,
D);
1663 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
1664 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
1671 CHKERR solve_equilibrate_solution();
1675 <<
"Equilibrated solution after mapping";
1680 if (ctx->mesh_changed == PETSC_FALSE)
1681 CHKERR check_element_quality();
1682 ctx->mesh_changed = PETSC_FALSE;
1683 if (el_q_map.size() > 0 || do_refine) {
1686 ctx->el_q_map = el_q_map;
1687 ctx->flipped_els = flipped_els;
1688 ctx->new_connectivity = new_connectivity;
1689 ctx->th_spatial_coords = th_spatial_coords;
1690 ctx->mesh_changed = PETSC_TRUE;
1698 CHKERR PetscBarrier((PetscObject)ts);
1710 auto &m_field = ptr->ExRawPtr->mField;
1731 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
1732 std::string thermoplastic_block_name,
1733 boost::shared_ptr<ThermoPlasticOps::ThermoPlasticBlockedParameters>
1735 boost::shared_ptr<ThermoElasticOps::BlockedThermalParameters>
1736 &blockedThermalParamsPtr,
1740 struct OpMatThermoPlasticBlocks :
public DomainEleOp {
1741 OpMatThermoPlasticBlocks(
1742 boost::shared_ptr<double> omega_0_ptr,
1743 boost::shared_ptr<double> omega_h_ptr,
1744 boost::shared_ptr<double> inelastic_heat_fraction_ptr,
1745 boost::shared_ptr<double> temp_0_ptr,
1747 boost::shared_ptr<double> heat_capacity,
1748 boost::shared_ptr<double> heat_conductivity_scaling,
1752 std::vector<const CubitMeshSets *> meshset_vec_ptr)
1754 omegaHPtr(omega_h_ptr),
1755 inelasticHeatFractionPtr(inelastic_heat_fraction_ptr),
1757 heatCapacityPtr(heat_capacity),
1758 heatConductivityScalingPtr(heat_conductivity_scaling),
1762 extractThermoPlasticBlockData(m_field, meshset_vec_ptr, sev),
1763 "Can not get data from block");
1770 auto scale_param = [
this](
auto parameter,
double scaling) {
1771 return parameter * scaling;
1774 for (
auto &b : blockData) {
1776 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
1777 *omega0Ptr = b.omega_0;
1778 *omegaHPtr = b.omega_h;
1779 *inelasticHeatFractionPtr = scale_param(
1780 b.inelastic_heat_fraction,
1781 inelasticHeatFractionScaling(
1783 *heatConductivityPtr / (*heatConductivityScalingPtr),
1784 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1785 *temp0Ptr = b.temp_0;
1792 *inelasticHeatFractionPtr =
1794 inelasticHeatFractionScaling(
1796 *heatConductivityPtr / (*heatConductivityScalingPtr),
1797 *heatCapacityPtr / (*heatCapacityScalingPtr)));
1805 boost::shared_ptr<double> heatConductivityPtr;
1806 boost::shared_ptr<double> heatCapacityPtr;
1807 boost::shared_ptr<double> heatConductivityScalingPtr;
1808 boost::shared_ptr<double> heatCapacityScalingPtr;
1817 std::vector<BlockData> blockData;
1821 std::vector<const CubitMeshSets *> meshset_vec_ptr,
Sev sev) {
1824 for (
auto m : meshset_vec_ptr) {
1826 std::vector<double> block_data;
1827 CHKERR m->getAttributes(block_data);
1828 if (block_data.size() < 3) {
1830 "Expected that block has four attributes");
1832 auto get_block_ents = [&]() {
1835 m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
1840 <<
m->getName() <<
": omega_0 = " << block_data[0]
1841 <<
" omega_h = " << block_data[1]
1842 <<
" inelastic_heat_fraction = " << block_data[2] <<
" temp_0 "
1845 blockData.push_back({block_data[0], block_data[1], block_data[2],
1846 block_data[3], get_block_ents()});
1852 boost::shared_ptr<double> omega0Ptr;
1853 boost::shared_ptr<double> omegaHPtr;
1854 boost::shared_ptr<double> inelasticHeatFractionPtr;
1855 boost::shared_ptr<double> temp0Ptr;
1858 pipeline.push_back(
new OpMatThermoPlasticBlocks(
1859 blockedParamsPtr->getOmega0Ptr(), blockedParamsPtr->getOmegaHPtr(),
1860 blockedParamsPtr->getInelasticHeatFractionPtr(),
1861 blockedParamsPtr->getTemp0Ptr(),
1862 blockedThermalParamsPtr->getHeatConductivityPtr(),
1863 blockedThermalParamsPtr->getHeatCapacityPtr(),
1864 blockedThermalParamsPtr->getHeatConductivityScalingPtr(),
1865 blockedThermalParamsPtr->getHeatCapacityScalingPtr(),
1866 inelastic_heat_fraction_scaling_func, m_field, sev,
1871 (boost::format(
"%s(.*)") % thermoplastic_block_name).str()
1884 std::vector<EntityHandle> &new_connectivity,
1885 bool &do_refine,
Tag &th_spatial_coords) {
1890 std::vector<double> coords(verts.size() * 3);
1892 auto t_x = getFTensor1FromPtr<3>(coords.data());
1894 auto save_tag = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
1897 auto field_data = ent_ptr->getEntFieldData();
1900 t_u = {field_data[0], field_data[1], 0.0};
1902 t_u = {field_data[0], field_data[1], field_data[2]};
1912 double def_coord[3] = {0.0, 0.0, 0.0};
1914 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
1915 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
1927 std::multimap<double, EntityHandle> candidate_el_q_map;
1928 double spatial_coords[9], material_coords[9];
1931 Range::iterator nit = all_els.begin();
1932 for (
int gg = 0; nit != all_els.end(); nit++, gg++) {
1939 double q = triangleAreaLengthQuality(spatial_coords);
1940 if (!std::isnormal(q))
1942 "Calculated quality of element is not "
1946 if (q < qual_tol && q > 0.)
1947 candidate_el_q_map.insert(std::pair<double, EntityHandle>(q, *nit));
1951 CHKERR minTriangleQuality(
mField, all_els, min_q, th_spatial_coords);
1953 <<
"Old minimum element quality: " << min_q;
1955 auto pair = candidate_el_q_map.begin();
1957 <<
"New minimum element quality: " << pair->first;
1959 for (
auto pair = candidate_el_q_map.begin(); pair != candidate_el_q_map.end();
1961 double quality = pair->first;
1963 element.insert(pair->second);
1964 if (!flipped_els.contains(element)) {
1971 double longest_edge_length = 0;
1972 std::vector<std::pair<double, EntityHandle>> edge_lengths;
1973 edge_lengths.reserve(edges.size());
1974 for (
auto edge : edges) {
1975 edge_lengths.emplace_back(
1978 if (!edge_lengths.empty()) {
1979 const auto it = std::max_element(
1980 edge_lengths.begin(), edge_lengths.end(),
1981 [](
const auto &
a,
const auto &b) { return a.first < b.first; });
1982 longest_edge_length = it->first;
1983 longest_edge = it->second;
1986 "Unable to calculate edge lengths to find longest edge.");
1990 <<
"Edge flip longest edge length: " << longest_edge_length
1991 <<
" for edge: " << longest_edge;
1993 auto get_skin = [&]() {
1999 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2004 Range boundary_ents;
2005 ParallelComm *pcomm =
2007 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2008 PSTATUS_NOT, -1, &boundary_ents);
2009 return boundary_ents;
2012 Range boundary_ents = get_skin();
2015 <<
"Boundary entities: " << boundary_ents;
2018 Range flip_candidate_els;
2020 false, flip_candidate_els);
2024 Range neighbouring_el = subtract(flip_candidate_els, element);
2028 if (boundary_ents.contains(
Range(longest_edge, longest_edge))) {
2032 if (flipped_els.contains(neighbouring_el))
2036 if (neighbouring_el.size() != 1) {
2038 "Should be 1 neighbouring element to bad element for edge "
2039 "flip. Instead, there are %zu",
2040 neighbouring_el.size());
2045 <<
"flip_candidate_els: " << flip_candidate_els;
2047 <<
"Neighbouring element: " << neighbouring_el;
2050 std::vector<EntityHandle> neighbouring_nodes;
2052 neighbouring_nodes,
true);
2054 std::vector<EntityHandle> element_nodes;
2056 element_nodes,
true);
2059 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2061 double neighbour_qual = triangleAreaLengthQuality(spatial_coords);
2062 if (!std::isnormal(neighbour_qual))
2064 "Calculated quality of neighbouring element is not as "
2072 <<
"Element nodes before swap: "
2075 <<
"Neighbouring nodes before swap: "
2084 std::vector<EntityHandle> reversed_neighbouring_nodes =
2086 std::reverse(reversed_neighbouring_nodes.begin(),
2087 reversed_neighbouring_nodes.end());
2089 int num_matches = 0;
2090 std::vector<bool> mismatch_mask(element_nodes.size());
2091 int loop_counter = 0;
2092 while (num_matches != 2) {
2094 std::rotate(reversed_neighbouring_nodes.begin(),
2095 reversed_neighbouring_nodes.begin() + 1,
2096 reversed_neighbouring_nodes.end());
2098 std::transform(element_nodes.begin(), element_nodes.end(),
2099 reversed_neighbouring_nodes.begin(),
2100 mismatch_mask.begin(), std::equal_to<EntityHandle>());
2103 std::count(mismatch_mask.begin(), mismatch_mask.end(),
true);
2106 if (loop_counter > 3) {
2108 "Not found matching nodes for edge flipping");
2113 std::vector<EntityHandle> matched_elements(element_nodes.size());
2114 std::transform(element_nodes.begin(), element_nodes.end(),
2115 mismatch_mask.begin(), matched_elements.begin(),
2117 return match ? el : -1;
2121 matched_elements.erase(
2122 std::remove(matched_elements.begin(), matched_elements.end(), -1),
2123 matched_elements.end());
2126 std::vector<EntityHandle> mismatched_elements(element_nodes.size()),
2127 neighbouring_mismatched_elements(neighbouring_nodes.size());
2128 std::transform(element_nodes.begin(), element_nodes.end(),
2129 mismatch_mask.begin(), mismatched_elements.begin(),
2131 return match ? -1 : el;
2133 std::transform(reversed_neighbouring_nodes.begin(),
2134 reversed_neighbouring_nodes.end(), mismatch_mask.begin(),
2135 neighbouring_mismatched_elements.begin(),
2137 return match ? -1 : el;
2141 mismatched_elements.erase(std::remove(mismatched_elements.begin(),
2142 mismatched_elements.end(), -1),
2143 mismatched_elements.end());
2144 neighbouring_mismatched_elements.erase(
2145 std::remove(neighbouring_mismatched_elements.begin(),
2146 neighbouring_mismatched_elements.end(), -1),
2147 neighbouring_mismatched_elements.end());
2149 mismatched_elements.insert(mismatched_elements.end(),
2150 neighbouring_mismatched_elements.begin(),
2151 neighbouring_mismatched_elements.end());
2154 <<
"Reversed neighbouring nodes: "
2166 auto replace_correct_nodes = [](std::vector<EntityHandle> &ABC,
2167 std::vector<EntityHandle> &DBA,
2168 const std::vector<EntityHandle> &AB,
2169 const std::vector<EntityHandle> &CD) {
2171 std::vector<std::vector<EntityHandle>> results;
2173 for (
int i = 0;
i < 2; ++
i) {
2174 for (
int j = 0;
j < 2; ++
j) {
2176 if (std::find(ABC.begin(), ABC.end(), CD[
j]) == ABC.end()) {
2177 std::vector<EntityHandle> tmp = ABC;
2179 auto it = std::find(tmp.begin(), tmp.end(), AB[
i]);
2180 if (it != tmp.end()) {
2182 results.push_back(tmp);
2188 if (results.size() != 2) {
2190 "Failed to find two valid vertex replacements for edge "
2200 CHKERR replace_correct_nodes(element_nodes, neighbouring_nodes,
2201 matched_elements, mismatched_elements);
2204 <<
"Element nodes after swap: "
2207 <<
"Neighbouring nodes after swap: "
2212 th_spatial_coords, &element_nodes.front(), 3, spatial_coords);
2214 double new_qual = triangleAreaLengthQuality(spatial_coords);
2215 if (new_qual < 0.0 || !std::isfinite(new_qual))
2217 "Calculated quality of new element is not as expected: %f",
2221 auto check_normal_direction = [&](
double qual_val) {
2225 double new_area = 0;
2226 std::array<double, 3> new_normal;
2227 CHKERR getTriangleAreaAndNormal(spatial_coords, new_area, new_normal);
2229 new_normal[0], new_normal[1], new_normal[2]);
2231 t_diff(
i) = t_new_normal(
i) - t_correct_normal(
i);
2232 if (qual_val > 1e-6 && t_diff(
i) * t_diff(
i) > 1e-6) {
2234 "Direction of element to be created is wrong orientation");
2239 CHKERR check_normal_direction(new_qual);
2243 th_spatial_coords, &neighbouring_nodes.front(), 3, spatial_coords);
2245 double new_neighbour_qual = triangleAreaLengthQuality(spatial_coords);
2246 if (new_neighbour_qual < 0.0 || !std::isfinite(new_neighbour_qual))
2248 "Calculated quality of new neighbouring element is not "
2250 new_neighbour_qual);
2253 CHKERR check_normal_direction(new_neighbour_qual);
2257 if (std::min(new_qual, new_neighbour_qual) >
2258 (1. +
qual_thresh) * std::min(quality, neighbour_qual)) {
2260 <<
"Element quality improved from " << quality <<
" and "
2261 << neighbour_qual <<
" to " << new_qual <<
" and "
2262 << new_neighbour_qual <<
" for elements" << element <<
" and "
2266 flipped_els.merge(flip_candidate_els);
2268 std::pair<double, EntityHandle>(pair->first, pair->second));
2269 new_connectivity.insert(new_connectivity.end(), element_nodes.begin(),
2270 element_nodes.end());
2271 new_connectivity.insert(new_connectivity.end(),
2272 neighbouring_nodes.begin(),
2273 neighbouring_nodes.end());
2278 if (el_q_map.size() > 0) {
2279 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"Flipped elements: " << flipped_els;
2288 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2289 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2291 Range prev_ref_ents;
2296 for (
auto e : edges) {
2300 std::array<double, 6> ref_coords, spatial_coords;
2303 spatial_coords.data());
2304 auto get_length = [](
auto &
a) {
2308 p1(
i) = p1(
i) - p0(
i);
2311 auto ref_edge_length = get_length(ref_coords);
2312 auto spatial_edge_length = get_length(spatial_coords);
2313 auto change = spatial_edge_length / ref_edge_length;
2315 !prev_ref_ents.contains(
Range(e, e))) {
2331 auto make_edge_flip = [&](
auto edge,
auto adj_faces,
Range &new_tris) {
2338 CHKERR moab.get_connectivity(e, conn, num_nodes,
true);
2339 std::copy(conn, conn + num_nodes, conn_cpy);
2343 auto get_tri_normals = [&](
auto &conn) {
2344 std::array<double, 18> coords;
2345 CHKERR moab.get_coords(conn.data(), 6, coords.data());
2346 std::array<FTensor::Tensor1<double, 3>, 2> tri_normals;
2347 for (
int t = 0;
t != 2; ++
t) {
2353 auto test_flip = [&](
auto &&t_normals) {
2355 if (t_normals[0](
i) * t_normals[1](
i) <
2356 std::numeric_limits<float>::epsilon())
2361 std::array<EntityHandle, 6> adj_conn;
2362 CHKERR get_conn(adj_faces[0], &adj_conn[0]);
2363 CHKERR get_conn(adj_faces[1], &adj_conn[3]);
2364 std::array<EntityHandle, 2> edge_conn;
2365 CHKERR get_conn(edge, edge_conn.data());
2366 std::array<EntityHandle, 2> new_edge_conn;
2369 for (
int i = 0;
i != 6; ++
i) {
2370 if (adj_conn[
i] != edge_conn[0] && adj_conn[
i] != edge_conn[1]) {
2371 new_edge_conn[
j] = adj_conn[
i];
2376 auto &new_conn = adj_conn;
2377 for (
int t = 0;
t != 2; ++
t) {
2378 for (
int i = 0;
i != 3; ++
i) {
2381 (adj_conn[3 *
t +
i % 3] == edge_conn[0] &&
2382 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[1])
2386 (adj_conn[3 *
t +
i % 3] == edge_conn[1] &&
2387 adj_conn[3 *
t + (
i + 1) % 3] == edge_conn[0])
2390 new_conn[3 *
t + (
i + 1) % 3] = new_edge_conn[
t];
2396 if (test_flip(get_tri_normals(new_conn))) {
2397 for (
int t = 0;
t != 2; ++
t) {
2405 new_tris.insert(tri);
2408 if (rtri.size() != 1) {
2410 <<
"Multiple tries created during edge flip for edge " << edge
2411 <<
" adjacent faces " << std::endl
2414 "Multiple tries created during edge flip");
2417 new_tris.merge(rtri);
2423 moab::Interface::UNION);
2427 MOFEM_LOG(
"SELF", Sev::warning) <<
"Edge flip rejected for edge " << edge
2428 <<
" adjacent faces " << adj_faces;
2438 Skinner skin(&moab);
2440 CHKERR skin.find_skin(0, tris,
false, skin_edges);
2444 edges = subtract(edges, skin_edges);
2448 Range new_tris, flipped_tris, forbidden_tris;
2450 for (
auto edge : edges) {
2451 Range adjacent_tris;
2452 CHKERR moab.get_adjacencies(&edge, 1,
SPACE_DIM,
true, adjacent_tris);
2454 adjacent_tris = intersect(adjacent_tris, tris);
2455 adjacent_tris = subtract(adjacent_tris, forbidden_tris);
2456 if (adjacent_tris.size() == 2) {
2459 int side_number0, sense0, offset0;
2462 int side_number1, sense1, offset1;
2465 if (sense0 * sense1 > 0)
2468 "Cannot flip edge with same orientation in both adjacent faces");
2471 Range new_flipped_tris;
2472 CHKERR make_edge_flip(edge, adjacent_tris, new_flipped_tris);
2473 if (new_flipped_tris.size()) {
2474 flipped_tris.merge(adjacent_tris);
2475 forbidden_tris.merge(adjacent_tris);
2476 new_tris.merge(new_flipped_tris);
2480 "flipped_tris_" + std::to_string(flip_count) +
".vtk",
2483 moab,
"new_flipped_tris_" + std::to_string(flip_count) +
".vtk",
2495 Range not_flipped_tris = subtract(all_tris, flipped_tris);
2498 <<
"Flipped " << flip_count <<
" edges with two adjacent faces.";
2504 child_bit,
BitRefLevel().set(),
"edge_flips_before_refinement.vtk",
"VTK",
2514 Range &flipped_els,
Tag &th_spatial_coords,
2515 std::vector<EntityHandle> &new_connectivity) {
2518 ReadUtilIface *read_util;
2521 const int num_ele = el_q_map.size() * 2;
2522 int num_nod_per_ele;
2523 EntityType ent_type;
2526 num_nod_per_ele = 3;
2529 num_nod_per_ele = 4;
2534 auto new_conn = new_connectivity.begin();
2535 for (
auto e = 0; e != num_ele; ++e) {
2537 for (
int n = 0;
n < num_nod_per_ele; ++
n) {
2538 conn[
n] = *new_conn;
2545 if (adj_ele.size()) {
2546 if (adj_ele.size() != 1) {
2548 "Element duplication");
2550 new_ele = adj_ele.front();
2556 new_elements.insert(new_ele);
2560 <<
"New elements from edge flipping: " << new_elements;
2569 auto get_adj = [&](
auto ents) {
2574 moab::Interface::UNION),
2575 "Getting adjacencies of dimension " + std::to_string(d) +
" failed");
2580 Range non_flipped_range;
2584 non_flipped_range = subtract(non_flipped_range, flipped_els);
2585 auto flip_bit_ents = new_elements;
2586 flip_bit_ents.merge(non_flipped_range);
2587 auto adj = get_adj(new_elements);
2595 "new_elements_after_edge_flips.vtk",
"VTK",
"");
2605 Tag th_spatial_coords;
2606 double def_coord[3] = {0.0, 0.0, 0.0};
2608 auto refined_mesh = [&](
auto level) {
2615 "SpatialCoord", 3, MB_TYPE_DOUBLE, th_spatial_coords,
2616 MB_TAG_DENSE | MB_TAG_CREAT, def_coord);
2620 for (
auto e : edges) {
2624 std::array<double, 6> ref_coords, spatial_coords;
2627 num_nodes, spatial_coords.data());
2628 auto get_length = [](
auto &
a) {
2632 p1(
i) = p1(
i) - p0(
i);
2635 auto ref_edge_length = get_length(ref_coords);
2636 auto spatial_edge_length = get_length(spatial_coords);
2637 auto change = spatial_edge_length / ref_edge_length;
2639 refine_edges.insert(e);
2643 if (refine_edges.size())
2646 Range prev_level_ents;
2650 Range prev_ref_ents;
2655 refine_edges.merge(intersect(prev_ref_ents, prev_level_ents));
2662 Range tris_to_refine;
2667 auto set_spatial_coords = [&]() {
2672 auto th_parent_handle =
2674 for (
auto v : new_vertices) {
2681 std::array<double, 6> spatial_coords;
2683 num_nodes, spatial_coords.data());
2684 for (
auto d = 0; d < 3; ++d) {
2685 spatial_coords[d] += spatial_coords[3 + d];
2687 for (
auto d = 0; d < 3; ++d) {
2688 spatial_coords[d] /= 2.0;
2691 spatial_coords.data());
2696 CHKERR set_spatial_coords();
2700 (
"A_refined_" + boost::lexical_cast<std::string>(level) +
".vtk")
2722 BitRefLevel().set(), 2,
"new_elements_after_edge_splits.vtk",
"VTK",
"");
2751 auto get_ents_by_dim = [&](
const auto dim) {
2764 auto get_base = [&]() {
2765 auto domain_ents = get_ents_by_dim(
SPACE_DIM);
2766 if (domain_ents.empty())
2784 const auto base = get_base();
2816 auto get_skin = [&]() {
2821 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2825 auto filter_blocks = [&](
auto skin) {
2826 bool is_contact_block =
false;
2827 Range contact_range;
2831 (boost::format(
"%s(.*)") %
"CONTACT").str()
2840 <<
"Find contact block set: " <<
m->getName();
2841 auto meshset =
m->getMeshset();
2842 Range contact_meshset_range;
2844 meshset,
SPACE_DIM - 1, contact_meshset_range,
true);
2847 contact_meshset_range);
2848 contact_range.merge(contact_meshset_range);
2850 if (is_contact_block) {
2852 <<
"Nb entities in contact surface: " << contact_range.size();
2854 skin = intersect(skin, contact_range);
2860 Range boundary_ents;
2861 ParallelComm *pcomm =
2863 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2864 PSTATUS_NOT, -1, &boundary_ents);
2865 return boundary_ents;
2876 if (
qual_tol < std::numeric_limits<double>::epsilon() &&
2899 auto get_command_line_parameters = [&]() {
2913 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Minimum dt: " <<
min_dt;
2918 <<
"Minumum quality for edge flipping: " <<
qual_tol;
2923 <<
"Quality improvement threshold for edge flipping: " <<
qual_thresh;
2931 <<
"Number of refinement levels for edge splitting: "
2968 (PetscInt *)&
ic_type, PETSC_NULLPTR);
2992 PetscBool tau_order_is_set;
2995 PetscBool ep_order_is_set;
2998 PetscBool flux_order_is_set;
3000 &flux_order_is_set);
3001 PetscBool T_order_is_set;
3024 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Hardening " <<
H;
3025 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Viscous hardening " <<
visH;
3026 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation yield stress " <<
Qinf;
3027 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Saturation exponent " <<
b_iso;
3028 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Kinematic hardening " <<
C1_k;
3045 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
3050 if (tau_order_is_set == PETSC_FALSE)
3052 if (ep_order_is_set == PETSC_FALSE)
3055 if (flux_order_is_set == PETSC_FALSE)
3057 if (T_order_is_set == PETSC_FALSE)
3060 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Approximation order " <<
order;
3062 <<
"Ep approximation order " <<
ep_order;
3064 <<
"Tau approximation order " <<
tau_order;
3066 <<
"FLUX approximation order " <<
flux_order;
3071 MOFEM_LOG(
"PLASTICITY", Sev::inform) <<
"Density " <<
rho;
3074 PetscBool is_scale = PETSC_TRUE;
3077 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform) <<
"Scaling used? " << is_scale;
3081 MOFEM_LOG(
"THERMOPLASTICITY", Sev::warning)
3082 <<
"Scaling does not yet work with radiation and convection BCs";
3087 if (heat_cap != 0.0 && thermal_cond != 0.0)
3088 return 1. / (thermal_cond * heat_cap);
3090 return 1. / thermal_cond;
3093 if (heat_cap != 0.0)
3094 return 1. / (thermal_cond * heat_cap);
3099 [&](
double young_modulus,
double thermal_cond,
double heat_cap) {
3100 if (heat_cap != 0.0)
3114 double thermal_cond,
3115 double heat_cap) {
return 1.0; };
3121 <<
"Thermal conductivity scale "
3125 <<
"Thermal capacity scale "
3128 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
3129 <<
"Inelastic heat fraction scale "
3143 CHKERR get_command_line_parameters();
3146 #ifdef ENABLE_PYTHON_BINDING
3147 sdfPythonPtr = boost::make_shared<ContactOps::SDFPython>();
3148 CHKERR sdfPythonPtr->sdfInit(
"sdf.py");
3149 ContactOps::sdfPythonWeakPtr = sdfPythonPtr;
3161 auto vol_rule = [](int, int,
int ao) {
return 2 * ao +
geom_order; };
3209 auto T_ptr = boost::make_shared<VectorDouble>();
3211 auto post_proc = [&](
auto dm) {
3214 auto post_proc_fe = boost::make_shared<PostProcEle>(
mField);
3218 post_proc_fe->getOpPtrVector().push_back(
3224 auto TAU_ptr = boost::make_shared<VectorDouble>();
3225 auto EP_ptr = boost::make_shared<MatrixDouble>();
3227 post_proc_fe->getOpPtrVector().push_back(
3229 post_proc_fe->getOpPtrVector().push_back(
3232 post_proc_fe->getOpPtrVector().push_back(
3234 new OpPPMap(post_proc_fe->getPostProcMesh(),
3235 post_proc_fe->getMapGaussPts(),
3237 {{
"T", T_ptr}, {
"TAU", TAU_ptr}},
3249 post_proc_fe->getOpPtrVector().push_back(
3251 new OpPPMap(post_proc_fe->getPostProcMesh(),
3252 post_proc_fe->getMapGaussPts(),
3268 CHKERR post_proc_fe->writeFile(
"out_init.h5m");
3273 auto solve_init = [&]() {
3276 auto set_domain_rhs = [&](
auto &pip) {
3283 "T",
nullptr, T_ptr,
nullptr, boost::make_shared<double>(
init_temp),
3284 boost::make_shared<double>(
peak_temp)));
3287 auto TAU_ptr = boost::make_shared<VectorDouble>();
3288 auto EP_ptr = boost::make_shared<MatrixDouble>();
3291 auto min_tau = boost::make_shared<double>(1.0);
3292 auto max_tau = boost::make_shared<double>(2.0);
3294 nullptr, min_tau, max_tau));
3298 auto min_EP = boost::make_shared<double>(0.0);
3299 auto max_EP = boost::make_shared<double>(0.01);
3301 "EP",
nullptr, EP_ptr,
nullptr, min_EP, max_EP));
3343 auto set_domain_lhs = [&](
auto &pip) {
3350 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"T",
"T"));
3352 pip.push_back(
new OpLhsScalarLeastSquaresProj(
"TAU",
"TAU"));
3398 auto dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
3402 for (
auto f : {
"T"}) {
3407 for (
auto f : {
"TAU",
"EP"}) {
3416 auto fe_rhs = boost::make_shared<DomainEle>(mField);
3417 auto fe_lhs = boost::make_shared<DomainEle>(mField);
3420 CHKERR set_domain_rhs(fe_rhs->getOpPtrVector());
3421 CHKERR set_domain_lhs(fe_lhs->getOpPtrVector());
3423 auto sub_dm = create_sub_dm(
simple->getDM());
3425 auto null_fe = boost::shared_ptr<FEMethod>();
3427 fe_lhs, null_fe, null_fe);
3432 CHKERR KSPSetDM(ksp, sub_dm);
3433 CHKERR KSPSetFromOptions(ksp);
3437 CHKERR KSPSolve(ksp, PETSC_NULLPTR,
D);
3439 CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
3440 CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
3449 MOFEM_LOG(
"THERMAL", Sev::inform) <<
"Set thermoelastic initial conditions";
3462 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
3465 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
3468 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
3471 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3472 "REMOVE_ALL",
"U", 0, 3,
true,
3476 for (
auto b : {
"FIX_X",
"REMOVE_X"})
3477 CHKERR bc_mng->removeBlockDOFsOnEntities(
3479 for (
auto b : {
"FIX_Y",
"REMOVE_Y"})
3480 CHKERR bc_mng->removeBlockDOFsOnEntities(
3482 for (
auto b : {
"FIX_Z",
"REMOVE_Z"})
3483 CHKERR bc_mng->removeBlockDOFsOnEntities(
3485 for (
auto b : {
"FIX_ALL",
"REMOVE_ALL"})
3486 CHKERR bc_mng->removeBlockDOFsOnEntities(
3488 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
3489 "NO_CONTACT",
"SIGMA", 0, 3,
false,
3494 simple->getProblemName(),
"U");
3496 auto &bc_map = bc_mng->getBcMapByBlockName();
3497 for (
auto bc : bc_map)
3498 MOFEM_LOG(
"PLASTICITY", Sev::verbose) <<
"Marker " << bc.first;
3514 auto get_skin = [&]() {
3521 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
3525 auto filter_flux_blocks = [&](
auto skin,
bool temp_bc =
false) {
3526 auto remove_cubit_blocks = [&](
auto c) {
3536 skin = subtract(skin, ents);
3541 auto remove_named_blocks = [&](
auto n) {
3546 (boost::format(
"%s(.*)") %
n).str()
3554 skin = subtract(skin, ents);
3560 "remove_cubit_blocks");
3562 "remove_named_blocks");
3565 "remove_cubit_blocks");
3573 Range boundary_ents;
3574 ParallelComm *pcomm =
3576 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
3577 PSTATUS_NOT, -1, &boundary_ents);
3578 return boundary_ents;
3582 auto remove_temp_bc_ents =
3590 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
3593 MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
3607 simple->getProblemName(),
"FLUX", remove_flux_ents);
3609 simple->getProblemName(),
"TBC", remove_temp_bc_ents);
3612 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"FLUX",
3615 ->removeDofsOnEntitiesNotDistributed(
simple->getProblemName(),
"TBC",
3616 remove_temp_bc_ents);
3628 simple->getProblemName(),
"FLUX",
false);
3641 auto boundary_marker =
3642 bc_mng->getMergedBlocksMarker(vector<string>{
"HEATFLUX"});
3644 auto integration_rule_bc = [](
int,
int,
int ao) {
return 2 * ao; };
3648 CHKERR pip_mng->setDomainRhsIntegrationRule(vol_rule);
3649 CHKERR pip_mng->setDomainLhsIntegrationRule(vol_rule);
3651 CHKERR pip_mng->setBoundaryLhsIntegrationRule(integration_rule_bc);
3652 CHKERR pip_mng->setBoundaryRhsIntegrationRule(integration_rule_bc);
3654 auto thermal_block_params =
3655 boost::make_shared<ThermoElasticOps::BlockedThermalParameters>();
3656 auto heat_conductivity_ptr = thermal_block_params->getHeatConductivityPtr();
3657 auto heat_capacity_ptr = thermal_block_params->getHeatCapacityPtr();
3659 auto thermoelastic_block_params =
3660 boost::make_shared<ThermoElasticOps::BlockedThermoElasticParameters>();
3661 auto coeff_expansion_ptr = thermoelastic_block_params->getCoeffExpansionPtr();
3662 auto ref_temp_ptr = thermoelastic_block_params->getRefTempPtr();
3666 boost::make_shared<TimeScale>(
"",
false, [](
const double) {
return 1; });
3667 auto def_time_scale = [time_scale](
const double time) {
3668 return (!time_scale->argFileScale) ? time : 1;
3670 auto def_file_name = [time_scale](
const std::string &&name) {
3671 return (!time_scale->argFileScale) ? name :
"";
3675 auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
3676 def_file_name(
"bodyforce_scale.txt"),
false, def_time_scale);
3677 auto time_heatsource_scaling = boost::make_shared<TimeScale>(
3678 def_file_name(
"heatsource_scale.txt"),
false, def_time_scale);
3679 auto time_temperature_scaling = boost::make_shared<TimeScale>(
3680 def_file_name(
"temperature_bc_scale.txt"),
false, def_time_scale);
3681 auto time_displacement_scaling = boost::make_shared<TimeScale>(
3682 def_file_name(
"displacement_bc_scale.txt"),
false, def_time_scale);
3683 auto time_flux_scaling = boost::make_shared<TimeScale>(
3684 def_file_name(
"flux_bc_scale.txt"),
false, def_time_scale);
3685 auto time_force_scaling = boost::make_shared<TimeScale>(
3686 def_file_name(
"force_bc_scale.txt"),
false, def_time_scale);
3688 auto add_boundary_ops_lhs = [&](
auto &pip) {
3691 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3698 pip,
mField,
"U", Sev::inform);
3702 ContactOps::opFactoryBoundaryLhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3705 ContactOps::opFactoryBoundaryToDomainLhs<SPACE_DIM, AT, IT, DomainEle>(
3706 mField, pip,
simple->getDomainFEName(),
"SIGMA",
"U",
"", vol_rule);
3711 using OpConvectionLhsBC =
3712 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3713 using OpRadiationLhsBC =
3714 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3715 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3717 T::AddFluxToPipeline<OpConvectionLhsBC>::add(pip,
mField,
"TBC",
"TBC",
3718 "CONVECTION", Sev::verbose);
3719 T::AddFluxToPipeline<OpRadiationLhsBC>::add(
3720 pip,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
3727 struct OpTBCTimesNormalFlux
3732 OpTBCTimesNormalFlux(
const std::string row_field_name,
3733 const std::string col_field_name,
3734 boost::shared_ptr<Range> ents_ptr =
nullptr)
3735 :
OP(row_field_name, col_field_name,
OP::OPROWCOL, ents_ptr) {
3737 this->assembleTranspose =
true;
3738 this->onlyTranspose =
false;
3748 auto t_w = OP::getFTensor0IntegrationWeight();
3752 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3754 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3756 auto a_mat_ptr = &*OP::locMat.data().begin();
3758 for (; rr != OP::nbRows; rr++) {
3760 const double alpha = t_w * t_row_base;
3764 for (
int cc = 0; cc != OP::nbCols; cc++) {
3768 *a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
3774 for (; rr < OP::nbRowBaseFunctions; ++rr)
3779 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3780 if (fe_type == MBTRI) {
3787 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC",
"FLUX"));
3792 auto add_boundary_ops_rhs = [&](
auto &pip) {
3799 pip,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
3800 "PRESSURE", Sev::inform);
3807 pip,
mField,
"FLUX", {time_scale, time_temperature_scaling},
3808 "TEMPERATURE", Sev::inform);
3818 pip,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
3822 using OpConvectionRhsBC =
3823 T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
3824 using OpRadiationRhsBC =
3825 T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
3826 auto temp_bc_ptr = boost::make_shared<VectorDouble>();
3828 T::AddFluxToPipeline<OpConvectionRhsBC>::add(
3829 pip,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
3830 T::AddFluxToPipeline<OpRadiationRhsBC>::add(pip,
mField,
"TBC", temp_bc_ptr,
3831 "RADIATION", Sev::inform);
3833 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
3842 struct OpTBCTimesNormalFlux
3847 OpTBCTimesNormalFlux(
const std::string
field_name,
3848 boost::shared_ptr<MatrixDouble> vec,
3849 boost::shared_ptr<Range> ents_ptr =
nullptr)
3856 auto t_w = OP::getFTensor0IntegrationWeight();
3860 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3866 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3868 const double alpha = t_w * (t_vec(
i) * t_normal(
i));
3871 for (; rr != OP::nbRows; ++rr) {
3872 OP::locF[rr] += alpha * t_row_base;
3875 for (; rr < OP::nbRowBaseFunctions; ++rr)
3881 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3882 if (fe_type == MBTRI) {
3889 boost::shared_ptr<MatrixDouble> sourceVec;
3891 pip.push_back(
new OpTBCTimesNormalFlux(
"TBC", mat_flux_ptr));
3893 struct OpBaseNormalTimesTBC
3898 OpBaseNormalTimesTBC(
const std::string
field_name,
3899 boost::shared_ptr<VectorDouble> vec,
3900 boost::shared_ptr<Range> ents_ptr =
nullptr)
3907 auto t_w = OP::getFTensor0IntegrationWeight();
3911 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
3915 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
3917 const double alpha = t_w * t_vec;
3920 for (; rr != OP::nbRows; ++rr) {
3921 OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
3924 for (; rr < OP::nbRowBaseFunctions; ++rr)
3930 EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
3931 if (fe_type == MBTRI) {
3938 boost::shared_ptr<VectorDouble> sourceVec;
3941 pip.push_back(
new OpBaseNormalTimesTBC(
"FLUX", temp_bc_ptr));
3944 CHKERR ContactOps::opFactoryBoundaryRhs<SPACE_DIM, AT, IT, BoundaryEleOp>(
3951 auto add_domain_ops_lhs = [&](
auto &pip) {
3954 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3957 mField, pip,
"MAT_THERMAL", thermal_block_params,
3971 auto get_inertia_and_mass_damping = [
this](
const double,
const double,
3975 return (
rho /
scale) * fe_domain_lhs->ts_aa +
3978 pip.push_back(
new OpMass(
"U",
"U", get_inertia_and_mass_damping));
3981 CHKERR opThermoPlasticFactoryDomainLhs<SPACE_DIM, AT, IT, DomainEleOp>(
3982 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
3983 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
3985 auto hencky_common_data_ptr =
3986 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
3987 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
3988 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
3989 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
3991 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
3993 auto resistance = [heat_conductivity_ptr](
const double,
const double,
3995 return (1. / (*heat_conductivity_ptr));
3997 auto capacity = [heat_capacity_ptr](
const double,
const double,
3999 return -(*heat_capacity_ptr);
4002 pip.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance, mat_grad_ptr));
4004 new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
4006 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4011 new OpHdivU(
"FLUX",
"U", mat_flux_ptr, resistance, mat_grad_ptr));
4013 auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
4014 op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
4015 return fe_ptr->ts_a;
4017 pip.push_back(op_capacity);
4021 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4024 pip,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
4031 auto add_domain_ops_rhs = [&](
auto &pip) {
4034 pip.push_back(
new OpSetBc(
"FLUX",
true, boundary_marker));
4037 mField, pip,
"MAT_THERMAL", thermal_block_params,
4044 auto hencky_common_data_ptr =
4045 HenckyOps::commonDataFactory<SPACE_DIM, IT, DomainEleOp>(
4046 mField, pip,
"U",
"MAT_PLASTIC", Sev::inform,
scale);
4047 auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
4048 auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
4049 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
4050 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4052 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4053 auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
4054 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4055 auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
4060 "FLUX", vec_temp_div_ptr));
4064 auto resistance = [heat_conductivity_ptr](
const double,
const double,
4066 return (1. / (*heat_conductivity_ptr));
4069 auto capacity = [heat_capacity_ptr](
const double,
const double,
4071 return -(*heat_capacity_ptr);
4077 new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
4078 pip.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
4079 pip.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
4080 pip.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
4084 {boost::make_shared<ScaledTimeScale>(
"body_force_hist.txt")},
4095 auto mat_acceleration = boost::make_shared<MatrixDouble>();
4097 "U", mat_acceleration));
4099 new OpInertiaForce(
"U", mat_acceleration, [](
double,
double,
double) {
4103 auto mat_velocity = boost::make_shared<MatrixDouble>();
4107 new OpInertiaForce(
"U", mat_velocity, [](
double,
double,
double) {
4113 CHKERR opThermoPlasticFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4114 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4115 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T");
4118 CHKERR ContactOps::opFactoryDomainRhs<SPACE_DIM, AT, IT, DomainEleOp>(
4127 auto create_reaction_pipeline = [&](
auto &pip) {
4130 CHKERR PlasticOps::opFactoryDomainReactions<SPACE_DIM, AT, IT, DomainEleOp>(
4131 mField,
"MAT_PLASTIC", pip,
"U",
"EP",
"TAU");
4142 auto get_bc_hook_rhs = [&]() {
4144 mField, pip_mng->getDomainRhsFE(),
4145 {time_scale, time_displacement_scaling});
4148 auto get_bc_hook_lhs = [&]() {
4150 mField, pip_mng->getDomainLhsFE(),
4151 {time_scale, time_displacement_scaling});
4155 pip_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
4156 pip_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
4158 CHKERR add_domain_ops_lhs(pip_mng->getOpDomainLhsPipeline());
4159 CHKERR add_domain_ops_rhs(pip_mng->getOpDomainRhsPipeline());
4162 CHKERR add_boundary_ops_lhs(pip_mng->getOpBoundaryLhsPipeline());
4163 CHKERR add_boundary_ops_rhs(pip_mng->getOpBoundaryRhsPipeline());
4195 PetscInt snes_iter_counter = 0;
4217 PetscBool *resize,
void *ctx) {
4221 PetscFunctionReturn(0);
4225 Vec ts_vecsout[],
void *ctx) {
4229 if (
auto ptr = rctx->
ptr.lock()) {
4244 std::string improved_reasons =
"";
4246 Range edges_to_not_refine;
4252 improved_reasons +=
", Edge flipping";
4255 bool refined =
false;
4257 CHKERR TSGetStepNumber(ts, &step);
4258 CHKERR ptr->ExRawPtr->doEdgeSplits(refined, (step) ?
true :
false);
4260 improved_reasons +=
", Edge splitting";
4264 improved_reasons.erase(0, 2);
4266 if (improved_reasons !=
"")
4268 <<
"Improved mesh quality by: " << improved_reasons;
4282 "before_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4291 "before_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4294 "before_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4298 MOFEM_LOG(
"REMESHING", Sev::verbose) <<
"number of vectors to map = " << nv;
4300 for (PetscInt
i = 0;
i < nv; ++
i) {
4302 CHKERR VecNorm(ts_vecsin[
i], NORM_2, &nrm);
4304 <<
"Before remeshing: ts_vecsin[" <<
i <<
"] norm = " << nrm;
4326 intermediate_dm, &m_field,
"INTERMEDIATE_DM",
4330 CHKERR DMSetFromOptions(intermediate_dm);
4334 CHKERR DMSetUp(intermediate_dm);
4336 Vec vec_in[nv], vec_out[nv];
4337 for (PetscInt
i = 0;
i < nv; ++
i) {
4338 CHKERR DMCreateGlobalVector(intermediate_dm, &vec_in[
i]);
4339 CHKERR VecDuplicate(vec_in[
i], &vec_out[
i]);
4342 VecScatter scatter_to_intermediate;
4344 for (PetscInt
i = 0;
i < nv; ++
i) {
4345 CHKERR scatter_mng->vecScatterCreate(
4348 CHKERR VecScatterBegin(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4349 INSERT_VALUES, SCATTER_FORWARD);
4350 CHKERR VecScatterEnd(scatter_to_intermediate, ts_vecsin[
i], vec_in[
i],
4351 INSERT_VALUES, SCATTER_FORWARD);
4354 CHKERR VecScatterDestroy(&scatter_to_intermediate);
4362 auto ts_problem_name =
simple->getProblemName();
4369 PetscBarrier(
nullptr);
4378 CHKERR ptr->ExRawPtr->mechanicalBC(
4381 CHKERR ptr->ExRawPtr->thermalBC(
4385 VecScatter scatter_to_final;
4387 for (PetscInt
i = 0;
i < nv; ++
i) {
4388 CHKERR DMCreateGlobalVector(
simple->getDM(), &ts_vecsout[
i]);
4389 CHKERR scatter_mng->vecScatterCreate(
4392 CHKERR VecScatterBegin(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4393 INSERT_VALUES, SCATTER_REVERSE);
4394 CHKERR VecScatterEnd(scatter_to_final, vec_out[
i], ts_vecsout[
i],
4395 INSERT_VALUES, SCATTER_REVERSE);
4396 CHKERR VecScatterDestroy(&scatter_to_final);
4399 for (PetscInt
i = 0;
i < nv; ++
i) {
4400 CHKERR VecDestroy(&vec_in[
i]);
4401 CHKERR VecDestroy(&vec_out[
i]);
4421 CHKERR bit_mng->lambdaBitRefLevel(set_all_bit);
4435 "after_mapping_comp_mesh_bit.vtk",
"VTK",
"");
4444 "after_mapping_prev_mesh_bit.vtk",
"VTK",
"");
4447 "after_mapping_virgin_mesh_bit.vtk",
"VTK",
"");
4459 CHKERR TSSetIJacobian(ts,
B,
B,
nullptr,
nullptr);
4462 for (PetscInt
i = 0;
i < nv; ++
i) {
4464 CHKERR VecNorm(ts_vecsout[
i], NORM_2, &nrm);
4466 <<
"After remeshing: ts_vecsout[" <<
i <<
"] norm = " << nrm;
4469 PetscFunctionReturn(0);
4483 auto set_section_monitor = [&](
auto solver) {
4486 CHKERR TSGetSNES(solver, &snes);
4487 CHKERR SNESMonitorSet(snes,
4490 (
void *)(snes_ctx_ptr.get()),
nullptr);
4494 auto create_post_process_elements = [&]() {
4495 auto pp_fe = boost::make_shared<PostProcEle>(
mField);
4497 auto push_vol_ops = [
this](
auto &pip) {
4504 const double) {
return 1.; };
4506 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4507 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4508 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4509 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4510 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1., unity_2_args,
4511 unity_2_args, unity_3_args, Sev::inform);
4513 if (common_hencky_ptr) {
4514 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
4518 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
4519 common_thermoplastic_ptr);
4522 auto push_vol_post_proc_ops = [
this](
auto &pp_fe,
auto &&p) {
4525 auto &pip = pp_fe->getOpPtrVector();
4527 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
4530 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
4531 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4533 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
4534 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
4536 auto u_ptr = boost::make_shared<MatrixDouble>();
4547 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4549 {{
"ISOTROPIC_HARDENING",
4550 common_plastic_ptr->getPlasticIsoHardeningPtr()},
4552 common_plastic_ptr->getPlasticSurfacePtr()},
4553 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4554 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4557 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4559 {{
"GRAD", common_hencky_ptr->matGradPtr},
4560 {
"FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()}},
4562 {{
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4563 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
4564 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
4565 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
4577 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
4579 {{
"PLASTIC_SURFACE",
4580 common_plastic_ptr->getPlasticSurfacePtr()},
4581 {
"PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()},
4582 {
"T", common_thermoplastic_ptr->getTempPtr()}},
4585 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
4589 {{
"STRAIN", common_plastic_ptr->mStrainPtr},
4590 {
"STRESS", common_plastic_ptr->mStressPtr},
4591 {
"PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()},
4592 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
4603 PetscBool post_proc_vol = PETSC_FALSE;
4604 PetscBool post_proc_skin = PETSC_TRUE;
4607 post_proc_vol = PETSC_TRUE;
4608 post_proc_skin = PETSC_FALSE;
4611 post_proc_vol = PETSC_FALSE;
4612 post_proc_skin = PETSC_TRUE;
4619 &post_proc_vol, PETSC_NULLPTR);
4621 &post_proc_skin, PETSC_NULLPTR);
4623 auto vol_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4625 if (post_proc_vol == PETSC_FALSE)
4626 return boost::shared_ptr<PostProcEle>();
4627 auto pp_fe = boost::make_shared<PostProcEle>(mField);
4629 push_vol_post_proc_ops(pp_fe, push_vol_ops(pp_fe->getOpPtrVector())),
4630 "push_vol_post_proc_ops");
4634 auto skin_post_proc = [
this, push_vol_post_proc_ops, push_vol_ops,
4635 &post_proc_skin]() {
4636 if (post_proc_skin == PETSC_FALSE)
4637 return boost::shared_ptr<SkinPostProcEle>();
4640 auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
4643 pp_fe->getOpPtrVector().push_back(op_side);
4645 pp_fe, push_vol_ops(op_side->getOpPtrVector())),
4646 "push_vol_post_proc_ops");
4650 return std::make_pair(vol_post_proc(), skin_post_proc());
4653 auto scatter_create = [&](
auto D,
auto coeff) {
4655 CHKERR is_manager->isCreateProblemFieldAndRank(
simple->getProblemName(),
4656 ROW,
"U", coeff, coeff, is);
4658 CHKERR ISGetLocalSize(is, &loc_size);
4660 CHKERR VecCreateMPI(mField.get_comm(), loc_size, PETSC_DETERMINE, &
v);
4662 CHKERR VecScatterCreate(
D, is,
v, PETSC_NULLPTR, &scatter);
4667 boost::shared_ptr<SetPtsData> field_eval_data;
4668 boost::shared_ptr<MatrixDouble> u_field_ptr;
4670 std::array<double, 3> field_eval_coords = {0., 0., 0.};
4673 field_eval_coords.data(), &coords_dim,
4676 boost::shared_ptr<std::map<std::string, boost::shared_ptr<VectorDouble>>>
4677 scalar_field_ptrs = boost::make_shared<
4678 std::map<std::string, boost::shared_ptr<VectorDouble>>>();
4679 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4680 vector_field_ptrs = boost::make_shared<
4681 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4682 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4683 sym_tensor_field_ptrs = boost::make_shared<
4684 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4685 boost::shared_ptr<std::map<std::string, boost::shared_ptr<MatrixDouble>>>
4686 tensor_field_ptrs = boost::make_shared<
4687 std::map<std::string, boost::shared_ptr<MatrixDouble>>>();
4689 auto test_monitor_ptr = boost::make_shared<FEMethod>();
4695 field_eval_data,
simple->getDomainFEName());
4697 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4698 auto no_rule = [](
int,
int,
int) {
return -1; };
4699 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
4700 field_eval_fe_ptr->getRuleHook = no_rule;
4703 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4709 const double) {
return 1.; };
4711 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4712 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4713 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4714 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4715 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4716 "TAU",
"T", 1., unity_2_args, unity_2_args, unity_3_args,
4719 auto u_field_ptr = boost::make_shared<MatrixDouble>();
4720 field_eval_fe_ptr->getOpPtrVector().push_back(
4722 auto T_field_ptr = boost::make_shared<VectorDouble>();
4723 field_eval_fe_ptr->getOpPtrVector().push_back(
4725 auto FLUX_field_ptr = boost::make_shared<MatrixDouble>();
4726 field_eval_fe_ptr->getOpPtrVector().push_back(
4729 if ((common_plastic_ptr) && (common_hencky_ptr) && (scalar_field_ptrs)) {
4731 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4732 scalar_field_ptrs->insert(std::make_pair(
4733 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4734 scalar_field_ptrs->insert(std::make_pair(
4735 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4736 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4737 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4738 sym_tensor_field_ptrs->insert(std::make_pair(
4739 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4740 sym_tensor_field_ptrs->insert(std::make_pair(
4741 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4742 sym_tensor_field_ptrs->insert(std::make_pair(
4743 "HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()));
4744 sym_tensor_field_ptrs->insert(
4745 std::make_pair(
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()));
4746 tensor_field_ptrs->insert(
4747 std::make_pair(
"GRAD", common_hencky_ptr->matGradPtr));
4748 tensor_field_ptrs->insert(std::make_pair(
4749 "FIRST_PIOLA", common_hencky_ptr->getMatFirstPiolaStress()));
4751 scalar_field_ptrs->insert(std::make_pair(
"TEMPERATURE", T_field_ptr));
4752 scalar_field_ptrs->insert(std::make_pair(
4753 "PLASTIC_SURFACE", common_plastic_ptr->getPlasticSurfacePtr()));
4754 scalar_field_ptrs->insert(std::make_pair(
4755 "PLASTIC_MULTIPLIER", common_plastic_ptr->getPlasticTauPtr()));
4756 vector_field_ptrs->insert(std::make_pair(
"U", u_field_ptr));
4757 vector_field_ptrs->insert(std::make_pair(
"FLUX", FLUX_field_ptr));
4758 sym_tensor_field_ptrs->insert(
4759 std::make_pair(
"STRAIN", common_plastic_ptr->mStrainPtr));
4760 sym_tensor_field_ptrs->insert(
4761 std::make_pair(
"STRESS", common_plastic_ptr->mStressPtr));
4762 sym_tensor_field_ptrs->insert(std::make_pair(
4763 "PLASTIC_STRAIN", common_plastic_ptr->getPlasticStrainPtr()));
4764 sym_tensor_field_ptrs->insert(std::make_pair(
4765 "PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()));
4773 field_eval_data,
simple->getDomainFEName());
4775 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
4776 auto no_rule = [](
int,
int,
int) {
return -1; };
4778 auto field_eval_fe_ptr = field_eval_data->feMethodPtr;
4779 field_eval_fe_ptr->getRuleHook = no_rule;
4782 field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
4788 const double) {
return 1.; };
4790 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
4791 common_thermoelastic_ptr, common_thermoplastic_ptr] =
4792 createCommonThermoPlasticOps<SPACE_DIM, IT, DomainEleOp>(
4793 mField,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
4794 "MAT_THERMOPLASTIC", field_eval_fe_ptr->getOpPtrVector(),
"U",
"EP",
4795 "TAU",
"T", 1, unity_2_args, unity_2_args, unity_3_args,
4798 auto dispGradPtr = common_hencky_ptr->matGradPtr;
4799 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
4801 auto coeff_expansion_ptr = common_thermoelastic_ptr->getCoeffExpansionPtr();
4802 auto ref_temp_ptr = common_thermoelastic_ptr->getRefTempPtr();
4804 field_eval_fe_ptr->getOpPtrVector().push_back(
4806 field_eval_fe_ptr->getOpPtrVector().push_back(
4808 field_eval_fe_ptr->getOpPtrVector().push_back(
4810 field_eval_fe_ptr->getOpPtrVector().push_back(
4813 plasticMultiplierFieldPtr = common_plastic_ptr->getPlasticTauPtr();
4814 plasticStrainFieldPtr = common_plastic_ptr->getPlasticStrainPtr();
4818 field_eval_fe_ptr->getOpPtrVector().push_back(
4819 new typename H::template OpCalculateHenckyThermoPlasticStress<
SPACE_DIM,
4821 "U", tempFieldPtr, common_hencky_ptr, coeff_expansion_ptr,
4824 field_eval_fe_ptr->getOpPtrVector().push_back(
4826 common_hencky_ptr->getMatFirstPiolaStress(), stressFieldPtr));
4827 field_eval_fe_ptr->getOpPtrVector().push_back(
4830 field_eval_fe_ptr->getOpPtrVector().push_back(
4831 new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
4832 "U", common_hencky_ptr));
4833 stressFieldPtr = common_hencky_ptr->getMatFirstPiolaStress();
4834 strainFieldPtr = common_hencky_ptr->getMatLogC();
4838 auto set_time_monitor = [&](
auto dm,
auto solver) {
4842 dm, create_post_process_elements(), reactionFe, uXScatter, uYScatter,
4843 uZScatter, field_eval_coords, field_eval_data, scalar_field_ptrs,
4844 vector_field_ptrs, sym_tensor_field_ptrs, tensor_field_ptrs));
4845 boost::shared_ptr<ForcesAndSourcesCore> null;
4847 monitor_ptr, null, null);
4850 test_monitor_ptr->preProcessHook = [&]() {
4854 ->evalFEAtThePoint<SPACE_DIM>(
4855 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
4856 simple->getDomainFEName(), field_eval_data,
4857 mField.get_comm_rank(), mField.get_comm_rank(),
nullptr,
4860 auto eval_num_vec =
createVectorMPI(mField.get_comm(), PETSC_DECIDE, 1);
4861 CHKERR VecZeroEntries(eval_num_vec);
4862 if (tempFieldPtr->size()) {
4863 CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
4865 CHKERR VecAssemblyBegin(eval_num_vec);
4866 CHKERR VecAssemblyEnd(eval_num_vec);
4869 CHKERR VecSum(eval_num_vec, &eval_num);
4870 if (!(
int)eval_num) {
4872 "atom test %d failed: did not find elements to evaluate "
4873 "the field, check the coordinates",
4877 if (tempFieldPtr->size()) {
4879 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4880 <<
"Eval point T magnitude: " << t_temp;
4881 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4882 if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
4884 "atom test %d failed: wrong temperature value",
4887 if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
4889 "atom test %d failed: wrong temperature value",
4892 if (
atom_test == 5 && fabs(t_temp - 1) > 1e-2) {
4894 "atom test %d failed: wrong temperature value",
4898 if (
atom_test == 8 && fabs(t_temp - 0.5) > 1e-12) {
4900 "atom test %d failed: wrong temperature value",
atom_test);
4903 if (fluxFieldPtr->size1()) {
4905 auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
4906 auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
4907 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4908 <<
"Eval point FLUX magnitude: " << flux_mag;
4909 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4910 if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
4912 "atom test %d failed: wrong flux value",
atom_test);
4914 if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
4916 "atom test %d failed: wrong flux value",
atom_test);
4918 if (
atom_test == 5 && fabs(flux_mag) > 1e-6) {
4920 "atom test %d failed: wrong flux value",
atom_test);
4924 if (dispFieldPtr->size1()) {
4926 auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
4927 auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
4928 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
4929 <<
"Eval point U magnitude: " << disp_mag;
4930 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4931 if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
4933 "atom test %d failed: wrong displacement value",
4937 fabs(disp_mag - 0.00265) > 1e-5) {
4939 "atom test %d failed: wrong displacement value",
4943 fabs(t_disp(0) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5 &&
4944 fabs(t_disp(1) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5) {
4946 "atom test %d failed: wrong displacement value",
4951 if (strainFieldPtr->size1()) {
4954 getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
4955 auto t_strain_trace = t_strain(
i,
i);
4956 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
4957 if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
4959 "atom test %d failed: wrong strain value",
atom_test);
4962 fabs(t_strain_trace - 0.00522) > 1e-5) {
4964 "atom test %d failed: wrong strain value",
atom_test);
4966 if ((
atom_test == 5) && fabs(t_strain_trace - 0.2) > 1e-5) {
4968 "atom test %d failed: wrong strain value",
atom_test);
4972 if (stressFieldPtr->size1()) {
4973 double von_mises_stress;
4974 auto getVonMisesStress = [&](
auto t_stress) {
4976 von_mises_stress = std::sqrt(
4978 ((t_stress(0, 0) - t_stress(1, 1)) *
4979 (t_stress(0, 0) - t_stress(1, 1)) +
4980 (
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
4981 (t_stress(1, 1) - t_stress(2, 2))
4983 (
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
4984 (t_stress(2, 2) - t_stress(0, 0))
4986 6 * (t_stress(0, 1) * t_stress(0, 1) +
4987 (
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
4988 (
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
4993 getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
4994 CHKERR getVonMisesStress(t_stress);
4997 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
4998 CHKERR getVonMisesStress(t_stress);
5000 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
5001 <<
"Eval point von Mises Stress: " << von_mises_stress;
5002 if (
atom_test && fabs(test_monitor_ptr->ts_t - 10) < 1e-12) {
5003 if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
5005 "atom test %d failed: wrong von Mises stress value",
5008 if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
5010 "atom test %d failed: wrong von Mises stress value",
5013 if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
5015 "atom test %d failed: wrong von Mises stress value",
5018 if (
atom_test == 5 && fabs(von_mises_stress) > 5e-2) {
5020 "atom test %d failed: wrong von Mises stress value",
5025 if (plasticMultiplierFieldPtr->size()) {
5026 auto t_plastic_multiplier =
5028 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
5029 <<
"Eval point TAU magnitude: " << t_plastic_multiplier;
5030 if (
atom_test == 8 && fabs(t_plastic_multiplier - 1.5) > 1e-12) {
5032 "atom test %d failed: wrong plastic multiplier value",
5036 if (plasticStrainFieldPtr->size1()) {
5039 auto t_plastic_strain =
5040 getFTensor2SymmetricFromMat<SPACE_DIM>(*plasticStrainFieldPtr);
5041 MOFEM_LOG(
"THERMOPLASTICITY", Sev::inform)
5042 <<
"Eval point EP(0,0) = " << t_plastic_strain(0, 0)
5043 <<
", EP(0,1) = " << t_plastic_strain(0, 1)
5044 <<
", EP(1,1) = " << t_plastic_strain(1, 1);
5046 if (fabs(t_plastic_strain(0, 0) - 0.005) > 1e-12) {
5048 "atom test %d failed: wrong EP(0,0) value",
atom_test);
5050 if (fabs(t_plastic_strain(0, 1) - 0.025) > 1e-12) {
5052 "atom test %d failed: wrong EP(0,1) value",
atom_test);
5054 if (fabs(t_plastic_strain(1, 1) - 0.015) > 1e-12) {
5056 "atom test %d failed: wrong EP(1,1) value",
atom_test);
5064 auto null = boost::shared_ptr<FEMethod>();
5066 test_monitor_ptr, null);
5072 auto set_schur_pc = [&](
auto solver,
5073 boost::shared_ptr<SetUpSchur> &schur_ptr) {
5076 auto name_prb =
simple->getProblemName();
5082 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5087 for (
auto f : {
"U",
"FLUX"}) {
5099 dm_sub =
createDM(mField.get_comm(),
"DMMOFEM");
5105 for (
auto f : {
"SIGMA",
"EP",
"TAU",
"T"}) {
5110 for (
auto f : {
"EP",
"TAU",
"T"}) {
5120 if constexpr (
AT == AssemblyType::BLOCK_SCHUR) {
5129 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5135 {simple->getDomainFEName(),
5158 {simple->getBoundaryFEName(),
5160 {{
"SIGMA",
"SIGMA"}, {
"U",
"SIGMA"}, {
"SIGMA",
"U"}
5170 {dm_schur, dm_block}, block_mat_data,
5172 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5180 auto get_nested_mat_data = [&](
auto schur_dm,
auto block_dm) {
5181 auto block_mat_data =
5184 {{simple->getDomainFEName(),
5210 {dm_schur, dm_block}, block_mat_data,
5212 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr}, false
5219 auto nested_mat_data = get_nested_mat_data(dm_schur, dm_block);
5222 auto block_is =
getDMSubData(dm_block)->getSmartRowIs();
5223 auto ao_schur =
getDMSubData(dm_schur)->getSmartRowMap();
5229 CHKERR schur_ptr->setUp(solver);
5235 auto dm =
simple->getDM();
5238 uXScatter = scatter_create(
D, 0);
5239 uYScatter = scatter_create(
D, 1);
5241 uZScatter = scatter_create(
D, 2);
5243 auto create_solver = [pip_mng]() {
5245 return pip_mng->createTSIM();
5247 return pip_mng->createTSIM2();
5257 CHKERR VecLoad(solution_vector, viewer);
5258 CHKERR PetscViewerDestroy(&viewer);
5263 auto solver = create_solver();
5265 auto active_pre_lhs = []() {
5272 auto active_post_lhs = [&]() {
5274 auto get_iter = [&]() {
5279 "Can not get iter");
5283 auto iter = get_iter();
5286 std::array<int, 5> activity_data;
5287 std::fill(activity_data.begin(), activity_data.end(), 0);
5289 activity_data.data(), activity_data.size(), MPI_INT,
5290 MPI_SUM, mField.get_comm());
5292 int &active_points = activity_data[0];
5293 int &avtive_full_elems = activity_data[1];
5294 int &avtive_elems = activity_data[2];
5295 int &nb_points = activity_data[3];
5296 int &nb_elements = activity_data[4];
5300 double proc_nb_points =
5301 100 *
static_cast<double>(active_points) / nb_points;
5302 double proc_nb_active =
5303 100 *
static_cast<double>(avtive_elems) / nb_elements;
5304 double proc_nb_full_active = 100;
5306 proc_nb_full_active =
5307 100 *
static_cast<double>(avtive_full_elems) / avtive_elems;
5310 "Iter %d nb pts %d nb active pts %d (%3.3f\%) nb active "
5312 "(%3.3f\%) nb full active elems %d (%3.3f\%)",
5313 iter, nb_points, active_points, proc_nb_points,
5314 avtive_elems, proc_nb_active, avtive_full_elems,
5315 proc_nb_full_active, iter);
5322 auto add_active_dofs_elem = [&](
auto dm) {
5324 auto fe_pre_proc = boost::make_shared<FEMethod>();
5325 fe_pre_proc->preProcessHook = active_pre_lhs;
5326 auto fe_post_proc = boost::make_shared<FEMethod>();
5327 fe_post_proc->postProcessHook = active_post_lhs;
5329 ts_ctx_ptr->getPreProcessIJacobian().push_front(fe_pre_proc);
5330 ts_ctx_ptr->getPostProcessIJacobian().push_back(fe_post_proc);
5334 auto set_essential_bc = [&](
auto dm,
auto solver) {
5338 auto pre_proc_ptr = boost::make_shared<FEMethod>();
5339 auto post_proc_rhs_ptr = boost::make_shared<FEMethod>();
5340 auto post_proc_lhs_ptr = boost::make_shared<FEMethod>();
5343 auto disp_time_scale = boost::make_shared<TimeScale>();
5345 auto get_bc_hook_rhs = [
this, pre_proc_ptr, disp_time_scale]() {
5347 {disp_time_scale},
false);
5350 pre_proc_ptr->preProcessHook = get_bc_hook_rhs();
5352 auto get_post_proc_hook_rhs = [
this, post_proc_rhs_ptr]() {
5355 mField, post_proc_rhs_ptr,
nullptr, Sev::verbose)();
5357 mField, post_proc_rhs_ptr, 1.)();
5360 auto get_post_proc_hook_lhs = [
this, post_proc_lhs_ptr]() {
5362 mField, post_proc_lhs_ptr, 1.);
5364 post_proc_rhs_ptr->postProcessHook = get_post_proc_hook_rhs;
5367 ts_ctx_ptr->getPreProcessIFunction().push_front(pre_proc_ptr);
5368 ts_ctx_ptr->getPreProcessIJacobian().push_front(pre_proc_ptr);
5369 ts_ctx_ptr->getPostProcessIFunction().push_back(post_proc_rhs_ptr);
5370 post_proc_lhs_ptr->postProcessHook = get_post_proc_hook_lhs();
5371 ts_ctx_ptr->getPostProcessIJacobian().push_back(post_proc_lhs_ptr);
5379 CHKERR TSSetSolution(solver,
D);
5381 CHKERR TS2SetSolution(solver,
D, DD);
5384 auto set_up_adapt = [&](
auto solver) {
5388 CHKERR TSGetAdapt(solver, &adapt);
5392 CHKERR set_section_monitor(solver);
5393 CHKERR set_time_monitor(dm, solver);
5394 CHKERR set_up_adapt(solver);
5395 CHKERR TSSetFromOptions(solver);
5404 CHKERR add_active_dofs_elem(dm);
5405 boost::shared_ptr<SetUpSchur> schur_ptr;
5406 CHKERR set_schur_pc(solver, schur_ptr);
5407 CHKERR set_essential_bc(dm, solver);
5409 auto my_ctx = boost::make_shared<MyTsCtx>();
5414 CHKERR TSGetSNES(solver, &snes);
5420 auto my_rhs = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec F,
void *ctx) {
5430 double time_increment;
5432 if (time_increment <
min_dt) {
5434 "Minimum time increment exceeded");
5438 int error = system(
"rm ./out_snes_residual_iter_*.h5m > /dev/null 2>&1");
5444 "Cannot get timestep from TS object");
5448 "Minimum timestep exceeded");
5452 auto post_proc = [&](
auto dm,
auto f_res,
auto sol,
auto sol_dot,
5461 boost::make_shared<PostProcBrokenMeshInMoab<DomainEle>>(
5463 auto &pip = post_proc_fe->getOpPtrVector();
5469 auto disp_res_mat = boost::make_shared<MatrixDouble>();
5470 auto tau_res_vec = boost::make_shared<VectorDouble>();
5471 auto plastic_strain_res_mat = boost::make_shared<MatrixDouble>();
5472 auto flux_res_mat = boost::make_shared<MatrixDouble>();
5473 auto temp_res_vec = boost::make_shared<VectorDouble>();
5476 "U", disp_res_mat, smart_f_res));
5480 "EP", plastic_strain_res_mat, smart_f_res));
5488 auto disp_mat = boost::make_shared<MatrixDouble>();
5489 auto tau_vec = boost::make_shared<VectorDouble>();
5490 auto plastic_strain_mat = boost::make_shared<MatrixDouble>();
5491 auto flux_mat = boost::make_shared<MatrixDouble>();
5492 auto temp_vec = boost::make_shared<VectorDouble>();
5497 "EP", plastic_strain_mat));
5504 auto disp_dot_mat = boost::make_shared<MatrixDouble>();
5505 auto tau_dot_vec = boost::make_shared<VectorDouble>();
5506 auto plastic_strain_dot_mat = boost::make_shared<MatrixDouble>();
5507 auto flux_dot_mat = boost::make_shared<MatrixDouble>();
5508 auto temp_dot_vec = boost::make_shared<VectorDouble>();
5511 "U", disp_dot_mat, smart_sol_dot));
5515 "EP", plastic_strain_dot_mat, smart_sol_dot));
5523 auto make_d_mat = [&]() {
5527 auto push_vol_ops = [&](
auto &pip) {
5532 const double) {
return 1.; };
5534 auto [common_plastic_ptr, common_hencky_ptr, common_thermal_ptr,
5535 common_thermoelastic_ptr, common_thermoplastic_ptr] =
5538 m_field,
"MAT_PLASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC",
5539 "MAT_THERMOPLASTIC", pip,
"U",
"EP",
"TAU",
"T", 1.,
5540 unity_2_args, unity_2_args, unity_3_args, Sev::inform);
5542 if (common_hencky_ptr) {
5543 if (common_plastic_ptr->mGradPtr != common_hencky_ptr->matGradPtr)
5545 "Wrong pointer for grad");
5548 return std::make_tuple(common_plastic_ptr, common_hencky_ptr,
5549 common_thermoplastic_ptr);
5552 auto push_vol_post_proc_ops = [&](
auto &pp_fe,
auto &&p) {
5555 auto &pip = pp_fe->getOpPtrVector();
5557 auto [common_plastic_ptr, common_hencky_ptr, common_thermoplastic_ptr] =
5560 auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
5561 auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
5563 auto vec_temp_ptr = boost::make_shared<VectorDouble>();
5564 auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
5566 auto u_ptr = boost::make_shared<MatrixDouble>();
5577 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5579 {{
"RESIDUAL_TAU", tau_res_vec},
5580 {
"RESIDUAL_T", temp_res_vec},
5583 {
"RATE_TAU", tau_dot_vec},
5584 {
"RATE_T", temp_dot_vec},
5585 {
"ISOTROPIC_HARDENING",
5586 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5588 common_plastic_ptr->getPlasticSurfacePtr()},
5589 {
"PLASTIC_MULTIPLIER",
5590 common_plastic_ptr->getPlasticTauPtr()},
5592 common_plastic_ptr->getPlasticSurfacePtr()},
5593 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5595 {{
"RESIDUAL_U", disp_res_mat},
5596 {
"RATE_U", disp_dot_mat},
5598 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5600 {{
"GRAD", common_hencky_ptr->matGradPtr},
5602 common_hencky_ptr->getMatFirstPiolaStress()}},
5604 {{
"RESIDUAL_EP", plastic_strain_res_mat},
5605 {
"RATE_EP", plastic_strain_dot_mat},
5607 common_plastic_ptr->getPlasticStrainPtr()},
5608 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()},
5609 {
"HENCKY_STRAIN", common_hencky_ptr->getMatLogC()},
5610 {
"HENCKY_STRESS", common_hencky_ptr->getMatHenckyStress()}}
5622 pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
5624 {{
"RESIDUAL_TAU", tau_res_vec},
5625 {
"RESIDUAL_T", temp_res_vec},
5628 {
"RATE_TAU", tau_dot_vec},
5629 {
"RATE_T", temp_dot_vec},
5630 {
"ISOTROPIC_HARDENING",
5631 common_plastic_ptr->getPlasticIsoHardeningPtr()},
5633 common_plastic_ptr->getPlasticSurfacePtr()},
5634 {
"PLASTIC_MULTIPLIER",
5635 common_plastic_ptr->getPlasticTauPtr()},
5637 common_plastic_ptr->getPlasticSurfacePtr()},
5638 {
"T", common_thermoplastic_ptr->getTempPtr()}},
5640 {{
"RESIDUAL_U", disp_res_mat},
5644 {
"RATE_U", disp_dot_mat},
5646 {
"FLUX", common_thermoplastic_ptr->getHeatFluxPtr()}},
5650 {{
"RESIDUAL_PLASTIC_STRAIN", plastic_strain_res_mat},
5651 {
"PLASTIC_STRAIN", plastic_strain_mat},
5652 {
"RATE_PLASTIC_STRAIN", plastic_strain_dot_mat},
5653 {
"STRAIN", common_plastic_ptr->mStrainPtr},
5654 {
"STRESS", common_plastic_ptr->mStressPtr},
5656 common_plastic_ptr->getPlasticStrainPtr()},
5657 {
"PLASTIC_FLOW", common_plastic_ptr->getPlasticFlowPtr()}}
5667 CHK_MOAB_THROW(push_vol_post_proc_ops(post_proc_fe, push_vol_ops(pip)),
5668 "push_vol_post_proc_ops");
5673 post_proc_fe->writeFile(out_name);
5684 "out_snes_residual_iter_" +
5689 PetscBool is_output_residual_fields = PETSC_FALSE;
5691 &is_output_residual_fields, PETSC_NULLPTR);
5693 if (is_output_residual_fields == PETSC_TRUE) {
5696 CHKERR TSSetIFunction(solver, PETSC_NULLPTR, my_rhs, my_ctx.get());
5699 CHKERR TSSetDM(solver, dm);
5701 auto ts_pre_post_proc = boost::make_shared<TSPrePostProc>();
5705 ptr->ExRawPtr =
this;
5706 std::multimap<double, EntityHandle> no_el_q_map;
5707 Range no_flipped_els;
5708 std::vector<EntityHandle> no_new_connectivity;
5709 Tag no_th_spatial_coords;
5712 &mField, PETSC_FALSE, no_el_q_map,
5713 no_flipped_els, no_new_connectivity, no_th_spatial_coords};
5714 PetscBool rollback =
5718 CHKERR TSSetApplicationContext(solver, (
void *)ctx);
5727 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
5728 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp";
5729 CHKERR ptr->tsSetUp(solver);
5731 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSetUp <= done";
5732 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve";
5733 CHKERR TSSolve(solver, PETSC_NULLPTR);
5734 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"TSSolve <= done";
5746 #ifdef ENABLE_PYTHON_BINDING
5753 const char param_file[] =
"param_file.petsc";
5757 auto core_log = logging::core::get();
5787 DMType dm_name =
"DMMOFEM";
5792 moab::Core mb_instance;
5793 moab::Interface &moab = mb_instance;
5813 char meshFileName[255];
5815 meshFileName, 255, PETSC_NULLPTR);
5837 #ifdef ENABLE_PYTHON_BINDING
5838 if (Py_FinalizeEx() < 0) {
5851 :
SetUpSchur(), mField(m_field), subDM(sub_dm),
5852 fieldSplitIS(field_split_is), aoSchur(ao_up) {
5855 "Is expected that schur matrix is not "
5856 "allocated. This is "
5857 "possible only is PC is set up twice");
5881 CHKERR TSGetSNES(solver, &snes);
5883 CHKERR SNESGetKSP(snes, &ksp);
5884 CHKERR KSPSetFromOptions(ksp);
5887 CHKERR KSPGetPC(ksp, &pc);
5888 PetscBool is_pcfs = PETSC_FALSE;
5889 PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
5893 "Is expected that schur matrix is not "
5894 "allocated. This is "
5895 "possible only is PC is set up twice");
5904 CHKERR TSGetDM(solver, &solver_dm);
5905 CHKERR DMSetMatType(solver_dm, MATSHELL);
5912 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t, PetscReal
a,
5913 Mat
A, Mat
B,
void *ctx) {
5916 CHKERR TSSetIJacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5918 auto swap_assemble = [](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec utt,
5919 PetscReal
a, PetscReal aa, Mat
A, Mat
B,
5923 CHKERR TSSetI2Jacobian(solver,
A, P, swap_assemble, ts_ctx_ptr.get());
5925 CHKERR KSPSetOperators(ksp,
A, P);
5927 auto set_ops = [&]() {
5933 pip_mng->getOpBoundaryLhsPipeline().push_front(
5937 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5942 pip_mng->getOpDomainLhsPipeline().push_front(
5946 {
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr},
aoSchur,
S,
false,
5952 double eps_stab = 1e-4;
5958 using OpMassStab = B::OpMass<3, SPACE_DIM * SPACE_DIM>;
5961 pip_mng->getOpBoundaryLhsPipeline().push_front(
5963 pip_mng->getOpBoundaryLhsPipeline().push_back(
5964 new OpMassStab(
"SIGMA",
"SIGMA", [eps_stab](
double,
double,
double) {
5969 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5974 pip_mng->getOpDomainLhsPipeline().push_front(
5978 {
"SIGMA",
"EP",
"TAU",
"T"}, {
nullptr,
nullptr,
nullptr,
nullptr},
5986 auto set_assemble_elems = [&]() {
5988 auto schur_asmb_pre_proc = boost::make_shared<FEMethod>();
5989 schur_asmb_pre_proc->preProcessHook = [
this]() {
5992 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble Begin";
5995 auto schur_asmb_post_proc = boost::make_shared<FEMethod>();
5997 schur_asmb_post_proc->postProcessHook = [
this, schur_asmb_post_proc]() {
5999 MOFEM_LOG(
"TIMER", Sev::verbose) <<
"Lhs Assemble End";
6002 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
6003 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
6010 ts_ctx_ptr->getPreProcessIJacobian().push_front(schur_asmb_pre_proc);
6011 ts_ctx_ptr->getPostProcessIJacobian().push_front(schur_asmb_post_proc);
6015 auto set_pc = [&]() {
6018 CHKERR PCFieldSplitSetSchurPre(pc, PC_FIELDSPLIT_SCHUR_PRE_USER,
S);
6022 auto set_diagonal_pc = [&]() {
6025 CHKERR PCFieldSplitSchurGetSubKSP(pc, PETSC_NULLPTR, &subksp);
6026 auto get_pc = [](
auto ksp) {
6028 CHKERR KSPGetPC(ksp, &pc_raw);
6033 CHKERR PetscFree(subksp);
6039 CHKERR set_assemble_elems();
6043 CHKERR set_diagonal_pc();
6046 pip_mng->getOpBoundaryLhsPipeline().push_front(
6048 pip_mng->getOpBoundaryLhsPipeline().push_back(
6051 pip_mng->getOpDomainLhsPipeline().push_back(
6060boost::shared_ptr<SetUpSchur>
6064 return boost::shared_ptr<SetUpSchur>(
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
Kronecker Delta class symmetric.
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define BITREFLEVEL_SIZE
max number of refinements
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
FieldSpace
approximation spaces
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_STD_EXCEPTION_THROW
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesVector< 1, SPACE_DIM, SPACE_DIM > OpInertiaForce
PetscErrorCode DMoFEMMeshToGlobalVector(DM dm, Vec g, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set ghosted vector values on all existing mesh entities
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 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 DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
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, RowColData rc=RowColData::COL)
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 DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
PetscErrorCode DMSetUp_MoFEM(DM dm)
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
MoFEMErrorCode lambdaBitRefLevel(boost::function< void(EntityHandle ent, BitRefLevel &bit)> fun) const
Process bit ref level by lambda function.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
virtual MoFEMErrorCode modify_problem_mask_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set dof mask ref level for problem
virtual MoFEMErrorCode modify_problem_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set ref level for problem
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
const FTensor::Tensor2< T, Dim, Dim > Vec
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
auto type_from_handle(const EntityHandle h)
get type from entity handle
auto createKSP(MPI_Comm comm)
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
PetscErrorCode TsSetIJacobian(TS ts, PetscReal t, Vec u, Vec u_t, PetscReal a, Mat A, Mat B, void *ctx)
Set function evaluating jacobian in TS solver.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
OpSchurAssembleBase * createOpSchurAssembleEnd(std::vector< std::string > fields_name, std::vector< boost::shared_ptr< Range > > field_ents, SmartPetscObj< AO > ao, SmartPetscObj< Mat > schur, bool sym_schur, bool symm_op)
Construct a new Op Schur Assemble End object.
auto createSNES(MPI_Comm comm)
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
MoFEMErrorCode setSchurA00MatSolvePC(SmartPetscObj< PC > pc)
Set PC for A00 block.
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode TsSetIFunction(TS ts, PetscReal t, Vec u, Vec u_t, Vec F, void *ctx)
Set IFunction for TS solver.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
auto getDMSubData(DM dm)
Get sub problem data structure.
auto getFTensor1FromMat(M &data, int rr=0, int cc=0)
Get tensor rank 1 (vector) form data matrix.
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.
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 >)
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
auto createDMNestSchurMat(DM dm)
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
PetscErrorCode TSAdaptCreateMoFEM(TSAdapt adapt)
Craete MOFEM adapt.
OpSchurAssembleBase * createOpSchurAssembleBegin()
auto createDMBlockMat(DM dm)
boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > Pip
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux times base of temperature (FLUX x T) and transpose of it,...
OpHdivHdivImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivHdiv
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpCapacity
Integrate Lhs base of temperature times (heat capacity) times base of temperature (T x T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
OpCalculateQdotQLhs_dU< SPACE_DIM, GAUSS, AssemblyDomainEleOp, IS_LARGE_STRAINS > OpHdivU
Integrate Lhs of flux term coupled to displacement field.
OpHdivFluxImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivFlux
MoFEMErrorCode addMatThermalBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, double default_heat_conductivity, double default_heat_capacity, double default_thermal_conductivity_scale, double default_thermal_capacity_scale, Sev sev, ScalerFunTwoArgs thermal_conductivity_scaling_func, ScalerFunTwoArgs heat_capacity_scaling_func)
MoFEMErrorCode addMatThermoElasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, double default_coeff_expansion, double default_ref_temp, Sev sev)
MoFEMErrorCode addMatThermoPlasticBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string thermoplastic_block_name, boost::shared_ptr< ThermoPlasticBlockedParameters > blockedParamsPtr, boost::shared_ptr< ThermoElasticOps::BlockedThermalParameters > &blockedThermalParamsPtr, Sev sev, ScalerFunThreeArgs inelastic_heat_fraction_scaling)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr IntegrationType I
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
constexpr auto field_name
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
constexpr double heat_conductivity
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
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 >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, -1 > OpKPiola
[Only used for dynamics]
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 >::FaceSideEle SideEle
PipelineManager::ElementsAndOpsByDim< 3 >::FaceSideEle SideEle
double getScale(const double time)
Get scaling at given time.
boost::shared_ptr< VectorDouble > tempFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainLhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
boost::shared_ptr< DomainEle > reactionFe
MoFEMErrorCode edgeFlips(BitRefLevel parent_bit, BitRefLevel child_bit)
boost::shared_ptr< MatrixDouble > strainFieldPtr
MoFEMErrorCode doEdgeSplits(bool &refine, bool add_ents)
[Do Edge Flips]
boost::shared_ptr< MatrixDouble > dispGradPtr
FieldApproximationBase base
Choice of finite element basis functions.
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uYScatter
MoFEMErrorCode createCommonData()
MoFEMErrorCode mechanicalBC(BitRefLevel bit, BitRefLevel mask)
[Initial conditions]
friend struct TSPrePostProc
MoFEMErrorCode getElementQuality(std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, std::vector< EntityHandle > &new_connectivity, bool &do_refine, Tag &th_spatial_coords)
[Get element quality]
boost::shared_ptr< VectorDouble > plasticMultiplierFieldPtr
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
boost::shared_ptr< MatrixDouble > stressFieldPtr
MoFEM::Interface & mField
Reference to MoFEM interface.
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uZScatter
boost::shared_ptr< MatrixDouble > fluxFieldPtr
MoFEMErrorCode setupProblem()
boost::shared_ptr< MatrixDouble > dispFieldPtr
boost::shared_ptr< MatrixDouble > plasticStrainFieldPtr
MoFEMErrorCode opThermoPlasticFactoryDomainRhs(MoFEM::Interface &m_field, std::string block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, Pip &pip, std::string u, std::string ep, std::string tau, std::string temperature)
MoFEMErrorCode thermalBC(BitRefLevel bit, BitRefLevel mask)
[Mechanical boundary conditions]
std::tuple< SmartPetscObj< Vec >, SmartPetscObj< VecScatter > > uXScatter
MoFEMErrorCode doEdgeFlips(std::multimap< double, EntityHandle > &el_q_map, Range &flipped_els, Tag &th_spatial_coords, std::vector< EntityHandle > &new_connectivity)
[Edge flips]
MoFEMErrorCode initialConditions()
[Create common data]
auto createCommonThermoPlasticOps(MoFEM::Interface &m_field, std::string plastic_block_name, std::string thermal_block_name, std::string thermoelastic_block_name, std::string thermoplastic_block_name, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string u, std::string ep, std::string tau, std::string temperature, double scale, ScalerFunTwoArgs thermal_conductivity_scaling, ScalerFunTwoArgs heat_capacity_scaling, ScalerFunThreeArgs inelastic_heat_fraction_scaling, Sev sev, bool with_rates=true)
Add operators pushing bases from local to physical configuration.
Boundary condition manager for finite element problem setup.
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
auto getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Class (Function) to enforce essential constrains on the left hand side diagonal.
Class (Function) to enforce essential constrains on the right hand side diagonal.
Class (Function) to calculate residual side diagonal.
Class (Function) to enforce essential constrains.
Structure for user loop methods on finite elements.
Field evaluator interface.
SetIntegrationPtsMethodData SetPtsData
structure to get information from mofem into EntitiesFieldData
Definition of the heat flux bc data structure.
Section manager is used to create indexes and sections.
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Mesh refinement interface.
MoFEMErrorCode addVerticesInTheMiddleOfEdges(const EntityHandle meshset, const BitRefLevel &bit, const bool recursive=false, int verb=QUIET, EntityHandle start_v=0)
make vertices in the middle of edges in meshset and add them to refinement levels defined by bit
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode updateAllMeshsetsByEntitiesChildren(const BitRefLevel &bit)
Update all blocksets, sidesets and node sets.
Natural boundary conditions.
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Specialization for double precision scalar field values calculation.
Calculate symmetric tensor field rates ant integratio pts.
Calculate symmetric tensor field values at integration pts.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Approximate field values for given petsc vector.
Specialization for MatrixDouble vector field values calculation.
Enforce essential constrains on lhs.
Enforce essential constrains on rhs.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
Set indices on entities on finite element.
Operator for symmetrizing tensor fields.
Unset indices on entities on finite element.
Template struct for dimension-specific finite element types.
PipelineManager interface.
MoFEM::VolumeElementForcesAndSourcesCore VolEle
boost::shared_ptr< FEMethod > & getDomainLhsFE()
Get domain left-hand side finite element.
MoFEM::FaceElementForcesAndSourcesCore FaceEle
MoFEM::EdgeElementForcesAndSourcesCore EdgeEle
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
MoFEMErrorCode getOptions()
get options
intrusive_ptr for managing petsc objects
Force scale operator for reading two columns.
double getScale(const double time)
Get scaling at a given time.
TimeScale(std::string file_name="", bool error_if_file_not_given=false, ScalingFun def_scaling_fun=[](double time) { return time;})
TimeScale constructor.
MoFEM::Interface & mField
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
Volume finite element base.
boost::shared_ptr< MoFEM::TsCtx > dmts_ctx
PetscInt snes_iter_counter
static std::array< int, 5 > activityData
boost::weak_ptr< TSPrePostProc > ptr
MoFEM::Interface * m_field
std::vector< EntityHandle > new_connectivity
std::multimap< double, EntityHandle > el_q_map
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
SmartPetscObj< DM > subDM
field split sub dm
SmartPetscObj< AO > aoSchur
MoFEMErrorCode setUp(TS solver)
SmartPetscObj< IS > fieldSplitIS
IS for split Schur block.
SetUpSchurImpl(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_is, SmartPetscObj< AO > ao_up)
MoFEMErrorCode setUp(SmartPetscObj< KSP >)
virtual ~SetUpSchurImpl()
MoFEMErrorCode postProc()
MoFEM::Interface & mField
[Push operators to pipeline]
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, SmartPetscObj< DM > sub_dm, SmartPetscObj< IS > field_split_it, SmartPetscObj< AO > ao_map)
Create data structure for handling Schur complement.
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field)
virtual MoFEMErrorCode setUp(TS solver)=0
MoFEMErrorCode mapFields(SmartPetscObj< DM > &intermediateDM, BitRefLevel parentBit, BitRefLevel childBit, PetscInt numVecs=1, Vec vecsToMapFrom[]=PETSC_NULLPTR, Vec vecsToMapTo[]=PETSC_NULLPTR)
MoFEMErrorCode reSetUp(std::vector< std::string > L2Fields, std::vector< int > L2Oders, std::vector< std::string > H1Fields, std::vector< int > H1Orders, std::vector< std::string > HdivFields, std::vector< int > HdivOrders, BitRefLevel bIt)
Set of functions called by PETSc solver used to refine and update mesh.
virtual ~TSPrePostProc()=default
static MoFEMErrorCode tsPreProc(TS ts)
Pre process time step.
static MoFEMErrorCode tsPostProc(TS ts)
Post process time step.
static MoFEMErrorCode tsPostProc(TS ts)
Post process time step.
static MoFEMErrorCode tsPreStage(TS ts)
static MoFEMErrorCode tsPreProc(TS ts)
Pre process time step.
MoFEMErrorCode tsSetUp(TS ts)
Used to setup TS solver.
constexpr AssemblyType AT
constexpr IntegrationType IT
double iso_hardening_dtemp(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
double young_modulus
Young modulus.
double default_heat_capacity_scale
constexpr AssemblyType AT
static boost::weak_ptr< TSPrePostProc > tsPrePostProc
double C1_k
Kinematic hardening.
int post_processing_counter
double exp_softening(double temp_hat)
double Qinf
Saturation yield stress.
constexpr IntegrationType IT
static char help[]
[Solve]
auto init_T
Initialisation function for temperature field.
double default_thermal_conductivity_scale
ScalerFunTwoArgs heat_capacity_scaling
double dH_thermal_dtemp(double H, double omega_h)
constexpr bool IS_LARGE_STRAINS
ScalerFunThreeArgs inelastic_heat_fraction_scaling
PetscBool is_distributed_mesh
#define EXECUTABLE_DIMENSION
PetscBool do_eval_field
Evaluate field.
PetscBool is_quasi_static
double dy_0_thermal_dtemp(double sigmaY, double omega_0)
boost::function< double(const double, const double, const double)> ScalerFunThreeArgs
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
boost::function< double(const double, const double)> ScalerFunTwoArgs
double iso_hardening(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
Example * thermoplastic_raw_ptr
PetscErrorCode MyTSResizeSetup(TS ts, PetscInt nstep, PetscReal time, Vec sol, PetscBool *resize, void *ctx)
BitRefLevel virgin_mesh_bit
static std::unordered_map< TS, ResizeCtx * > ts_to_rctx
PetscErrorCode MyTSResizeTransfer(TS, PetscInt, Vec[], Vec[], void *)
double Qinf_thermal(double Qinf, double omega_h, double temp_0, double temp)
BitRefLevel comp_mesh_bit
auto kinematic_hardening(FTensor::Tensor2_symmetric< T, DIM > &t_plastic_strain, double C1_k)
double default_heat_capacity
PetscBool set_timer
Set timer.
const char *const ICTypes[]
double temp_hat(double temp)
const bool is_large_strains
double edge_growth_thresh
auto postProcessHere(MoFEM::Interface &m_field, SmartPetscObj< DM > &dm, std::string output_name, int &counter= *(new int(0)))
int flux_order
Order of tau field.
MoFEMErrorCode TSIterationPreStage(TS ts, PetscReal stagetime)
double zeta
regularisation parameter
int T_order
Order of ep field.
BitRefLevel prev_mesh_bit
double y_0_thermal(double sigmaY, double omega_0, double temp_0, double temp)
double width
Width of Gaussian distribution.
double default_coeff_expansion
int tau_order
Order of tau field.
double iso_hardening_dtau(double tau, double H, double omega_0, double Qinf, double omega_h, double b_iso, double sigmaY, double temp_0, double temp)
auto uniform_distribution
auto get_string_from_vector
auto printOnAllCores(MoFEM::Interface &m_field, const std::string &out_put_string, const auto &out_put_quantity)
MoFEMErrorCode SNESIterationMonitor(SNES snes, PetscInt its, PetscReal norm, void *ctx)
double omega_0
flow stress softening
double iso_hardening_exp(double tau, double b_iso)
auto postProcessPETScHere(MoFEM::Interface &m_field, SmartPetscObj< DM > &dm, Vec sol, std::string output_name)
double H_thermal(double H, double omega_h, double temp_0, double temp)
int order
Order displacement.
double b_iso
Saturation exponent.
auto Gaussian_distribution
int geom_order
Order if fixed.
double sigmaY
Yield stress.
ScalerFunTwoArgs thermal_conductivity_scaling
double default_heat_conductivity
auto kinematic_hardening_dplastic_strain(double C1_k)
double inelastic_heat_fraction
fraction of plastic dissipation converted to heat
int num_refinement_levels
double temp_0
reference temperature for thermal softening
static std::unordered_map< TS, MyTsCtx * > ts_to_ctx
int ep_order
Order of ep field.
double dQinf_thermal_dtemp(double Qinf, double omega_h)
constexpr FieldSpace CONTACT_SPACE
double omega_h
hardening softening
double young_modulus
Young modulus.
double C1_k
Kinematic hardening.
double Qinf
Saturation yield stress.
PetscBool is_quasi_static
double visH
Viscous hardening.
double poisson_ratio
Poisson ratio.
PetscBool set_timer
Set timer.
double zeta
Viscous hardening.
int tau_order
Order of tau files.
double b_iso
Saturation exponent.
PetscBool is_large_strains
Large strains.
int geom_order
Order if fixed.
double sigmaY
Yield stress.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
int ep_order
Order of ep files.
constexpr FieldSpace CONTACT_SPACE
#define FINITE_DEFORMATION_FLAG
constexpr bool IS_LARGE_STRAINS
double default_heat_capacity
double default_coeff_expansion
double default_heat_conductivity
constexpr int SPACE_DIM
[Define dimension]
constexpr AssemblyType A
[Define dimension]