https://mooseframework.inl.gov
ElementJacobianDamper.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "ElementJacobianDamper.h"
11 #include "FEProblem.h"
12 #include "MooseMesh.h"
13 #include "DisplacedProblem.h"
14 #include "Assembly.h"
15 
16 #include "libmesh/quadrature.h" // _qrule
17 
18 registerMooseObject("SolidMechanicsApp", ElementJacobianDamper);
19 
22 {
24  params.addClassDescription("Damper that limits the change in element Jacobians");
25  params.addParam<std::vector<VariableName>>(
26  "displacements", {}, "The nonlinear displacement variables");
27  params.addParam<Real>(
28  "max_increment",
29  0.1,
30  "The maximum permissible relative increment in the Jacobian per Newton iteration");
31  params.set<bool>("use_displaced_mesh") = true;
32  return params;
33 }
34 
36  : GeneralDamper(parameters),
37  _tid(parameters.get<THREAD_ID>("_tid")),
38  _assembly(_subproblem.assembly(_tid, _sys.number())),
39  _qrule(_assembly.qRule()),
40  _JxW(_assembly.JxW()),
41  _fe_problem(*parameters.getCheckedPointerParam<FEProblemBase *>("_fe_problem_base")),
42  _displaced_problem(_fe_problem.getDisplacedProblem()),
43  _max_jacobian_diff(parameters.get<Real>("max_increment"))
44 {
45  if (_displaced_problem == NULL)
46  mooseError("ElementJacobianDamper: Must use displaced problem");
47 
48  _mesh = &_displaced_problem->mesh();
49 
50  const std::vector<VariableName> & nl_vnames(getParam<std::vector<VariableName>>("displacements"));
51  _ndisp = nl_vnames.size();
52 
53  for (unsigned int i = 0; i < _ndisp; ++i)
54  {
55  _disp_var.push_back(&_sys.getFieldVariable<Real>(_tid, nl_vnames[i]));
56  _disp_incr.push_back(_disp_var.back()->increment());
57  }
58 }
59 
60 void
62 {
63 }
64 
65 Real
67  const NumericVector<Number> & update)
68 {
69  // Maximum difference in the Jacobian for this Newton iteration
70  Real max_difference = 0.0;
71  MooseArray<Real> JxW_displaced;
72 
73  // Vector for storing the original node coordinates
74  std::vector<Point> point_copies;
75 
76  // Loop over elements in the mesh
77  for (auto & current_elem : _mesh->getMesh().active_local_element_ptr_range())
78  {
79  point_copies.clear();
80  point_copies.reserve(current_elem->n_nodes());
81 
82  // Displace nodes with current Newton increment
83  for (unsigned int i = 0; i < current_elem->n_nodes(); ++i)
84  {
85  Node & displaced_node = current_elem->node_ref(i);
86 
87  point_copies.push_back(displaced_node);
88 
89  for (unsigned int j = 0; j < _ndisp; ++j)
90  {
91  dof_id_type disp_dof_num =
92  displaced_node.dof_number(_sys.number(), _disp_var[j]->number(), 0);
93  displaced_node(j) += update(disp_dof_num);
94  }
95  }
96 
97  // Reinit element to compute Jacobian of displaced element
98  _assembly.reinit(current_elem);
99  JxW_displaced = _JxW;
100 
101  // Un-displace nodes
102  for (unsigned int i = 0; i < current_elem->n_nodes(); ++i)
103  {
104  Node & displaced_node = current_elem->node_ref(i);
105 
106  for (unsigned int j = 0; j < _ndisp; ++j)
107  displaced_node(j) = point_copies[i](j);
108  }
109 
110  // Reinit element to compute Jacobian before displacement
111  _assembly.reinit(current_elem);
112 
113  for (unsigned int qp = 0; qp < _qrule->n_points(); ++qp)
114  {
115  Real diff = std::abs(JxW_displaced[qp] - _JxW[qp]) / _JxW[qp];
116  if (diff > max_difference)
117  max_difference = diff;
118  }
119 
120  JxW_displaced.release();
121  }
122 
123  _communicator.max(max_difference);
124 
125  if (max_difference > _max_jacobian_diff)
126  return _max_jacobian_diff / max_difference;
127 
128  return 1.0;
129 }
static InputParameters validParams()
const QBase *const & _qrule
Quadrature rule.
This class implements a damper that limits the change in the Jacobian of elements.
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
unsigned int _ndisp
The number of displacement variables.
T & set(const std::string &name, bool quiet_mode=false)
static InputParameters validParams()
MooseSharedPointer< DisplacedProblem > _displaced_problem
The displaced problem.
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.
MeshBase & getMesh()
ElementJacobianDamper(const InputParameters &parameters)
virtual Real computeDamping(const NumericVector< Number > &, const NumericVector< Number > &update) override
Computes this Damper&#39;s damping.
const T & getParam(const std::string &name) const
std::vector< MooseVariable * > _disp_var
The displacement variables.
unsigned int number() const
THREAD_ID _tid
Thread ID.
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
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
SystemBase & _sys
const Elem & get(const ElemType type_in)
unsigned int THREAD_ID
uint8_t dof_id_type