v0.16.3
Loading...
Searching...
No Matches
auxiliary_logarithmic_stress_patch_atom.cpp
Go to the documentation of this file.
1/**
2 * @file auxiliary_logarithmic_stress_patch_atom.cpp
3 * @brief Homogeneous finite-deformation patch and boundary flux verification.
4 */
5
6#include <MoFEM.hpp>
7using namespace MoFEM;
10#include <Lie.hpp>
11using namespace EshelbianPlasticity;
12
13namespace {
14
15using VolumeElement = VolumeElementForcesAndSourcesCore;
16using FaceElement = FaceElementForcesAndSourcesCore;
17
18// Independent forward reference: diagonal logarithmic stretch followed by a
19// finite rotation. The boundary callback constructs the same F with Rodrigues.
20struct Reference {
21 const double c10 = 1.7;
22 const double bulk = 8.5;
23 const double theta = .03;
24 FTensor::Tensor1<double, 3> omega{.02, -.015, .01};
25 FTensor::Tensor2<double, 3, 3> deformation, piola;
27
28 Reference() {
29 FTENSOR_INDEXES(3, i, j, k);
30 FTensor::Tensor2_symmetric<double, 3> t_h{.04, 0., 0., -.015, 0., .005};
32 std::exp(.04), 0., 0., std::exp(-.015), 0., std::exp(.005)};
34 std::exp(-.04), 0., 0., std::exp(.015), 0., std::exp(-.005)};
35 const auto t_rotation = LieGroups::SO3::exp(omega, omega.l2());
36 FTensor::Tensor2<double, 3, 3> t_inverse_transpose;
37 deformation(i, j) = t_rotation(i, k) * t_u(k, j);
38 t_inverse_transpose(i, j) = t_rotation(i, k) * t_inverse_u(k, j);
39 const double jacobian = std::exp(theta);
40 const double invariant = deformation(i, j) * deformation(i, j);
41 piola(i, j) =
42 (2. * c10 * std::exp(-2. * theta / 3.)) *
43 (deformation(i, j) - (invariant / 3.) * t_inverse_transpose(i, j)) +
44 (bulk * jacobian * (jacobian - 1.)) * t_inverse_transpose(i, j);
45 deviator = Tensor2SymmetricDeviatorBasis::getCoordinates(t_h);
47 std::exp(.06), 0., 0., std::exp(-.05), 0., std::exp(-.01)};
48 stress = Tensor2SymmetricDeviatorBasis::getCoordinates(t_exp_2d);
49 FTensor::Index<'A', 5> A;
50 stress(A) *= 2. * c10;
51 }
52};
53
54struct Audit {
55 enum Error { F, P, D, THETA, TD, OMEGA, W, FLUX, FACE_FLUX, COUNT };
56 std::array<double, COUNT> error{};
57 std::array<double, 3> reaction{};
58 PetscInt volumePoints = 0;
59 PetscInt faces = 0;
60 double boundaryArea = 0.;
61 MatrixDouble exactTraction;
62};
63
64struct OpCheckVolume : VolumeElement::UserDataOperator {
65 OpCheckVolume(boost::shared_ptr<DataAtIntegrationPts> data,
66 boost::shared_ptr<Audit> audit,
67 boost::shared_ptr<Reference> reference)
68 : VolumeElement::UserDataOperator(NOSPACE, OPSPACE), dataPtr(data),
69 auditPtr(audit), referencePtr(reference) {}
70
71 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
73 FTENSOR_INDEXES(3, i, j);
74 FTensor::Index<'A', 5> A;
75 constexpr auto t_identity = FTensor::Kronecker_Delta<int>();
76 const int points = getGaussPts().size2();
77 if (points <= 1)
78 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
79 "Patch requires multiple volume quadrature points");
80 auto t_f = dataPtr->getFTensorSmallH(points);
81 auto t_p = dataPtr->getFTensorApproxP(points);
82 auto t_omega = dataPtr->getFTensorRotAxis(points);
83 auto t_w = dataPtr->getFTensorSmallWL2(points);
84 auto t_x = getFTensor1CoordsAtGaussPts();
85 auto t_d = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::get(
86 *dataPtr->auxiliaryData->logDeviator, points)();
87 auto t_theta = MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::get(
88 *dataPtr->auxiliaryData->logJacobian, points)();
89 auto t_stress = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::get(
90 *dataPtr->auxiliaryData->stress, points)();
91 const auto &reference = *referencePtr;
92 FTensor::Tensor2<double, 3, 3> t_matrix_error;
93 FTensor::Tensor1<double, 3> t_vector_error;
94 FTensor::Tensor1<double, 5> t_material_error;
95 const auto update = [&](Audit::Error index, double error) {
96 auditPtr->error[index] = std::max(
97 auditPtr->error[index], std::isfinite(error)
98 ? error
99 : std::numeric_limits<double>::infinity());
100 };
101 for (int gg = 0; gg != points; ++gg) {
102 t_matrix_error(i, j) = t_f(i, j) - reference.deformation(i, j);
103 update(Audit::F, std::sqrt(t_matrix_error(i, j) * t_matrix_error(i, j)));
104 t_matrix_error(i, j) = t_p(i, j) - reference.piola(i, j);
105 update(Audit::P, std::sqrt(t_matrix_error(i, j) * t_matrix_error(i, j)));
106 t_material_error(A) = t_d(A) - reference.deviator(A);
107 update(Audit::D, std::sqrt(t_material_error(A) * t_material_error(A)));
108 update(Audit::THETA, std::abs(t_theta(0) - reference.theta));
109 t_material_error(A) = t_stress(A) - reference.stress(A);
110 update(Audit::TD, std::sqrt(t_material_error(A) * t_material_error(A)));
111 t_vector_error(i) = t_omega(i) - reference.omega(i);
112 update(Audit::OMEGA, t_vector_error.l2());
113 t_vector_error(i) = t_w(i) -
114 (reference.deformation(i, j) - t_identity(i, j)) * t_x(j);
115 update(Audit::W, t_vector_error.l2());
116 ++t_f;
117 ++t_p;
118 ++t_omega;
119 ++t_w;
120 ++t_x;
121 ++t_d;
122 ++t_theta;
123 ++t_stress;
124 }
125 auditPtr->volumePoints += points;
127 }
128
129 boost::shared_ptr<DataAtIntegrationPts> dataPtr;
130 boost::shared_ptr<Audit> auditPtr;
131 boost::shared_ptr<Reference> referencePtr;
132};
133
134struct OpPatchTraction : OpCalculateTractionFromSideEle {
135 OpPatchTraction(boost::shared_ptr<DataAtIntegrationPts> data,
136 boost::shared_ptr<Audit> audit,
137 boost::shared_ptr<Reference> reference)
138 : OpCalculateTractionFromSideEle(data), auditPtr(audit),
139 referencePtr(reference) {}
140
141 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) override {
144 if (getLoopSize() != 1)
145 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
146 "Patch flux check requires an exterior face");
147 FTENSOR_INDEXES(3, i, j);
148 const int points = getGaussPts().size2();
149 auto t_normal = getFTensor1NormalsAtGaussPts();
150 auto t_exact = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
151 auditPtr->exactTraction, points)();
152 for (int gg = 0; gg != points; ++gg) {
153 t_exact(i) = referencePtr->piola(i, j) *
154 (getSkeletonSense() * t_normal(j) / t_normal.l2());
155 ++t_normal;
156 ++t_exact;
157 }
159 }
160
161 boost::shared_ptr<Audit> auditPtr;
162 boost::shared_ptr<Reference> referencePtr;
163};
164
165struct OpCheckFace : FaceElement::UserDataOperator {
166 OpCheckFace(boost::shared_ptr<DataAtIntegrationPts> data,
167 boost::shared_ptr<Audit> audit)
168 : FaceElement::UserDataOperator(NOSPACE, OPSPACE), dataPtr(data),
169 auditPtr(audit) {}
170
171 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
173 FTENSOR_INDEX(3, i);
174 const int points = getGaussPts().size2();
175 auto t_weight = getFTensor0IntegrationWeight();
176 auto t_traction = dataPtr->getFTensorTraction(points);
177 auto t_exact = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::get(
178 auditPtr->exactTraction, points)();
179 FTensor::Tensor1<double, 3> t_error, t_face_error{0., 0., 0.};
180 FTensor::Tensor1<double, 3> t_reaction{0., 0., 0.};
181 double area = 0.;
182 for (int gg = 0; gg != points; ++gg) {
183 const double weight = t_weight * getMeasure();
184 t_error(i) = t_traction(i) - t_exact(i);
185 if (!std::isfinite(t_error.l2()))
186 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
187 "Nonfinite patch traction error");
188 auditPtr->error[Audit::FLUX] =
189 std::max(auditPtr->error[Audit::FLUX], t_error.l2());
190 t_face_error(i) += weight * t_error(i);
191 t_reaction(i) += weight * t_traction(i);
192 area += weight;
193 ++t_weight;
194 ++t_traction;
195 ++t_exact;
196 }
197 if (!(area > 0.))
198 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
199 "Nonpositive patch face area");
200 auditPtr->error[Audit::FACE_FLUX] = std::max(
201 auditPtr->error[Audit::FACE_FLUX], t_face_error.l2() / area);
202 auditPtr->reaction[0] += t_reaction(0);
203 auditPtr->reaction[1] += t_reaction(1);
204 auditPtr->reaction[2] += t_reaction(2);
205 auditPtr->boundaryArea += area;
206 ++auditPtr->faces;
208 }
209
210 boost::shared_ptr<DataAtIntegrationPts> dataPtr;
211 boost::shared_ptr<Audit> auditPtr;
212};
213
214MoFEMErrorCode prepareMesh() {
216 int ranks;
217 CHKERR MPI_Comm_size(PETSC_COMM_WORLD, &ranks);
218 if (ranks != 1)
219 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
220 "Prepare the patch mesh on one rank before partitioning");
221 char source[PETSC_MAX_PATH_LEN] = "";
222 char output[PETSC_MAX_PATH_LEN] = "";
223 CHKERR PetscOptionsGetString(nullptr, nullptr, "-file_name", source,
224 sizeof(source), nullptr);
225 CHKERR PetscOptionsGetString(nullptr, nullptr, "-output_file", output,
226 sizeof(output), nullptr);
227 if (!source[0] || !output[0] || std::string(source) == output)
228 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
229 "Patch mesh preparation requires distinct source and output files");
230 moab::Core moab;
231 new ParallelComm(&moab, PETSC_COMM_WORLD);
232 CHKERR moab.load_file(source);
233 MoFEM::Core core(moab);
234 MoFEM::Interface &m_field = core;
235 auto *meshsets = m_field.getInterface<MeshsetsManager>();
236 CHKERR meshsets->setMeshsetFromFile();
237 std::vector<std::pair<CubitBCType, int>> old_sets;
238 for (auto it = meshsets->getBegin(); it != meshsets->getEnd(); ++it)
239 old_sets.emplace_back(CubitBCType(it->getMaskedBcTypeULong()),
240 it->getMeshsetId());
241 for (const auto &entry : old_sets)
242 CHKERR meshsets->deleteMeshset(entry.first, entry.second);
243 Range tets, skin;
244 CHKERR moab.get_entities_by_type(0, MBTET, tets);
245 if (tets.empty())
246 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
247 "Patch fixture requires tetrahedra");
248 Skinner skinner(&moab);
249 CHKERR skinner.find_skin(0, tets, false, skin);
250 const std::string name = "ANALYTICAL_DISPLACEMENT_1001";
251 CHKERR meshsets->addMeshset(BLOCKSET, 1001, name);
252 CHKERR meshsets->addEntitiesToMeshset(BLOCKSET, 1001, skin);
253 CHKERR meshsets->setAttributes(BLOCKSET, 1001, {1., 1., 1.}, name);
254 CHKERR moab.write_file(output);
255 CHKERR PetscPrintf(PETSC_COMM_WORLD,
256 "Prepared affine patch: %d tetrahedra, %d skin faces\n",
257 static_cast<int>(tets.size()), static_cast<int>(skin.size()));
259}
260
261MoFEMErrorCode runPatch(EshelbianCore &ep) {
263 auto reference = boost::make_shared<Reference>();
266 auto state = createDMVector(ep.dmElastic);
267 CHKERR VecZeroEntries(state);
268 auto ts = createTS(PETSC_COMM_WORLD);
269 CHKERR TSSetType(ts, TSBEULER);
270 CHKERR TSAdaptRegister(TSADAPTMOFEM, TSAdaptCreateMoFEM);
271 TSAdapt adapt;
272 CHKERR TSGetAdapt(ts, &adapt);
273 CHKERR TSAdaptSetType(adapt, TSADAPTNONE);
274 CHKERR ep.solveElastic(ts, state);
275 TSConvergedReason reason;
276 PetscReal time;
277 CHKERR TSGetConvergedReason(ts, &reason);
278 CHKERR TSGetTime(ts, &time);
279 if (reason <= 0 || std::abs(time - 1.) > 1.e-12)
281 "Patch solve did not reach t=1: reason %d, time %g", reason, time);
283 SCATTER_REVERSE);
284
285 auto audit = boost::make_shared<Audit>();
286 auto volume = boost::make_shared<VolumeElement>(ep.mField);
287 CHKERR ep.setBaseVolumeElementOps(1, false, false, false, volume);
288 volume->getOpPtrVector().push_back(
289 new OpCheckVolume(ep.dataAtPts, audit, reference));
291
292 auto face = boost::make_shared<FaceElement>(ep.mField);
293 face->getRuleHook = [](int, int, int order) { return 2 * order + 1; };
294 CHKERR EshelbianPlasticity::AddHOOps<2, 3, 3>::add(
295 face->getOpPtrVector(), {L2}, ep.materialH1Positions, ep.frontAdjEdges);
296 auto *side = new OpLoopSide<EleOnSide>(ep.mField, ep.elementVolumeName, 3,
297 Sev::noisy);
298 face->getOpPtrVector().push_back(side);
299 auto side_fe = side->getSideFEPtr();
300 side_fe->getUserPolynomialBase() =
301 boost::make_shared<CGGUserPolynomialBase>();
302 CHKERR EshelbianPlasticity::AddHOOps<3, 3, 3>::add(
303 side_fe->getOpPtrVector(), {H1, HDIV, L2}, ep.materialH1Positions,
304 ep.frontAdjEdges);
305 side_fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
306 ep.piolaStress, ep.dataAtPts->getApproxPAtPts(),
307 boost::make_shared<double>(1.)));
308 side_fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
309 ep.bubbleField, ep.dataAtPts->getApproxPAtPts(), MBMAXTYPE));
310 side_fe->getOpPtrVector().push_back(
311 new OpPatchTraction(ep.dataAtPts, audit, reference));
312 face->getOpPtrVector().push_back(new OpCheckFace(ep.dataAtPts, audit));
314
315 std::array<double, Audit::COUNT> error;
316 std::array<double, 3> reaction;
317 PetscInt points, faces;
318 double area;
319 CHKERR MPI_Allreduce(audit->error.data(), error.data(), Audit::COUNT,
320 MPI_DOUBLE, MPI_MAX, ep.mField.get_comm());
321 CHKERR MPI_Allreduce(audit->reaction.data(), reaction.data(), 3, MPI_DOUBLE,
322 MPI_SUM, ep.mField.get_comm());
323 CHKERR MPI_Allreduce(&audit->volumePoints, &points, 1, MPIU_INT, MPI_SUM,
324 ep.mField.get_comm());
325 CHKERR MPI_Allreduce(&audit->faces, &faces, 1, MPIU_INT, MPI_SUM,
326 ep.mField.get_comm());
327 CHKERR MPI_Allreduce(&audit->boundaryArea, &area, 1, MPI_DOUBLE, MPI_SUM,
328 ep.mField.get_comm());
329 double tolerance = 1.e-7;
330 CHKERR PetscOptionsGetReal(nullptr, nullptr, "-patch_tolerance", &tolerance,
331 nullptr);
332 if (!(tolerance > 0.) || points == 0 || faces == 0 || !(area > 0.))
334 "Invalid patch tolerance or incomplete quadrature coverage");
335 const std::array<const char *, Audit::COUNT> names{
336 "F", "P", "D", "theta", "Td", "omega", "w", "normal flux",
337 "integrated face flux/area"};
338 for (int index = 0; index != Audit::COUNT; ++index) {
339 CHKERR PetscPrintf(ep.mField.get_comm(), "Patch %s error %.3e\n",
340 names[index], error[index]);
341 if (!std::isfinite(error[index]) || error[index] > tolerance)
343 "Patch %s error %g exceeds %g", names[index], error[index],
344 tolerance);
345 }
346 const FTensor::Tensor1<double, 3> t_reaction{
347 reaction[0], reaction[1], reaction[2]};
348 if (!std::isfinite(t_reaction.l2()) || t_reaction.l2() / area > tolerance)
350 "Patch total flux/area %g exceeds %g", t_reaction.l2() / area,
351 tolerance);
352 CHKERR PetscPrintf(ep.mField.get_comm(),
353 "Auxiliary homogeneous patch passed: %d volume points, "
354 "%d faces, total flux/area %.3e\n",
355 static_cast<int>(points), static_cast<int>(faces),
356 t_reaction.l2() / area);
358}
359
360} // namespace
361
362static char help[] = "Prepare and solve an affine auxiliary logarithmic patch.\n";
363
364int main(int argc, char *argv[]) {
365 MoFEM::Core::Initialize(&argc, &argv, nullptr, help);
366#ifdef ENABLE_PYTHON_BINDING
367 Py_Initialize();
368 np::initialize();
369#endif
370 auto core_log = logging::core::get();
371 core_log->add_sink(LogManager::createSink(LogManager::getStrmWorld(), "EP"));
372 LogManager::setLog("EP");
373 core_log->add_sink(LogManager::createSink(LogManager::getStrmSelf(), "EPSELF"));
374 LogManager::setLog("EPSELF");
375 core_log->add_sink(LogManager::createSink(LogManager::getStrmSync(), "EPSYNC"));
376 LogManager::setLog("EPSYNC");
377 try {
379 // Read the mode before loading its mesh. The normal test setup creates its
380 // own MoFEM database and applies the same JSON configuration there.
381 {
382 moab::Core options_moab;
383 MoFEM::Core options_core(options_moab);
384 options_core.getInterface<JsonConfigManager>();
385 }
386 PetscBool prepare = PETSC_FALSE;
387 CHKERR PetscOptionsGetBool(nullptr, nullptr, "-patch_prepare", &prepare,
388 nullptr);
389 if (prepare)
390 CHKERR prepareMesh();
391 else
393 }
396 return 0;
397}
Shared mesh and problem setup for auxiliary formulation atoms.
Evaluation of independent logarithmic material fields.
std::string type
Lie algebra implementation.
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
#define TSADAPTMOFEM
Definition TsCtx.hpp:10
int main()
Kronecker Delta class.
#define CATCH_ERRORS
Catch errors.
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ BLOCKSET
@ MOFEM_ATOM_TEST_INVALID
Definition definitions.h:40
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr int order
constexpr double omega
Save field DOFS on vertices/tags.
@ F
double W
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
MoFEMErrorCode runAuxiliaryLogarithmicStressTest(const std::function< MoFEMErrorCode(EshelbianCore &)> &test)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< 32 > CubitBCType
Definition Types.hpp:52
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
auto createTS(MPI_Comm comm)
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
PetscErrorCode TSAdaptCreateMoFEM(TSAdapt adapt)
Craete MOFEM adapt.
Definition TsCtx.cpp:829
auto deviator(FTensor::Tensor2_symmetric< T, DIM > &t_stress, double trace, FTensor::Tensor2_symmetric< double, DIM > &t_alpha, FTensor::Number< DIM >)
const double D
diffusivity
constexpr AssemblyType A
MoFEMErrorCode setElasticElementOps(const int tag)
boost::shared_ptr< Range > frontAdjEdges
MoFEM::Interface & mField
const std::string materialH1Positions
const std::string elementVolumeName
MoFEMErrorCode solveElastic(TS ts, Vec x)
const std::string piolaStress
MoFEMErrorCode setElasticElementToTs(DM dm)
const std::string bubbleField
const std::string skinElement
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, const bool add_bubble=true)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
SmartPetscObj< DM > dmElastic
Elastic problem.
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:69
virtual MPI_Comm & get_comm() const =0
Core (interface) class.
Definition Core.hpp:83
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
Definition Core.cpp:68
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Definition Core.cpp:123
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
static MoFEMErrorCode setMeshFileFromJson()
Set -file_name from JSON before Core is available.
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.
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode setMeshsetFromFile(const string file_name, const bool clean_file_options=true)
add blocksets reading config file
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
Element used to execute operators on side of the element.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)