v0.16.3
Loading...
Searching...
No Matches
plastic_convergence_atom.cpp
Go to the documentation of this file.
1/** @file plastic_convergence_atom.cpp
2 * @brief Check scaled joint gradient and hardening-sensitive slack acceptance.
3 */
4
5#include <MoFEM.hpp>
6using namespace MoFEM;
9using namespace EshelbianPlasticity;
10
11namespace {
12
13/** Give each scaled gradient block the same prescribed Euclidean norm. */
15 Vec gradient, const double norm) {
17 CHKERR VecZeroEntries(gradient);
18 for (const auto &[field, scale] : problem.getControlFieldScales()) {
19 IS raw_is = nullptr;
21 field.c_str(), &raw_is);
22 SmartPetscObj<IS> field_is(raw_is);
23 PetscInt size = 0;
24 CHKERR ISGetSize(field_is, &size);
25 if (!size)
26 SETERRQ(PETSC_COMM_WORLD, MOFEM_ATOM_TEST_INVALID,
27 "Gradient fixture requires both control fields");
28 Vec block = nullptr;
29 CHKERR VecGetSubVector(gradient, field_is, &block);
30 const auto error = VecSet(block, norm / (scale * std::sqrt(double(size))));
31 CHKERR VecRestoreSubVector(gradient, field_is, &block);
32 CHKERR error;
33 }
35}
36
37/** Only the leading Legendre coefficient carries a constant latent value. */
38MoFEMErrorCode setSlack(EshelbianCore &ep, Vec control, const double slack) {
40 const Problem *problem;
42 PetscInt size = 0;
43 CHKERR VecGetLocalSize(control, &size);
44 PetscScalar *values = nullptr;
45 CHKERR VecGetArray(control, &values);
46 for (const auto &dof : *problem->getNumeredRowDofsPtr()) {
47 const auto index = dof->getPetscLocalDofIdx();
48 if (dof->getName() == ep.plasticLatentField && index >= 0 && index < size)
49 values[index] = dof->getEntDofIdx() == 0 ? std::log(slack) : 0.;
50 }
51 CHKERR VecRestoreArray(control, &values);
52 CHKERR VecGhostUpdateBegin(control, INSERT_VALUES, SCATTER_FORWARD);
53 CHKERR VecGhostUpdateEnd(control, INSERT_VALUES, SCATTER_FORWARD);
55}
56
57MoFEMErrorCode runConvergenceAtom(EshelbianCore &ep) {
59 auto ts = createTS(ep.mField.get_comm());
60 CHKERR TSSetDM(ts, ep.dmElastic);
62 CHKERR VecZeroEntries(state);
65 auto gradient = vectorDuplicate(context->candidateControl);
66 constexpr double tolerance = 1.e-3;
67 double norm = 0;
68 std::string diagnostics;
69 CHKERR setGradientBlocks(problem, gradient, 0.6 * tolerance);
70 CHKERR problem.updateGradientDiagnostics(gradient, norm);
71 if (std::abs(norm - std::sqrt(2.) * 0.6 * tolerance) > 1.e-12 * tolerance)
73 "Joint gradient norm has incorrect scaling or MPI ownership");
74 CHKERR problem.validateSolution(context->candidateControl, gradient,
75 tolerance, diagnostics);
76 // Each scaled block is below tolerance, but their joint norm exceeds it.
77 CHKERR setGradientBlocks(problem, gradient, 0.8 * tolerance);
78 CHKERR PetscPushErrorHandler(PetscReturnErrorHandler, nullptr);
79 const auto rejection = problem.validateSolution(
80 context->candidateControl, gradient, tolerance, diagnostics);
81 CHKERR PetscPopErrorHandler();
82 if (!rejection)
84 "Unresolved joint gradient was accepted");
85
86 double slack_tolerance = 0;
88 nullptr, nullptr, "-incremental_optimization_plastic_slack_tolerance",
89 &slack_tolerance, nullptr);
90 const double factor = std::max(1., problem.getIsotropicHardeningModulus() /
91 problem.getInitialYieldStress());
92 bool converged = false;
93 CHKERR setSlack(ep, context->candidateControl,
94 0.5 * slack_tolerance / factor);
95 CHKERR problem.assessProximalConvergence(context->candidateControl, converged,
96 diagnostics);
97 if (!converged)
99 "Resolved physical slack was rejected");
100 CHKERR setSlack(ep, context->candidateControl, 2. * slack_tolerance / factor);
101 CHKERR problem.assessProximalConvergence(context->candidateControl, converged,
102 diagnostics);
103 if (converged)
105 "Unresolved strain/hardening slack was accepted");
106 CHKERR PetscPrintf(ep.mField.get_comm(),
107 "Joint gradient and combined slack acceptance verified\n");
109}
110
111} // namespace
112
113static char help[] = "Verify the two plastic acceptance criteria.\n";
114
115int main(int argc, char *argv[]) {
116 MoFEM::Core::Initialize(&argc, &argv, nullptr, help);
117 auto core_log = logging::core::get();
118 core_log->add_sink(LogManager::createSink(LogManager::getStrmWorld(), "EP"));
119 LogManager::setLog("EP");
120 core_log->add_sink(
122 LogManager::setLog("EPSELF");
123 core_log->add_sink(
125 LogManager::setLog("EPSYNC");
126 try {
127 CHKERR runAuxiliaryLogarithmicStressTest(runConvergenceAtom);
128 }
131 return 0;
132}
Shared mesh and problem setup for auxiliary formulation atoms.
boost::shared_ptr< IncrementalOptimizationContext > context
VectorDouble slack
exp(psi)
Plasticity implementation of incremental optimization.
EshelbianCore * ep
SmartPetscObj< Vec > gradient
SmartPetscObj< Vec > values
PetscInt size
int main()
@ ROW
#define CATCH_ERRORS
Catch errors.
#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.
PetscErrorCode DMMoFEMGetProblemPtr(DM dm, const MoFEM::Problem **problem_ptr)
Get pointer to problem data structure.
Definition DMMoFEM.cpp:451
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
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
const FTensor::Tensor2< T, Dim, Dim > Vec
MoFEMErrorCode runAuxiliaryLogarithmicStressTest(const std::function< MoFEMErrorCode(EshelbianCore &)> &test)
boost::shared_ptr< IncrementalOptimizationContext > createPlasticIncrementalOptimizationContext(EshelbianCore &ep, SmartPetscObj< TS > ts, SmartPetscObj< Vec > state)
PlasticIncrementalOptimizationProblem & getPlasticIncrementalOptimizationProblem(const boost::shared_ptr< IncrementalOptimizationContext > &context)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createTS(MPI_Comm comm)
static char help[]
MoFEM::Interface & mField
SmartPetscObj< DM > dmElastic
Elastic problem.
SmartPetscObj< DM > dmIncrementalOptimization
const std::string plasticLatentField
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
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.
keeps basic data about problem
intrusive_ptr for managing petsc objects
double scale
Definition plastic.cpp:124