16 #include "libmesh/quadrature.h" 28 restoreNodes(Elem & elem,
const std::vector<Point> & point_copies)
30 mooseAssert(elem.n_nodes() == point_copies.size(),
"Node restore cache is the wrong size");
32 for (
const auto i :
make_range(elem.n_nodes()))
33 elem.node_ref(i) = point_copies[i];
42 params.
addParam<std::vector<VariableName>>(
43 "displacements", {},
"The nonlinear displacement variables");
47 "The maximum permissible relative increment in the Jacobian per Newton iteration");
51 "If true, iteratively cut back the probed Newton update when a full trial update would " 52 "create a degenerate displaced element map. The accepted trial must also satisfy " 57 "backtrack_factor > 0 & backtrack_factor < 1",
58 "Multiplicative cutback applied to the trial damping during ElementJacobianDamper " 61 "max_backtrack_steps", 12,
"Maximum number of ElementJacobianDamper backtracking attempts.");
62 params.
set<
bool>(
"use_displaced_mesh") =
true;
69 _assembly(_subproblem.assembly(_tid, _sys.number())),
70 _qrule(_assembly.qRule()),
71 _JxW(_assembly.JxW()),
72 _fe_problem(*parameters.getCheckedPointerParam<
FEProblemBase *>(
"_fe_problem_base")),
73 _displaced_problem(_fe_problem.getDisplacedProblem()),
74 _max_jacobian_diff(getParam<
Real>(
"max_increment")),
75 _use_backtracking(getParam<bool>(
"use_backtracking")),
76 _backtrack_factor(getParam<
Real>(
"backtrack_factor")),
77 _max_backtrack_steps(getParam<unsigned
int>(
"max_backtrack_steps"))
80 mooseError(
"ElementJacobianDamper: Must use displaced problem");
84 const std::vector<VariableName> & nl_vnames(
getParam<std::vector<VariableName>>(
"displacements"));
87 for (
unsigned int i = 0; i <
_ndisp; ++i)
104 [&](
const Real trial_damping,
Real & max_difference, std::string & error_message)
106 const bool trial_nondegenerate_local =
107 probeDamping(update, trial_damping, max_difference, error_message);
111 const unsigned int invalid_local = trial_nondegenerate_local ? 0 : 1;
112 unsigned int invalid = invalid_local;
118 invalid_local ?
_communicator.
rank() : std::numeric_limits<processor_id_type>::max();
128 Real max_difference = 0.0;
129 std::string error_message;
133 if (!probe_trial(1.0, max_difference, error_message))
144 const Real minimum_trial_damping = std::max(
_min_damping, std::numeric_limits<Real>::epsilon());
146 std::string error_message;
151 Real max_difference = 0.0;
152 bool trial_nondegenerate =
false;
154 PARALLEL_TRY { trial_nondegenerate = probe_trial(damping, max_difference, error_message); }
162 if (!trial_nondegenerate)
164 ?
"ElementJacobianDamper could not find a nondegenerate " 169 "increment below max_increment without driving the damping " 170 "factor below a usable threshold.");
177 if (!trial_nondegenerate)
190 Real & max_difference,
191 std::string & error_message)
196 std::vector<Point> point_copies;
198 max_difference = 0.0;
199 error_message.
clear();
204 for (
auto & current_elem :
_mesh->
getMesh().active_local_element_ptr_range())
206 point_copies.clear();
207 point_copies.reserve(current_elem->n_nodes());
210 for (
unsigned int i = 0; i < current_elem->n_nodes(); ++i)
212 Node & displaced_node = current_elem->node_ref(i);
214 point_copies.push_back(displaced_node);
216 for (
unsigned int j = 0;
j <
_ndisp; ++
j)
220 displaced_node(
j) += damping * update(disp_dof_num);
228 JxW_displaced =
_JxW;
230 catch (
const std::exception & e)
232 restoreNodes(*current_elem, point_copies);
235 if (strstr(e.what(),
"Jacobian") || strstr(e.what(),
"singular") ||
236 strstr(e.what(),
"det != 0"))
238 error_message = e.what();
245 restoreNodes(*current_elem, point_copies);
252 catch (
const std::exception & e)
254 if (strstr(e.what(),
"Jacobian") || strstr(e.what(),
"singular") ||
255 strstr(e.what(),
"det != 0"))
257 error_message = e.what();
264 for (
unsigned int qp = 0; qp <
_qrule->n_points(); ++qp)
267 const Real diff = std::abs(JxW_displaced[qp] -
_JxW[qp]) / denominator;
268 if (diff > max_difference)
269 max_difference = diff;
277 error_message = e.
what();
static InputParameters validParams()
virtual const char * what() const
const QBase *const & _qrule
Quadrature rule.
This class implements a damper that limits the change in the Jacobian of elements.
const T & getParam(const std::string &name) const
unsigned int _ndisp
The number of displacement variables.
const bool _use_backtracking
Whether to backtrack the trial update when probing would otherwise create a degenerate map...
static constexpr Real TOLERANCE
static InputParameters validParams()
virtual void setException(const std::string &message)
MooseSharedPointer< DisplacedProblem > _displaced_problem
The displaced problem.
processor_id_type rank() const
const unsigned int _max_backtrack_steps
Maximum number of backtracking attempts.
registerMooseObject("SolidMechanicsApp", ElementJacobianDamper)
const Parallel::Communicator & _communicator
std::vector< VariableValue > _disp_incr
The current Newton increment in the displacement variables.
MooseMesh * _mesh
The displaced mesh.
void reinit(const Elem *elem)
const Real _max_jacobian_diff
Maximum allowed relative increment in Jacobian.
const MooseArray< Real > & _JxW
Transformed Jacobian weights.
uint8_t processor_id_type
FEProblemBase & _fe_problem
The FE problem.
ElementJacobianDamper(const InputParameters ¶meters)
void min(const T &r, T &o, Request &req) const
virtual Real computeDamping(const NumericVector< Number > &, const NumericVector< Number > &update) override
Computes this Damper's damping.
const Real & _min_damping
std::vector< MooseVariable * > _disp_var
The displacement variables.
bool probeDamping(const NumericVector< Number > &update, Real damping, Real &max_difference, std::string &error_message)
Probe a damped update on the displaced mesh and report the maximum relative change in JxW...
unsigned int number() const
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
MooseVariableFE< T > & getFieldVariable(THREAD_ID tid, const std::string &var_name)
virtual void initialSetup() override
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
const Real _backtrack_factor
Multiplicative cutback applied during backtracking.
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)