19using namespace PlasticIncrementalOptimizationInternal;
21namespace PlasticIncrementalOptimizationInternal {
28 auto save = [&](boost::shared_ptr<FieldEntity> field_entity_ptr) {
30 auto field_data = field_entity_ptr->getEntFieldData();
33 "Equilibrated-value test requires five trace-free P0 plasticH "
34 "coordinates per cell; got %zu",
37 std::copy(field_data.begin(), field_data.end(), values.begin());
38 history.emplace(field_entity_ptr->getEnt(), values);
53 const auto t_direction_coordinates =
55 auto set = [&](boost::shared_ptr<FieldEntity> field_entity_ptr) {
57 const auto history_it = history.find(field_entity_ptr->getEnt());
58 if (history_it == history.end())
60 "Missing saved plasticH data for entity %llu",
61 static_cast<unsigned long long>(field_entity_ptr->getEnt()));
62 auto field_data = field_entity_ptr->getEntFieldData();
63 if (field_data.size() != history_it->second.size())
65 "Changed plasticH coefficient count while restoring history");
66 std::copy(history_it->second.begin(), history_it->second.end(),
68 auto t_field = getFTensor1FromPtr<plasticLogarithmicStretchCoordinateSize>(
71 t_field(
L) +=
scale * t_direction_coordinates(
L);
83 auto save = [&](boost::shared_ptr<FieldEntity> field_entity_ptr) {
85 auto field_data = field_entity_ptr->getEntFieldData();
86 if (field_data.size() != 1)
88 "Committed plastic kappa requires one P0 coefficient per "
91 const double kappa = field_data[0];
94 "Committed plastic kappa on entity %llu must be finite and "
95 "non-negative; got %g",
96 static_cast<unsigned long long>(field_entity_ptr->getEnt()),
98 history.emplace(field_entity_ptr->getEnt(),
kappa);
109 auto set = [&](boost::shared_ptr<FieldEntity> field_entity_ptr) {
111 const auto history_it = history.find(field_entity_ptr->getEnt());
112 if (history_it == history.end())
114 "Missing saved plastic kappa for entity %llu",
115 static_cast<unsigned long long>(field_entity_ptr->getEnt()));
116 auto field_data = field_entity_ptr->getEntFieldData();
117 if (field_data.size() != 1)
119 "Changed plastic-kappa coefficient count while restoring "
121 field_data[0] = history_it->second;
139 CHKERR VecGhostUpdateBegin(
state, INSERT_VALUES, SCATTER_FORWARD);
140 CHKERR VecGhostUpdateEnd(
state, INSERT_VALUES, SCATTER_FORWARD);
150 : ep(ep), timeSolver(
std::move(ts)) {}
177 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline)
const {
188 "Plastic incremental optimization requires -plastic_volume 1 "
189 "and -cohesive_interface_on 0");
192 "Plastic incremental-optimization control DM is not available");
195 "Plastic incremental optimization requires a state TS");
207 "Plastic trial-control vector is not available");
211 CHKERR VecZeroEntries(committed_control);
212 CHKERR VecZeroEntries(candidate_control);
216 "-incremental_optimization_yield_stress",
220 "-incremental_optimization_isotropic_hardening_modulus",
223 "-incremental_optimization_dissipation_epsilon",
227 "Initial plastic yield stress must be finite and positive");
231 "Isotropic hardening modulus must be finite and non-negative");
235 "Plastic dissipation epsilon must be finite and non-negative");
239 <<
"Plastic model parameters: initial yield stress "
243 <<
", constraint scaling sqrt(reference cell volume)";
253 "Plastic constraint DM is null");
266 DM constraint_dm, Vec multipliers) {
273 Vec committed_control, Vec reference_control) {
275 (void)committed_control;
278 CHKERR VecZeroEntries(reference_control);
300 Vec smooth_gradient) {
313 Vec control, Vec smooth_gradient, Vec objective_gradient) {
320 Vec control, Vec constraints) {
326 Vec control, Vec smooth_gradient, Mat jacobian) {
337 "Fallback plastic Jacobian scratch vector is unavailable");
346boost::shared_ptr<IncrementalOptimizationContext>
350 auto problem = boost::make_shared<PlasticIncrementalOptimizationProblem>(
356 const boost::shared_ptr<IncrementalOptimizationContext> &
context) {
359 "Incremental-optimization context has no problem");
360 auto plastic_problem =
361 boost::dynamic_pointer_cast<PlasticIncrementalOptimizationProblem>(
363 if (!plastic_problem)
365 "Incremental-optimization problem is not plasticity");
366 return *plastic_problem;
375 "Selected material does not provide the Helmholtz free energy "
376 "required by the equilibrated mechanical value");
383 "Equilibrated mechanical value requires explicit logarithmic "
384 "stretch, -grad no_h1, -rotations large, and -no_stretch 0");
388 if (std::abs(ep.
alphaRho) > std::numeric_limits<double>::epsilon())
390 "Incremental optimization currently supports first-order "
391 "pseudo-time relaxation only; set -density_alpha_rho 0");
395 "The material Helmholtz derivative with imposed external strain "
396 "is not implemented");
399 "Equilibrated mechanical value does not include cracking or "
400 "contact contributions");
403 "Equilibrated mechanical value does not include initial "
417 "Fixed-control equilibrium requires a TS and a state vector");
419 PetscReal initial_dt = 0;
420 CHKERR TSGetTimeStep(ts, &initial_dt);
424 CHKERR TSSetStepNumber(ts, 0);
429 PetscBool previous_force_iteration = PETSC_FALSE;
430 CHKERR TSGetSNES(ts, &snes);
431 CHKERR SNESGetForceIteration(snes, &previous_force_iteration);
436 CHKERR SNESSetForceIteration(snes, PETSC_TRUE);
439 SNESSetForceIteration(snes, previous_force_iteration);
440 const MoFEMErrorCode restore_dt_error = TSSetTimeStep(ts, initial_dt);
441 CHKERR restore_force_error;
449 TSConvergedReason reason;
450 CHKERR TSGetConvergedReason(ts, &reason);
457 PetscReal pseudo_time = 0;
458 PetscReal final_pseudo_time = 0;
459 CHKERR TSGetTime(ts, &pseudo_time);
460 CHKERR TSGetMaxTime(ts, &final_pseudo_time);
461 const double tolerance =
462 100. * std::numeric_limits<double>::epsilon() *
463 std::max(1., std::abs(
static_cast<double>(final_pseudo_time)));
464 if (pseudo_time + tolerance < final_pseudo_time) {
465 if (reason != TS_CONVERGED_ITS) {
471 CHKERR TSGetStepNumber(ts, &steps);
473 <<
"Fixed-control equilibrium reached the TS step limit after " << steps
474 <<
" steps at pseudo-time " << pseudo_time <<
" (target "
476 <<
"); continuing with the final state and checking its rate-free "
477 "equilibrium residual";
482 CHKERR VecGhostUpdateBegin(
state, INSERT_VALUES, SCATTER_FORWARD);
483 CHKERR VecGhostUpdateEnd(
state, INSERT_VALUES, SCATTER_FORWARD);
492 CHKERR VecZeroEntries(zero_pseudo_rate);
493 CHKERR TSComputeIFunction(ts, pseudo_time,
state, zero_pseudo_rate,
494 rate_free_residual, PETSC_FALSE);
495 PetscReal pseudo_time_equation_norm = 0;
496 CHKERR SNESGetFunctionNorm(snes, &pseudo_time_equation_norm);
497 PetscReal rate_free_norm = 0;
498 CHKERR VecNorm(rate_free_residual, NORM_2, &rate_free_norm);
500 <<
"Pseudo-time equation residual " << pseudo_time_equation_norm
501 <<
", rate-free equilibrium residual " << rate_free_norm
502 <<
" at pseudo-time " << pseudo_time;
508namespace PlasticIncrementalOptimizationInternal {
516 const int local_code =
static_cast<int>(local_error);
518 CHKERR MPI_Allreduce(&local_code, &global_code, 1, MPI_INT, MPI_MAX, comm);
527 Vec committed_control, Vec candidate_control, Vec reference_control) {
548 auto mesh_control_before =
553 first_error = next_error;
555 local_stage_error = VecCopy(committed_control, control_before);
556 record_first_error(local_stage_error,
557 VecCopy(candidate_control, candidate_before));
558 record_first_error(local_stage_error,
559 VecCopy(reference_control, reference_before));
560 record_first_error(local_stage_error,
561 VecCopy(equilibrated_state, state_before));
572 const auto commit = [&]() {
581 std::map<EntityHandle, PackedPlasticCoordinates> plastic_increment;
583 auto save_increment = [&](boost::shared_ptr<FieldEntity> field_entity) {
585 auto data = field_entity->getEntFieldData();
588 "Plastic increment does not have five trace-free P0 "
591 std::copy(data.begin(), data.end(), values.begin());
592 plastic_increment.emplace(field_entity->getEnt(), values);
598 CHKERR synchroniseCommitStageError(
602 auto add_increment = [&](boost::shared_ptr<FieldEntity> field_entity) {
604 auto data = field_entity->getEntFieldData();
605 const auto increment = plastic_increment.find(field_entity->getEnt());
606 if (increment == plastic_increment.end() ||
609 "Plastic commit entity layout is inconsistent");
610 for (
int coordinate = 0;
613 data[coordinate] += increment->second[coordinate];
619 CHKERR synchroniseCommitStageError(
626 auto add_kappa_increment =
627 [&](boost::shared_ptr<FieldEntity> field_entity) {
629 auto data = field_entity->getEntFieldData();
630 const auto history = kappa_before.find(field_entity->getEnt());
631 if (history == kappa_before.end() || data.size() != 1)
633 "Plastic-kappa commit entity layout is inconsistent");
634 const double delta_kappa = data[0];
635 if (!std::isfinite(delta_kappa))
637 "Accepted plastic-kappa increment on entity %llu must "
639 static_cast<unsigned long long>(field_entity->getEnt()),
644 data[0] = history->second + std::max(0., delta_kappa);
651 CHKERR synchroniseCommitStageError(
659 local_stage_error = VecZeroEntries(committed_control);
660 record_first_error(local_stage_error, VecZeroEntries(candidate_control));
661 record_first_error(local_stage_error, VecZeroEntries(reference_control));
677 VecCopy(control_before, committed_control);
679 VecCopy(candidate_before, candidate_control);
681 VecCopy(reference_before, reference_control);
688 VecCopy(state_before, equilibrated_state);
693 VecGhostUpdateBegin(equilibrated_state, INSERT_VALUES,
696 VecGhostUpdateEnd(equilibrated_state, INSERT_VALUES,
699 ep.
dmElastic, equilibrated_state, INSERT_VALUES, SCATTER_REVERSE,
702 if (!local_restore_error)
703 local_restore_error = restore_control_error;
704 if (!local_restore_error)
705 local_restore_error = restore_candidate_error;
706 if (!local_restore_error)
707 local_restore_error = restore_reference_error;
708 if (!local_restore_error)
709 local_restore_error = restore_mesh_control_error;
710 if (!local_restore_error)
711 local_restore_error = restore_kappa_error;
712 if (!local_restore_error)
713 local_restore_error = restore_state_error;
714 if (!local_restore_error)
715 local_restore_error = restore_state_ghost_begin_error;
716 if (!local_restore_error)
717 local_restore_error = restore_state_ghost_end_error;
718 if (!local_restore_error)
719 local_restore_error = restore_mesh_state_error;
722 local_restore_error, restore_error);
732 DM constraint_dm, Vec control, Vec smooth_gradient,
733 Vec inequality_multipliers, PetscReal gradient_tolerance,
734 PetscReal constraint_tolerance, std::string &diagnostics) {
736 *
this, constraint_dm, control, smooth_gradient, inequality_multipliers,
737 gradient_tolerance, constraint_tolerance, diagnostics);
741 Vec solution, Vec equilibrated_state, Vec committed_control,
742 Vec candidate_control, Vec reference_control) {
744 ep, solution, equilibrated_state, committed_control, candidate_control,
Eshelbian plasticity interface.
boost::shared_ptr< IncrementalOptimizationContext > context
Lie algebra implementation.
Shared implementation details for plastic incremental optimization.
Plasticity implementation of incremental optimization.
#define FTENSOR_INDEX(DIM, I)
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#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
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
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
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
#define MOFEM_LOG(channel, severity)
Log.
std::map< EntityHandle, double > PlasticKappaHistory
MoFEMErrorCode assemblePlasticInequalityJacobian(PlasticIncrementalOptimizationProblem &problem, Vec control, Vec smooth_gradient, Mat jacobian)
MoFEMErrorCode setPlasticHistory(EshelbianCore &ep, const PlasticHistory &history, const FTensor::Tensor2_symmetric< double, SPACE_DIM > &t_direction, const double scale)
MoFEMErrorCode clearPlasticIncrementFields(EshelbianCore &ep)
MoFEMErrorCode assembleIncrementalObjectiveGradient(PlasticIncrementalOptimizationProblem &problem, Vec control, Vec smooth_gradient, Vec objective_gradient)
MoFEMErrorCode initialisePlasticInequalityMultipliers(const PlasticIncrementalOptimizationProblem &problem, DM constraint_dm, Vec multipliers)
MoFEMErrorCode setPlasticKappaHistory(EshelbianCore &ep, const PlasticKappaHistory &history)
MoFEMErrorCode setStateOnMesh(EshelbianCore &ep, Vec state)
MoFEMErrorCode savePlasticHistory(EshelbianCore &ep, PlasticHistory &history)
MoFEMErrorCode evaluatePlasticInequalityConstraints(const PlasticIncrementalOptimizationProblem &problem, Vec control, Vec constraints)
std::array< double, plasticLogarithmicStretchCoordinateSize > PackedPlasticCoordinates
MoFEMErrorCode savePlasticKappaHistory(EshelbianCore &ep, PlasticKappaHistory &history)
MoFEMErrorCode validatePlasticIncrementalSolution(PlasticIncrementalOptimizationProblem &problem, DM constraint_dm, Vec control, Vec smooth_gradient, Vec inequality_multipliers, PetscReal gradient_tolerance, PetscReal constraint_tolerance, std::string &diagnostics)
MoFEMErrorCode evaluatePlasticIncrementalResistanceValue(const PlasticIncrementalOptimizationProblem &problem, Vec control, double &value)
FTensor::Tensor1< double, plasticLogarithmicStretchCoordinateSize > plasticLogarithmicStretchCoordinatesFromTensor(const FTensor::Tensor2_symmetric< T, SPACE_DIM > &t_values)
MoFEMErrorCode assembleReducedHelmholtzGradient(EshelbianCore &ep, TS ts, Vec gradient)
std::map< EntityHandle, PackedPlasticCoordinates > PlasticHistory
MoFEMErrorCode commitIncrementalOptimizationLoadStep(EshelbianCore &ep, Vec solution, Vec equilibrated_state, Vec committed_control, Vec candidate_control, Vec reference_control)
boost::shared_ptr< IncrementalOptimizationContext > createIncrementalOptimizationContext(boost::shared_ptr< IncrementalOptimizationProblem > problem, SmartPetscObj< Vec > state)
constexpr int plasticLogarithmicStretchCoordinateSize
MoFEMErrorCode validateEquilibratedMechanicalValueScope(EshelbianCore &ep)
boost::shared_ptr< IncrementalOptimizationContext > createPlasticIncrementalOptimizationContext(EshelbianCore &ep, SmartPetscObj< TS > ts, SmartPetscObj< Vec > state)
MoFEMErrorCode solveEquilibriumStateTS(TopologicalTAOCtxImpl *ctx_impl_ptr)
MoFEMErrorCode solveIncrementalOptimizationTAO(const boost::shared_ptr< IncrementalOptimizationContext > &context, Vec state)
MoFEMErrorCode evaluateEquilibratedMechanicalValue(EshelbianCore &ep, TS ts, double &value)
PlasticIncrementalOptimizationProblem & getPlasticIncrementalOptimizationProblem(const boost::shared_ptr< IncrementalOptimizationContext > &context)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
SmartPetscObj< Vec > incrementalTrialControl
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
static enum StretchSelector stretchSelector
boost::shared_ptr< Range > contactFaces
MoFEM::Interface & mField
boost::shared_ptr< Range > plasticVolumes
const std::string materialH1Positions
static PetscBool crackingOn
const std::string elementVolumeName
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
const std::string plasticHField
const std::string plasticFlowField
MoFEMErrorCode runIncrementalOptimizationTAO(TS ts, Vec x)
boost::shared_ptr< PhysicalEquations > physicalEquations
static std::string internalStressTagName
static PetscBool plasticVolume
static PetscBool interfaceCrack
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string plasticKappaField
SmartPetscObj< DM > dmIncrementalOptimization
Incremental-optimization control problem.
EquilibriumSolveStatus status
static const Features noStretchMask
double dissipationRegularizationEpsilon
double initialYieldStress
SmartPetscObj< TS > timeSolver
MoFEMErrorCode initialiseInequalityMultipliers(DM constraint_dm, Vec multipliers) override
MoFEMErrorCode assembleConservativeGradient(Vec smooth_gradient) override
const std::string & getPlasticKappaFieldName() const
const std::string & getVolumeElementName() const
MoFEMErrorCode initialiseReferenceControl(Vec committed_control, Vec reference_control) override
MoFEMErrorCode createControlData(SmartPetscObj< Vec > &committed_control, SmartPetscObj< Vec > &candidate_control) override
const std::string & getPlasticFlowFieldName() const
SmartPetscObj< Vec > fallbackJacobianSmoothGradient
MoFEMErrorCode assembleObjectiveGradient(Vec control, Vec smooth_gradient, Vec objective_gradient) override
MoFEMErrorCode solveState(Vec state, EquilibriumSolveReport &report) override
PlasticIncrementalOptimizationProblem(EshelbianCore &ep, SmartPetscObj< TS > ts)
MoFEMErrorCode evaluateInequalityConstraints(Vec control, Vec constraints) override
MoFEMErrorCode commit(Vec solution, Vec equilibrated_state, Vec committed_control, Vec candidate_control, Vec reference_control) override
std::string getName() const override
MoFEMErrorCode evaluateConservativeValue(double &value) override
MoFEMErrorCode validateSolution(DM constraint_dm, Vec control, Vec smooth_gradient, Vec inequality_multipliers, PetscReal gradient_tolerance, PetscReal constraint_tolerance, std::string &diagnostics) override
DM getControlDM() const override
MoFEMErrorCode configureConstraintDM(DM constraint_dm) override
MoFEMErrorCode evaluateDissipation(Vec control, double &value) override
MoFEMErrorCode restoreState(Vec state) override
MoFEMErrorCode assembleInequalityJacobian(Vec control, Vec smooth_gradient, Mat jacobian) override
MoFEMErrorCode assembleInequalityJacobianWithoutSmoothGradient(Vec control, Mat jacobian) override
MoFEMErrorCode addConstitutiveGeometryOperators(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline) const
MoFEMErrorCode validate() override
double isotropicHardeningModulus
Add operators pushing bases from local to physical configuration.
virtual MPI_Comm & get_comm() const =0
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.