141 {
143
144
145 auto get_ents_on_mesh_skin = [&]() {
146 std::map<std::string, Range> boundary_entities_vec;
147
148 auto get_block_vec_impl = [&](auto block_name) {
150 std::regex(
151
152 (boost::format("%s(.*)") % block_name).str()
153
154 ));
155 };
156
157 auto add_blockset_ents_impl = [&](auto &&vec) {
159 for (auto it : vec) {
160 Range boundary_entities;
162 boundary_entities, true);
163 std::string meshset_name = it->getName();
164 boundary_entities_vec[meshset_name] = boundary_entities;
165 boundary_entities.clear();
166 }
168 };
169
170 for (auto block_name : {"SPATIAL_DISP", "FIX", "CONTACT",
171 "SPATIAL_ROTATION", "NORMAL_DISPLACEMENT"}) {
173 "add blockset entities");
174 }
175
176 return boundary_entities_vec;
177 };
178
179 auto boundary_entities_vec = get_ents_on_mesh_skin();
180
181 std::vector<std::tuple<std::string, Range, std::array<double, 6>>>
182 reactionForces;
183 for (const auto &pair : boundary_entities_vec) {
184 reactionForces.push_back(
185 std::make_tuple(pair.first, pair.second,
186 std::array<double, 6>{0.0, 0.0, 0.0, 0.0, 0.0, 0.0}));
187 }
188
191 };
192 auto face_fe = boost::make_shared<FaceElementForcesAndSourcesCore>(
eP.
mField);
193 auto no_rule = [](
int,
int,
int) {
return -1; };
194 face_fe->getRuleHook = integration_rule_face;
196 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
199
200 auto op_side =
202 face_fe->getOpPtrVector().push_back(op_side);
203 auto side_fe_ptr = op_side->getSideFEPtr();
204 auto base_ptr =
205 boost::make_shared<EshelbianPlasticity::CGGUserPolynomialBase>();
206 side_fe_ptr->getUserPolynomialBase() = base_ptr;
208 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
211 auto piola_scale_ptr = boost::make_shared<double>(1.0);
212 side_fe_ptr->getOpPtrVector().push_back(
213 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
215 side_fe_ptr->getOpPtrVector().push_back(
216 new OpCalculateHTensorTensorField<3, 3>(
218 side_fe_ptr->getOpPtrVector().push_back(
220 side_fe_ptr->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
222 for (auto &[name, ents, reaction_vec] : reactionForces) {
223 face_fe->getOpPtrVector().push_back(
225 }
226
228 *face_fe);
229
230 for (auto &[name, ents, reaction_vec] : reactionForces) {
231 std::array<double, 6> block_reaction_force{0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
232
233 MPI_Allreduce(reaction_vec.data(), &block_reaction_force, 6, MPI_DOUBLE,
235
236 for (auto &force : block_reaction_force) {
237 if (std::abs(force) < 1e-12) {
238 force = 0.0;
239 }
240 }
241
244 "Step %d time %3.4g Block %s Reaction force [%3.6e, "
245 "%3.6e, %3.6e]",
246 ts_step, ts_t, name.c_str(), block_reaction_force[0],
247 block_reaction_force[1], block_reaction_force[2]);
249 "Step %d time %3.4g Block %s Moment [%3.6e, %3.6e, %3.6e]",
250 ts_step, ts_t, name.c_str(), block_reaction_force[3],
251 block_reaction_force[4], block_reaction_force[5]);
252 }
254};
static constexpr int approx_order
boost::shared_ptr< Range > frontAdjEdges
const std::string spatialL2Disp
const std::string materialH1Positions
const std::string piolaStress
const std::string bubbleField
const std::string skinElement
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
std::map< std::string, std::array< double, 6 > > reactionForcesMap