v0.16.3
Loading...
Searching...
No Matches
IncrementalMechanics.cpp
Go to the documentation of this file.
1/**
2 * @file IncrementalMechanics.cpp
3 * @brief Mechanical equilibrium shared by the incremental-optimisation physics
4 */
5
6#define SINGULARITY
7#include <MoFEM.hpp>
8using namespace MoFEM;
9
11
15
16namespace EshelbianPlasticity {
17
18using namespace PlasticIncrementalOptimizationInternal;
19
23
28 "Incremental-optimisation control storage is unavailable");
29 CHKERR VecGhostUpdateBegin(ep.incrementalTrialControl, INSERT_VALUES,
30 SCATTER_FORWARD);
31 CHKERR VecGhostUpdateEnd(ep.incrementalTrialControl, INSERT_VALUES,
32 SCATTER_FORWARD);
34 ep.incrementalTrialControl, INSERT_VALUES,
35 SCATTER_REVERSE, RowColData::ROW);
37}
38
40 Vec second,
41 PetscBool &equal) {
43 equal = PETSC_TRUE;
44 for (const auto &field : stateControlFields) {
45 IS raw_is = nullptr;
47 field.c_str(), &raw_is);
48 SmartPetscObj<IS> field_is(raw_is);
49 Vec first_block = nullptr, second_block = nullptr;
50 CHKERR VecGetSubVector(first, field_is, &first_block);
51 CHKERR VecGetSubVector(second, field_is, &second_block);
52 PetscBool block_equal = PETSC_FALSE;
53 CHKERR VecEqual(first_block, second_block, &block_equal);
54 CHKERR VecRestoreSubVector(second, field_is, &second_block);
55 CHKERR VecRestoreSubVector(first, field_is, &first_block);
56 if (!block_equal) {
57 equal = PETSC_FALSE;
58 break;
59 }
60 }
62}
63
66 for (const auto &field : stateControlFields) {
67 IS raw_is = nullptr;
69 field.c_str(), &raw_is);
70 SmartPetscObj<IS> field_is(raw_is);
71 Vec block = nullptr;
72 CHKERR VecGetSubVector(control, field_is, &block);
73 CHKERR VecZeroEntries(block);
74 CHKERR VecRestoreSubVector(control, field_is, &block);
75 }
76 CHKERR VecGhostUpdateBegin(control, INSERT_VALUES, SCATTER_FORWARD);
77 CHKERR VecGhostUpdateEnd(control, INSERT_VALUES, SCATTER_FORWARD);
79}
80
82IncrementalMechanics::snapshotHistory(std::vector<FieldSnapshot> &snapshot) {
84 snapshot.clear();
85 snapshot.resize(historyFields.size());
86 for (std::size_t f = 0; f != historyFields.size(); ++f) {
87 auto &field_snapshot = snapshot[f];
88 auto save = [&](boost::shared_ptr<FieldEntity> field_entity) {
90 auto data = field_entity->getEntFieldData();
91 field_snapshot.emplace(field_entity->getEnt(),
92 std::vector<double>(data.begin(), data.end()));
94 };
95 CHKERR ep.mField.getInterface<FieldBlas>()->fieldLambdaOnEntities(
96 save, historyFields[f]);
97 }
99}
100
105 std::vector<FieldSnapshot> history;
106 CHKERR snapshotHistory(history);
107 PetscBool same_control = PETSC_FALSE;
108 if (cacheValid)
110 same_control);
111 int local_changed = !cacheValid || !same_control ||
113 history != cachedHistory;
114 int changed = 0;
115 CHKERR MPI_Allreduce(&local_changed, &changed, 1, MPI_INT, MPI_MAX,
116 ep.mField.get_comm());
117 if (!changed) {
118 CHKERR VecCopy(cachedState, state);
120 report = cachedReport;
121 report.mechanicalSolveCount = 0;
123 }
124 // Only converged states are cached. A rejected trial keeps the previous
125 // cache usable while the optimiser rolls the control back.
126 gradientValid = false;
129 report.mechanicalSolveCount = 1;
131 if (!cachedControl)
133 if (!cachedState)
136 CHKERR VecCopy(state, cachedState);
137 cachedHistory = std::move(history);
139 cachedReport = report;
140 cacheValid = true;
141 }
143}
144
147 current = true;
148 if (!cacheValid)
150 std::vector<FieldSnapshot> history;
151 CHKERR snapshotHistory(history);
152 int local_changed =
154 int changed = 0;
155 CHKERR MPI_Allreduce(&local_changed, &changed, 1, MPI_INT, MPI_MAX,
156 ep.mField.get_comm());
157 current = !changed;
159}
160
167
169 double &value) {
171 // The baseline is the equilibrium without any increment. Zero the control
172 // blocks that enter equilibrium, solve, and put the trial control back so
173 // the current trial is not lost.
174 auto trial_before = vectorDuplicate(ep.incrementalTrialControl);
175 CHKERR VecCopy(ep.incrementalTrialControl, trial_before);
178 const MoFEMErrorCode solve_error =
180 MoFEMErrorCode value_error = 0;
181 if (!solve_error && report.status == EquilibriumSolveStatus::Converged)
183 CHKERR VecCopy(trial_before, ep.incrementalTrialControl);
184 CHKERR VecGhostUpdateBegin(ep.incrementalTrialControl, INSERT_VALUES,
185 SCATTER_FORWARD);
186 CHKERR VecGhostUpdateEnd(ep.incrementalTrialControl, INSERT_VALUES,
187 SCATTER_FORWARD);
188 CHKERR solve_error;
191 "Zero-increment baseline did not equilibrate (residual %g)",
192 report.equilibriumNorm);
193 CHKERR value_error;
195}
196
200
204 if (!cacheValid || !cachedState)
206 "The conservative gradient needs an equilibrated state");
207 if (!cachedGradient)
208 cachedGradient = createDMVector(control_dm);
209 CHKERR VecZeroEntries(cachedGradient);
210 if (supportsHessianAction()) {
211 // Keep the base adjoint; prepareHessian() freezes it for the shell.
218 ep, control_dm,
221 } else {
224 }
225 gradientValid = true;
227}
228
238
240 return ep.physicalEquations &&
241 ep.physicalEquations->providesHelmholtzCurvature();
242}
243
245 Vec control) {
249 "The selected material does not provide the curvature of the "
250 "reduced mechanical energy");
251 if (!gradientValid)
253 if (!hessianWorkspace)
258}
259
262 if (!hessianWorkspace)
264 "Mechanical Hessian action requested before prepareHessian()");
268}
269
279
285
286} // namespace EshelbianPlasticity
Eshelbian plasticity interface.
Mechanical equilibrium shared by the incremental-optimisation physics.
SmartPetscObj< Mat > metric
boost::shared_ptr< DataAtIntegrationPts > data
boost::shared_ptr< MatrixDouble > direction
Shared implementation details for plastic incremental optimization.
Plasticity implementation of incremental optimization.
EshelbianCore * ep
SmartPetscObj< Vec > gradient
@ ROW
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
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:543
PetscErrorCode DMMoFEMGetFieldIS(DM dm, RowColData rc, const char field_name[], IS *is)
get field is in the problem
Definition DMMoFEM.cpp:1536
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1250
MoFEMErrorCode assemblePlasticAdjointContribution(EshelbianCore &ep, DM flow_output_dm, Vec adjoint, Vec gradient)
MoFEMErrorCode assembleReducedBulkMaterialEnergyGradient(EshelbianCore &ep, TS ts, Vec gradient)
MoFEMErrorCode freezeReducedBulkMaterialEnergyHessian(const ReducedBulkMaterialEnergyHessianWorkspace &source, Vec control, ReducedBulkMaterialEnergyHessianWorkspace &target)
MoFEMErrorCode prepareReducedBulkMaterialEnergyHessian(EshelbianCore &ep, TS ts, Vec control, Vec equilibrated_state, ReducedBulkMaterialEnergyHessianWorkspace &workspace)
PetscInt getReducedBulkMaterialEnergyDirectionalSolveCount(const ReducedBulkMaterialEnergyHessianWorkspace &workspace)
Vec getReducedBulkMaterialEnergyBaseAdjoint(const ReducedBulkMaterialEnergyHessianWorkspace &workspace)
MoFEMErrorCode assembleReducedBulkMaterialEnergyHessianAction(EshelbianCore &ep, TS ts, ReducedBulkMaterialEnergyHessianWorkspace &workspace, Vec direction, Vec action)
boost::shared_ptr< ReducedBulkMaterialEnergyHessianWorkspace > createReducedBulkMaterialEnergyHessianWorkspace()
MoFEMErrorCode assembleReducedBulkMaterialEnergyFlowPreconditioner(EshelbianCore &ep, ReducedBulkMaterialEnergyHessianWorkspace &workspace, Mat preconditioner, bool retain_base_adjoint=true)
MoFEMErrorCode solveEquilibriumStateTS(TopologicalTAOCtxImpl *ctx_impl_ptr)
MoFEMErrorCode evaluateEquilibratedMechanicalValue(EshelbianCore &ep, TS ts, double &value)
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.
SmartPetscObj< Vec > incrementalTrialControl
MoFEM::Interface & mField
static double currentPhysicalTime
boost::shared_ptr< PhysicalEquations > physicalEquations
SmartPetscObj< DM > dmIncrementalOptimization
MoFEMErrorCode assembleConservativeGradient(DM control_dm, Vec gradient)
MoFEMErrorCode refreshConservativeGradient(DM control_dm)
MoFEMErrorCode snapshotHistory(std::vector< FieldSnapshot > &snapshot)
MoFEMErrorCode assembleHessianPreconditioner(Mat metric)
MoFEMErrorCode solveState(Vec state, EquilibriumSolveReport &report)
MoFEMErrorCode prepareHessian(DM control_dm, Vec control)
MoFEMErrorCode evaluateBaseline(Vec state, double &value)
boost::shared_ptr< PlasticIncrementalOptimizationInternal::ReducedBulkMaterialEnergyHessianWorkspace > gradientWorkspace
boost::shared_ptr< PlasticIncrementalOptimizationInternal::ReducedBulkMaterialEnergyHessianWorkspace > hessianWorkspace
MoFEMErrorCode applyHessian(Vec direction, Vec action)
IncrementalMechanics(EshelbianCore &ep, SmartPetscObj< TS > ts)
MoFEMErrorCode evaluateConservativeValue(double &value)
MoFEMErrorCode stateControlBlocksEqual(Vec first, Vec second, PetscBool &equal)
MoFEMErrorCode fixedDataAreCurrent(bool &current)
virtual MPI_Comm & get_comm() const =0
Basic algebra on fields.
Definition FieldBlas.hpp:21
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.