https://mooseframework.inl.gov
Loading...
Searching...
No Matches
MortarScalarBase.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 "MortarScalarBase.h"
11
12// MOOSE includes
13#include "Assembly.h"
14#include "FEProblemBase.h"
15#include "SystemBase.h"
16#include "MooseVariable.h"
17#include "MooseVariableScalar.h"
18
21{
23 // This parameter can get renamed in derived class to a more relevant variable name
24 params.addCoupledVar("scalar_variable", "Primary coupled scalar variable");
25 params.addParam<bool>("compute_scalar_residuals", true, "Whether to compute scalar residuals");
26 return params;
27}
28
30 : MortarConstraint(parameters),
31 _use_scalar(isParamValid("scalar_variable") ? true : false),
32 _compute_scalar_residuals(!_use_scalar ? false : getParam<bool>("compute_scalar_residuals")),
33 _kappa_var_ptr(_use_scalar ? getScalarVar("scalar_variable", 0) : nullptr),
34 _kappa_var(_use_scalar ? _kappa_var_ptr->number() : 0),
35 _k_order(_use_scalar ? _kappa_var_ptr->order() : 0),
36 _kappa(_use_scalar ? (_is_implicit ? _kappa_var_ptr->sln() : _kappa_var_ptr->slnOld()) : _zero)
37{
38}
39
40void
42{
44
46 return;
47
48 std::vector<Real> scalar_residuals(_k_order);
49 for (_qp = 0; _qp < _qrule_msm->n_points(); _qp++)
50 {
52 for (_h = 0; _h < _k_order; _h++)
53 scalar_residuals[_h] += _JxW_msm[_qp] * _coord[_qp] * computeScalarQpResidual();
54 }
55
58}
59
60void
62{
63 // d-_var-residual / d-_var and d-_var-residual / d-jvar
65
66 if (!_use_scalar)
67 return;
68
69 // Get the list of coupled scalar vars and compute their off-diag jacobians
70 const auto & coupled_scalar_vars = getCoupledMooseScalarVars();
71
72 // Handle ALL d-_var-residual / d-scalar columns like computeOffDiagJacobianScalar
74 // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones), and only if
75 // this coupling is being used by the preconditioner (otherwise the value is zero)
76 for (const auto & svariable : coupled_scalar_vars)
77 if (_sys.hasScalarVariable(svariable->name()))
78 {
79 // Compute the jacobian for the secondary interior primal dofs
80 if (_fe_problem.areCoupled(_secondary_var.number(), svariable->number(), _sys.number()))
82 // Compute the jacobian for the primary interior primal dofs.
83 if (_fe_problem.areCoupled(_primary_var.number(), svariable->number(), _sys.number()))
85 }
86
88 // Do: dvar / dscalar_var, only want to process only nl-variables (not aux ones), and only if
89 // this coupling is being used by the preconditioner (otherwise the value is zero)
90 for (const auto & svariable : coupled_scalar_vars)
91 if (_sys.hasScalarVariable(svariable->name()) && _var &&
92 _fe_problem.areCoupled(_var->number(), svariable->number(), _sys.number()))
93 // Compute the jacobian for the lower dimensional LM dofs (if we even have an LM variable)
95
97 {
98 // Handle ALL d-_kappa-residual / d-_var and d-_kappa-residual / d-jvar columns
100
101 // Do: d-_kappa-residual / d-_kappa and d-_kappa-residual / d-jvar,
102 // only want to process only nl-variables (not aux ones), and only if this coupling is being
103 // used by the preconditioner (otherwise the value is zero)
104 for (const auto & svariable : coupled_scalar_vars)
105 {
106 if (_sys.hasScalarVariable(svariable->name()))
107 {
108 const unsigned int svar_num = svariable->number();
109 if (svar_num == _kappa_var)
110 computeScalarJacobian(); // d-_kappa-residual / d-_kappa
111 else if (_fe_problem.areCoupled(_kappa_var, svar_num, _sys.number()))
112 computeScalarOffDiagJacobianScalar(svar_num); // d-_kappa-residual / d-svar
113 }
114 }
115 }
116}
117
118void
136
137void
139{
140 typedef Moose::MortarType MType;
141 std::array<MType, 3> mortar_types = {{MType::Secondary, MType::Primary, MType::Lower}};
142
144 for (const auto & it : ce)
145 {
146 MooseVariableScalar & ivariable = *(it.first);
147 MooseVariableFEBase & jvariable = *(it.second);
148
149 const unsigned int ivar_num = ivariable.number();
150 const unsigned int jvar_num = jvariable.number();
151
152 if (ivar_num != _kappa_var) // only do the row for _kappa_var in this object
153 continue;
154
155 // Load shape functions of different types for easy access; identical to MortarConstraint.C
156 std::array<size_t, 3> shape_space_sizes{{jvariable.dofIndices().size(),
157 jvariable.dofIndicesNeighbor().size(),
158 jvariable.dofIndicesLower().size()}};
159 std::array<const VariablePhiValue *, 3> phis;
160 std::array<const VariablePhiGradient *, 3> grad_phis;
161 std::array<const VectorVariablePhiValue *, 3> vector_phis;
162 std::array<const VectorVariablePhiGradient *, 3> vector_grad_phis;
163 if (jvariable.isVector())
164 {
165 const auto & temp_var = cast_ref<MooseVariableFE<RealVectorValue> &>(jvariable);
166 vector_phis = {{&temp_var.phiFace(), &temp_var.phiFaceNeighbor(), &temp_var.phiLower()}};
167 vector_grad_phis = {
168 {&temp_var.gradPhiFace(), &temp_var.gradPhiFaceNeighbor(), &temp_var.gradPhiLower()}};
169 }
170 else
171 {
172 const auto & temp_var = cast_ref<MooseVariableFE<Real> &>(jvariable);
173 phis = {{&temp_var.phiFace(), &temp_var.phiFaceNeighbor(), &temp_var.phiLower()}};
174 grad_phis = {
175 {&temp_var.gradPhiFace(), &temp_var.gradPhiFaceNeighbor(), &temp_var.gradPhiLower()}};
176 }
177
178 // Loop over 3 types of spatial variables, find out what jvar_num is
179 for (MooseIndex(3) type_index = 0; type_index < 3; ++type_index)
180 {
181 const auto mortar_type = mortar_types[type_index];
182 const auto shape_space_size = shape_space_sizes[type_index];
183 std::vector<dof_id_type> dof_indices;
184 switch (mortar_type)
185 {
186 case MType::Secondary:
187 dof_indices = jvariable.dofIndices();
188 break;
189
190 case MType::Primary:
191 dof_indices = jvariable.dofIndicesNeighbor();
192 break;
193
194 case MType::Lower:
195 dof_indices = jvariable.dofIndicesLower();
196 break;
197 }
198
200 if (jvariable.isVector())
201 {
202 _vector_phi = vector_phis[type_index];
203 _vector_grad_phi = vector_grad_phis[type_index];
204 }
205 else
206 {
207 _phi = phis[type_index];
208 _grad_phi = grad_phis[type_index];
209 }
210
211 _local_ke.resize(_k_order, shape_space_size);
212
213 for (_qp = 0; _qp < _qrule_msm->n_points(); _qp++)
214 {
215 initScalarQpOffDiagJacobian(mortar_type, jvar_num);
216 const Real dV = _JxW_msm[_qp] * _coord[_qp];
217 for (_h = 0; _h < _k_order; _h++)
218 {
219 for (_j = 0; _j < shape_space_size; _j++)
220 {
221 _local_ke(_h, _j) += computeScalarQpOffDiagJacobian(mortar_type, jvar_num) * dV;
222 }
223 }
224 }
225
227 _local_ke,
229 dof_indices,
231 }
232 }
233}
234
235void
237{
238 unsigned int test_space_size = 0;
239 std::vector<dof_id_type> dof_indices;
240 Real scaling_factor = 1;
241 switch (mortar_type)
242 {
244 test_space_size = _test_secondary.size();
245 dof_indices = _secondary_var.dofIndices();
246 scaling_factor = _secondary_var.scalingFactor();
247 break;
248
250 test_space_size = _test_primary.size();
251 dof_indices = _primary_var.dofIndicesNeighbor();
252 scaling_factor = _primary_var.scalingFactor();
253 break;
254
256 mooseAssert(_var, "LM variable is null");
257 test_space_size = _test.size();
258 dof_indices = _var->dofIndicesLower();
259 scaling_factor = _var->scalingFactor();
260 break;
261 }
262
263 // Get dofs and order of this scalar; at least one will be _kappa_var
264 const auto & svar = _sys.getScalarVariable(_tid, svar_num);
265 const unsigned int s_order = svar.order();
266
267 _local_ke.resize(test_space_size, s_order);
268
269 for (_qp = 0; _qp < _qrule_msm->n_points(); _qp++)
270 {
271 initScalarQpOffDiagJacobian(mortar_type, svar_num);
272 const Real dV = _JxW_msm[_qp] * _coord[_qp];
273 for (_h = 0; _h < s_order; _h++)
274 for (_i = 0; _i < test_space_size; _i++)
275 { // This assumes Galerkin, i.e. the test and trial functions are the
276 // same
277 _j = _i;
278 _local_ke(_i, _h) += computeQpOffDiagJacobianScalar(mortar_type, svar_num) * dV;
279 }
280 }
281
282 addJacobian(_assembly, _local_ke, dof_indices, svar.dofIndices(), scaling_factor);
283}
284
285void
287{
288 // Get dofs and order of this scalar; will NOT be _kappa_var
289 const auto & svar = _sys.getScalarVariable(_tid, svar_num);
290 const unsigned int s_order = svar.order();
291
292 _local_ke.resize(_k_order, s_order);
293 for (_qp = 0; _qp < _qrule_msm->n_points(); _qp++)
294 {
295 initScalarQpJacobian(svar_num);
296 for (_h = 0; _h < _k_order; _h++)
297 for (_l = 0; _l < s_order; _l++)
298 _local_ke(_h, _l) +=
300 }
301
303 _local_ke,
305 svar.dofIndices(),
307}
const std::vector< std::pair< MooseVariableScalar *, MooseVariableFieldBase * > > & scalarFieldCouplingEntries() const
Definition Assembly.h:1305
unsigned int _qp
Definition Constraint.h:36
unsigned int _j
Definition Constraint.h:35
unsigned int _i
Definition Constraint.h:35
bool areCoupled(const unsigned int ivar, const unsigned int jvar, const unsigned int nl_sys_num) const
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addCoupledVar(const std::string &name, const std::string &doc_string)
This method adds a coupled variable name pair.
virtual const std::vector< dof_id_type > & dofIndices() const
Get local DoF indices.
void scalingFactor(const std::vector< Real > &factor)
Set the scaling factor for this variable.
libMesh::Order order() const
Get the order of this variable Note: Order enum can be implicitly converted to unsigned int.
unsigned int number() const
Get variable number coming from libMesh.
const std::vector< dof_id_type > & dofIndicesLower() const final
Get dof indices for the current lower dimensional element (this is meaningful when performing mortar ...
This class provides an interface for common operations on field variables of both FE and FV types wit...
virtual const std::vector< dof_id_type > & dofIndicesLower() const =0
Get dof indices for the current lower dimensional element (this is meaningful when performing mortar ...
virtual bool isVector() const =0
virtual const std::vector< dof_id_type > & dofIndicesNeighbor() const =0
Get neighbor DOF indices for currently selected element.
Class for scalar variables (they are different).
MooseVariableField< Real > & _primary_var
Reference to the primary variable.
MooseVariable *const _var
Pointer to the lagrange multipler variable. nullptr if none.
const VariableTestValue & _test_secondary
The shape functions corresponding to the secondary interior primal variable.
FEProblemBase & _fe_problem
Reference to the finite element problem.
const MooseArray< Real > & _coord
Member for handling change of coordinate systems (xyz, rz, spherical)
const bool _compute_primal_residuals
Whether to compute primal residuals.
MooseVariableField< Real > & _secondary_var
Reference to the secondary variable.
const VariableTestValue & _test
The shape functions corresponding to the lagrange multiplier variable.
const bool _compute_lm_residuals
Whether to compute lagrange multiplier residuals.
virtual void computeJacobian() override
Method for computing the Jacobian.
virtual void computeResidual() override
Method for computing the residual.
const VariableTestValue & _test_primary
The shape functions corresponding to the primary interior primal variable.
const VariablePhiGradient * _grad_phi
The current shape function gradients.
const VariablePhiValue * _phi
The current shape functions.
const VectorVariablePhiGradient * _vector_grad_phi
The current shape function gradients for vector variables.
static InputParameters validParams()
const VectorVariablePhiValue * _vector_phi
The current shape functions for vector variables.
const libMesh::QBase *const & _qrule_msm
The quadrature rule on the mortar segment element.
const std::vector< Real > & _JxW_msm
The element Jacobian times weights.
void computeScalarOffDiagJacobian()
Method for computing an off-diagonal jacobian component d-_kappa-residual / d-jvar.
virtual Real computeScalarQpResidual()
Method for computing the scalar part of residual at quadrature points.
const unsigned int _k_order
Order of the scalar variable, used in several places.
MortarScalarBase(const InputParameters &parameters)
virtual Real computeQpOffDiagJacobianScalar(const Moose::MortarType, unsigned int)
For coupling scalar variables.
virtual void initScalarQpOffDiagJacobian(const Moose::MortarType, const unsigned int)
Put necessary evaluations depending on qp but independent of test and shape functions here for off-di...
const bool _use_scalar
Whether a scalar variable is declared for this constraint.
unsigned int _h
Used internally to iterate over each scalar component.
virtual void initScalarQpResidual()
Put necessary evaluations depending on qp but independent of test functions here.
virtual Real computeScalarQpOffDiagJacobian(const Moose::MortarType, const unsigned int)
Method for computing an off-diagonal jacobian component at quadrature points.
void computeScalarOffDiagJacobianScalar(const unsigned int svar_num)
Method for computing an off-diagonal jacobian component d-_kappa-residual / d-scalar.
const bool _compute_scalar_residuals
Whether to compute scalar contributions for this instance.
const unsigned int _kappa_var
The unknown scalar variable ID.
virtual Real computeScalarQpJacobian()
Method for computing the scalar variable part of Jacobian at quadrature points.
const MooseVariableScalar *const _kappa_var_ptr
(Pointer to) Scalar variable this kernel operates on
virtual void initScalarQpJacobian(const unsigned int)
Put necessary evaluations depending on qp but independent of test and shape functions here.
virtual Real computeScalarQpOffDiagJacobianScalar(const unsigned int)
Method for computing an off-diagonal jacobian component at quadrature points.
virtual void computeJacobian() override
Computes d-_var-residual / d-_var and d-_var-residual / d-jvar, as well as d-_kappa-residual / d-_var...
static InputParameters validParams()
void computeOffDiagJacobianScalar(unsigned int) override final
Computes jacobian block with respect to a scalar variable.
virtual void computeScalarJacobian()
Method for computing the scalar variable part of Jacobian.
virtual void computeResidual() override
Computes _var-residuals as well as _kappa-residual.
THREAD_ID _tid
The thread ID for this kernel.
Assembly & _assembly
Reference to this Kernel's assembly object.
SystemBase & _sys
Reference to the EquationSystem object.
const std::vector< MooseVariableScalar * > & getCoupledMooseScalarVars()
Get the list of coupled scalar variables.
unsigned int number() const
Gets the number of this system.
virtual MooseVariableScalar & getScalarVariable(THREAD_ID tid, const std::string &var_name) const
Gets a reference to a scalar variable with specified number.
Definition SystemBase.C:144
virtual bool hasScalarVariable(const std::string &var_name) const
Definition SystemBase.C:873
DenseMatrix< Number > _local_ke
Holds local Jacobian entries as they are accumulated by this Kernel.
void addJacobian(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
Add the provided residual derivatives into the Jacobian for the provided dof indices.
void addResiduals(Assembly &assembly, const Residuals &residuals, const Indices &dof_indices, Real scaling_factor)
Add the provided incoming residuals corresponding to the provided dof indices.
void resize(const unsigned int new_m, const unsigned int new_n)
unsigned int n_points() const