v0.16.3
Loading...
Searching...
No Matches
auxiliary_logarithmic_stress_space_atom.cpp
Go to the documentation of this file.
1/**
2 * @file auxiliary_logarithmic_stress_space_atom.cpp
3 * @brief Weak mesh-stress closure, observability and coefficient elimination.
4 */
5
6#include <MoFEM.hpp>
7using namespace MoFEM;
10#include <IntegrationRules.hpp>
11
12namespace {
13
15using Coordinates = Material::Coordinates;
17
18MoFEMErrorCode checkNear(const double value, const double expected,
19 const double tolerance, const char *description) {
21 if (!std::isfinite(value) ||
22 std::abs(value - expected) > tolerance * std::max(1., std::abs(expected)))
23 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
24 "%s: expected %.16e, obtained %.16e", description, expected, value);
26}
27
28MoFEMErrorCode makeQuadrature(const int order, MatrixDouble &points,
29 VectorDouble &weights) {
31 const auto *rule = IntRules::XiaoGimbutas::getTetrahedronRule(order);
32 if (!rule || rule->numBarycentricCoordinates != 4)
33 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
34 "Space atom requires a tetrahedral Xiao-Gimbutas rule");
35 points.resize(3, rule->numPoints, false);
36 weights.resize(rule->numPoints, false);
37 double sum = 0.;
38 for (unsigned int gg = 0; gg != rule->numPoints; ++gg) {
39 points(0, gg) = rule->points[4 * gg + 1];
40 points(1, gg) = rule->points[4 * gg + 2];
41 points(2, gg) = rule->points[4 * gg + 3];
42 weights[gg] = rule->weights[gg] / 6.;
43 if (!(weights[gg] > 0.) || !std::isfinite(weights[gg]))
44 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
45 "Space comparisons require strictly positive quadrature weights");
46 sum += weights[gg];
47 }
48 CHKERR checkNear(sum, 1. / 6., 1.e-13, "reference tetrahedron volume");
50}
51
52/** Evaluate the production USER_BASE directly on the reference tetrahedron. */
53MoFEMErrorCode evaluateBasis(MatrixDouble &points, const int order,
54 MatrixDouble &basis) {
56 EntitiesFieldData data(MBTET);
57 data.dataOnEntities[MBTET][0].getOrder() = order;
58 auto context = boost::make_shared<EntPolynomialBaseCtx>(
59 data, L2, DISCONTINUOUS, USER_BASE);
60 EshelbianPlasticity::CGGUserPolynomialBase user_base(nullptr, true);
61 CHKERR user_base.getValue(points, context);
62 basis = data.dataOnEntities[MBTET][0].getN(USER_BASE);
63 if (basis.size2() != (order + 1) * (order + 2) * (order + 3) / 6)
64 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
65 "Unexpected tetrahedral USER_BASE dimension");
67}
68
69MoFEMErrorCode makeKinematics(const MatrixDouble &basis, MatrixDouble &values,
70 const bool constant = false) {
72 FTensor::Index<'a', 5> a;
73 const Coordinates t_constant(.12, -.07, .04, .03, -.05);
74 const Coordinates t_first(.22, .09, -.13, .07, .11);
75 const Coordinates t_second(-.08, .18, .07, -.10, .05);
76 const Coordinates t_third(.12, -.15, .09, .03, -.08);
77 auto t_d = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::size(
78 values, basis.size1())();
79 for (unsigned int gg = 0; gg != basis.size1(); ++gg) {
80 t_d(a) = t_constant(a);
81 if (!constant)
82 t_d(a) += basis(gg, 1) * t_first(a) + basis(gg, 2) * t_second(a) +
83 basis(gg, 3) * t_third(a);
84 ++t_d;
85 }
87}
88
89struct CoefficientState {
90 VectorDouble residual;
91 MatrixDouble compliance;
92 double gap = 0.;
93 double minimumGap = 0.;
94 double maximumMismatch = 0.;
95};
96
97/** Dense coefficient oracle, with tensor components contracted by FTensor.
98 * These arrays represent the small reference-cell system, not global FE
99 * assembly. Basis indices remain explicit and stress is interpolated before
100 * every material inverse; it is never replaced by the pointwise direct law.
101 */
102MoFEMErrorCode evaluateCoefficients(
103 const Material::Parameters &parameters, const MatrixDouble &basis,
104 const VectorDouble &weights, MatrixDouble &kinematics,
105 VectorDouble &coefficients, CoefficientState &state, const bool tangent) {
107 const int nb_basis = basis.size2();
108 const int nb_gauss = basis.size1();
109 if (coefficients.size() != 5 * nb_basis || weights.size() != nb_gauss)
110 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
111 "Inconsistent coefficient-space test data");
112 state.residual.resize(5 * nb_basis, false);
113 state.residual.clear();
114 if (tangent) {
115 state.compliance.resize(5 * nb_basis, 5 * nb_basis, false);
116 state.compliance.clear();
117 }
118 state.gap = 0.;
119 state.minimumGap = std::numeric_limits<double>::infinity();
120 state.maximumMismatch = 0.;
121 FTensor::Index<'a', 5> a;
122 FTensor::Index<'b', 5> b;
123 auto t_kinematic =
125 kinematics, nb_gauss)();
126 for (int gg = 0; gg != nb_gauss; ++gg) {
127 Coordinates t_stress, t_d, t_mismatch;
128 t_stress(a) = 0.;
129 auto t_coefficient = getFTensor1FromArray<5, 5>(coefficients);
130 for (int bb = 0; bb != nb_basis; ++bb) {
131 t_stress(a) += basis(gg, bb) * t_coefficient(a);
132 ++t_coefficient;
133 }
134 t_d(a) = t_kinematic(a);
136 CHKERR Material::evaluateInverse(parameters, t_stress, inverse);
137 double gap;
138 CHKERR Material::evaluateFenchelGap(parameters, t_d, t_stress, inverse, gap);
139 t_mismatch(a) = t_d(a) - inverse.tMaterialDeviator(a);
140 state.gap += weights[gg] * gap;
141 state.minimumGap = std::min(state.minimumGap, gap);
142 state.maximumMismatch = std::max(
143 state.maximumMismatch, std::sqrt(t_mismatch(a) * t_mismatch(a)));
144 auto t_residual = getFTensor1FromArray<5, 5>(state.residual);
145 for (int rr = 0; rr != nb_basis; ++rr) {
146 const double alpha = weights[gg] * basis(gg, rr);
147 t_residual(a) += alpha * t_mismatch(a);
148 if (tangent && alpha != 0.) {
149 auto t_c = getFTensor2FromArray<5, 5, 5>(state.compliance, 5 * rr);
150 for (int cc = 0; cc != nb_basis; ++cc) {
151 t_c(a, b) += (alpha * basis(gg, cc)) * inverse.tCompliance(a, b);
152 ++t_c;
153 }
154 }
155 ++t_residual;
156 }
157 ++t_kinematic;
158 }
160}
161
162MoFEMErrorCode solveCoefficients(
163 const Material::Parameters &parameters, const MatrixDouble &basis,
164 const VectorDouble &weights, MatrixDouble &kinematics,
165 VectorDouble &coefficients, const double tolerance,
166 CoefficientState &state) {
168 for (int iteration = 0; iteration != 30; ++iteration) {
169 CHKERR evaluateCoefficients(parameters, basis, weights, kinematics,
170 coefficients, state, true);
171 const double residual_norm = norm_2(state.residual);
172 if (residual_norm < tolerance)
174 VectorDouble step = state.residual;
175 CHKERR solveLinearSystem(static_cast<const MatrixDouble &>(state.compliance),
176 step);
177 bool accepted = false;
178 for (double alpha = 1.; alpha >= 1.e-7; alpha *= .5) {
179 VectorDouble trial = coefficients + alpha * step;
180 CoefficientState trial_state;
181 CHKERR evaluateCoefficients(parameters, basis, weights, kinematics, trial,
182 trial_state, false);
183 if (norm_2(trial_state.residual) <=
184 (1. - 1.e-4 * alpha) * residual_norm) {
185 coefficients.swap(trial);
186 accepted = true;
187 break;
188 }
189 }
190 if (!accepted)
191 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
192 "Stress coefficient Newton line search failed");
193 }
194 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
195 "Stress coefficient moments did not converge");
197}
198
199MatrixDouble crossMass(const MatrixDouble &row_basis,
200 const MatrixDouble &col_basis,
201 const VectorDouble &weights) {
202 MatrixDouble matrix(5 * row_basis.size2(), 5 * col_basis.size2());
203 matrix.clear();
204 FTensor::Index<'a', 5> a;
205 FTensor::Index<'b', 5> b;
206 constexpr auto t_identity = FTensor::Kronecker_Delta<int>();
207 for (unsigned int rr = 0; rr != row_basis.size2(); ++rr) {
208 auto t_m = getFTensor2FromArray<5, 5, 5>(matrix, 5 * rr);
209 for (unsigned int cc = 0; cc != col_basis.size2(); ++cc) {
210 double pairing = 0.;
211 for (unsigned int gg = 0; gg != weights.size(); ++gg)
212 pairing += weights[gg] * row_basis(gg, rr) * col_basis(gg, cc);
213 t_m(a, b) = pairing * t_identity(a, b);
214 ++t_m;
215 }
216 }
217 return matrix;
218}
219
220MoFEMErrorCode checkPositiveDefinite(const MatrixDouble &matrix,
221 const char *description) {
223 VectorDouble eigenvalues;
224 MatrixDouble eigenvectors;
225 CHKERR computeEigenValuesSymmetric(matrix, eigenvalues, eigenvectors);
226 if (!(eigenvalues[0] > 1.e-12 * eigenvalues[eigenvalues.size() - 1]))
227 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
228 "%s is not observable with the selected positive quadrature",
229 description);
230 const double condition = eigenvalues[eigenvalues.size() - 1] / eigenvalues[0];
231 MatrixDouble scaled(matrix);
232 for (unsigned int row = 0; row != scaled.size1(); ++row)
233 for (unsigned int col = 0; col != scaled.size2(); ++col)
234 scaled(row, col) /= std::sqrt(matrix(row, row) * matrix(col, col));
235 CHKERR computeEigenValuesSymmetric(scaled, eigenvalues, eigenvectors);
236 CHKERR PetscPrintf(PETSC_COMM_WORLD,
237 "%s (%d coefficients): condition %.6e, "
238 "diagonally scaled condition %.6e\n",
239 description, static_cast<int>(matrix.size1()), condition,
240 eigenvalues[eigenvalues.size() - 1] / eigenvalues[0]);
242}
243
244MoFEMErrorCode checkExactCases(
245 const Material::Parameters &parameters, const MatrixDouble &constant_basis,
246 const VectorDouble &weights, MatrixDouble &kinematics,
247 const double tolerance, const double newton_tolerance) {
249 FTensor::Index<'a', 5> a;
250 MatrixDouble constant_kinematics;
251 CHKERR makeKinematics(constant_basis, constant_kinematics, true);
252 VectorDouble coefficients(5);
253 coefficients.clear();
254 CoefficientState state;
255 CHKERR solveCoefficients(parameters, constant_basis, weights,
256 constant_kinematics, coefficients, newton_tolerance,
257 state);
258 CHKERR checkNear(state.maximumMismatch, 0., tolerance, "P0 constant copy");
259 CHKERR checkNear(state.gap, 0., tolerance, "P0 constant Fenchel gap");
260 const Coordinates t_constant(.12, -.07, .04, .03, -.05);
261 Coordinates t_exact, t_error;
262 double energy;
263 CHKERR Material::evaluateDeviator(parameters, t_constant, energy, &t_exact);
264 auto t_coefficient = getFTensor1FromArray<5, 5>(coefficients);
265 t_error(a) = t_coefficient(a) - t_exact(a);
266 CHKERR checkNear(std::sqrt(t_error(a) * t_error(a)), 0., tolerance,
267 "P0 coefficient direct-law recovery");
268
269 // Only this separate reference space has independent quadrature copies.
270 const int nb_gauss = weights.size();
271 MatrixDouble independent_basis(nb_gauss, nb_gauss);
272 independent_basis.clear();
273 for (int gg = 0; gg != nb_gauss; ++gg)
274 independent_basis(gg, gg) = 1.;
275 coefficients.resize(5 * nb_gauss, false);
276 coefficients.clear();
277 CHKERR solveCoefficients(parameters, independent_basis, weights, kinematics,
278 coefficients, newton_tolerance, state);
279 CHKERR checkNear(state.maximumMismatch, 0., tolerance,
280 "independent quadrature material copies");
281 CHKERR checkNear(state.gap, 0., tolerance, "independent-copy Fenchel gap");
282 auto t_d = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::get(
283 kinematics, nb_gauss)();
284 auto t_independent = getFTensor1FromArray<5, 5>(coefficients);
285 for (int gg = 0; gg != nb_gauss; ++gg) {
286 Coordinates t_kinematic;
287 t_kinematic(a) = t_d(a);
288 CHKERR Material::evaluateDeviator(parameters, t_kinematic, energy, &t_exact);
289 t_error(a) = t_independent(a) - t_exact(a);
290 CHKERR checkNear(std::sqrt(t_error(a) * t_error(a)), 0., tolerance,
291 "independent-copy direct-law recovery");
292 ++t_d;
293 ++t_independent;
294 }
296}
297
298MoFEMErrorCode checkLostMode(
299 const Material::Parameters &parameters, const MatrixDouble &constant_basis,
300 const MatrixDouble &linear_basis, const VectorDouble &weights,
301 const double tolerance) {
303 const auto cross = crossMass(constant_basis, linear_basis, weights);
304 CHKERR checkPositiveDefinite(crossMass(linear_basis, linear_basis, weights),
305 "P1 kinematic mass");
306 // P0 stress sees five averages, whereas P1 kinematics has twenty DOFs.
307 VectorDouble lost_mode(20);
308 lost_mode.clear();
309 lost_mode[5 + 2] = 1.;
310 lost_mode[2] = -cross(2, 5 + 2) / cross(2, 2);
311 const VectorDouble weak = prod(cross, lost_mode);
312 CHKERR checkNear(norm_2(weak), 0., tolerance, "underresolved cross-mass mode");
313 const auto mass = crossMass(linear_basis, linear_basis, weights);
314 const VectorDouble mass_mode = prod(mass, lost_mode);
315 if (!(inner_prod(lost_mode, mass_mode) > 1.e-3))
316 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
317 "The allegedly lost kinematic mode has zero physical norm");
318 for (unsigned int gg = 0; gg != weights.size(); ++gg) {
319 const double value = linear_basis(gg, 1) +
320 lost_mode[2] * linear_basis(gg, 0);
321 Coordinates t_d(0., 0., value, 0., 0.), t_stress, t_error;
322 double energy;
323 CHKERR Material::evaluateDeviator(parameters, t_d, energy, &t_stress);
325 CHKERR Material::evaluateInverse(parameters, t_stress, inverse);
326 FTensor::Index<'a', 5> a;
327 t_error(a) = inverse.tMaterialDeviator(a) - t_d(a);
328 CHKERR checkNear(std::sqrt(t_error(a) * t_error(a)), 0., tolerance,
329 "material inverse on the unobservable kinematic mode");
330 }
331 CHKERR PetscPrintf(PETSC_COMM_WORLD,
332 "Underresolved P0/P1 pairing: rank 5 of 20, "
333 "nonzero deviatoric mode invisible; all inverses valid\n");
335}
336
337MoFEMErrorCode checkCoefficientElimination(
338 const Material::Parameters &parameters, const MatrixDouble &basis,
339 const VectorDouble &weights, MatrixDouble &kinematics,
340 const VectorDouble &equilibrated_stress, const double tolerance) {
342 VectorDouble stress = .6 * equilibrated_stress;
343 CoefficientState state;
344 CHKERR evaluateCoefficients(parameters, basis, weights, kinematics, stress,
345 state, true);
346 if (!(norm_2(state.residual) > 1.e-4))
347 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
348 "Elimination test requires a nonzero copy residual");
349 const MatrixDouble coupling = crossMass(basis, basis, weights);
350 // A positive mass block supplies a fixed mechanical test problem. The
351 // constitutive row, its compliance and both cross blocks use the actual
352 // mesh-stress discretisation at the deliberately unequilibrated state.
353 const MatrixDouble mechanical = 1.3 * coupling;
354 const int size = stress.size();
355 VectorDouble mechanical_residual(size);
356 for (int ii = 0; ii != size; ++ii)
357 mechanical_residual[ii] = .01 * std::sin(ii + 1.);
358
359 MatrixDouble enlarged(2 * size, 2 * size);
360 VectorDouble explicit_step(2 * size);
361 for (int rr = 0; rr != size; ++rr) {
362 explicit_step[rr] = -mechanical_residual[rr];
363 explicit_step[size + rr] = -state.residual[rr];
364 for (int cc = 0; cc != size; ++cc) {
365 enlarged(rr, cc) = mechanical(rr, cc);
366 enlarged(rr, size + cc) = coupling(rr, cc);
367 enlarged(size + rr, cc) = coupling(cc, rr);
368 enlarged(size + rr, size + cc) = -state.compliance(rr, cc);
369 }
370 }
371 CHKERR solveLinearSystem(enlarged, explicit_step);
372
373 MatrixDouble inverse_coupling(size, size);
374 for (int cc = 0; cc != size; ++cc) {
375 VectorDouble column(size);
376 for (int rr = 0; rr != size; ++rr)
377 column[rr] = coupling(cc, rr);
378 CHKERR solveLinearSystem(static_cast<const MatrixDouble &>(state.compliance),
379 column);
380 for (int rr = 0; rr != size; ++rr)
381 inverse_coupling(rr, cc) = column[rr];
382 }
383 VectorDouble inverse_residual = state.residual;
384 CHKERR solveLinearSystem(static_cast<const MatrixDouble &>(state.compliance),
385 inverse_residual);
386 MatrixDouble schur = mechanical + prod(coupling, inverse_coupling);
387 VectorDouble rhs_correction = prod(coupling, inverse_residual);
388 VectorDouble condensed_d = -mechanical_residual - rhs_correction;
389 CHKERR solveLinearSystem(static_cast<const MatrixDouble &>(schur), condensed_d);
390 const VectorDouble condensed_t =
391 inverse_residual + prod(inverse_coupling, condensed_d);
392 VectorDouble difference = explicit_step;
393 for (int ii = 0; ii != size; ++ii) {
394 difference[ii] -= condensed_d[ii];
395 difference[size + ii] -= condensed_t[ii];
396 }
397 CHKERR checkNear(norm_2(difference) / std::max(1., norm_2(explicit_step)), 0.,
398 tolerance, "explicit/coefficient-Schur Newton step");
399 VectorDouble omitted_correction = -mechanical_residual;
400 CHKERR solveLinearSystem(static_cast<const MatrixDouble &>(schur),
401 omitted_correction);
402 omitted_correction -= condensed_d;
403 if (!(norm_2(omitted_correction) > 1.e-4))
404 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
405 "Omitting the nonzero copy-residual correction did not change "
406 "the condensed Newton step");
407 CHKERR PetscPrintf(PETSC_COMM_WORLD,
408 "Coefficient Schur step agrees; copy residual %.6e, "
409 "omitted-correction error %.6e\n",
410 norm_2(state.residual), norm_2(omitted_correction));
412}
413
414MoFEMErrorCode runSpaceAtom(const Material::Parameters &parameters,
415 const int quadrature_order, const double tolerance,
416 const double newton_tolerance) {
418 MatrixDouble points;
419 VectorDouble weights;
420 CHKERR makeQuadrature(quadrature_order, points, weights);
421 std::array<MatrixDouble, 3> bases;
422 for (int order = 0; order != 3; ++order) {
423 CHKERR evaluateBasis(points, order, bases[order]);
424 CHKERR checkPositiveDefinite(crossMass(bases[order], bases[order], weights),
425 "nested stress-space mass");
426 if (order)
427 for (unsigned int gg = 0; gg != weights.size(); ++gg)
428 for (unsigned int bb = 0; bb != bases[order - 1].size2(); ++bb)
429 CHKERR checkNear(bases[order](gg, bb), bases[order - 1](gg, bb),
430 tolerance, "actual USER_BASE nesting");
431 }
432 MatrixDouble kinematics;
433 CHKERR makeKinematics(bases[1], kinematics);
434 CHKERR checkExactCases(parameters, bases[0], weights, kinematics, tolerance,
435 newton_tolerance);
436 VectorDouble coefficients, previous, linear_solution;
437 double previous_gap = std::numeric_limits<double>::infinity();
438 for (int order = 0; order != 3; ++order) {
439 coefficients.resize(5 * bases[order].size2(), false);
440 coefficients.clear();
441 std::copy(previous.begin(), previous.end(), coefficients.begin());
442 CoefficientState state;
443 CHKERR solveCoefficients(parameters, bases[order], weights, kinematics,
444 coefficients, newton_tolerance, state);
445 CHKERR checkPositiveDefinite(state.compliance,
446 "assembled stress coefficient compliance");
447 if (state.minimumGap < -tolerance || state.gap < -tolerance ||
448 (order && !(state.gap < previous_gap - 1.e-3 * tolerance)))
449 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
450 "Nested mesh-stress Fenchel gaps are negative or fail to decrease");
451 if (order == 1) {
452 linear_solution = coefficients;
453 if (!(state.maximumMismatch > 1.e-5))
454 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
455 "Weak P1 closure unexpectedly imposed pointwise material copies");
456 }
457 CHKERR PetscPrintf(PETSC_COMM_WORLD,
458 "Mesh stress P%d: %d coefficients, moment %.6e, "
459 "gap %.12e, maximum copy mismatch %.6e\n",
460 order, static_cast<int>(coefficients.size()),
461 norm_2(state.residual), state.gap, state.maximumMismatch);
462 previous = coefficients;
463 previous_gap = state.gap;
464 }
465 CHKERR checkLostMode(parameters, bases[0], bases[1], weights, tolerance);
466 CHKERR checkCoefficientElimination(parameters, bases[1], weights, kinematics,
467 linear_solution, tolerance);
468 CHKERR PetscPrintf(PETSC_COMM_WORLD,
469 "Auxiliary logarithmic stress space atom passed "
470 "with %d fixed positive quadrature points\n",
471 static_cast<int>(weights.size()));
473}
474
475} // namespace
476
477static char help[] =
478 "Check weak auxiliary stress spaces and coefficient Schur elimination.\n";
479
480int main(int argc, char *argv[]) {
481 MoFEM::Core::Initialize(&argc, &argv, nullptr, help);
482 try {
483 moab::Core moab;
484 MoFEM::Core core(moab);
485 MoFEM::Interface &m_field = core;
486 auto *json = m_field.getInterface<JsonConfigManager>();
487 auto *meshsets = m_field.getInterface<MeshsetsManager>();
488 CHKERR meshsets->addMeshset(BLOCKSET, 1001, "MAT_NEOHOOKEAN");
489 CHKERR meshsets->setMeshsetFromFile();
490 const auto block = json->getParamsFromBlockset("MAT_NEOHOOKEAN", 1001);
491 if (block.size() != 2 || !block.count("c10") || !block.count("k"))
492 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
493 "Space atom requires MAT_NEOHOOKEAN JSON block 1001 with c10,k");
494 const Material::Parameters parameters{block.at("c10"), block.at("k")};
496 PetscInt quadrature_order = 0;
497 PetscReal tolerance = 0., newton_tolerance = 0.;
498 CHKERR PetscOptionsGetInt(nullptr, nullptr, "-auxiliary_space_quadrature_order",
499 &quadrature_order, nullptr);
500 CHKERR PetscOptionsGetReal(nullptr, nullptr, "-auxiliary_space_tolerance",
501 &tolerance, nullptr);
502 CHKERR PetscOptionsGetReal(nullptr, nullptr,
503 "-auxiliary_space_newton_tolerance",
504 &newton_tolerance, nullptr);
505 if (quadrature_order < 4 || !std::isfinite(tolerance) || tolerance <= 0. ||
506 !std::isfinite(newton_tolerance) || newton_tolerance <= 0. ||
507 newton_tolerance >= tolerance)
508 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
509 "Space atom requires positive finite JSON tolerances and "
510 "quadrature order at least four");
511 CHKERR runSpaceAtom(parameters, quadrature_order, tolerance, newton_tolerance);
512 }
515 return 0;
516}
Eshelbian plasticity interface.
boost::shared_ptr< IncrementalOptimizationContext > context
Neo-Hookean material law in orthonormal logarithmic coordinates.
int main()
constexpr double a
Kronecker Delta class.
#define CATCH_ERRORS
Catch errors.
@ USER_BASE
user implemented approximation base
Definition definitions.h:68
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
#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
auto cross(const Tensor1_Expr< A, T, 3, i > &a, const Tensor1_Expr< B, U, 3, j > &b, const Index< k, 3 > &)
Definition cross.hpp:10
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
Definition MatHuHu.hpp:33
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
MoFEMErrorCode solveLinearSystem(MatrixDouble &mat, VectorDouble &f)
solve linear system with lapack dgesv
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
static MoFEMErrorCode evaluateInverse(const Parameters &parameters, const Coordinates &t_stress, InverseState &state)
Recover Dm(Td), its compliance and conjugate energy; no state is cached.
static MoFEMErrorCode validateParameters(const Parameters &parameters)
Check finite, strictly positive C10, K and representable mu = 2*C10.
static MoFEMErrorCode evaluateDeviator(const Parameters &parameters, const Coordinates &t_deviator, double &energy, Coordinates *stress_ptr=nullptr, Tangent *hessian_ptr=nullptr)
Evaluate f(D), optionally its five-component gradient and Hessian.
static MoFEMErrorCode evaluateFenchelGap(const Parameters &parameters, const Coordinates &t_deviator, const Coordinates &t_stress, const InverseState &inverse, double &gap, double *energy_ptr=nullptr)
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 structure for finite element entity
std::map< std::string, double > getParamsFromBlockset(const std::string &type_name, int meshset_id) const
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.