9#include <boost/python.hpp>
10#include <boost/python/def.hpp>
11#include <boost/python/numpy.hpp>
12namespace bp = boost::python;
13namespace np = boost::python::numpy;
28 IntegrationType::GAUSS;
67template <
int SPACE_DIM, IntegrationType I,
typename OpBase>
70template <
int SPACE_DIM, IntegrationType I,
typename OpBase>
91 boost::shared_ptr<MatrixDouble> u_ptr,
92 boost::shared_ptr<MatrixDouble> stress_ptr,
93 boost::shared_ptr<MatrixDouble> strain_ptr,
94 boost::shared_ptr<VectorDouble> o_ptr) = 0;
98 boost::shared_ptr<MatrixDouble> u_ptr,
99 boost::shared_ptr<MatrixDouble> stress_ptr,
100 boost::shared_ptr<MatrixDouble> strain_ptr,
101 boost::shared_ptr<MatrixDouble> o_ptr) = 0;
105 boost::shared_ptr<MatrixDouble> u_ptr,
106 boost::shared_ptr<MatrixDouble> stress_ptr,
107 boost::shared_ptr<MatrixDouble> strain_ptr,
108 boost::shared_ptr<MatrixDouble> o_ptr) = 0;
113 std::array<double, 3> ¢roid,
114 std::array<double, 6> &bbox,
120boost::shared_ptr<ObjectiveFunctionData>
124 const std::string block_name,
int dim);
149 Vec objective_function_gradient,
168 char objective_function_file_name[255] =
"objective_function.py";
170 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
171 objective_function_file_name, 255, PETSC_NULLPTR);
172 auto file_exists = [](std::string myfile) {
173 std::ifstream file(myfile.c_str());
179 if (!file_exists(objective_function_file_name)) {
180 MOFEM_LOG(
"WORLD", Sev::error) <<
"Objective function file NOT found: "
181 << objective_function_file_name;
200 auto create_vec_modes = [&](
auto block_name) {
205 std::regex((boost::format(
"%s(.*)") % block_name).str())
209 int nb_total_modes = 0;
210 for (
auto &bc : bcs) {
211 auto id = bc->getMeshsetId();
214 nb_total_modes += nb_modes;
218 <<
"Total number of modes to apply: " << nb_total_modes;
225 auto get_modes_bounding_boxes = [&](
auto block_name) {
230 std::regex((boost::format(
"%s(.*)") % block_name).str())
234 for (
auto &bc : bcs) {
235 auto meshset = bc->getMeshset();
240 std::vector<double> x(verts.size());
241 std::vector<double> y(verts.size());
242 std::vector<double> z(verts.size());
244 std::array<double, 3> centroid = {0, 0, 0};
245 for (
int i = 0;
i != verts.size(); ++
i) {
250 MPI_Allreduce(MPI_IN_PLACE, centroid.data(), 3, MPI_DOUBLE, MPI_SUM,
252 int nb_vertex = verts.size();
253 MPI_Allreduce(MPI_IN_PLACE, &nb_vertex, 1, MPI_INT, MPI_SUM,
256 centroid[0] /= nb_vertex;
257 centroid[1] /= nb_vertex;
258 centroid[2] /= nb_vertex;
260 std::array<double, 6> bbox = {centroid[0], centroid[1], centroid[2],
261 centroid[0], centroid[1], centroid[2]};
262 for (
int i = 0;
i != verts.size(); ++
i) {
263 bbox[0] = std::min(bbox[0], x[
i]);
264 bbox[1] = std::min(bbox[1], y[
i]);
265 bbox[2] = std::min(bbox[2], z[
i]);
266 bbox[3] = std::max(bbox[3], x[
i]);
267 bbox[4] = std::max(bbox[4], y[
i]);
268 bbox[5] = std::max(bbox[5], z[
i]);
270 MPI_Allreduce(MPI_IN_PLACE, &bbox[0], 3, MPI_DOUBLE, MPI_MIN,
272 MPI_Allreduce(MPI_IN_PLACE, &bbox[3], 3, MPI_DOUBLE, MPI_MAX,
276 <<
"Block: " << bc->getName() <<
" centroid: " << centroid[0] <<
" "
277 << centroid[1] <<
" " << centroid[2];
279 <<
"Block: " << bc->getName() <<
" bbox: " << bbox[0] <<
" "
280 << bbox[1] <<
" " << bbox[2] <<
" " << bbox[3] <<
" " << bbox[4]
290 auto eval_objective_and_gradient = [](Tao tao, Vec x, PetscReal *
f, Vec
g,
291 void *ctx) -> PetscErrorCode {
296 CHKERR TaoGetIterationNumber(tao, &iter);
298 auto set_geometry = [&](Vec x) {
303 CHKERR VecScatterCreateToAll(x, &ctx, &x_local);
305 CHKERR VecScatterBegin(ctx, x, x_local, INSERT_VALUES, SCATTER_FORWARD);
306 CHKERR VecScatterEnd(ctx, x, x_local, INSERT_VALUES, SCATTER_FORWARD);
308 CHKERR VecScatterDestroy(&ctx);
311 CHKERR VecCopy(ex_ptr->initialGeometry, current_geometry);
313 CHKERR VecGetArrayRead(x_local, &
a);
314 const double *coeff =
a;
315 for (
auto &mode_vec : ex_ptr->modeVecs) {
317 <<
"Adding mode with coeff: " << *coeff;
318 CHKERR VecAXPY(current_geometry, (*coeff), mode_vec);
321 CHKERR VecRestoreArrayRead(x_local, &
a);
322 CHKERR VecGhostUpdateBegin(current_geometry, INSERT_VALUES,
324 CHKERR VecGhostUpdateEnd(current_geometry, INSERT_VALUES,
327 ->setOtherLocalGhostVector(
"ADJOINT",
"ADJOINT_FIELD",
"GEOMETRY",
329 INSERT_VALUES, SCATTER_REVERSE);
331 CHKERR VecDestroy(&x_local);
336 CHKERR KSPReset(ex_ptr->kspElastic);
337 CHKERR ex_ptr->solveElastic();
340 CHKERR ex_ptr->calculateGradient(f,
g, adjoint_vector);
341 CHKERR ex_ptr->postprocessElastic(iter, adjoint_vector);
346 CHKERR create_vec_modes(
"OPTIMISE");
347 CHKERR get_modes_bounding_boxes(
"OPTIMISE");
349 CHKERR TaoSetType(tao, TAOLMVM);
360 INSERT_VALUES, SCATTER_FORWARD);
366 CHKERR TaoSetSolution(tao, x0);
367 CHKERR TaoSetFromOptions(tao);
391 enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
392 const char *list_bases[LASBASETOPT] = {
"ainsworth",
"demkowicz"};
393 PetscInt choice_base_value = AINSWORTH;
395 LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
397 switch (choice_base_value) {
401 <<
"Set AINSWORTH_LEGENDRE_BASE for displacements";
406 <<
"Set DEMKOWICZ_JACOBI_BASE for displacements";
425 auto project_ho_geometry = [&]() {
429 CHKERR project_ho_geometry();
445 auto create_adjoint_dm = [&]() {
448 auto add_field = [&]() {
453 for (
auto tt = MBEDGE; tt <= moab::CN::TypeDimensionMap[
SPACE_DIM].second;
463 auto add_adjoint_fe_impl = [&]() {
488 auto block_name =
"OPTIMISE";
492 std::regex((boost::format(
"%s(.*)") % block_name).str())
496 for (
auto bc : bcs) {
498 bc->getMeshset(),
SPACE_DIM - 1,
"ADJOINT_BOUNDARY_FE");
504 simple->getBitRefLevelMask());
509 auto set_adjoint_dm_imp = [&]() {
513 simple->getBitRefLevelMask());
515 CHKERR DMSetFromOptions(adjoint_dm);
522 CHKERR DMSetUp(adjoint_dm);
547 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_X",
549 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Y",
551 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
"REMOVE_Z",
553 CHKERR bc_mng->removeBlockDOFsOnEntities(
simple->getProblemName(),
554 "REMOVE_ALL",
"U", 0, 3);
556 simple->getProblemName(),
"U");
572 boost::make_shared<Range>(opt_ents));
574 boost::make_shared<Range>(opt_ents));
575 CHKERR DMSetUp(subset_dm_bdy);
583 CHKERR DMSetUp(subset_dm_domain);
586 auto remove_dofs = [&]() {
589 std::array<Range, 3> remove_dim_ents;
597 for (
int d = 0; d != 3; ++d) {
599 <<
"Removing topology modes on block OPT_REMOVE_" << (char)(
'X' + d)
600 <<
" with " << remove_dim_ents[d].size() <<
" entities";
608 CHKERR skin.find_skin(0, body_ents,
false, boundary_ents);
609 for (
int d = 0; d != 3; ++d) {
610 boundary_ents = subtract(boundary_ents, remove_dim_ents[d]);
612 ParallelComm *pcomm =
614 CHKERR pcomm->filter_pstatus(boundary_ents,
615 PSTATUS_SHARED | PSTATUS_MULTISHARED,
616 PSTATUS_NOT, -1,
nullptr);
617 for (
auto d =
SPACE_DIM - 2; d >= 0; --d) {
621 moab::Interface::UNION);
622 boundary_ents.merge(ents);
626 boundary_ents.merge(verts);
631 boundary_ents.merge(opt_ents);
633 "SUBSET_DOMAIN",
"ADJOINT_FIELD", boundary_ents);
634 for (
int d = 0; d != 3; ++d) {
636 "SUBSET_DOMAIN",
"ADJOINT_FIELD", remove_dim_ents[d], d, d);
651 auto get_lhs_fe = [&]() {
652 auto fe_lhs = boost::make_shared<BoundaryEle>(
mField);
653 fe_lhs->getRuleHook = [](int, int,
int p_data) {
654 return 2 * p_data + p_data - 1;
656 auto &pip = fe_lhs->getOpPtrVector();
661 pip.push_back(
new OpMass(
"ADJOINT_FIELD",
"ADJOINT_FIELD",
662 [](
double,
double,
double) {
return 1.; }));
666 auto get_rhs_fe = [&]() {
667 auto fe_rhs = boost::make_shared<BoundaryEle>(
mField);
668 fe_rhs->getRuleHook = [](int, int,
int p_data) {
669 return 2 * p_data + p_data - 1;
671 auto &pip = fe_rhs->getOpPtrVector();
678 auto block_name =
"OPTIMISE";
682 std::regex((boost::format(
"%s(.*)") % block_name).str())
691 struct OpMode :
public OP {
692 OpMode(
const std::string name,
693 boost::shared_ptr<ObjectiveFunctionData> python_ptr,
int id,
695 std::vector<std::array<double, 3>> mode_centroids,
696 std::vector<std::array<double, 6>> mode_bboxes,
int block_counter,
697 int mode_counter, boost::shared_ptr<Range> range =
nullptr)
698 :
OP(name, name, OP::OPROW, range), pythonPtr(python_ptr), iD(
id),
699 modeVecs(mode_vecs), modeCentroids(mode_centroids),
700 modeBboxes(mode_bboxes), blockCounter(block_counter),
701 modeCounter(mode_counter) {}
707 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
715 auto nb_base_functions = data.
getN().size2();
718 CHKERR pythonPtr->blockModes(iD, OP::getCoordsAtGaussPts(),
719 modeCentroids[blockCounter],
720 modeBboxes[blockCounter], blockModes);
722 auto nb_integration_pts = getGaussPts().size2();
723 if (blockModes.size2() != 3 * nb_integration_pts) {
725 <<
"Number of modes does not match number of integration points: "
726 << blockModes.size2() <<
"!=" << 3 * nb_integration_pts;
732 int nb_modes = blockModes.size1();
733 for (
auto mode = 0; mode != nb_modes; ++mode) {
738 const double vol = OP::getMeasure();
740 auto t_w = OP::getFTensor0IntegrationWeight();
744 for (
int gg = 0; gg != nb_integration_pts; gg++) {
747 const double alpha = t_w * vol;
751 for (; rr != nb_rows /
SPACE_DIM; ++rr) {
752 t_nf(
i) += alpha * t_base * t_mode(
i);
756 for (; rr < nb_base_functions; ++rr)
761 Vec vec = modeVecs[modeCounter + mode];
763 auto *indices = data.
getIndices().data().data();
764 auto *nf_data = nf.data().data();
772 boost::shared_ptr<ObjectiveFunctionData> pythonPtr;
774 std::vector<std::array<double, 3>> modeCentroids;
775 std::vector<std::array<double, 6>> modeBboxes;
777 std::vector<SmartPetscObj<Vec>> modeVecs;
782 auto solve_bdy = [&]() {
785 auto fe_lhs = get_lhs_fe();
786 auto fe_rhs = get_rhs_fe();
787 int block_counter = 0;
788 int mode_counter = 0;
789 for (
auto &bc : bcs) {
790 auto id = bc->getMeshsetId();
794 auto range = boost::make_shared<Range>(ents);
795 auto &pip_rhs = fe_rhs->getOpPtrVector();
798 mode_counter, range));
805 mode_counter += nb_modes;
807 <<
"Setting mode block block: " << bc->getName()
808 <<
" with ID: " << bc->getMeshsetId()
809 <<
" total modes: " << mode_counter;
815 CHKERR VecGhostUpdateBegin(
v, ADD_VALUES, SCATTER_REVERSE);
816 CHKERR VecGhostUpdateEnd(
v, ADD_VALUES, SCATTER_REVERSE);
823 CHKERR MatAssemblyBegin(
M, MAT_FINAL_ASSEMBLY);
824 CHKERR MatAssemblyEnd(
M, MAT_FINAL_ASSEMBLY);
827 CHKERR KSPSetOperators(solver,
M,
M);
828 CHKERR KSPSetFromOptions(solver);
837 CHKERR VecGhostUpdateBegin(
v, INSERT_VALUES, SCATTER_FORWARD);
838 CHKERR VecGhostUpdateEnd(
v, INSERT_VALUES, SCATTER_FORWARD);
846 auto get_elastic_fe_lhs = [&]() {
847 auto fe = boost::make_shared<DomainEle>(
mField);
848 fe->getRuleHook = [](int, int,
int p_data) {
849 return 2 * p_data + p_data - 1;
851 auto &pip = fe->getOpPtrVector();
855 mField, pip,
"ADJOINT_FIELD",
"MAT_ADJOINT", Sev::noisy);
859 auto get_elastic_fe_rhs = [&]() {
860 auto fe = boost::make_shared<DomainEle>(
mField);
861 fe->getRuleHook = [](int, int,
int p_data) {
862 return 2 * p_data + p_data - 1;
864 auto &pip = fe->getOpPtrVector();
868 mField, pip,
"ADJOINT_FIELD",
"MAT_ADJOINT", Sev::noisy);
872 auto adjoint_gradient_postprocess = [&](
auto mode) {
874 auto post_proc_mesh = boost::make_shared<moab::Core>();
875 auto post_proc_begin =
876 boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
mField,
878 auto post_proc_end = boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
881 auto geom_vec = boost::make_shared<MatrixDouble>();
884 boost::make_shared<PostProcEleDomain>(
mField, post_proc_mesh);
886 post_proc_fe->getOpPtrVector(), {H1},
"GEOMETRY");
887 post_proc_fe->getOpPtrVector().push_back(
893 post_proc_fe->getOpPtrVector().push_back(
897 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
901 {{
"MODE", geom_vec}},
912 post_proc_begin->getFEMethod());
916 post_proc_begin->getFEMethod());
918 CHKERR post_proc_end->writeFile(
"mode_" + std::to_string(mode) +
".h5m");
923 auto solve_domain = [&]() {
925 auto fe_lhs = get_elastic_fe_lhs();
926 auto fe_rhs = get_elastic_fe_rhs();
935 CHKERR MatAssemblyBegin(M, MAT_FINAL_ASSEMBLY);
936 CHKERR MatAssemblyEnd(M, MAT_FINAL_ASSEMBLY);
938 auto solver =
createKSP(mField.get_comm());
939 CHKERR KSPSetOperators(solver, M, M);
940 CHKERR KSPSetFromOptions(solver);
943 int mode_counter = 0;
944 for (
auto &f : modeVecs) {
953 CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
954 CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
956 CHKERR VecGhostUpdateBegin(
v, INSERT_VALUES, SCATTER_FORWARD);
957 CHKERR VecGhostUpdateEnd(
v, INSERT_VALUES, SCATTER_FORWARD);
971 for (
int i = 0;
i < modeVecs.size(); ++
i) {
972 CHKERR adjoint_gradient_postprocess(
i);
989 auto integration_rule_bc = [](int, int,
int approx_order) {
995 CHKERR pip->setBoundaryRhsIntegrationRule(integration_rule_bc);
996 CHKERR pip->setBoundaryLhsIntegrationRule(integration_rule_bc);
1000 pip->getOpDomainLhsPipeline(), {H1},
"GEOMETRY");
1002 pip->getOpDomainRhsPipeline(), {H1},
"GEOMETRY");
1004 pip->getOpBoundaryRhsPipeline(), {NOSPACE},
"GEOMETRY");
1006 pip->getOpBoundaryLhsPipeline(), {NOSPACE},
"GEOMETRY");
1011 mField, pip->getOpDomainLhsPipeline(),
"U",
"MAT_ELASTIC", Sev::noisy);
1016 mField, pip->getOpDomainRhsPipeline(),
"U",
"MAT_ELASTIC", Sev::noisy);
1020 pip->getOpDomainRhsPipeline(),
mField,
"U", Sev::inform);
1026 pip->getOpBoundaryRhsPipeline(),
mField,
"U", -1, Sev::inform);
1029 pip->getOpBoundaryLhsPipeline(),
mField,
"U", Sev::noisy);
1042 CHKERR VecZeroEntries(d);
1045 auto set_essential_bc = [&]() {
1050 auto pre_proc_rhs = boost::make_shared<FEMethod>();
1051 auto post_proc_rhs = boost::make_shared<FEMethod>();
1052 auto post_proc_lhs = boost::make_shared<FEMethod>();
1054 auto get_pre_proc_hook = [&]() {
1058 pre_proc_rhs->preProcessHook = get_pre_proc_hook();
1060 auto get_post_proc_hook_rhs = [
this, post_proc_rhs]() {
1064 post_proc_rhs, 1.)();
1068 auto get_post_proc_hook_lhs = [
this, post_proc_lhs]() {
1072 post_proc_lhs, 1.)();
1076 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1077 post_proc_lhs->postProcessHook = get_post_proc_hook_lhs;
1079 ksp_ctx_ptr->getPreProcComputeRhs().push_front(pre_proc_rhs);
1080 ksp_ctx_ptr->getPostProcComputeRhs().push_back(post_proc_rhs);
1081 ksp_ctx_ptr->getPostProcSetOperators().push_back(post_proc_lhs);
1085 auto setup_and_solve = [&](
auto solver) {
1087 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
1088 MOFEM_LOG(
"TIMER", Sev::noisy) <<
"KSPSetUp";
1090 MOFEM_LOG(
"TIMER", Sev::noisy) <<
"KSPSetUp <= Done";
1091 MOFEM_LOG(
"TIMER", Sev::noisy) <<
"KSPSolve";
1092 CHKERR KSPSolve(solver, f, d);
1093 MOFEM_LOG(
"TIMER", Sev::noisy) <<
"KSPSolve <= Done";
1100 CHKERR set_essential_bc();
1103 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
1104 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
1107 auto evaluate_field_at_the_point = [&]() {
1111 std::array<double, 3> field_eval_coords{0.0, 0.0, 0.0};
1114 field_eval_coords.data(), &coords_dim,
1120 auto field_eval_data =
1124 ->buildTree<SPACE_DIM>(field_eval_data,
simple->getDomainFEName());
1126 field_eval_data->setEvalPoints(field_eval_coords.data(), 1);
1127 auto no_rule = [](int, int, int) {
return -1; };
1128 auto field_eval_fe_ptr = field_eval_data->feMethodPtr.lock();
1129 field_eval_fe_ptr->getRuleHook = no_rule;
1131 field_eval_fe_ptr->getOpPtrVector().push_back(
1135 ->evalFEAtThePoint<SPACE_DIM>(
1136 field_eval_coords.data(), 1e-12,
simple->getProblemName(),
1137 simple->getDomainFEName(), field_eval_data,
1144 MOFEM_LOG(
"FieldEvaluator", Sev::inform)
1145 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1);
1147 MOFEM_LOG(
"FieldEvaluator", Sev::inform)
1148 <<
"U_X: " << t_disp(0) <<
" U_Y: " << t_disp(1)
1149 <<
" U_Z: " << t_disp(2);
1157 CHKERR evaluate_field_at_the_point();
1169 auto det_ptr = boost::make_shared<VectorDouble>();
1170 auto jac_ptr = boost::make_shared<MatrixDouble>();
1171 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1173 pip->getDomainRhsFE().reset();
1174 pip->getDomainLhsFE().reset();
1175 pip->getBoundaryRhsFE().reset();
1176 pip->getBoundaryLhsFE().reset();
1180 auto post_proc_mesh = boost::make_shared<moab::Core>();
1181 auto post_proc_begin = boost::make_shared<PostProcBrokenMeshInMoabBaseBegin>(
1183 auto post_proc_end = boost::make_shared<PostProcBrokenMeshInMoabBaseEnd>(
1188 auto calculate_stress_ops = [&](
auto &pip) {
1194 mField, pip,
"U",
"MAT_ELASTIC", Sev::noisy);
1197 auto u_ptr = boost::make_shared<MatrixDouble>();
1199 auto x_ptr = boost::make_shared<MatrixDouble>();
1203 using DataMapMat = std::map<std::string, boost::shared_ptr<MatrixDouble>>;
1205 DataMapMat vec_map = {{
"U", u_ptr}, {
"GEOMETRY", x_ptr}};
1206 DataMapMat sym_map = {{
"STRAIN", common_ptr->getMatStrain()},
1207 {
"STRESS", common_ptr->getMatCauchyStress()}};
1209 if (adjoint_vector) {
1210 auto adjoint_ptr = boost::make_shared<MatrixDouble>();
1212 "U", adjoint_ptr, adjoint_vector));
1213 vec_map[
"ADJOINT"] = adjoint_ptr;
1217 return boost::make_tuple(u_ptr, x_ptr, common_ptr->getMatStrain(),
1218 common_ptr->getMatCauchyStress(), vec_map,
1222 auto get_tag_id_on_pmesh = [&](
bool post_proc_skin) {
1223 int def_val_int = 0;
1226 "MAT_ELASTIC", 1, MB_TYPE_INTEGER, tag_mat,
1227 MB_TAG_CREAT | MB_TAG_SPARSE, &def_val_int);
1228 auto meshset_vec_ptr =
1230 std::regex((boost::format(
"%s(.*)") %
"MAT_ELASTIC").str()));
1233 std::unique_ptr<Skinner> skin_ptr;
1234 if (post_proc_skin) {
1236 auto boundary_meshset =
simple->getBoundaryMeshSet();
1241 for (
auto m : meshset_vec_ptr) {
1245 int const id =
m->getMeshsetId();
1246 ents_3d = ents_3d.subset_by_dimension(
SPACE_DIM);
1247 if (post_proc_skin) {
1249 CHKERR skin_ptr->find_skin(0, ents_3d,
false, skin_faces);
1250 ents_3d = intersect(skin_ents, skin_faces);
1258 auto post_proc_domain = [&](
auto post_proc_mesh) {
1260 boost::make_shared<PostProcEleDomain>(
mField, post_proc_mesh);
1263 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr, vec_map, sym_map] =
1264 calculate_stress_ops(post_proc_fe->getOpPtrVector());
1266 post_proc_fe->getOpPtrVector().push_back(
1270 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
1284 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(
false)});
1285 return post_proc_fe;
1288 auto post_proc_boundary = [&](
auto post_proc_mesh) {
1290 boost::make_shared<PostProcEleBdy>(
mField, post_proc_mesh);
1292 post_proc_fe->getOpPtrVector(), {},
"GEOMETRY");
1296 auto [u_ptr, x_ptr, mat_strain_ptr, mat_stress_ptr, vec_map, sym_map] =
1297 calculate_stress_ops(op_loop_side->getOpPtrVector());
1298 post_proc_fe->getOpPtrVector().push_back(op_loop_side);
1299 auto mat_traction_ptr = boost::make_shared<MatrixDouble>();
1300 post_proc_fe->getOpPtrVector().push_back(
1303 vec_map[
"T"] = mat_traction_ptr;
1307 post_proc_fe->getOpPtrVector().push_back(
1311 post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
1325 post_proc_fe->setTagsToTransfer({get_tag_id_on_pmesh(
true)});
1326 return post_proc_fe;
1329 PetscBool post_proc_skin_only = PETSC_FALSE;
1331 post_proc_skin_only = PETSC_TRUE;
1333 &post_proc_skin_only, PETSC_NULLPTR);
1335 if (post_proc_skin_only == PETSC_FALSE) {
1336 pip->getDomainRhsFE() = post_proc_domain(post_proc_mesh);
1338 pip->getBoundaryRhsFE() = post_proc_boundary(post_proc_mesh);
1342 post_proc_begin->getFEMethod());
1343 CHKERR pip->loopFiniteElements();
1345 post_proc_end->getFEMethod());
1347 CHKERR post_proc_end->writeFile(
"out_elastic_" + std::to_string(iter) +
1357template <
int SPACE_DIM>
1364 boost::shared_ptr<HookeOps::CommonData> comm_ptr)
1372template <
int SPACE_DIM>
1385 const double vol = OP::getMeasure();
1387 auto t_w = OP::getFTensor0IntegrationWeight();
1391 auto t_cauchy_stress =
1394 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1396 const double alpha = t_w * vol;
1399 auto t_nf = OP::template getNf<SPACE_DIM>();
1402 for (; rr != OP::nbRows /
SPACE_DIM; rr++) {
1404 t_nf(
j) += alpha * t_row_grad(
i) * t_cauchy_stress(
i,
j);
1409 for (; rr < OP::nbRowBaseFunctions; ++rr) {
1419template <
int SPACE_DIM>
1426 boost::shared_ptr<HookeOps::CommonData> comm_ptr,
1427 boost::shared_ptr<MatrixDouble> jac,
1428 boost::shared_ptr<MatrixDouble> diff_jac,
1429 boost::shared_ptr<VectorDouble> cof_vals)
1431 jac(jac), diffJac(diff_jac), cofVals(cof_vals) {}
1435 boost::shared_ptr<MatrixDouble>
jac;
1450 t_diff(
i,
j,
k,
l) = 0;
1451 t_diff(0, 0, 0, 0) = 1;
1452 t_diff(1, 1, 1, 1) = 1;
1454 t_diff(1, 0, 1, 0) = 0.5;
1455 t_diff(1, 0, 0, 1) = 0.5;
1457 t_diff(0, 1, 0, 1) = 0.5;
1458 t_diff(0, 1, 1, 0) = 0.5;
1460 if constexpr (DIM == 3) {
1461 t_diff(2, 2, 2, 2) = 1;
1463 t_diff(2, 0, 2, 0) = 0.5;
1464 t_diff(2, 0, 0, 2) = 0.5;
1465 t_diff(0, 2, 0, 2) = 0.5;
1466 t_diff(0, 2, 2, 0) = 0.5;
1468 t_diff(2, 1, 2, 1) = 0.5;
1469 t_diff(2, 1, 1, 2) = 0.5;
1470 t_diff(1, 2, 1, 2) = 0.5;
1471 t_diff(1, 2, 2, 1) = 0.5;
1477template <
int SPACE_DIM>
1492 const double vol = OP::getMeasure();
1494 auto t_w = OP::getFTensor0IntegrationWeight();
1507 auto t_cauchy_stress =
1513 for (
int gg = 0; gg != OP::nbIntegrationPts; gg++) {
1515 const double alpha = t_w * vol;
1523 t_diff_inv_jac(
i,
j) =
1524 -(t_inv_jac(
i,
I) * t_diff_jac(
I,
J)) * t_inv_jac(
J,
j);
1526 t_diff_grad(
i,
j) = t_grad_u(
i,
k) * t_diff_inv_jac(
k,
j);
1530 t_diff_strain(
i,
j) = t_diff_symm(
i,
j,
k,
l) * t_diff_grad(
k,
l);
1534 t_diff_stress(
i,
j) = t_D(
i,
j,
k,
l) * t_diff_strain(
k,
l);
1537 auto t_nf = OP::template getNf<SPACE_DIM>();
1540 for (; rr != OP::nbRows /
SPACE_DIM; rr++) {
1543 t_diff_row_grad(
k) = t_row_grad(
j) * t_diff_inv_jac(
j,
k);
1546 t_nf(
j) += alpha * t_diff_row_grad(
i) * t_cauchy_stress(
i,
j);
1549 t_nf(
j) += (alpha * t_cof) * t_row_grad(
i) * t_cauchy_stress(
i,
j);
1552 t_nf(
j) += alpha * t_row_grad(
i) * t_diff_stress(
i,
j);
1557 for (; rr < OP::nbRowBaseFunctions; ++rr) {
1572 using OP = ForcesAndSourcesCore::UserDataOperator;
1574 boost::shared_ptr<HookeOps::CommonData> comm_ptr,
1575 boost::shared_ptr<MatrixDouble> jac_ptr,
1576 boost::shared_ptr<MatrixDouble> diff_jac,
1577 boost::shared_ptr<VectorDouble> cof_vals,
1578 boost::shared_ptr<MatrixDouble> d_grad_ptr,
1579 boost::shared_ptr<MatrixDouble> u_ptr,
1580 boost::shared_ptr<double> glob_objective_ptr,
1581 boost::shared_ptr<double> glob_objective_grad_ptr)
1603 auto nb_gauss_pts = getGaussPts().size2();
1604 auto objective_ptr = boost::make_shared<VectorDouble>(nb_gauss_pts);
1605 auto objective_dstress =
1606 boost::make_shared<MatrixDouble>(symm_size, nb_gauss_pts);
1607 auto objective_dstrain =
1608 boost::make_shared<MatrixDouble>(symm_size, nb_gauss_pts);
1609 auto obj_grad = boost::make_shared<MatrixDouble>(
SPACE_DIM, nb_gauss_pts);
1611 auto evaluate_python = [&]() {
1613 auto &coords = OP::getCoordsAtGaussPts();
1634 auto t_obj_dstress =
1636 auto t_obj_dstrain =
1639 auto vol = OP::getMeasure();
1640 auto t_w = getFTensor0IntegrationWeight();
1641 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1648 t_diff_inv_jac(
i,
j) =
1649 -(t_inv_jac(
i,
I) * t_diff_jac(
I,
J)) * t_inv_jac(
J,
j);
1651 t_diff_grad(
i,
j) = t_grad_u(
i,
k) * t_diff_inv_jac(
k,
j);
1654 t_d_strain(
i,
j) = t_diff_symm(
i,
j,
k,
l) * (
1664 auto alpha = t_w * vol;
1666 (*globObjectivePtr) += alpha * t_obj;
1667 (*globObjectiveGradPtr) +=
1671 t_obj_dstress(
i,
j) * (t_D(
i,
j,
k,
l) * t_d_strain(
k,
l))
1675 t_obj_dstrain(
i,
j) * t_d_strain(
i,
j)
1698 CHKERR evaluate_python();
1710 boost::shared_ptr<MatrixDouble>
uPtr;
1717 Vec objective_function_gradient,
1718 Vec adjoint_vector) {
1725 auto get_essential_fe = [
this]() {
1726 auto post_proc_rhs = boost::make_shared<FEMethod>();
1727 auto get_post_proc_hook_rhs = [
this, post_proc_rhs]() {
1731 post_proc_rhs, 0)();
1734 post_proc_rhs->postProcessHook = get_post_proc_hook_rhs;
1735 return post_proc_rhs;
1738 auto get_fd_direvative_fe = [&]() {
1739 auto fe = boost::make_shared<DomainEle>(
mField);
1740 fe->getRuleHook = [](int, int,
int p_data) {
1741 return 2 * p_data + p_data - 1;
1743 auto &pip = fe->getOpPtrVector();
1746 constexpr bool debug =
false;
1747 if constexpr (
debug) {
1749 mField, pip,
"U",
"MAT_ELASTIC", Sev::noisy);
1754 mField, pip,
"U",
"MAT_ELASTIC", Sev::noisy);
1759 auto calulate_fd_residual = [&](
auto eps,
auto diff_vec,
auto fd_vec) {
1762 constexpr bool debug =
false;
1768 auto norm2_field = [&](
const double val) {
1773 MPI_Allreduce(MPI_IN_PLACE, &nrm2, 1, MPI_DOUBLE, MPI_SUM,
1775 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Geometry norm: " << sqrt(nrm2);
1779 if constexpr (
debug)
1785 initial_current_geometry, INSERT_VALUES, SCATTER_FORWARD);
1786 CHKERR VecAssemblyBegin(initial_current_geometry);
1787 CHKERR VecAssemblyEnd(initial_current_geometry);
1789 if constexpr (
debug)
1792 auto perturb_geometry = [&](
auto eps,
auto diff_vec) {
1795 CHKERR VecCopy(initial_current_geometry, current_geometry);
1796 CHKERR VecAXPY(current_geometry,
eps, diff_vec);
1799 current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1803 auto fe = get_fd_direvative_fe();
1806 auto calc_impl = [&](
auto f,
auto eps) {
1808 CHKERR VecZeroEntries(f);
1812 simple->getDomainFEName(), fe);
1813 CHKERR VecAssemblyBegin(f);
1814 CHKERR VecAssemblyEnd(f);
1815 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
1816 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
1817 auto post_proc_rhs = get_essential_fe();
1818 post_proc_rhs->f = f;
1820 post_proc_rhs.get());
1825 CHKERR VecWAXPY(fd_vec, -1.0, fm, fp);
1826 CHKERR VecScale(fd_vec, 1.0 / (2.0 *
eps));
1830 initial_current_geometry, INSERT_VALUES, SCATTER_REVERSE);
1832 if constexpr (
debug)
1838 auto get_direvative_fe = [&](
auto diff_vec) {
1839 auto fe_adjoint = boost::make_shared<DomainEle>(
mField);
1840 fe_adjoint->getRuleHook = [](int, int,
int p_data) {
1841 return 2 * p_data + p_data - 1;
1843 auto &pip = fe_adjoint->getOpPtrVector();
1845 auto jac_ptr = boost::make_shared<MatrixDouble>();
1846 auto det_ptr = boost::make_shared<VectorDouble>();
1847 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1848 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1849 auto cof_ptr = boost::make_shared<VectorDouble>();
1857 "GEOMETRY", jac_ptr));
1863 pip.push_back(
new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1867 mField, pip,
"U",
"MAT_ELASTIC", Sev::noisy);
1869 "U", common_ptr, jac_ptr, diff_jac_ptr, cof_ptr));
1874 auto get_objective_fe = [&](
auto diff_vec,
auto grad_vec,
1875 auto glob_objective_ptr,
1876 auto glob_objective_grad_ptr) {
1877 auto fe_adjoint = boost::make_shared<DomainEle>(
mField);
1878 fe_adjoint->getRuleHook = [](int, int,
int p_data) {
1879 return 2 * p_data + p_data - 1;
1881 auto &pip = fe_adjoint->getOpPtrVector();
1884 auto jac_ptr = boost::make_shared<MatrixDouble>();
1885 auto det_ptr = boost::make_shared<VectorDouble>();
1886 auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
1887 auto diff_jac_ptr = boost::make_shared<MatrixDouble>();
1888 auto cof_ptr = boost::make_shared<VectorDouble>();
1889 auto d_grad_ptr = boost::make_shared<MatrixDouble>();
1890 auto u_ptr = boost::make_shared<MatrixDouble>();
1895 "GEOMETRY", jac_ptr));
1900 pip.push_back(
new OpCoFactor(jac_ptr, diff_jac_ptr, cof_ptr));
1902 "U", d_grad_ptr, grad_vec));
1906 mField, pip,
"U",
"MAT_ELASTIC", Sev::noisy);
1908 pythonPtr, common_ptr, jac_ptr, diff_jac_ptr, cof_ptr, d_grad_ptr,
1909 u_ptr, glob_objective_ptr, glob_objective_grad_ptr));
1914 auto dm =
simple->getDM();
1919 auto adjoint_fe = get_direvative_fe(dm_diff_vec);
1920 auto glob_objective_ptr = boost::make_shared<double>(0.0);
1921 auto glob_objective_grad_ptr = boost::make_shared<double>(0.0);
1922 auto objective_fe = get_objective_fe(dm_diff_vec, d, glob_objective_ptr,
1923 glob_objective_grad_ptr);
1925 auto set_variance_of_geometry = [&](
auto mode,
auto mod_vec) {
1931 dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1932 CHKERR VecGhostUpdateBegin(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1933 CHKERR VecGhostUpdateEnd(dm_diff_vec, INSERT_VALUES, SCATTER_FORWARD);
1937 auto calculate_variance_internal_forces = [&](
auto mode,
auto mod_vec) {
1939 CHKERR VecZeroEntries(f);
1940 CHKERR VecGhostUpdateBegin(f, INSERT_VALUES, SCATTER_FORWARD);
1941 CHKERR VecGhostUpdateEnd(f, INSERT_VALUES, SCATTER_FORWARD);
1944 CHKERR VecAssemblyBegin(f);
1945 CHKERR VecAssemblyEnd(f);
1946 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
1947 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
1948 auto post_proc_rhs = get_essential_fe();
1949 post_proc_rhs->f = f;
1951 post_proc_rhs.get());
1952 CHKERR VecScale(f, -1.0);
1955 constexpr bool debug =
false;
1956 if constexpr (
debug) {
1958 CHKERR VecNorm(f, NORM_2, &norm0);
1961 CHKERR calulate_fd_residual(
eps, dm_diff_vec, fd_check);
1963 CHKERR VecAXPY(fd_check, -1.0, f);
1964 CHKERR VecNorm(fd_check, NORM_2, &nrm);
1966 <<
" FD check for internal forces [ " << mode <<
" ]: " << nrm
1967 <<
" / " << norm0 <<
" ( " << (nrm / norm0) <<
" )";
1974 auto calulate_variance_of_displacemnte = [&](
auto mode,
auto mod_vec) {
1977 CHKERR VecGhostUpdateBegin(d, INSERT_VALUES, SCATTER_FORWARD);
1978 CHKERR VecGhostUpdateEnd(d, INSERT_VALUES, SCATTER_FORWARD);
1982 auto calculate_variance_of_objective_function = [&](
auto mode,
auto mod_vec) {
1984 *glob_objective_ptr = 0.0;
1985 *glob_objective_grad_ptr = 0.0;
1988 CHKERR VecSetValue(objective_function_gradient, mode,
1989 *glob_objective_grad_ptr, ADD_VALUES);
1990 std::array<double, 2> array = {*glob_objective_ptr,
1991 *glob_objective_grad_ptr};
1992 MPI_Allreduce(MPI_IN_PLACE, array.data(), 2, MPI_DOUBLE, MPI_SUM,
1994 *glob_objective_ptr = array[0];
1995 *glob_objective_grad_ptr = array[1];
1996 (*objective_function_value) += *glob_objective_ptr;
1998 MOFEM_LOG(
"WORLD", Sev::verbose) <<
" Objective gradient [ " << mode
1999 <<
" ]: " << *glob_objective_grad_ptr;
2003 CHKERR VecZeroEntries(objective_function_gradient);
2004 CHKERR VecZeroEntries(adjoint_vector);
2005 *objective_function_value = 0.0;
2009 CHKERR set_variance_of_geometry(mode, mod_vec);
2010 CHKERR calculate_variance_internal_forces(mode, mod_vec);
2011 CHKERR calulate_variance_of_displacemnte(mode, mod_vec);
2012 CHKERR calculate_variance_of_objective_function(mode, mod_vec);
2014 CHKERR VecAXPY(adjoint_vector, *glob_objective_grad_ptr, dm_diff_vec);
2018 (*objective_function_value) /=
modeVecs.size();
2020 <<
"Objective function: " << *glob_objective_ptr;
2022 CHKERR VecAssemblyBegin(objective_function_gradient);
2023 CHKERR VecAssemblyEnd(objective_function_gradient);
2025 CHKERR VecAssemblyBegin(adjoint_vector);
2026 CHKERR VecAssemblyEnd(adjoint_vector);
2027 CHKERR VecGhostUpdateBegin(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2028 CHKERR VecGhostUpdateEnd(adjoint_vector, INSERT_VALUES, SCATTER_FORWARD);
2042 const char param_file[] =
"param_file.petsc";
2045 auto core_log = logging::core::get();
2057 DMType dm_name =
"DMMOFEM";
2059 DMType dm_name_mg =
"DMMOFEM_MG";
2064 moab::Core mb_instance;
2065 moab::Interface &moab = mb_instance;
2082 if (Py_FinalizeEx() < 0) {
2095 boost::shared_ptr<MatrixDouble> u_ptr,
2096 boost::shared_ptr<MatrixDouble> stress_ptr,
2097 boost::shared_ptr<MatrixDouble> strain_ptr,
2098 boost::shared_ptr<VectorDouble> o_ptr);
2102 boost::shared_ptr<MatrixDouble> u_ptr,
2103 boost::shared_ptr<MatrixDouble> stress_ptr,
2104 boost::shared_ptr<MatrixDouble> strain_ptr,
2105 boost::shared_ptr<MatrixDouble> o_ptr);
2109 boost::shared_ptr<MatrixDouble> u_ptr,
2110 boost::shared_ptr<MatrixDouble> stress_ptr,
2111 boost::shared_ptr<MatrixDouble> strain_ptr,
2112 boost::shared_ptr<MatrixDouble> o_ptr);
2116 boost::shared_ptr<MatrixDouble> u_ptr,
2117 boost::shared_ptr<MatrixDouble> stress_ptr,
2118 boost::shared_ptr<MatrixDouble> strain_ptr,
2119 boost::shared_ptr<MatrixDouble> o_ptr);
2124 std::array<double, 3> ¢roid,
2138 np::ndarray coords, np::ndarray u,
2140 np::ndarray stress, np::ndarray strain, np::ndarray &o
2146 np::ndarray coords, np::ndarray u,
2148 np::ndarray stress, np::ndarray strain, np::ndarray &o
2154 np::ndarray coords, np::ndarray u,
2156 np::ndarray stress, np::ndarray strain, np::ndarray &o
2162 np::ndarray coords, np::ndarray u,
2164 np::ndarray stress, np::ndarray strain, np::ndarray &o
2170 int block_id, np::ndarray coords, np::ndarray centroid, np::ndarray bbodx,
2184boost::shared_ptr<ObjectiveFunctionData>
2186 auto ptr = boost::make_shared<ObjectiveFunctionDataImpl>();
2197 auto main_module = bp::import(
"__main__");
2208 }
catch (bp::error_already_set
const &) {
2223 for (
int ii = 0; ii != s.size2(); ++ii) {
2224 t_f(
i,
j) = t_s(
i,
j);
2236 ptr + 0 * s.size2(), ptr + 1 * s.size2(),
2237 ptr + 2 * s.size2(), ptr + 3 * s.size2(),
2238 ptr + 4 * s.size2(), ptr + 5 * s.size2(),
2239 ptr + 6 * s.size2(), ptr + 7 * s.size2(),
2244 for (
int ii = 0; ii != s.size2(); ++ii) {
2245 t_s(
i,
j) = (t_f(
i,
j) || t_f(
j,
i)) / 2.0;
2252 MatrixDouble &coords, boost::shared_ptr<MatrixDouble> u_ptr,
2253 boost::shared_ptr<MatrixDouble> stress_ptr,
2254 boost::shared_ptr<MatrixDouble> strain_ptr,
2255 boost::shared_ptr<VectorDouble> o_ptr) {
2261 auto np_u =
convertToNumPy(u_ptr->data(), u_ptr->size1(), u_ptr->size2());
2263 auto full_stress =
copyToFull(*(stress_ptr));
2264 auto full_strain =
copyToFull(*(strain_ptr));
2266 auto np_stress =
convertToNumPy(full_stress.data(), full_stress.size1(),
2267 full_stress.size2());
2268 auto np_strain =
convertToNumPy(full_strain.data(), full_strain.size1(),
2269 full_strain.size2());
2270 np::ndarray np_output = np::empty(bp::make_tuple(strain_ptr->size2()),
2271 np::dtype::get_builtin<double>());
2274 o_ptr->resize(stress_ptr->size2(),
false);
2275 double *val_ptr =
reinterpret_cast<double *
>(np_output.get_data());
2276 std::copy(val_ptr, val_ptr + strain_ptr->size2(), o_ptr->data().begin());
2278 }
catch (bp::error_already_set
const &) {
2286 MatrixDouble &coords, boost::shared_ptr<MatrixDouble> u_ptr,
2287 boost::shared_ptr<MatrixDouble> stress_ptr,
2288 boost::shared_ptr<MatrixDouble> strain_ptr,
2289 boost::shared_ptr<MatrixDouble> o_ptr) {
2295 auto np_u =
convertToNumPy(u_ptr->data(), u_ptr->size1(), u_ptr->size2());
2297 auto full_stress =
copyToFull(*(stress_ptr));
2298 auto full_strain =
copyToFull(*(strain_ptr));
2300 auto np_stress =
convertToNumPy(full_stress.data(), full_stress.size1(),
2301 full_stress.size2());
2302 auto np_strain =
convertToNumPy(full_strain.data(), full_strain.size1(),
2303 full_strain.size2());
2304 np::ndarray np_output =
2305 np::empty(bp::make_tuple(full_strain.size1(), full_strain.size2()),
2306 np::dtype::get_builtin<double>());
2309 o_ptr->resize(stress_ptr->size1(), stress_ptr->size2(),
false);
2310 double *val_ptr =
reinterpret_cast<double *
>(np_output.get_data());
2313 }
catch (bp::error_already_set
const &) {
2321 MatrixDouble &coords, boost::shared_ptr<MatrixDouble> u_ptr,
2322 boost::shared_ptr<MatrixDouble> stress_ptr,
2323 boost::shared_ptr<MatrixDouble> strain_ptr,
2324 boost::shared_ptr<MatrixDouble> o_ptr) {
2330 auto np_u =
convertToNumPy(u_ptr->data(), u_ptr->size1(), u_ptr->size2());
2332 auto full_stress =
copyToFull(*(stress_ptr));
2333 auto full_strain =
copyToFull(*(strain_ptr));
2334 auto np_stress =
convertToNumPy(full_stress.data(), full_stress.size1(),
2335 full_stress.size2());
2336 auto np_strain =
convertToNumPy(full_strain.data(), full_strain.size1(),
2337 full_strain.size2());
2339 np::ndarray np_output =
2340 np::empty(bp::make_tuple(full_strain.size1(), full_strain.size2()),
2341 np::dtype::get_builtin<double>());
2344 o_ptr->resize(strain_ptr->size1(), strain_ptr->size2(),
false);
2345 double *val_ptr =
reinterpret_cast<double *
>(np_output.get_data());
2348 }
catch (bp::error_already_set
const &) {
2356 MatrixDouble &coords, boost::shared_ptr<MatrixDouble> u_ptr,
2357 boost::shared_ptr<MatrixDouble> stress_ptr,
2358 boost::shared_ptr<MatrixDouble> strain_ptr,
2359 boost::shared_ptr<MatrixDouble> o_ptr) {
2365 auto np_u =
convertToNumPy(u_ptr->data(), u_ptr->size1(), u_ptr->size2());
2367 auto full_stress =
copyToFull(*(stress_ptr));
2368 auto full_strain =
copyToFull(*(strain_ptr));
2369 auto np_stress =
convertToNumPy(full_stress.data(), full_stress.size1(),
2370 full_stress.size2());
2371 auto np_strain =
convertToNumPy(full_strain.data(), full_strain.size1(),
2372 full_strain.size2());
2374 np::ndarray np_output =
2375 np::empty(bp::make_tuple(u_ptr->size1(), u_ptr->size2()),
2376 np::dtype::get_builtin<double>());
2379 o_ptr->resize(u_ptr->size1(), u_ptr->size2(),
false);
2380 double *val_ptr =
reinterpret_cast<double *
>(np_output.get_data());
2381 std::copy(val_ptr, val_ptr + u_ptr->size1() * u_ptr->size2(),
2382 o_ptr->data().begin());
2384 }
catch (bp::error_already_set
const &) {
2392 int block_id,
MatrixDouble &coords, std::array<double, 3> ¢roid,
2405 np::ndarray np_output =
2406 np::empty(bp::make_tuple(coords.size1(), nb_modes, 3),
2407 np::dtype::get_builtin<double>());
2411 o_ptr.resize(nb_modes, coords.size1() * coords.size2(),
false);
2412 double *val_ptr =
reinterpret_cast<double *
>(np_output.get_data());
2413 std::copy(val_ptr, val_ptr + coords.size1() * coords.size2() * nb_modes,
2414 o_ptr.data().begin());
2416 }
catch (bp::error_already_set
const &) {
2425 np::ndarray coords, np::ndarray u,
2427 np::ndarray stress, np::ndarray strain, np::ndarray &o
2436 }
catch (bp::error_already_set
const &) {
2446 np::ndarray coords, np::ndarray u,
2448 np::ndarray stress, np::ndarray strain, np::ndarray &o
2455 o = bp::extract<np::ndarray>(
2458 }
catch (bp::error_already_set
const &) {
2468 np::ndarray coords, np::ndarray u,
2470 np::ndarray stress, np::ndarray strain, np::ndarray &o
2477 o = bp::extract<np::ndarray>(
2480 }
catch (bp::error_already_set
const &) {
2490 np::ndarray coords, np::ndarray u,
2492 np::ndarray stress, np::ndarray strain, np::ndarray &o
2501 }
catch (bp::error_already_set
const &) {
2516 }
catch (bp::error_already_set
const &) {
2526 np::ndarray centroid,
2532 o = bp::extract<np::ndarray>(
2534 }
catch (bp::error_already_set
const &) {
2565 auto dtype = np::dtype::get_builtin<double>();
2566 auto size = bp::make_tuple(rows, nb_gauss_pts);
2567 auto stride = bp::make_tuple(nb_gauss_pts *
sizeof(
double),
sizeof(
double));
2568 return (np::from_data(data.data(), dtype, size, stride, bp::object()));
2573 auto dtype = np::dtype::get_builtin<double>();
2574 auto size = bp::make_tuple(s);
2575 auto stride = bp::make_tuple(
sizeof(
double));
2576 return (np::from_data(ptr, dtype, size, stride, bp::object()));
2580 const std::string block_name,
int dim) {
2586 std::regex((boost::format(
"%s(.*)") % block_name).str())
2590 for (
auto bc : bcs) {
2594 "get meshset ents");
2598 for (
auto dd = dim - 1; dd >= 0; --dd) {
2602 moab::Interface::UNION),
2622 CHKERR moab.add_entities(*out_meshset, r);
2623 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
Calculate traction for linear problem.
Implementation of elastic spring bc.
Natural boundary condition applying pressure from fluid.
Implementation of Hookes operator Hookes for linear elastic problems in MoFEM.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
Implementation of natural boundary conditions.
Boundary conditions in domain, i.e. body forces.
#define FTENSOR_INDEX(DIM, I)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
auto diff_symmetrize(FTensor::Number< DIM >)
static char help[]
[calculateGradient]
PetscBool is_plane_strain
constexpr int SPACE_DIM
[Define dimension]
constexpr double poisson_ratio
constexpr double shear_modulus_G
constexpr IntegrationType I
constexpr double bulk_modulus_K
FormsIntegrators< DomainEleOp >::Assembly< A >::OpBase DomainBaseOp
[Postprocess results]
boost::shared_ptr< ObjectiveFunctionData > create_python_objective_function(std::string py_file)
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
constexpr double young_modulus
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
#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()
#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_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#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 ...
PostProcEleByDim< SPACE_DIM >::PostProcEleDomain PostProcEleDomain
PostProcEleByDim< SPACE_DIM >::PostProcEleBdy PostProcEleBdy
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 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 DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
MoFEMErrorCode DMRegister_MGViaApproxOrders(const char sname[])
Register DM for Multi-Grid via approximation orders.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm)
Get smart vector from DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
auto createDMMatrix(DM dm)
Get smart matrix from DM.
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual MoFEMErrorCode add_ents_to_finite_element_by_dim(const EntityHandle entities, const int dim, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HookeOps::CommonData > common_ptr, Sev sev)
Assemble domain LHS K factory (LHS first overload) Initializes and pushes operators to assemble the L...
auto commonDataFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string block_name, Sev sev, double scale=1)
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HookeOps::CommonData > common_ptr, Sev sev, bool is_non_linear=false)
Factory function to create and push internal force operators for the domain RHS. (RHS first overload)...
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
auto createKSP(MPI_Comm comm)
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
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.
static FTensor::Ddg< FTensor::PackPtr< T *, 1 >, Tensor_Dim01, Tensor_Dim23 > getFTensor4DdgFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 4 on first two and last indices from form data matrix.
auto getDMKspCtx(DM dm)
Get KSP context data structure used by DM.
FTensor::Tensor1< FTensor::PackPtr< T *, S >, Tensor_Dim > getFTensor1FromMat(ublas::matrix< T, L, A > &data)
Get tensor rank 1 (vector) form data matrix.
static MoFEMErrorCode invertTensor(FTensor::Tensor2< T1, DIM, DIM > &t, T2 &det, FTensor::Tensor2< T3, DIM, DIM > &inv_t)
FTensor::Tensor2< FTensor::PackPtr< double *, 1 >, Tensor_Dim1, Tensor_Dim2 > getFTensor2FromMat(MatrixDouble &data)
Get tensor rank 2 (matrix) form data matrix.
static auto getFTensor2SymmetricFromMat(ublas::matrix< T, L, A > &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
FTensor::Tensor1< FTensor::PackPtr< double *, S >, DIM > getFTensor1FromPtr(double *ptr)
Make Tensor1 from pointer.
static auto determinantTensor(FTensor::Tensor2< T, DIM, DIM > &t)
Calculate the determinant of a tensor of rank DIM.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
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.
PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g, void *ctx)
Sets the objective function value and gradient for a TAO optimization solver.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
auto createTao(MPI_Comm comm)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
#define EXECUTABLE_DIMENSION
PetscBool do_eval_field
Evaluate field.
ElementsAndOps< SPACE_DIM >::SideEle SideEle
constexpr auto field_name
static constexpr int approx_order
OpBaseImpl< PETSC, EdgeEleOp > OpBase
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMass
[Only used with Hooke equation (linear material model)]
FTensor::Index< 'm', 3 > m
MoFEMErrorCode boundaryCondition()
MoFEMErrorCode assembleSystem()
MoFEMErrorCode readMesh()
SmartPetscObj< KSP > kspElastic
std::vector< SmartPetscObj< Vec > > modeVecs
FieldApproximationBase base
std::vector< std::array< double, 3 > > modeCentroids
MoFEMErrorCode topologyModes()
[Boundary condition]
SmartPetscObj< Vec > initialGeometry
Example(MoFEM::Interface &m_field)
MoFEMErrorCode runProblem()
MoFEMErrorCode calculateGradient(PetscReal *objective_function_value, Vec objective_function_gradient, Vec adjoint_vector)
MoFEMErrorCode setupAdJoint()
[Set up problem]
MoFEM::Interface & mField
std::vector< std::array< double, 6 > > modeBBoxes
boost::shared_ptr< ObjectiveFunctionData > pythonPtr
SmartPetscObj< DM > adjointDM
MoFEMErrorCode setupProblem()
MoFEMErrorCode postprocessElastic(int iter, SmartPetscObj< Vec > adjoint_vector=nullptr)
[Solve]
MoFEMErrorCode solveElastic()
[Push operators to pipeline]
boost::shared_ptr< MatrixDouble > vectorFieldPtr
Add operators pushing bases from local to physical configuration.
Simple interface for fast problem set-up.
MoFEMErrorCode synchroniseEntities(Range &ent, std::map< int, Range > *received_ents, int verb=DEFAULT_VERBOSITY)
synchronize entity range on processors (collective)
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
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::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of dofs on entity.
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 enforce essential constrains.
MoFEMErrorCode fieldLambdaOnValues(OneFieldFunctionOnValues lambda, const std::string field_name, Range *ents_ptr=nullptr)
field lambda
Field evaluator interface.
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.
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Interface for managing meshsets containing materials and boundary conditions.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Get values at integration pts for tensor field rank 1, i.e. vector field.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
Simple interface for fast problem set-up.
MoFEMErrorCode getOptions()
get options
MoFEMErrorCode getDM(DM *dm)
Get DM.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
MoFEMErrorCode objectiveGradientStrainImpl(np::ndarray coords, np::ndarray u, np::ndarray stress, np::ndarray strain, np::ndarray &o)
MoFEMErrorCode numberOfModes(int block_id, int &modes)
MoFEMErrorCode blockModesImpl(int block_id, np::ndarray coords, np::ndarray centroid, np::ndarray bbodx, np::ndarray &o_ptr)
bp::object objectNumberOfModes
MoFEMErrorCode evalObjectiveGradientStrain(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > o_ptr)
bp::object objectiveGradientStress
ObjectiveFunctionDataImpl()=default
MoFEMErrorCode initPython(const std::string py_file)
MoFEMErrorCode blockModes(int block_id, MatrixDouble &coords, std::array< double, 3 > ¢roid, std::array< double, 6 > &bbodx, MatrixDouble &o_ptr)
bp::object objectiveGradientStrain
MoFEMErrorCode evalObjectiveGradientU(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > o_ptr)
virtual ~ObjectiveFunctionDataImpl()=default
MoFEMErrorCode evalObjectiveGradientStress(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > o_ptr)
bp::object objectiveFunction
MoFEMErrorCode evalObjectiveFunction(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< VectorDouble > o_ptr)
bp::object objectiveGradientU
MatrixDouble copyToFull(MatrixDouble &s)
np::ndarray convertToNumPy(std::vector< double > &data, int rows, int nb_gauss_pts)
Converts a std::vector<double> to a NumPy ndarray.
MoFEMErrorCode objectiveGradientUImpl(np::ndarray coords, np::ndarray u, np::ndarray stress, np::ndarray strain, np::ndarray &o)
MoFEMErrorCode objectiveGradientStressImpl(np::ndarray coords, np::ndarray u, np::ndarray stress, np::ndarray strain, np::ndarray &o)
void copyToSymmetric(double *ptr, MatrixDouble &s)
bp::object objectBlockModes
MoFEMErrorCode objectiveFunctionImpl(np::ndarray coords, np::ndarray u, np::ndarray stress, np::ndarray strain, np::ndarray &o)
virtual ~ObjectiveFunctionData()=default
virtual MoFEMErrorCode evalObjectiveGradientStress(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > o_ptr)=0
virtual MoFEMErrorCode evalObjectiveGradientStrain(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > o_ptr)=0
virtual MoFEMErrorCode numberOfModes(int block_id, int &modes)=0
virtual MoFEMErrorCode blockModes(int block_id, MatrixDouble &coords, std::array< double, 3 > ¢roid, std::array< double, 6 > &bbox, MatrixDouble &o_ptr)=0
virtual MoFEMErrorCode evalObjectiveFunction(MatrixDouble &coords, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< VectorDouble > o_ptr)=0
boost::shared_ptr< MatrixDouble > diffJac
boost::shared_ptr< MatrixDouble > jac
OpAdJointGradTimesSymTensor(const std::string field_name, boost::shared_ptr< HookeOps::CommonData > comm_ptr, boost::shared_ptr< MatrixDouble > jac, boost::shared_ptr< MatrixDouble > diff_jac, boost::shared_ptr< VectorDouble > cof_vals)
boost::shared_ptr< HookeOps::CommonData > commPtr
boost::shared_ptr< VectorDouble > cofVals
boost::shared_ptr< MatrixDouble > dGradPtr
boost::shared_ptr< double > globObjectiveGradPtr
boost::shared_ptr< ObjectiveFunctionData > pythonPtr
boost::shared_ptr< double > globObjectivePtr
ForcesAndSourcesCore::UserDataOperator OP
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::shared_ptr< HookeOps::CommonData > commPtr
boost::shared_ptr< VectorDouble > cofVals
boost::shared_ptr< MatrixDouble > uPtr
OpAdJointObjective(boost::shared_ptr< ObjectiveFunctionData > python_ptr, boost::shared_ptr< HookeOps::CommonData > comm_ptr, boost::shared_ptr< MatrixDouble > jac_ptr, boost::shared_ptr< MatrixDouble > diff_jac, boost::shared_ptr< VectorDouble > cof_vals, boost::shared_ptr< MatrixDouble > d_grad_ptr, boost::shared_ptr< MatrixDouble > u_ptr, boost::shared_ptr< double > glob_objective_ptr, boost::shared_ptr< double > glob_objective_grad_ptr)
boost::shared_ptr< MatrixDouble > diffJacPtr
boost::shared_ptr< MatrixDouble > jacPtr
OpAdJointTestOp(const std::string field_name, boost::shared_ptr< HookeOps::CommonData > comm_ptr)
boost::shared_ptr< HookeOps::CommonData > commPtr