Line data Source code
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 "ADNodalBC.h"
11 : #include "NodalBCBase.h"
12 : #include "ADDirichletBCBase.h"
13 :
14 : // MOOSE includes
15 : #include "Assembly.h"
16 : #include "SubProblem.h"
17 : #include "SystemBase.h"
18 : #include "MooseVariableFE.h"
19 : #include "MooseVariableScalar.h"
20 : #include "FEProblemBase.h"
21 :
22 : #include "libmesh/quadrature.h"
23 :
24 : template <typename T, typename Base>
25 : InputParameters
26 74349 : ADNodalBCTempl<T, Base>::validParams()
27 : {
28 74349 : return Base::validParams();
29 : }
30 :
31 : template <>
32 : InputParameters
33 14309 : ADNodalBCTempl<RealVectorValue, NodalBCBase>::validParams()
34 : {
35 14309 : InputParameters params = NodalBCBase::validParams();
36 : // The below parameters are useful for vector Nodal BCs
37 14309 : params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
38 14309 : params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
39 14309 : params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
40 14309 : return params;
41 0 : }
42 :
43 : template <>
44 : InputParameters
45 14565 : ADNodalBCTempl<RealVectorValue, ADDirichletBCBase>::validParams()
46 : {
47 14565 : InputParameters params = ADDirichletBCBase::validParams();
48 : // The below parameters are useful for vector Nodal BCs
49 14565 : params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
50 14565 : params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
51 14565 : params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
52 14565 : return params;
53 0 : }
54 :
55 : template <typename T, typename Base>
56 1748 : ADNodalBCTempl<T, Base>::ADNodalBCTempl(const InputParameters & parameters)
57 : : Base(parameters),
58 : MooseVariableInterface<T>(this,
59 : true,
60 : "variable",
61 : Moose::VarKindType::VAR_SOLVER,
62 : std::is_same<T, Real>::value ? Moose::VarFieldType::VAR_FIELD_STANDARD
63 : : Moose::VarFieldType::VAR_FIELD_VECTOR),
64 : ADFunctorInterface(this),
65 3496 : _var(*this->mooseVariable()),
66 1748 : _current_node(_var.node()),
67 3496 : _u(_var.adNodalValue()),
68 2270 : _set_components(
69 348 : {std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_x_comp")
70 : : true,
71 348 : std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_y_comp")
72 : : true,
73 174 : std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_z_comp")
74 : : true}),
75 3670 : _undisplaced_assembly(_fe_problem.assembly(_tid, _sys.number()))
76 : {
77 1748 : _subproblem.haveADObjects(true);
78 :
79 1748 : addMooseVariableDependency(this->mooseVariable());
80 1748 : }
81 :
82 : namespace
83 : {
84 : const ADReal &
85 326695 : conversionHelper(const ADReal & value, const unsigned int)
86 : {
87 326695 : return value;
88 : }
89 :
90 : const ADReal &
91 203906 : conversionHelper(const libMesh::VectorValue<ADReal> & value, const unsigned int i)
92 : {
93 203906 : return value(i);
94 : }
95 : }
96 :
97 : template <typename T, typename Base>
98 : template <typename ADResidual>
99 : void
100 345069 : ADNodalBCTempl<T, Base>::addResidual(const ADResidual & residual,
101 : const std::vector<dof_id_type> & dof_indices)
102 : {
103 : mooseAssert(dof_indices.size() <= _set_components.size(),
104 : "The number of dof indices must be less than the number of settable components");
105 :
106 774063 : for (const auto i : index_range(dof_indices))
107 428994 : if (_set_components[i])
108 428994 : setResidual(_sys, raw_value(conversionHelper(residual, i)), dof_indices[i]);
109 345069 : }
110 :
111 : template <typename T, typename Base>
112 : template <typename ADResidual>
113 : void
114 83759 : ADNodalBCTempl<T, Base>::addJacobian(const ADResidual & residual,
115 : const std::vector<dof_id_type> & dof_indices)
116 : {
117 : mooseAssert(dof_indices.size() <= _set_components.size(),
118 : "The number of dof indices must be less than the number of settable components");
119 :
120 185366 : for (const auto i : index_range(dof_indices))
121 101607 : if (_set_components[i])
122 : // If we store into the displaced assembly for nodal bc objects the data never actually makes
123 : // it into the global Jacobian
124 203214 : addJacobian(_undisplaced_assembly,
125 137318 : std::array<ADReal, 1>{{conversionHelper(residual, i)}},
126 : std::array<dof_id_type, 1>{{dof_indices[i]}},
127 : /*scaling_factor=*/1);
128 185366 : }
129 :
130 : template <typename T, typename Base>
131 : void
132 332948 : ADNodalBCTempl<T, Base>::computeResidual()
133 : {
134 332948 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
135 332948 : if (dof_indices.empty())
136 0 : return;
137 :
138 332948 : const auto residual = computeQpResidual();
139 :
140 332948 : addResidual(residual, dof_indices);
141 332948 : }
142 :
143 : template <typename T, typename Base>
144 : void
145 71638 : ADNodalBCTempl<T, Base>::computeJacobian()
146 : {
147 71638 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
148 71638 : if (dof_indices.empty())
149 0 : return;
150 :
151 71638 : const auto residual = computeQpResidual();
152 :
153 71638 : addJacobian(residual, dof_indices);
154 71638 : }
155 :
156 : template <typename T, typename Base>
157 : void
158 12121 : ADNodalBCTempl<T, Base>::computeResidualAndJacobian()
159 : {
160 12121 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
161 12121 : if (dof_indices.empty())
162 0 : return;
163 :
164 12121 : const auto residual = computeQpResidual();
165 :
166 12121 : addResidual(residual, dof_indices);
167 12121 : addJacobian(residual, dof_indices);
168 12121 : }
169 :
170 : template <typename T, typename Base>
171 : void
172 74258 : ADNodalBCTempl<T, Base>::computeOffDiagJacobian(const unsigned int jvar_num)
173 : {
174 : // Only need to do this once because AD does all the derivatives at once
175 74258 : if (jvar_num == _var.number())
176 71638 : computeJacobian();
177 74258 : }
178 :
179 : template <typename T, typename Base>
180 : void
181 327 : ADNodalBCTempl<T, Base>::computeOffDiagJacobianScalar(unsigned int)
182 : {
183 : // scalar coupling will have been included in the all-at-once handling in computeOffDiagJacobian
184 327 : }
185 :
186 : template class ADNodalBCTempl<Real, NodalBCBase>;
187 : template class ADNodalBCTempl<RealVectorValue, NodalBCBase>;
188 : template class ADNodalBCTempl<Real, ADDirichletBCBase>;
189 : template class ADNodalBCTempl<RealVectorValue, ADDirichletBCBase>;
|