v0.16.3
Loading...
Searching...
No Matches
neohookean_direct_logarithmic_atom.cpp
Go to the documentation of this file.
1/**
2 * @file neohookean_direct_logarithmic_atom.cpp
3 * @brief Direct six-coefficient constitutive law and coupled Jacobian checks.
4 */
5
6#include <MoFEM.hpp>
7using namespace MoFEM;
9using namespace EshelbianPlasticity;
10
11namespace {
12
13using VolumeElement = VolumeElementForcesAndSourcesCore;
14constexpr double c10 = 1.7;
15constexpr double bulk = 8.5;
16constexpr double deltaTime = .5;
17
18SmartPetscObj<IS> getFieldIS(EshelbianCore &ep, const std::string &name) {
19 IS indices;
21 DMMoFEMGetFieldIS(ep.dmElastic, RowColData::ROW, name.c_str(), &indices),
22 "Get direct material test field indices");
23 return SmartPetscObj<IS>(indices);
24}
25
26MoFEMErrorCode getFieldNorm(Vec vector, IS field, PetscReal &norm) {
28 Vec subvector;
29 CHKERR VecGetSubVector(vector, field, &subvector);
30 CHKERR VecNorm(subvector, NORM_INFINITY, &norm);
31 CHKERR VecRestoreSubVector(vector, field, &subvector);
33}
34
35MoFEMErrorCode setState(EshelbianCore &ep, Vec state) {
37 const Problem *problem;
39 PetscInt first, last;
40 CHKERR VecGetOwnershipRange(state, &first, &last);
41 const std::array<double, 6> h{{.12, .035, -.021, -.045, .027, .018}};
42 const std::array<double, 3> rotation{{.14, -.11, .07}};
43 for (const auto &dof : *problem->getNumeredRowDofsPtr()) {
44 const auto index = dof->getPetscGlobalDofIdx();
45 if (index < first || index >= last)
46 continue;
47 double value = .01 * std::sin(.37 * (index + 1));
48 if (dof->getName() == ep.stretchTensor) {
49 if (dof->getDofOrder() == 0)
50 value = h.at(dof->getDofCoeffIdx());
51 else
52 value *= .2 / (1 + dof->getDofOrder());
53 } else if (dof->getName() == ep.rotAxis && dof->getDofOrder() == 0) {
54 value = rotation.at(dof->getDofCoeffIdx());
55 }
56 CHKERR VecSetValue(state, index, value, INSERT_VALUES);
57 }
58 CHKERR VecAssemblyBegin(state);
59 CHKERR VecAssemblyEnd(state);
60 CHKERR VecGhostUpdateBegin(state, INSERT_VALUES, SCATTER_FORWARD);
61 CHKERR VecGhostUpdateEnd(state, INSERT_VALUES, SCATTER_FORWARD);
63}
64
65struct Audit {
66 double noncoaxial = 0.;
67 double rateGradient = 0.;
68 double energyError = 0.;
69 PetscInt points = 0;
70};
71
72struct OpAuditState : VolumeElement::UserDataOperator {
73 OpAuditState(boost::shared_ptr<DataAtIntegrationPts> data,
74 boost::shared_ptr<Audit> audit)
75 : VolumeElement::UserDataOperator(NOSPACE, OPSPACE), dataPtr(data),
76 auditPtr(audit) {}
77 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
79 FTENSOR_INDEXES(3, i, j, k);
80 FTENSOR_INDEX(6, L);
81 const int points = getGaussPts().size2();
82 if (points <= 1)
83 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
84 "Direct material atom requires multiple Gauss points");
85 auto t_h = dataPtr->getFTensorLogStretch(points);
86 auto t_p = dataPtr->getFTensorAdjointPdstretch(points);
87 auto t_gradient = dataPtr->getFTensorGradLogStretchDot(points);
90 for (int gg = 0; gg != points; ++gg) {
91 t_symmetric_p(i, j) = (t_p(i, j) || t_p(j, i)) / 2.;
92 t_commutator(i, j) =
93 t_h(i, k) * t_symmetric_p(k, j) - t_symmetric_p(i, k) * t_h(k, j);
94 auditPtr->noncoaxial =
95 std::max(auditPtr->noncoaxial,
96 std::sqrt(t_commutator(i, j) * t_commutator(i, j)));
97 auditPtr->rateGradient =
98 std::max(auditPtr->rateGradient,
99 std::sqrt(t_gradient(L, i) * t_gradient(L, i)));
100 ++t_h;
101 ++t_p;
102 ++t_gradient;
103 }
104 auditPtr->points += points;
106 }
107 boost::shared_ptr<DataAtIntegrationPts> dataPtr;
108 boost::shared_ptr<Audit> auditPtr;
109};
110
111struct OpReferenceStress : VolumeElement::UserDataOperator {
112 OpReferenceStress(boost::shared_ptr<DataAtIntegrationPts> data,
113 MatrixPtr stress, boost::shared_ptr<Audit> audit)
114 : VolumeElement::UserDataOperator(NOSPACE, OPSPACE), dataPtr(data),
115 stressPtr(stress), auditPtr(audit) {}
116
117 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
119 FTENSOR_INDEXES(3, i, j, k);
120 FTENSOR_INDEX(6, L);
121 constexpr auto t_identity = FTensor::Kronecker_Delta<int>();
122 const auto t_packed_basis = FTensor::SymmLTensor<double, 3>();
123 const int points = getGaussPts().size2();
124 auto t_h = dataPtr->getFTensorLogStretch(points);
125 auto t_energy = getFTensor0FromVec(dataPtr->energyAtPts);
126 auto t_stress =
128 *stressPtr, points)();
129 FTensor::Tensor2<double, 3, 3> t_argument, t_exponential, t_term, t_product;
130 FTensor::Tensor2<double, 3, 3> t_material_stress;
131 for (int gg = 0; gg != points; ++gg) {
132 const double theta = t_h(i, i);
133 t_argument(i, j) = 2. * t_h(i, j) - (2. * theta / 3.) * t_identity(i, j);
134 const double argument_norm =
135 std::sqrt(t_argument(i, j) * t_argument(i, j));
136 if (!(argument_norm < .75))
137 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
138 "Test state exceeds matrix exponential reference bound");
139 // At ||2D|| < .75, 24 Taylor terms bound the omitted series by 1e-27.
140 // This reference does not call the material kernel or its spectral map.
141 t_exponential(i, j) = t_identity(i, j);
142 t_term(i, j) = t_identity(i, j);
143 for (int order = 1; order <= 24; ++order) {
144 t_product(i, j) = t_term(i, k) * t_argument(k, j);
145 t_term(i, j) = t_product(i, j) / order;
146 t_exponential(i, j) += t_term(i, j);
147 }
148 const double trace_exponential = t_exponential(i, i);
149 const double jacobian = std::exp(theta);
150 t_material_stress(i, j) =
151 2. * c10 *
152 (t_exponential(i, j) -
153 (trace_exponential / 3.) * t_identity(i, j)) +
154 (bulk * jacobian * (jacobian - 1.)) * t_identity(i, j);
155 t_stress(L) = t_packed_basis(i, j, L) * t_material_stress(i, j);
156 const double energy = c10 * (trace_exponential - 3.) +
157 .5 * bulk * (jacobian - 1.) * (jacobian - 1.);
158 const double error = std::abs(t_energy - energy);
159 if (!std::isfinite(error))
160 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
161 "Nonfinite direct material energy");
162 auditPtr->energyError = std::max(auditPtr->energyError, error);
163 ++t_h;
164 ++t_energy;
165 ++t_stress;
166 }
168 }
169 boost::shared_ptr<DataAtIntegrationPts> dataPtr;
170 MatrixPtr stressPtr;
171 boost::shared_ptr<Audit> auditPtr;
172};
173
175 SmartPetscObj<Vec> zero) {
177 Range entities;
178 CHKERR ep.mField.get_moab().get_entities_by_type(0, MBTET, entities);
179 auto blocks = boost::make_shared<ExternalStrainVec>();
180 blocks->emplace_back("EXTERNALSTRAIN_FIRST", std::vector<double>{.07, 2.},
181 entities);
182 blocks->emplace_back("EXTERNALSTRAIN_SECOND", std::vector<double>{-.01, 5.},
183 entities);
184 blocks->emplace_back("EXTERNALSTRAIN_OTHER", std::vector<double>{1., 20.},
185 Range());
186 const auto first_scale = [](double time) { return 1. + 2. * time; };
187 const auto second_scale = [](double time) { return time - .3; };
188 std::map<std::string, boost::shared_ptr<ScalingMethod>> scaling{
189 {"EXTERNALSTRAIN_FIRST",
190 boost::make_shared<TimeScale>("", false, first_scale)},
191 {"EXTERNALSTRAIN_SECOND",
192 boost::make_shared<TimeScale>("", false, second_scale)}};
193
194 auto production = boost::make_shared<VolumeElement>(ep.mField);
195 CHKERR ep.setBaseVolumeElementOps(1, false, false, false, production);
196 production->getOpPtrVector().push_back(
197 ep.physicalEquations->returnOpSpatialPhysicalExternalStrain(
198 ep.stretchTensor, ep.dataAtPts, blocks, scaling));
199 auto reference = boost::make_shared<VolumeElement>(ep.mField);
200 CHKERR ep.setBaseVolumeElementOps(1, false, false, false, reference);
201 auto pressure = boost::make_shared<double>(0.);
204 reference->getOpPtrVector().push_back(
205 new OpReferenceLoad(ep.stretchTensor, [pressure](double, double, double) {
206 return FTensor::Tensor1<double, 6>{-*pressure, 0., 0.,
207 -*pressure, 0., -*pressure};
208 }));
209 auto *tester = ep.mField.getInterface<OperatorsTester>();
210 for (const double time : {.2, .7}) {
211 const double load_time = ep.physicalTimeFlg ? ep.currentPhysicalTime : time;
212 *pressure = 3. * (2. * .07 * first_scale(load_time) +
213 5. * -.01 * second_scale(load_time));
214 auto assembled =
215 tester->assembleVec(ep.dmElastic, ep.elementVolumeName, production,
216 state, zero, zero, time, deltaTime, {});
217 auto expected =
218 tester->assembleVec(ep.dmElastic, ep.elementVolumeName, reference,
219 state, zero, zero, time, deltaTime, {});
220 PetscReal norm, error;
221 CHKERR VecNorm(expected, NORM_INFINITY, &norm);
222 CHKERR VecAXPY(assembled, -1., expected);
223 CHKERR VecNorm(assembled, NORM_INFINITY, &error);
224 if (!(norm > 0.) || !std::isfinite(error) ||
225 error > 1.e-12 * std::max(1., norm))
227 "External-strain residual error %g at time %g (norm %g)", error,
228 time, norm);
229 CHKERR PetscPrintf(ep.mField.get_comm(),
230 "Direct external strain: time %.2f, pressure %.6f, "
231 "assembled error %.3e\n",
232 time, *pressure, error);
233 }
235}
236
237MoFEMErrorCode runDirectAtom(EshelbianCore &ep) {
239 if (ep.physicalEquations->getFeatures().test(
242 "Direct atom requires the ordinary six-coefficient field");
243 auto state = createDMVector(ep.dmElastic);
244 auto rates = createDMVector(ep.dmElastic);
245 auto zero = createDMVector(ep.dmElastic);
246 CHKERR setState(ep, state);
247 // OperatorsTester takes increments and divides by deltaTime internally.
248 CHKERR VecCopy(state, rates);
249 CHKERR VecZeroEntries(zero);
250 CHKERR VecCopy(state, ep.solTSStep);
251 CHKERR VecGhostUpdateBegin(ep.solTSStep, INSERT_VALUES, SCATTER_FORWARD);
252 CHKERR VecGhostUpdateEnd(ep.solTSStep, INSERT_VALUES, SCATTER_FORWARD);
253 boost::shared_ptr<VolumeElement> rhs, lhs;
255 CHKERR ep.setVolumeElementOps(1, true, false, rhs, lhs);
256 auto audit = boost::make_shared<Audit>();
257 rhs->getOpPtrVector().push_back(new OpAuditState(ep.dataAtPts, audit));
258 auto *tester = ep.mField.getInterface<OperatorsTester>();
259 auto jacobian = tester->assembleMat(ep.dmElastic, ep.elementVolumeName, lhs,
260 state, rates, zero, 1., deltaTime, {});
261 auto residual = tester->assembleVec(ep.dmElastic, ep.elementVolumeName, rhs,
262 state, rates, zero, 1., deltaTime, {});
263 const std::vector<std::string> fields{ep.stretchTensor, ep.piolaStress,
264 ep.bubbleField, ep.rotAxis,
266 std::map<std::string, SmartPetscObj<IS>> indices;
267 for (const auto &field : fields) {
268 auto field_is = getFieldIS(ep, field);
269 PetscInt size;
270 CHKERR ISGetSize(field_is, &size);
271 if (!size)
273 "Direct test field %s is empty", field.c_str());
274 indices.emplace(field, field_is);
275 }
276 auto trial = vectorDuplicate(state);
277 auto trial_rates = vectorDuplicate(state);
278 auto direction = vectorDuplicate(state);
279 auto mixed = vectorDuplicate(state);
280 auto error = vectorDuplicate(residual);
281 auto action = vectorDuplicate(residual);
282 CHKERR VecZeroEntries(mixed);
283 const OperatorsTester::VectorFunction evaluate = [&](Vec input, Vec output) {
285 CHKERR VecCopy(input, trial);
286 CHKERR VecGhostUpdateBegin(trial, INSERT_VALUES, SCATTER_FORWARD);
287 CHKERR VecGhostUpdateEnd(trial, INSERT_VALUES, SCATTER_FORWARD);
288 CHKERR VecCopy(trial, trial_rates);
289 auto value =
290 tester->assembleVec(ep.dmElastic, ep.elementVolumeName, rhs, trial,
291 trial_rates, zero, 1., deltaTime, {});
292 CHKERR VecCopy(value, output);
294 };
295 auto check_direction = [&](const std::string &name) {
297 CHKERR tester->checkVectorCentralFiniteDifference(
298 state, direction, residual, jacobian, 2.e-6, evaluate, error);
299 CHKERR MatMult(jacobian, direction, action);
300 PetscReal maximum = 0.;
301 for (const auto &field : fields) {
302 PetscReal row_error, row_action;
303 CHKERR getFieldNorm(error, indices.at(field), row_error);
304 CHKERR getFieldNorm(action, indices.at(field), row_action);
305 const double tolerance = 2.e-8 + 2.e-6 * row_action;
306 if (!std::isfinite(row_error) || row_error > tolerance)
308 "Direct Jacobian row %s, direction %s: error %g exceeds %g",
309 field.c_str(), name.c_str(), row_error, tolerance);
310 maximum = std::max(maximum, row_error);
311 }
312 CHKERR PetscPrintf(ep.mField.get_comm(),
313 "Direct Jacobian direction %s: error %.3e\n",
314 name.c_str(), maximum);
316 };
317 const Problem *problem;
319 PetscInt first, last;
320 CHKERR VecGetOwnershipRange(state, &first, &last);
321 for (const auto &field : fields) {
322 const int components = field == ep.stretchTensor ? 6 : 1;
323 for (int component = 0; component != components; ++component) {
324 CHKERR VecZeroEntries(direction);
325 for (const auto &dof : *problem->getNumeredRowDofsPtr()) {
326 const auto index = dof->getPetscGlobalDofIdx();
327 if (index < first || index >= last || dof->getName() != field ||
328 (components == 6 && dof->getDofCoeffIdx() != component))
329 continue;
330 CHKERR VecSetValue(direction, index, std::sin(.71 * (index + 1)) + .3,
331 INSERT_VALUES);
332 }
333 CHKERR VecAssemblyBegin(direction);
334 CHKERR VecAssemblyEnd(direction);
335 PetscReal norm;
336 CHKERR VecNormalize(direction, &norm);
337 if (!(norm > 0.))
339 "Empty direct material direction");
340 CHKERR VecGhostUpdateBegin(direction, INSERT_VALUES, SCATTER_FORWARD);
341 CHKERR VecGhostUpdateEnd(direction, INSERT_VALUES, SCATTER_FORWARD);
342 CHKERR VecAXPY(mixed, 1., direction);
343 CHKERR check_direction(field + ":" + std::to_string(component));
344 }
345 }
346 CHKERR VecCopy(mixed, direction);
347 CHKERR VecNormalize(direction, nullptr);
348 CHKERR VecGhostUpdateBegin(direction, INSERT_VALUES, SCATTER_FORWARD);
349 CHKERR VecGhostUpdateEnd(direction, INSERT_VALUES, SCATTER_FORWARD);
350 CHKERR check_direction("mixed");
351
352 // Zero P and all rates isolate the direct material row of the production
353 // residual. Retain the varying, non-diagonal logarithmic field.
354 CHKERR VecCopy(state, trial);
355 for (const auto &field : {ep.piolaStress, ep.bubbleField}) {
356 Vec subvector;
357 CHKERR VecGetSubVector(trial, indices.at(field), &subvector);
358 CHKERR VecZeroEntries(subvector);
359 CHKERR VecRestoreSubVector(trial, indices.at(field), &subvector);
360 }
361 CHKERR VecGhostUpdateBegin(trial, INSERT_VALUES, SCATTER_FORWARD);
362 CHKERR VecGhostUpdateEnd(trial, INSERT_VALUES, SCATTER_FORWARD);
363 auto direct = tester->assembleVec(ep.dmElastic, ep.elementVolumeName, rhs,
364 trial, zero, zero, 1., deltaTime, {});
365 auto reference = boost::make_shared<VolumeElement>(ep.mField);
366 CHKERR ep.setBaseVolumeElementOps(1, false, false, false, reference);
367 reference->getOpPtrVector().push_back(
368 ep.physicalEquations->returnOpCalculateHelmholtzFreeEnergy(ep.dataAtPts,
369 nullptr));
370 auto reference_stress = boost::make_shared<MatrixDouble>();
371 reference->getOpPtrVector().push_back(
372 new OpReferenceStress(ep.dataAtPts, reference_stress, audit));
373 using OpReferenceResidual = FormsIntegrators<VolUserDataOperator>::Assembly<
375 reference->getOpPtrVector().push_back(
376 new OpReferenceResidual(ep.stretchTensor, reference_stress));
377 auto independent =
378 tester->assembleVec(ep.dmElastic, ep.elementVolumeName, reference, trial,
379 zero, zero, 1., deltaTime, {});
380 CHKERR VecAXPY(independent, -1., direct);
381 PetscReal stress_error, stress_norm;
382 CHKERR getFieldNorm(independent, indices.at(ep.stretchTensor), stress_error);
383 CHKERR getFieldNorm(direct, indices.at(ep.stretchTensor), stress_norm);
384 if (!std::isfinite(stress_error) ||
385 stress_error > 1.e-11 * std::max(1., stress_norm))
387 "Independent direct material residual error %g, norm %g",
388 stress_error, stress_norm);
389 std::array<double, 3> local{audit->noncoaxial, audit->rateGradient,
390 audit->energyError},
391 global;
392 PetscInt points;
393 CHKERR MPI_Allreduce(local.data(), global.data(), 3, MPI_DOUBLE, MPI_MAX,
394 ep.mField.get_comm());
395 CHKERR MPI_Allreduce(&audit->points, &points, 1, MPIU_INT, MPI_SUM,
396 ep.mField.get_comm());
397 if (!points || !(global[0] > 1.e-7) || !(global[1] > 1.e-7) ||
398 !std::isfinite(global[2]) || global[2] > 1.e-12)
400 "Direct reference coverage failed: noncoaxial %g, rate gradient "
401 "%g, energy error %g",
402 global[0], global[1], global[2]);
403 CHKERR PetscPrintf(ep.mField.get_comm(),
404 "Direct logarithmic material passed: stress error %.3e, "
405 "energy error %.3e, noncoaxial %.3e, rate gradient %.3e\n",
406 stress_error, global[2], global[0], global[1]);
407 CHKERR checkExternalStrain(ep, state, zero);
409}
410
411} // namespace
412
413static char help[] =
414 "Check direct logarithmic Neo-Hookean material equations.\n";
415
416int main(int argc, char *argv[]) {
417 MoFEM::Core::Initialize(&argc, &argv, nullptr, help);
418 auto core_log = logging::core::get();
419 core_log->add_sink(LogManager::createSink(LogManager::getStrmWorld(), "EP"));
420 LogManager::setLog("EP");
421 core_log->add_sink(
423 LogManager::setLog("EPSELF");
424 core_log->add_sink(
426 LogManager::setLog("EPSYNC");
427 try {
429 }
432 return 0;
433}
Shared mesh and problem setup for auxiliary formulation atoms.
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
int main()
Kronecker Delta class.
@ ROW
#define CATCH_ERRORS
Catch errors.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ 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
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:422
PetscErrorCode DMMoFEMGetFieldIS(DM dm, RowColData rc, const char field_name[], IS *is)
get field is in the problem
Definition DMMoFEM.cpp:1507
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
const FTensor::Tensor2< T, Dim, Dim > Vec
MoFEMErrorCode runAuxiliaryLogarithmicStressTest(const std::function< MoFEMErrorCode(EshelbianCore &)> &test)
boost::shared_ptr< MatrixDouble > MatrixPtr
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
constexpr AssemblyType A
double h
MoFEM::Interface & mField
const std::string spatialL2Disp
const std::string elementVolumeName
const std::string piolaStress
MoFEMErrorCode setVolumeElementOps(const int tag, const bool add_elastic, const bool add_material, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_lhs)
static PetscBool physicalTimeFlg
const std::string bubbleField
static double currentPhysicalTime
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
boost::shared_ptr< ForcesAndSourcesCore > contactTreeRhs
Make a contact tree.
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)
MoFEMErrorCode setContactElementRhsOps(boost::shared_ptr< ForcesAndSourcesCore > &fe_contact_tree)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
const std::string hybridSpatialDisp
SmartPetscObj< Vec > solTSStep
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string stretchTensor
@ AUXILIARY_LOGARITHMIC_STRESS
Auxiliary logarithmic stress formulation.
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
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
Data on single entity (This is passed as argument to DataOperator::doWork)
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.
Calculate directional derivative of the right hand side and compare it with tangent matrix derivative...
keeps basic data about problem
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.