v0.16.3
Loading...
Searching...
No Matches
PlasticFlowPreconditionerTests.hpp
Go to the documentation of this file.
1#ifndef MOFEM_PLASTIC_FLOW_PRECONDITIONER_TESTS_HPP
2#define MOFEM_PLASTIC_FLOW_PRECONDITIONER_TESTS_HPP
3
5
6namespace EshelbianPlasticity {
7namespace {
8
9/** Flow-only matrices on the control DM leave the latent rows empty. Put a
10 * unit diagonal there so the flow block can be factorised and applied. */
11MoFEMErrorCode addLatentIdentityRows(EshelbianCore &ep, DM control_dm,
12 Mat matrix) {
14 IS raw_is = nullptr;
16 ep.plasticLatentField.c_str(), &raw_is);
17 SmartPetscObj<IS> latent_is(raw_is);
18 PetscInt size = 0;
19 const PetscInt *indices = nullptr;
20 CHKERR ISGetLocalSize(latent_is, &size);
21 CHKERR ISGetIndices(latent_is, &indices);
22 for (PetscInt i = 0; i != size; ++i)
23 CHKERR MatSetValue(matrix, indices[i], indices[i], 1., ADD_VALUES);
24 CHKERR ISRestoreIndices(latent_is, &indices);
25 CHKERR MatAssemblyBegin(matrix, MAT_FINAL_ASSEMBLY);
26 CHKERR MatAssemblyEnd(matrix, MAT_FINAL_ASSEMBLY);
28}
29
30/** Check the Gauss-point local curvature against shell/gradient differences
31 * and verify numerical factor refresh at changing flow and hardening. */
32MoFEMErrorCode testLocalFlowPreconditioner(
33 EshelbianCore &ep, DM flow_dm, Vec flow_template, DM latent_dm, Vec latent,
34 Vec latent_centre,
36 parameters,
37 Vec direction) {
38 using namespace PlasticIncrementalOptimizationInternal;
40 Mat raw_matrix = nullptr;
41 CHKERR DMCreateMatrix(flow_dm, &raw_matrix);
42 SmartPetscObj<Mat> matrix(raw_matrix);
43 auto flow = vectorDuplicate(flow_template);
45 auto reference = vectorDuplicate(flow);
46 auto trial = vectorDuplicate(flow);
47 auto plus = vectorDuplicate(flow);
48 auto minus = vectorDuplicate(flow);
49 auto zero_latent = vectorDuplicate(latent);
50 auto solution = vectorDuplicate(flow);
51 auto solve_residual = vectorDuplicate(flow);
52 KSP raw_ksp = nullptr;
53 CHKERR KSPCreate(ep.mField.get_comm(), &raw_ksp);
54 SmartPetscObj<KSP> ksp(raw_ksp);
55 CHKERR KSPSetOptionsPrefix(ksp, "incremental_optimization_tensor_");
56 PC pc = nullptr;
57 CHKERR KSPGetPC(ksp, &pc);
58 CHKERR PCSetType(pc, PCBJACOBI);
59 CHKERR KSPSetFromOptions(ksp);
60 CHKERR VecZeroEntries(zero_latent);
61 parameters.regularisationEpsilon = 1e-4;
62 PetscReal direction_norm = 0;
63 CHKERR VecNorm(direction, NORM_2, &direction_norm);
64 const double step = 1e-7 / std::max(1., direction_norm);
65 for (const double hardening : {0., .3}) {
66 parameters.hardeningModulus = hardening;
67 for (const double flow_scale : {0., .01, .1}) {
68 CHKERR VecCopy(direction, flow);
69 CHKERR VecShift(flow, .13);
70 CHKERR VecScale(flow, flow_scale);
72 ep, flow_dm, flow, latent_dm, latent, latent_dm, latent_centre,
73 parameters, matrix);
74 CHKERR MatMult(matrix, direction, action);
75 CHKERR VecZeroEntries(reference);
77 ep, flow_dm, flow, latent_dm, latent, latent_dm, latent_centre,
78 direction, zero_latent, parameters, reference);
79 PetscReal norm = 0, action_error = 0;
80 CHKERR VecNorm(reference, NORM_2, &norm);
81 CHKERR VecAXPY(reference, -1., action);
82 CHKERR VecNorm(reference, NORM_2, &action_error);
83 if (!std::isfinite(action_error) || action_error > 1e-11 * (1. + norm))
85 "Local matrix/action mismatch %g, norm %g, "
86 "flow scale %g, hardening %g",
87 action_error, norm, flow_scale, hardening);
88
89 const auto gradient = [&](double shift, Vec out) {
91 CHKERR VecWAXPY(trial, shift, direction, flow);
92 CHKERR VecZeroEntries(out);
94 ep, flow_dm, trial, latent_dm, latent, latent_dm, latent_centre,
95 parameters, out);
97 };
98 CHKERR gradient(step, plus);
99 CHKERR gradient(-step, minus);
100 CHKERR VecAXPY(plus, -1., minus);
101 CHKERR VecScale(plus, .5 / step);
102 CHKERR VecAXPY(plus, -1., action);
103 PetscReal fd_error = 0;
104 CHKERR VecNorm(plus, NORM_2, &fd_error);
105 if (!std::isfinite(fd_error) || fd_error > 1e-8 + 1e-5 * norm)
107 "Local matrix gradient difference error %g, "
108 "norm %g, flow scale %g, hardening %g",
109 fd_error, norm, flow_scale, hardening);
110 MOFEM_LOG("EP", Sev::inform)
111 << "Local flow preconditioner verified: flow scale " << flow_scale
112 << ", hardening " << hardening << ", action error " << action_error
113 << ", FD error " << fd_error;
114
115 // Reuse one Pmat and one PC across changing flow and hardening. Check
116 // the actual inverse action, so stale LU factors fail this regression.
117 CHKERR addLatentIdentityRows(ep, flow_dm, matrix);
118 CHKERR KSPSetOperators(ksp, matrix, matrix);
119 CHKERR KSPSetUp(ksp);
120 CHKERR PCApply(pc, direction, solution);
121 CHKERR MatMult(matrix, solution, solve_residual);
122 CHKERR VecAXPY(solve_residual, -1., direction);
123 PetscReal solve_error = 0;
124 CHKERR VecNorm(solve_residual, NORM_2, &solve_error);
125 if (!std::isfinite(solve_error) ||
126 solve_error > 1e-8 * std::max(direction_norm, PETSC_SMALL))
128 "Updated flow preconditioner inverse failed: "
129 "relative residual %g, flow scale %g, hardening %g",
130 solve_error / std::max(direction_norm, PETSC_SMALL), flow_scale,
131 hardening);
132 MOFEM_LOG("EP", Sev::inform)
133 << "Flow preconditioner factors verified: flow scale " << flow_scale
134 << ", hardening " << hardening << ", relative inverse residual "
135 << solve_error / std::max(direction_norm, PETSC_SMALL);
136 }
137 }
139}
140
141using TestMaterialActionByElement = std::map<EntityHandle, MatrixDouble>;
142
143/** Independent fixed-F differences are a test oracle only. Production reads
144 * Ue directly and never reconstructs the perturbed elastic deformation. */
145struct OpTestLocalMaterialFlowAction : VolUserDataOperator {
146 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
147 OpTestLocalMaterialFlowAction(
148 boost::shared_ptr<DataAtIntegrationPts> data,
149 boost::shared_ptr<MatrixDouble> direction,
150 boost::shared_ptr<TestMaterialActionByElement> actions)
152 actions(actions) {}
153 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
155 FTENSOR_INDEXES(3, i, j, k);
156 FTensor::Index<'a', 5> a;
157 FTensor::Index<'b', 5> b;
158 const int count = getGaussPts().size2();
159 if (count <= 1)
160 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
161 "Local material assembly test requires multiple Gauss points");
162 auto hp = data->getFTensorPlasticH(count);
163 auto ue = data->getFTensorStretch(count);
164 auto he = data->getFTensorLogStretch(count);
165 auto v = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::get(
166 *direction, count)();
167 auto out = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::size(
168 (*actions)[getFEEntityHandle()], count)();
169 const auto function = [](const FTensor::Tensor2_symmetric<double, 3> &h,
171 FTENSOR_INDEXES(3, m, n);
174 vectors(m, n) = h(m, n);
176 "Diagonalise independent material action test tensor");
177 return EigenMatrix::getMat(values, vectors, f);
178 };
179 const auto &basis = Tensor2SymmetricDeviatorBasis::getBasis();
180 for (int gg = 0; gg != count; ++gg) {
182 h(i, j) = hp(i, j);
183 u(i, j) = ue(i, j);
184 elastic_h(i, j) = he(i, j);
185 const auto fp = function(h, [](double x) { return std::exp(x); });
187 anchor(i, j) = u(i, k) * fp(k, j);
189 constexpr double step = 2e-6;
190 for (int col = 0; col != 5; ++col) {
191 FTensor::Tensor1<double, 5> unit, coordinates;
192 unit(a) = 0.;
193 unit(col) = 1.;
194 FTensor::Tensor2_symmetric<double, 3> tensor_v, difference;
195 tensor_v(i, j) = basis(i, j, a) * unit(a);
196 const auto evaluate = [&](double shift) {
198 trial(i, j) = h(i, j) + shift * tensor_v(i, j);
199 const auto inverse =
200 function(trial, [](double x) { return std::exp(-x); });
202 fe(i, j) = anchor(i, k) * inverse(k, j);
203 cauchy(i, j) = fe(k, i) * fe(k, j);
204 metric(i, j) = (cauchy(i, j) || cauchy(j, i)) / 2.;
205 return function(metric, [](double x) { return .5 * std::log(x); });
206 };
207 const auto plus = evaluate(step), minus = evaluate(-step);
208 difference(i, j) = (plus(i, j) - minus(i, j)) / (2. * step);
209 coordinates(a) = basis(i, j, a) * difference(i, j);
210 for (int row = 0; row != 5; ++row)
211 map(row, col) = coordinates(row);
212 }
214 CHKERR data->physicsPtr->evaluateElasticLogarithmicMaterialHessian(
215 getFEEntityHandle(), gg, *data, elastic_h, tangent);
216 FTensor::Tensor1<double, 5> direction_h, stress, source;
217 direction_h(a) = map(a, b) * v(b);
218 stress(a) = tangent(a, b) * direction_h(b);
219 source(a) = map(b, a) * stress(b);
220 out(a) = source(a);
221 // The zero-adjoint material response independently validates the pure
222 // tangent API and packed shear conventions, for both material adapters.
223 LogarithmicMaterialCurvature oracle;
224 oracle.stretch(i, j) = elastic_h(i, j);
225 oracle.direction(i, j) = basis(i, j, a) * direction_h(a);
226 oracle.adjoint(i, j) = 0.;
227 oracle.stressAdjoint(a) = 0.;
228 oracle.stressDirection(a) = 0.;
229 CHKERR data->physicsPtr->evaluateHelmholtzCurvature(getFEEntityHandle(),
230 gg, *data, oracle);
232 oracle.stretchResult(0), .5 * oracle.stretchResult(1),
233 .5 * oracle.stretchResult(2), oracle.stretchResult(3),
234 .5 * oracle.stretchResult(4), oracle.stretchResult(5));
236 error(a) = stress(a) - basis(i, j, a) * covector(i, j);
237 if (std::sqrt(error(a) * error(a)) >
238 1e-9 * (1. + std::sqrt(stress(a) * stress(a))))
239 SETERRQ(PETSC_COMM_SELF, MOFEM_ATOM_TEST_INVALID,
240 "Pure material Hessian differs from zero-adjoint response");
241 ++hp;
242 ++ue;
243 ++he;
244 ++v;
245 ++out;
246 }
248 }
249 boost::shared_ptr<DataAtIntegrationPts> data;
250 boost::shared_ptr<MatrixDouble> direction;
251 boost::shared_ptr<TestMaterialActionByElement> actions;
252};
253
254struct OpTestLoadLocalMaterialAction : VolUserDataOperator {
255 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
256 OpTestLoadLocalMaterialAction(
257 boost::shared_ptr<TestMaterialActionByElement> actions,
258 boost::shared_ptr<MatrixDouble> values)
260 values(values) {}
261 MoFEMErrorCode doWork(int, EntityType, EntData &) override {
263 FTensor::Index<'a', 5> a;
264 const int count = getGaussPts().size2();
265 auto input = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::get(
266 actions->at(getFEEntityHandle()), count)();
267 auto output = MatrixSizeHelper<GetFTensor1FromMatType<5, -1, DL>, DL>::size(
268 *values, count)();
269 for (int gg = 0; gg != count; ++gg) {
270 output(a) = input(a);
271 ++input;
272 ++output;
273 }
275 }
276 boost::shared_ptr<TestMaterialActionByElement> actions;
277 boost::shared_ptr<MatrixDouble> values;
278};
279
280MoFEMErrorCode assembleTestLocalMaterialFlowAction(EshelbianCore &ep,
281 DM flow_dm, Vec direction,
282 Vec action) {
284 const int order =
287 1);
288 const auto plastic_only = [&ep](FEMethod *method) {
289 return ep.plasticVolumes->find(method->getFEEntityHandle()) !=
290 ep.plasticVolumes->end();
291 };
292 auto actions = boost::make_shared<TestMaterialActionByElement>();
293 auto values = boost::make_shared<MatrixDouble>();
294 auto mechanical =
295 boost::make_shared<VolumeElementForcesAndSourcesCore>(ep.mField);
296 mechanical->ts_ctx = TSMethod::CTX_TSSETIJACOBIAN;
297 CHKERR ep.setBaseVolumeElementOps(1, false, false, false, mechanical);
298 mechanical->getRuleHook = [order](int, int, int) { return order; };
299 mechanical->exeTestHook = plastic_only;
300 mechanical->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<5>(
301 SmartPetscObj<DM>(flow_dm, true), VolUserDataOperator::OPCOL,
302 ep.plasticFlowField, values, SmartPetscObj<Vec>(direction, true), MBTET));
303 mechanical->getOpPtrVector().push_back(
304 new OpTestLocalMaterialFlowAction(ep.dataAtPts, values, actions));
305 TetPolynomialBase::switchCacheBaseOn<HDIV>({mechanical.get()});
306 const auto error =
308 TetPolynomialBase::switchCacheBaseOff<HDIV>({mechanical.get()});
309 CHKERR error;
310 auto flow = boost::make_shared<VolumeElementForcesAndSourcesCore>(ep.mField);
311 flow->getUserPolynomialBase() =
312 boost::make_shared<CGGUserPolynomialBase>(nullptr, true);
313 flow->ksp_f = action;
314 flow->getRuleHook = mechanical->getRuleHook;
315 flow->exeTestHook = plastic_only;
317 flow->getOpPtrVector(), {NOSPACE}, ep.materialH1Positions);
318 flow->getOpPtrVector().push_back(
319 new OpTestLoadLocalMaterialAction(actions, values));
320 using Form = FormsIntegrators<VolUserDataOperator>::Assembly<A>::LinearForm<
321 GAUSS>::OpBaseTimesVector<1, 5, 5>;
322 flow->getOpPtrVector().push_back(new Form(ep.plasticFlowField, values));
323 CHKERR VecZeroEntries(action);
325 CHKERR VecAssemblyBegin(action);
326 CHKERR VecAssemblyEnd(action);
327 CHKERR VecGhostUpdateBegin(action, ADD_VALUES, SCATTER_REVERSE);
328 CHKERR VecGhostUpdateEnd(action, ADD_VALUES, SCATTER_REVERSE);
330}
331
332/** Independent fixed-state/fixed-adjoint gradient difference, including
333 * higher-order basis integration. No perturbed equilibrium or adjoint solve. */
334MoFEMErrorCode testFrozenFlowPreconditioner(
335 EshelbianCore &ep,
336 PlasticIncrementalOptimizationInternal::
337 ReducedBulkMaterialEnergyHessianWorkspace &workspace,
338 TS ts, DM flow_dm, Vec base_flow, Vec base_state, Vec direction) {
339 using namespace PlasticIncrementalOptimizationInternal;
341 Mat raw_matrix = nullptr;
342 CHKERR DMCreateMatrix(flow_dm, &raw_matrix);
343 SmartPetscObj<Mat> matrix(raw_matrix);
344 KSP raw_ksp = nullptr;
345 CHKERR KSPCreate(ep.mField.get_comm(), &raw_ksp);
346 SmartPetscObj<KSP> ksp(raw_ksp);
347 CHKERR KSPSetOptionsPrefix(ksp, "incremental_optimization_tensor_");
348 PC pc = nullptr;
349 CHKERR KSPGetPC(ksp, &pc);
350 CHKERR PCSetType(pc, PCBJACOBI);
351 CHKERR KSPSetFromOptions(ksp);
352 auto current_flow = vectorDuplicate(base_flow);
353 for (const double flow_shift : {0., .03, .12}) {
354 CHKERR VecWAXPY(current_flow, flow_shift, direction, base_flow);
356 ep, ts, flow_dm, current_flow, base_state, workspace);
357 CHKERR MatZeroEntries(matrix);
359 matrix);
360 auto action = vectorDuplicate(base_flow);
361 CHKERR MatMult(matrix, direction, action);
362 auto material_action = vectorDuplicate(base_flow);
363 CHKERR assembleTestLocalMaterialFlowAction(ep, flow_dm, direction,
364 material_action);
365 auto trial = vectorDuplicate(base_flow);
366 auto plus = vectorDuplicate(base_flow);
367 auto minus = vectorDuplicate(base_flow);
368 const auto set_flow = [&](Vec flow) {
371 CHKERR setStateOnMesh(ep, base_state);
373 };
374 constexpr double step = 1e-4;
375 const auto gradient = [&](double shift, Vec out) {
377 CHKERR VecWAXPY(trial, shift, direction, current_flow);
378 CHKERR set_flow(trial);
380 ep, flow_dm, getReducedBulkMaterialEnergyBaseAdjoint(workspace), out);
382 };
383 const auto plus_error = gradient(step, plus);
384 const auto minus_error = plus_error ? 0 : gradient(-step, minus);
385 const auto restore_error = set_flow(current_flow);
386 CHKERR plus_error;
387 CHKERR minus_error;
388 CHKERR restore_error;
389 CHKERR VecAXPY(plus, -1., minus);
390 CHKERR VecScale(plus, .5 / step);
391 CHKERR VecAXPY(plus, 1., material_action);
392 PetscReal reference_norm = 0;
393 CHKERR VecNorm(plus, NORM_2, &reference_norm);
394 CHKERR VecAXPY(plus, -1., action);
395 PetscReal error = 0;
396 CHKERR VecNorm(plus, NORM_2, &error);
397 if (!std::isfinite(error) || error > 1e-8 + 1e-5 * reference_norm)
398 SETERRQ(
400 "Frozen flow plus local material curvature failed: error %g, norm %g",
401 error, reference_norm);
402
403 auto second = vectorDuplicate(direction);
404 CHKERR VecCopy(direction, second);
405 CHKERR VecShift(second, .17);
406 auto second_action = vectorDuplicate(action);
407 CHKERR MatMult(matrix, second, second_action);
408 PetscScalar uv = 0, vu = 0;
409 CHKERR VecDot(direction, second_action, &uv);
410 CHKERR VecDot(second, action, &vu);
411 const double symmetry_error = std::abs(PetscRealPart(uv - vu));
412 if (symmetry_error > 1e-10 * (1. + std::max(std::abs(PetscRealPart(uv)),
413 std::abs(PetscRealPart(vu)))))
415 "Frozen flow curvature symmetry error %g", symmetry_error);
416 MOFEM_LOG("EP", Sev::inform)
417 << "Frozen flow plus local material preconditioner verified: FD error "
418 << error << ", norm " << reference_norm << ", symmetry error "
419 << symmetry_error;
420 auto solution = vectorDuplicate(base_flow);
421 auto residual = vectorDuplicate(base_flow);
422 CHKERR addLatentIdentityRows(ep, flow_dm, matrix);
423 CHKERR KSPSetOperators(ksp, matrix, matrix);
424 CHKERR KSPSetUp(ksp);
425 CHKERR PCApply(pc, direction, solution);
426 CHKERR MatMult(matrix, solution, residual);
427 CHKERR VecAXPY(residual, -1., direction);
428 PetscReal inverse_error = 0., rhs_norm = 0.;
429 CHKERR VecNorm(residual, NORM_2, &inverse_error);
430 CHKERR VecNorm(direction, NORM_2, &rhs_norm);
431 if (!std::isfinite(inverse_error) || inverse_error > 1e-8 * rhs_norm)
433 "Local material Pmat factor refresh failed: relative residual %g",
434 inverse_error / rhs_norm);
435 MOFEM_LOG("EP", Sev::inform)
436 << "Local material Pmat factors verified: flow shift " << flow_shift
437 << ", relative inverse residual " << inverse_error / rhs_norm;
438 }
439 CHKERR prepareReducedBulkMaterialEnergyHessian(ep, ts, flow_dm, base_flow,
440 base_state, workspace);
442}
443
444} // namespace
445} // namespace EshelbianPlasticity
446#endif
SmartPetscObj< KSP > ksp
SmartPetscObj< Mat > metric
Mixed directional derivatives of matrix exponentials for the reduced Hessian of the logarithmic plast...
boost::shared_ptr< DataAtIntegrationPts > data
boost::shared_ptr< MatrixDouble > direction
boost::shared_ptr< TestMaterialActionByElement > actions
boost::shared_ptr< MatrixDouble > flow
boost::shared_ptr< VectorDouble > latent
PetscErrorCode(* function)(TS, PetscReal, Vec, Vec, Vec, void *)
EshelbianCore * ep
SmartPetscObj< Vec > residual
SmartPetscObj< Vec > gradient
SmartPetscObj< Vec > values
PetscInt size
SmartPetscObj< Mat > inverse
#define FTENSOR_INDEXES(DIM,...)
constexpr double a
@ ROW
#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 DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:605
PetscErrorCode DMMoFEMGetFieldIS(DM dm, RowColData rc, const char field_name[], IS *is)
get field is in the problem
Definition DMMoFEM.cpp:1536
@ GAUSS
Gaussian quadrature integration.
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
boost::function< T(const T)> Fun
const FTensor::Tensor2< T, Dim, Dim > Vec
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
MoFEMErrorCode assemblePlasticAdjointContribution(EshelbianCore &ep, DM flow_output_dm, Vec adjoint, Vec gradient)
MoFEMErrorCode assemblePlasticReconstructedLocalFlowGradient(EshelbianCore &ep, DM flow_dm, Vec flow, DM latent_dm, Vec latent, DM centre_dm, Vec latent_centre, const PlasticLocalLawParameters &parameters, Vec flow_gradient)
MoFEMErrorCode assemblePlasticReconstructedLocalFlowHessianAction(EshelbianCore &ep, DM flow_dm, Vec flow, DM latent_dm, Vec latent, DM centre_dm, Vec latent_centre, Vec flow_direction, Vec latent_direction, const PlasticLocalLawParameters &parameters, Vec flow_action)
MoFEMErrorCode prepareReducedBulkMaterialEnergyHessian(EshelbianCore &ep, TS ts, Vec control, Vec equilibrated_state, ReducedBulkMaterialEnergyHessianWorkspace &workspace)
Vec getReducedBulkMaterialEnergyBaseAdjoint(const ReducedBulkMaterialEnergyHessianWorkspace &workspace)
MoFEMErrorCode assemblePlasticReconstructedLocalFlowPreconditioner(EshelbianCore &ep, DM flow_dm, Vec flow, DM latent_dm, Vec latent, DM centre_dm, Vec latent_centre, const PlasticLocalLawParameters &parameters, Mat preconditioner)
MoFEMErrorCode setReducedHessianControl(EshelbianCore &ep, DM control_dm, Vec control)
MoFEMErrorCode assembleReducedBulkMaterialEnergyFlowPreconditioner(EshelbianCore &ep, ReducedBulkMaterialEnergyHessianWorkspace &workspace, Mat preconditioner, bool retain_base_adjoint=true)
VolumeElementForcesAndSourcesCore::UserDataOperator VolUserDataOperator
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
Definition MatHuHu.hpp:33
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
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
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
constexpr AssemblyType A
double h
FTensor::Index< 'm', 3 > m
MoFEM::Interface & mField
boost::shared_ptr< Range > plasticVolumes
const std::string materialH1Positions
const std::string elementVolumeName
const std::string plasticFlowField
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.
const std::string plasticLatentField
Add operators pushing bases from local to physical configuration.
virtual MPI_Comm & get_comm() const =0
Data on single entity (This is passed as argument to DataOperator::doWork)
@ OPCOL
operator doWork function is executed on FE columns