20 using namespace MoFEM;
30 #include <VolumeLengthQuality.hpp>
37 boost::shared_ptr<DofEntity> arc_length_dof)
38 : mField(m_field), mwlsMoab(mwlsCore), F_lambda(PETSC_NULL),
39 arcLengthDof(arc_length_dof), nbBasePolynomials(1), dmFactor(1),
40 maxElemsInDMFactor(2),
41 useGlobalBaseAtMaterialReferenceConfiguration(PETSC_FALSE),
42 useNodalData(PETSC_FALSE), mwlsAnalyticalInternalStressTest(PETSC_FALSE),
43 approxPointCoords(3) {
45 if (!LogManager::checkIfChannelExist(
"MWLSWorld")) {
46 auto core_log = logging::core::get();
49 LogManager::createSink(LogManager::getStrmWorld(),
"MWLSWorld"));
51 LogManager::createSink(LogManager::getStrmSync(),
"MWLSSync"));
53 LogManager::createSink(LogManager::getStrmSelf(),
"MWLSSelf"));
55 LogManager::setLog(
"MWLSWorld");
56 LogManager::setLog(
"MWLSSync");
57 LogManager::setLog(
"MWLSSelf");
64 MOFEM_LOG(
"MWLSWorld", Sev::noisy) <<
"MWLS created";
74 "Get options for moving least square approximation",
77 CHKERR PetscOptionsScalar(
"-mwls_dm",
78 "edge length scaling for influence radius",
"",
80 MOFEM_LOG_C(
"MWLSWorld", Sev::inform,
"### Input parameter: -mwls_dm %6.4e",
84 "-mwls_number_of_base_functions",
85 "1 = constant, 4 = linear, 10 = quadratic approximation",
"",
88 "### Input parameter: -mwls_number_of_base_functions %d",
91 CHKERR PetscOptionsInt(
"-mwls_max_elems_factor",
92 "Set max elements factor max_nb_elems = "
93 "maxElemsInDMFactor * nbBasePolynomials",
97 "### Input parameter: -mwls_max_elems_factor %d",
101 "-mwls_use_global_base_at_reference_configuration",
102 "true local mwls base functions at reference configuration are used",
"",
108 "-mwls_use_nodal_data",
109 "true nodal data values are used (without averaging to the midpoint)",
"",
112 "### Input parameter: -mwls_use_nodal_data %d",
useNodalData);
115 "-mwls_analytical_internal_stress",
116 "use analytical strain field for internal stress mwls test",
"",
120 "### Input parameter: -test_mwls_internal_stress_analytical %d",
124 CHKERR PetscOptionsInt(
"-mwls_tree_depth",
"maximal three depths",
"",
129 CHKERR PetscOptionsInt(
"-mwls_splits_per_dir",
"splits per direction",
"",
134 ierr = PetscOptionsEnd();
150 "No 3d element in MWLS mesh");
154 moab::Interface::UNION);
165 std::vector<double> edge_length;
171 EntityType tit_type =
mwlsMoab.type_from_handle(tet);
183 double edge_node_coords[6];
186 &edge_node_coords[2]),
188 &edge_node_coords[5])};
199 t_node_edge[0](
i) -= t_node_edge[1](
i);
200 double l = sqrt(t_node_edge[0](
i) * t_node_edge[0](
i));
208 std::ostringstream opts;
212 FileOptions tree_opts(opts.str().c_str());
216 BOOST_LOG_SCOPED_THREAD_ATTR(
"Timeline", attrs::timer());
217 MOFEM_LOG(
"MWLSWorld", Sev::verbose) <<
"Build tree ... ";
219 MOFEM_LOG(
"MWLSWorld", Sev::verbose) <<
"done";
227 auto map_elems_positions = [&]() {
228 std::map<EntityHandle, std::array<double, 3>> elem_coords_map;
232 for (
auto p = tets.pair_begin(); p != tets.pair_end(); ++p) {
234 int count, verts_per_e;
235 Range slot(p->first, p->second);
238 if (count != (
int)slot.size())
240 elem_coords.resize(verts_per_e, 3,
false);
242 for (
auto t = 0;
t != count; ++
t) {
244 &*elem_coords.data().begin());
245 auto get_center = [&]() {
246 std::array<double, 3>
c{0, 0, 0};
247 for (
auto d : {0, 1, 2})
248 for (
auto n = 0;
n < verts_per_e; ++
n)
249 c[
d] += elem_coords(
n,
d);
250 for (
auto d : {0, 1, 2})
254 elem_coords_map.emplace(std::make_pair(p->first +
t, get_center()));
258 return elem_coords_map;
266 std::array<double, 9> def;
269 MB_TAG_CREAT | MB_TAG_SPARSE, def.data());
281 MB_TAG_CREAT | MB_TAG_DENSE);
295 if (name.compare(
"RHO") == 0) {
301 for (
auto &
n : nodes) {
306 avg_val /= nodes.size();
322 CHKERR get_data_to_node(tet);
327 EntityType tet_type =
mwlsMoab.type_from_handle(tet);
335 PetscBool add_analytical_internal_stress_operators = PETSC_FALSE;
337 "-add_analytical_internal_stress_operators",
338 &add_analytical_internal_stress_operators, NULL);
346 EntityType tet_type =
mwlsMoab.type_from_handle(tet);
350 if (add_analytical_internal_stress_operators == PETSC_FALSE) {
354 &coords[0], &coords[1], &coords[2]);
357 constexpr
double K = 166.666666666e9;
361 vals[0] = 3 *
K * t_strain(0, 0);
362 vals[1] = 3 *
K * t_strain(1, 1);
363 vals[2] = 3 *
K * t_strain(2, 2);
374 constexpr
double eps_overlap = 0.01;
378 using DistEntPair = std::pair<double, EntityHandle>;
379 using DistEntMap = multi_index_container<
383 ordered_non_unique<member<DistEntPair, double, &DistEntPair::first>>
395 for (
int dd : {0, 1, 2})
401 auto find_leafs = [&](
const auto dm) {
413 [](
const auto &
a,
const auto &b) { return a.first < b.first; });
417 auto get_influence_nodes = [&](
const auto &tets) {
418 std::vector<EntityHandle> influence_nodes;
420 influence_nodes.resize(tets.size());
422 &*influence_nodes.begin());
425 CHKERR mwlsMoab.get_connectivity(&*tets.begin(), tets.size(), nodes,
427 influence_nodes.clear();
428 influence_nodes.reserve(nodes.size());
430 influence_nodes.emplace_back(
n);
432 return influence_nodes;
435 auto to_range = [&](
auto ents) {
437 r.insert_list(ents.begin(), ents.end());
441 auto save_entities = [&](
const std::string name,
Range ents) {
457 std::vector<EntityHandle> leafs_tets;
460 auto get_dm2_from_influence_points = [&]() {
465 &*node_coors_vec.begin());
467 material_coords[0], material_coords[1], material_coords[2]);
469 &node_coors_vec[0], &node_coors_vec[1], &node_coors_vec[2]);
472 t_node_coords(
i) -= t_approx_point(
i);
473 const double r2 = t_node_coords(
i) * t_node_coords(
i);
482 double set_dm2 = shorten_dm2;
483 auto min_max_dist_it = dist_map.get<0>().begin();
486 for (
auto l : leafs) {
487 if (dist_map.size() < max_nb_elems ||
488 ((
l.first *
l.first) <
489 (set_dm2 + std::numeric_limits<double>::epsilon()))) {
503 for (
auto ii : {0, 1, 2}) {
504 t_c(ii) =
c[ii] - material_coords[ii];
517 if (dist_map.size() > max_nb_elems)
518 set_dm2 = std::min(min_max_dist_it->first, shorten_dm2);
520 if (t_c(0) < set_dm2 && t_c(1) < set_dm2 && t_c(2) < set_dm2) {
521 double dm2 = t_c(
i) * t_c(
i);
524 dist_map.get<0>().emplace(std::make_pair(dm2, tet)).first;
525 if (dist_map.size() > max_nb_elems) {
526 int nb = std::distance(dist_map.get<0>().begin(),
528 for (; nb < max_nb_elems; ++nb)
544 const double dm2 = set_dm2 + std::numeric_limits<double>::epsilon();
545 auto hi_it = dist_map.get<0>().upper_bound(dm2);
546 for (
auto it = dist_map.get<0>().begin(); it != hi_it; ++it)
550 for (
auto &it : dist_map)
552 <<
"dm map " << it.first <<
" " << it.second;
554 MOFEM_LOG(
"MWLSWorld", Sev::error) <<
"leafs found " << leafs.size();
556 <<
"dist map size " << dist_map.size();
557 MOFEM_LOG(
"MWLSWorld", Sev::error) <<
"dm2 " << dm2;
559 MOFEM_LOG_C(
"MWLSWorld", Sev::error,
"point: ( %g %g %g )",
566 const auto dm2_from_influence_pts = get_dm2_from_influence_points();
567 shortenDm = (1 + eps_overlap) * sqrt(dm2_from_influence_pts);
577 bool global_derivatives) {
580 auto to_range = [&](
auto ents) {
582 r.insert_list(ents.begin(), ents.end());
586 auto save_entities = [&](
const std::string name,
Range ents) {
600 auto trim_nodes = [&](
const double dm) {
608 &*node_coors_vec.begin());
610 &node_coors_vec[0], &node_coors_vec[1], &node_coors_vec[2]);
614 t_node_coords(
i) -= t_approx_point(
i);
615 const double r2 = t_node_coords(
i) * t_node_coords(
i);
617 influence_nodes_tmp.emplace_back(node);
624 auto eval_AB = [
this, global_derivatives](
const double dm) {
632 for (
int d = 0;
d != 3;
d++) {
644 &*nodes_coords.begin());
645 double *ptr = &*nodes_coords.begin();
647 ptr, ptr + 1, ptr + 2);
649 double min_distance = -1;
653 t_node_coords(
i) -= t_approx_point(
i);
655 const double r = sqrt(t_node_coords(
i) * t_node_coords(
i));
659 if (!ii ||
r < min_distance) {
666 t_diff_r(
i) = (1. /
r) * t_node_coords(
i) * (-1 /
shortenDm);
672 calculateBase<FTensor::Tensor1<FTensor::PackPtr<double *, 3>, 3>>(
686 for (
int j = 0;
j <=
k;
j++) {
690 if (global_derivatives) {
692 const double diff_wp_r = diff_w_r *
baseFun[
k];
693 for (
int d = 0;
d != 3;
d++) {
694 const double diff_wp_r_dx = diff_wp_r * t_diff_r(
d);
695 for (
int j = 0;
j <=
k;
j++) {
698 diffB[
d](
k, ii) = diff_wp_r_dx;
706 "Nearest node not found \n");
713 auto invert_A = [
this]() {
716 auto solve = [&](
const size_t nb_base_functions) {
717 A.resize(nb_base_functions, nb_base_functions,
true);
718 L.resize(nb_base_functions, nb_base_functions,
false);
723 MatrixDouble inv_a(nb_base_functions, nb_base_functions,
false);
724 for (
int k = 0;
k != nb_base_functions;
k++) {
725 ublas::matrix_column<MatrixDouble> mr(inv_a,
k);
735 for (
size_t i = 0;
i != nb_base_functions; ++
i)
736 for (
size_t j = 0;
j != nb_base_functions; ++
j)
744 auto throw_error = [&]() {
748 cerr <<
"Point: " << t_approx_point << endl;
749 cerr <<
"Matrix A: " <<
A << endl;
751 "Failed to invert matrix - solution could be "
752 "to increase dmFactor to bigger value, e.g. -mwls_dm 4, "
753 "or reduce of number of base fuctions "
754 "-mwls_number_of_base_functions 1. The number of nodes "
761 auto solve_one = [&]() {
783 auto calculate_shape_functions_coefficients = [
this]() {
796 CHKERR calculate_shape_functions_coefficients();
805 auto cal_base_functions_at_eval_point = [
this, eval_point](
const double dm) {
815 t_delta(
i) = t_eval_point(
i) - t_approx_point(
i);
822 auto calculate_shape_functions = [
this]() {
831 CHKERR calculate_shape_functions();
837 bool global_derivatives) {
840 auto cal_diff_base_functions_at_eval_point = [
this,
841 eval_point](
const double dm) {
851 t_delta(
i) = t_eval_point(
i) - t_approx_point(
i);
858 auto calculate_global_shape_functions_derivatives = [
this]() {
867 for (
int d = 0;
d != 3;
d++) {
872 for (
int d = 0;
d != 3;
d++) {
878 for (
int d = 0;
d != 3; ++
d) {
896 auto calculate_local_shape_functions_derivatives = [
this]() {
902 for (
int d = 0;
d != 3; ++
d) {
912 if (global_derivatives)
913 CHKERR calculate_global_shape_functions_derivatives();
915 CHKERR calculate_local_shape_functions_derivatives();
922 bool global_derivatives) {
925 auto cal_diff_diff_base_functions_at_eval_point =
926 [
this, eval_point](
const double dm) {
936 t_delta(
i) = t_eval_point(
i) - t_approx_point(
i);
943 auto calculate_global_shape_functions_second_derivatives = [
this]() {
949 auto calculate_local_shape_functions_second_derivatives = [
this]() {
957 for (
int n = 0;
n != 3; ++
n) {
958 for (
int d = 0;
d != 3; ++
d) {
959 const int indx =
d + 3 *
n;
969 if (global_derivatives) {
973 CHKERR calculate_local_shape_functions_second_derivatives();
1008 Tag
th,
double &total_stress_at_node,
double &total_stress_error_at_node,
1009 double &hydro_static_error_at_node,
double &deviatoric_error_at_node,
1010 double &total_energy,
double &total_energy_error,
1022 auto get_compliance_matrix = [&]() {
1024 t_C(
i,
j,
k,
l) = 0;
1028 t_C(0, 0, 1, 1) = -
c;
1029 t_C(0, 0, 2, 2) = -
c;
1031 t_C(1, 1, 0, 0) = -
c;
1033 t_C(1, 1, 2, 2) = -
c;
1035 t_C(2, 2, 0, 0) = -
c;
1036 t_C(2, 2, 1, 1) = -
c;
1040 t_C(0, 1, 0, 1) =
d;
1041 t_C(0, 2, 0, 2) =
d;
1042 t_C(1, 2, 1, 2) =
d;
1047 auto t_C = get_compliance_matrix();
1051 "Tag length is not consistent with outData size. \nMost probably "
1052 "getTagData has not been invoked yet!\n");
1055 val_at_nearest_influence_node.resize(length,
false);
1056 val_at_nearest_influence_node.clear();
1058 &*val_at_nearest_influence_node.begin());
1062 auto get_symm_tensor = [](
auto &
m) {
1065 &
m(0), &
m(3), &
m(4),
1076 auto t_stress_at_nearset_node =
1077 get_symm_tensor(val_at_nearest_influence_node);
1078 auto t_mwls_stress = get_symm_tensor(
outData);
1080 auto get_energy_norm = [&](
auto &t_s) {
1081 return 0.5 * t_s(
i,
j) * (t_C(
i,
j,
k,
l) * t_s(
k,
l));
1083 auto get_stress_nrm2 = [
i,
j](
auto &t_s) {
return t_s(
i,
j) * t_s(
i,
j); };
1085 total_stress_at_node = get_stress_nrm2(t_stress_at_nearset_node);
1086 total_energy = get_energy_norm(t_stress_at_nearset_node);
1088 t_total_stress_error(
i,
j) =
1089 t_mwls_stress(
i,
j) - t_stress_at_nearset_node(
i,
j);
1090 total_stress_error_at_node = get_stress_nrm2(t_total_stress_error);
1091 total_energy_error = get_energy_norm(t_total_stress_error);
1095 double hydro_static_difference =
1096 (
t_kd(
i,
j) * t_total_stress_error(
i,
j)) / 3.;
1097 hydro_static_error_at_node =
1098 hydro_static_difference * hydro_static_difference;
1103 t_total_stress_error(
i,
j) - hydro_static_difference *
t_kd(
i,
j);
1104 deviatoric_error_at_node = get_stress_nrm2(t_dev_error);
1114 if (
type != MBVERTEX) {
1118 if (std::is_same<T, VolumeElementForcesAndSourcesCore>::value)
1119 if (mwlsApprox->tetsInBlock.find(this->getFEEntityHandle()) ==
1120 mwlsApprox->tetsInBlock.end()) {
1124 if (std::is_same<T, FaceElementForcesAndSourcesCore>::value)
1125 if (mwlsApprox->trisInBlock.find(this->getFEEntityHandle()) ==
1126 mwlsApprox->trisInBlock.end()) {
1130 const int nb_gauss_pts = data.getN().size1();
1135 mwlsApprox->approxBasePoint.resize(3, nb_gauss_pts,
false);
1136 mwlsApprox->approxBasePoint.clear();
1137 mwlsApprox->singularInitialDisplacement.resize(3, nb_gauss_pts,
false);
1138 mwlsApprox->singularInitialDisplacement.clear();
1139 mwlsApprox->singularCurrentDisplacement.resize(3, nb_gauss_pts,
false);
1140 mwlsApprox->singularCurrentDisplacement.clear();
1142 if (
auto fe_ptr = feSingularPtr.lock()) {
1144 if (fe_ptr && fe_ptr->singularElement) {
1146 if (!matPosAtPtsPtr)
1148 "Matrix for material positions not acclocated");
1150 auto t_material_positions = getFTensor1FromMat<3>(*matPosAtPtsPtr);
1151 mwlsApprox->mwlsMaterialPositions.resize(matPosAtPtsPtr->size1(),
1152 matPosAtPtsPtr->size2(),
false);
1153 auto t_mwls_material_positions =
1154 getFTensor1FromMat<3>(mwlsApprox->mwlsMaterialPositions);
1157 t_singular_displacement(&fe_ptr->singularDisp(0, 0),
1158 &fe_ptr->singularDisp(0, 1),
1159 &fe_ptr->singularDisp(0, 2));
1161 auto t_inital_singular_displacement =
1162 getFTensor1FromMat<3>(mwlsApprox->singularInitialDisplacement);
1163 auto t_current_singular_displacement =
1164 getFTensor1FromMat<3>(mwlsApprox->singularCurrentDisplacement);
1165 if (!matGradPosAtPtsPtr)
1167 "Matrix for gradient of positions not allocated");
1168 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
1169 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1171 t_inital_singular_displacement(
i) = t_singular_displacement(
i);
1172 t_current_singular_displacement(
i) =
1173 t_H(
i,
j) * t_singular_displacement(
j);
1174 t_mwls_material_positions(
i) =
1175 t_material_positions(
i) + t_current_singular_displacement(
i);
1177 ++t_mwls_material_positions;
1178 ++t_material_positions;
1180 ++t_singular_displacement;
1181 ++t_inital_singular_displacement;
1182 ++t_current_singular_displacement;
1185 mwlsApprox->mwlsMaterialPositions = *matPosAtPtsPtr;
1189 const bool use_global_base =
1190 mwlsApprox->getUseGlobalBaseAtMaterialReferenceConfiguration();
1192 if (use_global_base) {
1193 auto t_mwls_material_positions =
1194 getFTensor1FromMat<3>(mwlsApprox->mwlsMaterialPositions);
1195 auto t_approx_base_point =
1196 getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1197 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1198 t_approx_base_point(
i) = t_mwls_material_positions(
i);
1199 ++t_approx_base_point;
1200 ++t_mwls_material_positions;
1204 auto fe_ptr = feSingularPtr.lock();
1205 if (fe_ptr && fe_ptr->singularElement) {
1206 auto t_inital_singular_displacement =
1207 getFTensor1FromMat<3>(mwlsApprox->singularInitialDisplacement);
1208 auto t_approx_base_point =
1209 getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1210 auto t_coords_of_gauss_point = this->getFTensor1CoordsAtGaussPts();
1211 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1212 t_approx_base_point(
i) =
1213 t_coords_of_gauss_point(
i) + t_inital_singular_displacement(
i);
1214 ++t_approx_base_point;
1215 ++t_coords_of_gauss_point;
1216 ++t_inital_singular_displacement;
1219 auto t_approx_base_point =
1220 getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1221 auto t_coords_of_gauss_point = this->getFTensor1CoordsAtGaussPts();
1222 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1223 t_approx_base_point(
i) = t_coords_of_gauss_point(
i);
1224 ++t_approx_base_point;
1225 ++t_coords_of_gauss_point;
1242 const int nb_gauss_pts = data.getN().size1();
1243 auto &mwls = this->mwlsApprox;
1245 if (mwls->invABMap.find(this->getFEEntityHandle()) == mwls->invABMap.end() ||
1246 mwls->influenceNodesMap.find(this->getFEEntityHandle()) ==
1247 mwls->influenceNodesMap.end()) {
1251 const bool use_global_base =
1252 mwls->getUseGlobalBaseAtMaterialReferenceConfiguration();
1253 if (use_global_base)
1255 "Coefficients can be precalculated only for local base in "
1256 "reference configuration");
1258 auto &inv_AB_map = mwls->invABMap[this->getFEEntityHandle()];
1259 inv_AB_map.resize(nb_gauss_pts);
1260 auto &influence_nodes_map =
1261 mwls->influenceNodesMap[this->getFEEntityHandle()];
1262 influence_nodes_map.resize(nb_gauss_pts);
1263 auto &dm_nodes_map = mwls->dmNodesMap[this->getFEEntityHandle()];
1264 dm_nodes_map.resize(nb_gauss_pts);
1266 auto t_approx_base_point = getFTensor1FromMat<3>(mwls->approxBasePoint);
1267 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1270 t_approx_base_pos(
i) = t_approx_base_point(
i);
1272 CHKERR mwls->getInfluenceNodes(&t_approx_base_pos(0));
1273 CHKERR mwls->calculateApproxCoeff(
true,
false);
1275 influence_nodes_map[gg] = mwls->influenceNodes;
1277 inv_AB_map[gg].resize(invAB.size1(), invAB.size2(),
false);
1278 noalias(inv_AB_map[gg]) = invAB;
1279 dm_nodes_map[gg] = mwls->shortenDm;
1281 ++t_approx_base_point;
1298 cerr <<
"Element " << getFEEntityHandle() << endl;
1299 const bool use_global_base =
1300 mwlsApprox->getUseGlobalBaseAtMaterialReferenceConfiguration();
1301 if (use_global_base)
1303 "Coefficients can be precalculated only for local base in "
1304 "reference configuration");
1311 const int nb_gauss_pts = data.getN().size1();
1312 auto &inv_AB_map =
mwlsApprox->invABMap.at(getFEEntityHandle());
1313 auto &influence_nodes_map =
1314 mwlsApprox->influenceNodesMap.at(getFEEntityHandle());
1315 auto &dm_nodes_map =
mwlsApprox->dmNodesMap.at(this->getFEEntityHandle());
1318 rho.resize(nb_gauss_pts,
false);
1320 diff_rho.resize(3, nb_gauss_pts,
false);
1323 diff_diff_rho.resize(9, nb_gauss_pts,
false);
1325 auto t_mwls_material_positions =
1326 getFTensor1FromMat<3>(
mwlsApprox->mwlsMaterialPositions);
1327 auto t_approx_base_point = getFTensor1FromMat<3>(
mwlsApprox->approxBasePoint);
1329 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1332 t_mat_pos(
i) = t_mwls_material_positions(
i);
1335 cerr <<
"material_positions " << t_mwls_material_positions << endl;
1338 for (
int dd : {0, 1, 2})
1341 mwlsApprox->influenceNodes = influence_nodes_map[gg];
1353 const auto &vals =
mwlsApprox->getDataApprox();
1357 const auto &diff_vals =
mwlsApprox->getDiffDataApprox();
1358 for (
int ii = 0; ii != 3; ++ii) {
1359 diff_rho(ii, gg) = diff_vals(ii, 0);
1364 const auto &diff_diff_vals =
mwlsApprox->getDiffDiffDataApprox();
1365 for (
int ii = 0; ii != 3; ++ii) {
1366 for (
int jj = 0; jj != 3; ++jj)
1367 diff_diff_rho(jj * 3 + ii, gg) = diff_diff_vals(jj * 3 + ii, 0);
1371 ++t_mwls_material_positions;
1372 ++t_approx_base_point;
1376 cerr <<
"rho " <<
rho << endl;
1387 cerr <<
"Element " << getFEEntityHandle() << endl;
1391 const int nb_gauss_pts = data.getN().size1();
1392 const bool use_global_base =
1393 mwlsApprox->getUseGlobalBaseAtMaterialReferenceConfiguration();
1395 CHKERR mwlsApprox->mwlsMoab.tag_get_handle(rhoTagName.c_str(),
th);
1398 rho.resize(nb_gauss_pts,
false);
1399 MatrixDouble &diff_rho = *mwlsApprox->diffRhoAtGaussPts;
1400 diff_rho.resize(3, nb_gauss_pts,
false);
1401 MatrixDouble &diff_diff_rho = *mwlsApprox->diffDiffRhoAtGaussPts;
1402 if (calculate2ndDerivative)
1403 diff_diff_rho.resize(9, nb_gauss_pts,
false);
1405 auto t_mwls_material_positions =
1406 getFTensor1FromMat<3>(mwlsApprox->mwlsMaterialPositions);
1407 auto t_approx_base_point = getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1408 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1411 t_mat_pos(
i) = t_mwls_material_positions(
i);
1413 t_approx_base_pos(
i) = t_approx_base_point(
i);
1416 cerr <<
"material_positions " << t_mwls_material_positions << endl;
1417 cerr <<
"approx_base_point " << t_approx_base_point << endl;
1419 CHKERR mwlsApprox->getInfluenceNodes(&t_approx_base_pos(0));
1420 CHKERR mwlsApprox->calculateApproxCoeff(
true, use_global_base);
1421 CHKERR mwlsApprox->evaluateApproxFun(&t_mat_pos(0));
1422 CHKERR mwlsApprox->evaluateFirstDiffApproxFun(&t_mat_pos(0),
1424 if (calculate2ndDerivative)
1425 CHKERR mwlsApprox->evaluateSecondDiffApproxFun(&t_mat_pos(0),
1428 const auto &vals = mwlsApprox->getDataApprox();
1431 if (calculateDerivative) {
1432 const auto &diff_vals = mwlsApprox->getDiffDataApprox();
1433 for (
int ii = 0; ii != 3; ++ii) {
1434 diff_rho(ii, gg) = diff_vals(ii, 0);
1438 if (calculate2ndDerivative) {
1439 const auto &diff_diff_vals = mwlsApprox->getDiffDiffDataApprox();
1440 for (
int ii = 0; ii != 3; ++ii) {
1441 for (
int jj = 0; jj != 3; ++jj)
1442 diff_diff_rho(ii + 3 * jj, gg) = diff_diff_vals(jj, ii);
1446 ++t_mwls_material_positions;
1447 ++t_approx_base_point;
1451 cerr <<
"rho " <<
rho << endl;
1461 if (
type != MBVERTEX) {
1464 auto &mwls_approx = *mwlsApproxPtr;
1465 if (mwls_approx.tetsInBlock.find(getFEEntityHandle()) ==
1466 mwls_approx.tetsInBlock.end()) {
1470 auto &post_proc_mesh = *postProcMeshPtr;
1471 const auto &map_gauss_pts = *mapGaussPtsPtr;
1472 const auto &rho_at_gauss = *mwls_approx.rhoAtGaussPts;
1473 const auto &rho_diff_at_gauss = *mwls_approx.diffRhoAtGaussPts;
1477 diff_rho_tag.clear();
1481 CHKERR post_proc_mesh.tag_get_handle(
"RHO_APPROX", 1, MB_TYPE_DOUBLE, tag_rho,
1482 MB_TAG_CREAT | MB_TAG_SPARSE, &rho_tag);
1483 CHKERR post_proc_mesh.tag_get_handle(
1484 "RHO_DIFF_APPROX", 3, MB_TYPE_DOUBLE, tag_diff_rho,
1485 MB_TAG_CREAT | MB_TAG_SPARSE, &*diff_rho_tag.begin());
1487 const int nb_gauss_pts = data.getN().size1();
1491 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1493 rho_tag = rho_at_gauss(gg);
1494 CHKERR post_proc_mesh.tag_set_data(tag_rho, &post_proc_node, 1, &rho_tag);
1495 for (
int ii : {0, 1, 2})
1496 diff_rho_tag[ii] = rho_diff_at_gauss(ii, gg);
1497 CHKERR post_proc_mesh.tag_set_data(tag_diff_rho, &post_proc_node, 1,
1498 &*diff_rho_tag.begin());
1509 cerr <<
"Element " << getFEEntityHandle() << endl;
1511 const bool use_global_base =
1512 mwlsApprox->getUseGlobalBaseAtMaterialReferenceConfiguration();
1513 if (use_global_base)
1515 "Coefficients can be precalculated only for local base in "
1516 "reference configuration");
1521 CHKERR mwlsApprox->mwlsMoab.tag_get_handle(stressTagName.c_str(),
th);
1523 const int nb_gauss_pts = data.getN().size1();
1524 auto &inv_AB_map = mwlsApprox->invABMap.at(getFEEntityHandle());
1525 auto &influence_nodes_map =
1526 mwlsApprox->influenceNodesMap.at(getFEEntityHandle());
1527 auto &dm_nodes_map = mwlsApprox->dmNodesMap.at(this->getFEEntityHandle());
1530 stress.resize(6, nb_gauss_pts,
false);
1531 MatrixDouble &diff_stress = mwlsApprox->diffStressAtGaussPts;
1532 diff_stress.resize(18, nb_gauss_pts,
false);
1534 auto t_mwls_material_positions =
1535 getFTensor1FromMat<3>(mwlsApprox->mwlsMaterialPositions);
1536 auto t_approx_base_point = getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1538 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1541 t_mat_pos(
i) = t_mwls_material_positions(
i);
1544 cerr <<
"material_positions " << t_mwls_material_positions << endl;
1547 for (
int dd : {0, 1, 2})
1548 mwlsApprox->approxPointCoords[
dd] = t_approx_base_point(
dd);
1550 mwlsApprox->influenceNodes = influence_nodes_map[gg];
1551 mwlsApprox->invAB = inv_AB_map[gg];
1552 mwlsApprox->shortenDm = dm_nodes_map[gg];
1554 CHKERR mwlsApprox->evaluateApproxFun(&t_mat_pos(0));
1555 CHKERR mwlsApprox->evaluateFirstDiffApproxFun(&t_mat_pos(0),
1559 const auto &vals = mwlsApprox->getDataApprox();
1561 for (
int ii = 0; ii != 6; ++ii)
1562 stress(ii, gg) = vals[ii];
1563 if (calculateDerivative) {
1564 const auto &diff_vals = mwlsApprox->getDiffDataApprox();
1565 for (
int ii = 0; ii != 6; ++ii) {
1566 for (
int jj = 0; jj != 3; ++jj)
1567 diff_stress(jj * 6 + ii, gg) = diff_vals(jj, ii);
1570 ++t_mwls_material_positions;
1571 ++t_approx_base_point;
1575 cerr <<
"stress " << stress << endl;
1587 cerr <<
"Element " << getFEEntityHandle() << endl;
1591 const int nb_gauss_pts = data.getN().size1();
1592 const bool use_global_base =
1593 mwlsApprox->getUseGlobalBaseAtMaterialReferenceConfiguration();
1595 CHKERR mwlsApprox->mwlsMoab.tag_get_handle(stressTagName.c_str(),
th);
1598 stress.resize(6, nb_gauss_pts,
false);
1599 MatrixDouble &diff_stress = mwlsApprox->diffStressAtGaussPts;
1600 diff_stress.resize(18, nb_gauss_pts,
false);
1602 auto t_mwls_material_positions =
1603 getFTensor1FromMat<3>(mwlsApprox->mwlsMaterialPositions);
1604 auto t_approx_base_point = getFTensor1FromMat<3>(mwlsApprox->approxBasePoint);
1605 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1607 auto t_material_positions = getFTensor1FromMat<3>(*matPosAtPtsPtr);
1610 t_mat_pos(
i) = t_mwls_material_positions(
i);
1612 t_approx_base_pos(
i) = t_approx_base_point(
i);
1615 cerr <<
"material_positions " << t_mwls_material_positions << endl;
1616 cerr <<
"approx_base_point " << t_approx_base_point << endl;
1618 CHKERR mwlsApprox->getInfluenceNodes(&t_approx_base_pos(0));
1619 CHKERR mwlsApprox->calculateApproxCoeff(
true, use_global_base);
1620 CHKERR mwlsApprox->evaluateApproxFun(&t_mat_pos(0));
1621 CHKERR mwlsApprox->evaluateFirstDiffApproxFun(&t_mat_pos(0),
1625 const auto &vals = mwlsApprox->getDataApprox();
1627 for (
int ii = 0; ii != 6; ++ii)
1628 stress(ii, gg) = vals[ii];
1629 if (calculateDerivative) {
1630 const auto &diff_vals = mwlsApprox->getDiffDataApprox();
1631 for (
int ii = 0; ii != 6; ++ii) {
1632 for (
int jj = 0; jj != 3; ++jj)
1633 diff_stress(jj * 6 + ii, gg) = diff_vals(jj, ii);
1636 ++t_mwls_material_positions;
1637 ++t_approx_base_point;
1641 cerr <<
"stress " << stress << endl;
1651 if (
type != MBVERTEX) {
1654 auto &mwls_approx = *mwlsApproxPtr;
1655 if (mwls_approx.tetsInBlock.find(getFEEntityHandle()) ==
1656 mwls_approx.tetsInBlock.end()) {
1660 auto &post_proc_mesh = *postProcMeshPtr;
1661 const auto &map_gauss_pts = *mapGaussPtsPtr;
1662 const auto &stress = mwls_approx.stressAtGaussPts;
1668 CHKERR post_proc_mesh.tag_get_handle(
"STRESS_APPROX", 9, MB_TYPE_DOUBLE,
1669 tag_stress, MB_TAG_CREAT | MB_TAG_SPARSE,
1670 &*stress_tag.begin());
1672 const int nb_gauss_pts = data.getN().size1();
1673 for (
int gg = 0; gg != nb_gauss_pts; gg++) {
1675 for (
int ii = 0; ii != 6; ++ii)
1676 stress_tag[ii] = stress(ii, gg);
1679 CHKERR post_proc_mesh.tag_set_data(tag_stress, &post_proc_node, 1,
1680 &*stress_tag.begin());
1689 if (
type != MBVERTEX)
1695 auto &mwls_approx = *mwlsApproxPtr;
1696 if (mwls_approx.tetsInBlock.find(getFEEntityHandle()) ==
1697 mwls_approx.tetsInBlock.end()) {
1701 const int nb_gauss_pts = data.getN().size1();
1704 MatrixDouble &stress = mwlsApproxPtr->stressAtGaussPts;
1706 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(1, 0), &stress(5, 0),
1709 auto get_symm_tensor = [](
auto &
m) {
1712 &
m[0], &
m[3], &
m[4],
1722 auto get_stress_nrm2 = [
i,
j](
auto &t_s) {
return t_s(
i,
j) * t_s(
i,
j); };
1725 val_at_nearest_influence_node.resize(9,
false);
1726 val_at_nearest_influence_node.clear();
1729 CHKERR mwls_approx.mwlsMoab.tag_get_handle(stressTagName.c_str(),
th);
1735 CHKERR mwls_approx.mwlsMoab.tag_get_data(
1736 th, &mwls_approx.nearestInfluenceNode, 1,
1737 &*val_at_nearest_influence_node.data().begin());
1738 auto t_stress_at_nearset_node =
1739 get_symm_tensor(val_at_nearest_influence_node);
1741 auto t_w = getFTensor0IntegrationWeight();
1742 auto vol = getVolume();
1744 double int_stress = vol * get_stress_nrm2(t_stress_at_nearset_node);
1745 double stress_error = 0;
1746 double hydrostatic_error = 0;
1747 double deviatoric_error = 0;
1749 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1750 const double a = t_w * vol;
1753 t_diff_stress(
i,
j) = t_stress(
i,
j) - t_stress_at_nearset_node(
i,
j);
1754 stress_error +=
a * get_stress_nrm2(t_diff_stress);
1758 const double hydrostatic_error_at_gg =
1759 (
t_kd(
i,
j) * t_diff_stress(
i,
j)) / 3.;
1760 hydrostatic_error +=
a * hydrostatic_error_at_gg * hydrostatic_error_at_gg;
1764 t_dev_error(
i,
j) = t_diff_stress(
i,
j) - hydrostatic_error *
t_kd(
i,
j);
1765 deviatoric_error +=
a * get_stress_nrm2(t_dev_error);
1771 auto create_tag = [&](
auto name) {
1772 constexpr
double zero = 0;
1775 name, 1, MB_TYPE_DOUBLE, tag, MB_TAG_CREAT | MB_TAG_SPARSE, &zero);
1779 auto save_val = [&](
auto &&tag,
auto &val) {
1781 auto const fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1786 stress_error /= int_stress;
1787 hydrostatic_error /= int_stress;
1788 deviatoric_error /= int_stress;
1789 stress_error = sqrt(stress_error);
1790 hydrostatic_error = sqrt(hydrostatic_error);
1791 deviatoric_error = sqrt(deviatoric_error);
1793 CHKERR save_val(create_tag(
"INT_STRESS_ERROR"), stress_error);
1794 CHKERR save_val(create_tag(
"INT_HYDROSTATIC_ERROR"), hydrostatic_error);
1795 CHKERR save_val(create_tag(
"INT_DEVIATORIC_ERROR"), deviatoric_error);
1803 if (mwlsApprox->tetsInBlock.find(getFEEntityHandle()) ==
1804 mwlsApprox->tetsInBlock.end()) {
1807 const int nb_dofs = data.getIndices().size();
1811 auto t_diff_n = data.getFTensor1DiffN<3>();
1816 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(1, 0), &stress(5, 0),
1820 nF.resize(nb_dofs,
false);
1822 const int nb_gauss_pts = data.getN().size1();
1823 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
1824 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1830 cerr <<
"V*det " << gg <<
" " << det * getVolume() << endl;
1832 double val = getVolume() * getGaussPts()(3, gg) * det;
1836 for (; bb != nb_dofs / 3; ++bb) {
1838 t_current_diff_n(
j) = t_inv_H(
i,
j) * t_diff_n(
i);
1839 rhs(
i) += val * t_stress(
i,
j) * t_current_diff_n(
j);
1843 for (; bb != data.getN().size2(); ++bb) {
1849 Vec f = mwlsApprox->F_lambda != PETSC_NULL ? mwlsApprox->F_lambda
1850 : getFEMethod()->snes_f;
1851 if (mwlsApprox->F_lambda == PETSC_NULL) {
1852 if (
auto arc_dof = mwlsApprox->arcLengthDof.lock()) {
1853 nF *= arc_dof->getFieldData();
1857 cerr <<
"Element Spatial " << getFEEntityHandle() <<
" " << nF << endl;
1867 if (mwlsApprox->tetsInBlock.find(getFEEntityHandle()) ==
1868 mwlsApprox->tetsInBlock.end()) {
1871 const int nb_dofs = data.getIndices().size();
1875 auto t_diff_n = data.getFTensor1DiffN<3>();
1880 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(1, 0), &stress(5, 0),
1886 nF.resize(nb_dofs,
false);
1888 const int nb_gauss_pts = data.getN().size1();
1889 auto t_h = getFTensor2FromMat<3, 3>(*spaceGradPosAtPtsPtr);
1890 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
1891 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
1896 double val = getVolume() * getGaussPts()(3, gg) * det;
1900 t_F(
i,
k) = t_h(
i,
j) * t_inv_H(
j,
k);
1904 t_eshelby_stress(
i,
k) = -t_F(
j,
i) * t_stress(
j,
k);
1907 for (; bb != nb_dofs / 3; ++bb) {
1909 t_current_diff_n(
j) = t_inv_H(
i,
j) * t_diff_n(
i);
1910 rhs(
i) += val * t_eshelby_stress(
i,
j) * t_current_diff_n(
j);
1914 for (; bb != data.getN().size2(); ++bb) {
1921 int *indices_ptr = &data.getIndices()[0];
1922 if (!forcesOnlyOnEntitiesRow.empty()) {
1923 iNdices.resize(nb_dofs);
1924 noalias(iNdices) = data.getIndices();
1925 indices_ptr = &iNdices[0];
1926 auto &dofs = data.getFieldDofs();
1927 auto dit = dofs.begin();
1928 for (
int ii = 0; dit != dofs.end(); dit++, ii++) {
1929 if (
auto dof = (*dit)) {
1930 if (forcesOnlyOnEntitiesRow.find(dof->getEnt()) ==
1931 forcesOnlyOnEntitiesRow.end()) {
1938 if (mwlsApprox->F_lambda == PETSC_NULL) {
1939 if (
auto arc_dof = mwlsApprox->arcLengthDof.lock()) {
1940 nF *= arc_dof->getFieldData();
1943 CHKERR VecSetOption(
f, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE);
1949 int row_side,
int col_side, EntityType row_type, EntityType col_type,
1953 if (mwlsApprox->tetsInBlock.find(getFEEntityHandle()) ==
1954 mwlsApprox->tetsInBlock.end()) {
1957 const int row_nb_dofs = row_data.getIndices().size();
1961 const int col_nb_dofs = col_data.getIndices().size();
1965 nA.resize(row_nb_dofs, col_nb_dofs,
false);
1971 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(1, 0), &stress(5, 0),
1973 MatrixDouble &d_stress = mwlsApprox->diffStressAtGaussPts;
1976 &d_stress(0 * 6 + 0, 0), &d_stress(0 * 6 + 3, 0), &d_stress(0 * 6 + 4, 0),
1977 &d_stress(0 * 6 + 1, 0), &d_stress(0 * 6 + 5, 0), &d_stress(0 * 6 + 2, 0),
1979 &d_stress(1 * 6 + 0, 0), &d_stress(1 * 6 + 3, 0), &d_stress(1 * 6 + 4, 0),
1980 &d_stress(1 * 6 + 1, 0), &d_stress(1 * 6 + 5, 0), &d_stress(1 * 6 + 2, 0),
1982 &d_stress(2 * 6 + 0, 0), &d_stress(2 * 6 + 3, 0), &d_stress(2 * 6 + 4, 0),
1983 &d_stress(2 * 6 + 1, 0), &d_stress(2 * 6 + 5, 0), &d_stress(2 * 6 + 2, 0)
1989 if (
auto arc_dof = mwlsApprox->arcLengthDof.lock()) {
1990 lambda = arc_dof->getFieldData();
1993 auto t_row_diff_n = row_data.getFTensor1DiffN<3>();
1994 const int nb_row_base = row_data.getN().size2();
1995 const int nb_gauss_pts = row_data.getN().size1();
1996 auto t_initial_singular_displacement =
1997 getFTensor1FromMat<3>(mwlsApprox->singularInitialDisplacement);
1998 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
2006 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
2013 double val = getVolume() * getGaussPts()(3, gg) * det;
2015 for (; rr != row_nb_dofs / 3; ++rr) {
2017 t_current_row_diff_n(
j) = t_inv_H(
i,
j) * t_row_diff_n(
i);
2018 auto t_col_diff_n = col_data.getFTensor1DiffN<3>(gg, 0);
2019 auto t_col_n = col_data.getFTensor0N(gg, 0);
2021 &nA(3 * rr + 0, 0), &nA(3 * rr + 0, 1), &nA(3 * rr + 0, 2),
2022 &nA(3 * rr + 1, 0), &nA(3 * rr + 1, 1), &nA(3 * rr + 1, 2),
2023 &nA(3 * rr + 2, 0), &nA(3 * rr + 2, 1), &nA(3 * rr + 2, 2));
2025 t_a(
i) = val *
lambda * t_stress(
i,
j) * t_current_row_diff_n(
j);
2027 t_b(
i,
j) = val *
lambda * t_d_stress(
i,
j,
k) * t_current_row_diff_n(
k);
2029 t_c(
i,
m,
n) = -val *
lambda * (t_stress(
i,
j) * t_inv_H(
n,
j)) *
2030 (t_inv_H(
k,
m) * t_row_diff_n(
k));
2031 for (
int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2032 t_mat(
i,
j) += t_a(
i) * t_inv_H(
k,
j) * t_col_diff_n(
k);
2033 t_mat(
i,
j) += t_b(
j,
i) * t_col_n;
2035 t_b(
j,
i) * t_col_diff_n(
k) * t_initial_singular_displacement(
k);
2036 t_mat(
i,
m) += t_c(
i,
m,
n) * t_col_diff_n(
n);
2043 for (; rr != nb_row_base; ++rr) {
2056 ++t_initial_singular_displacement;
2059 &*row_data.getIndices().begin(), col_nb_dofs,
2060 &*col_data.getIndices().begin(), &*nA.data().begin(),
2066 int row_side,
int col_side, EntityType row_type, EntityType col_type,
2070 if (mwlsApprox->tetsInBlock.find(getFEEntityHandle()) ==
2071 mwlsApprox->tetsInBlock.end()) {
2074 const int row_nb_dofs = row_data.getIndices().size();
2078 const int col_nb_dofs = col_data.getIndices().size();
2082 nA.resize(row_nb_dofs, col_nb_dofs,
false);
2086 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(1, 0), &stress(5, 0),
2089 auto t_row_diff_n = row_data.getFTensor1DiffN<3>();
2090 const int nb_row_base = row_data.getN().size2();
2091 const int nb_gauss_pts = row_data.getN().size1();
2092 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
2093 auto t_h = getFTensor2FromMat<3, 3>(*spaceGradPosAtPtsPtr);
2103 if (
auto arc_dof = mwlsApprox->arcLengthDof.lock()) {
2104 lambda = arc_dof->getFieldData();
2107 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
2113 double val = getVolume() * getGaussPts()(3, gg) * det;
2116 for (; rr != row_nb_dofs / 3; ++rr) {
2117 auto t_col_diff_n = col_data.getFTensor1DiffN<3>(gg, 0);
2119 t_current_row_diff_n(
j) = t_inv_H(
i,
j) * t_row_diff_n(
i);
2121 &nA(3 * rr + 0, 0), &nA(3 * rr + 0, 1), &nA(3 * rr + 0, 2),
2122 &nA(3 * rr + 1, 0), &nA(3 * rr + 1, 1), &nA(3 * rr + 1, 2),
2123 &nA(3 * rr + 2, 0), &nA(3 * rr + 2, 1), &nA(3 * rr + 2, 2), 3);
2125 t_a(
j) = -val *
lambda * t_stress(
j,
k) * t_current_row_diff_n(
k);
2127 for (; cc != col_nb_dofs / 3; cc++) {
2128 t_mat(
i,
j) += t_inv_H(
l,
i) * t_a(
j) * t_col_diff_n(
l);
2134 for (; rr != nb_row_base; ++rr) {
2141 int *indices_ptr = &row_data.getIndices()[0];
2142 if (!forcesOnlyOnEntitiesRow.empty()) {
2143 iNdices.resize(row_nb_dofs);
2144 noalias(iNdices) = row_data.getIndices();
2145 indices_ptr = &iNdices[0];
2146 auto &dofs = row_data.getFieldDofs();
2147 auto dit = dofs.begin();
2148 for (
int ii = 0; dit != dofs.end(); dit++, ii++) {
2149 if (
auto dof = (*dit)) {
2150 if (forcesOnlyOnEntitiesRow.find(dof->getEnt()) ==
2151 forcesOnlyOnEntitiesRow.end()) {
2158 col_nb_dofs, &*col_data.getIndices().begin(),
2159 &*nA.data().begin(), ADD_VALUES);
2164 int row_side,
int col_side, EntityType row_type, EntityType col_type,
2168 if (mwlsApprox->tetsInBlock.find(getFEEntityHandle()) ==
2169 mwlsApprox->tetsInBlock.end()) {
2172 const int row_nb_dofs = row_data.getIndices().size();
2176 const int col_nb_dofs = col_data.getIndices().size();
2180 nA.resize(row_nb_dofs, col_nb_dofs,
false);
2185 &stress(0, 0), &stress(3, 0), &stress(4, 0), &stress(3, 0), &stress(1, 0),
2186 &stress(5, 0), &stress(4, 0), &stress(5, 0), &stress(2, 0));
2187 MatrixDouble &d_stress = mwlsApprox->diffStressAtGaussPts;
2189 &d_stress(0 * 6 + 0, 0), &d_stress(0 * 6 + 3, 0), &d_stress(0 * 6 + 4, 0),
2190 &d_stress(0 * 6 + 3, 0), &d_stress(0 * 6 + 1, 0), &d_stress(0 * 6 + 5, 0),
2191 &d_stress(0 * 6 + 4, 0), &d_stress(0 * 6 + 5, 0), &d_stress(0 * 6 + 2, 0),
2193 &d_stress(1 * 6 + 0, 0), &d_stress(1 * 6 + 3, 0), &d_stress(1 * 6 + 4, 0),
2194 &d_stress(1 * 6 + 3, 0), &d_stress(1 * 6 + 1, 0), &d_stress(1 * 6 + 5, 0),
2195 &d_stress(1 * 6 + 4, 0), &d_stress(1 * 6 + 5, 0), &d_stress(1 * 6 + 2, 0),
2197 &d_stress(2 * 6 + 0, 0), &d_stress(2 * 6 + 3, 0), &d_stress(2 * 6 + 4, 0),
2198 &d_stress(2 * 6 + 3, 0), &d_stress(2 * 6 + 1, 0), &d_stress(2 * 6 + 5, 0),
2199 &d_stress(2 * 6 + 4, 0), &d_stress(2 * 6 + 5, 0), &d_stress(2 * 6 + 2, 0)
2202 auto t_initial_singular_displacement =
2203 getFTensor1FromMat<3>(mwlsApprox->singularInitialDisplacement);
2205 auto t_row_diff_n = row_data.getFTensor1DiffN<3>();
2206 const int nb_row_base = row_data.getN().size2();
2207 const int nb_gauss_pts = row_data.getN().size1();
2208 auto t_H = getFTensor2FromMat<3, 3>(*matGradPosAtPtsPtr);
2209 auto t_h = getFTensor2FromMat<3, 3>(*spaceGradPosAtPtsPtr);
2219 if (
auto arc_dof = mwlsApprox->arcLengthDof.lock()) {
2220 lambda = arc_dof->getFieldData();
2223 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
2229 double val = getVolume() * getGaussPts()(3, gg) * det;
2232 t_F(
i,
j) = t_h(
i,
k) * t_inv_H(
k,
j);
2236 t_b(
i,
k,
m,
n) = val *
lambda * t_h(
j,
l) * t_inv_H(
l,
m) * t_inv_H(
n,
i) *
2239 t_c(
i,
k) = -val *
lambda * t_F(
j,
i) * t_stress(
j,
k);
2241 for (; rr != row_nb_dofs / 3; ++rr) {
2243 t_current_row_diff_n(
j) = t_inv_H(
i,
j) * t_row_diff_n(
i);
2244 auto t_col_diff_n = col_data.getFTensor1DiffN<3>(gg, 0);
2245 auto t_col_n = col_data.getFTensor0N(gg, 0);
2247 &nA(3 * rr + 0, 0), &nA(3 * rr + 0, 1), &nA(3 * rr + 0, 2),
2248 &nA(3 * rr + 1, 0), &nA(3 * rr + 1, 1), &nA(3 * rr + 1, 2),
2249 &nA(3 * rr + 2, 0), &nA(3 * rr + 2, 1), &nA(3 * rr + 2, 2), 3);
2251 t_a_a(
i,
l) = t_a(
i,
k,
l) * t_current_row_diff_n(
k);
2253 t_b_b(
i,
m,
n) = t_b(
i,
k,
m,
n) * t_current_row_diff_n(
k);
2255 t_c_c0(
i) = t_c(
i,
k) * t_current_row_diff_n(
k);
2258 -t_c(
i,
l) * t_inv_H(
k,
m) * t_inv_H(
n,
l) * t_row_diff_n(
k);
2260 for (; cc != col_nb_dofs / 3; cc++) {
2261 t_mat(
i,
l) += t_a_a(
i,
l) * t_col_n;
2263 t_a_a(
i,
l) * t_col_diff_n(
k) * t_initial_singular_displacement(
k);
2264 t_mat(
i,
m) += t_b_b(
i,
m,
n) * t_col_diff_n(
n);
2265 t_mat(
i,
m) += t_c_c0(
i) * t_inv_H(
n,
m) * t_col_diff_n(
n);
2266 t_mat(
i,
m) += t_c_c1(
i,
m,
n) * t_col_diff_n(
n);
2273 for (; rr != nb_row_base; ++rr) {
2278 ++t_initial_singular_displacement;
2282 int *indices_ptr = &row_data.getIndices()[0];
2283 if (!forcesOnlyOnEntitiesRow.empty()) {
2284 iNdices.resize(row_nb_dofs);
2285 noalias(iNdices) = row_data.getIndices();
2286 indices_ptr = &iNdices[0];
2287 auto &dofs = row_data.getFieldDofs();
2288 auto dit = dofs.begin();
2289 for (
int ii = 0; dit != dofs.end(); dit++, ii++) {
2290 if (
auto dof = (*dit)) {
2291 if (forcesOnlyOnEntitiesRow.find(dof->getEnt()) ==
2292 forcesOnlyOnEntitiesRow.end()) {
2299 col_nb_dofs, &*col_data.getIndices().begin(),
2300 &*nA.data().begin(), ADD_VALUES);