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 74523 : ADNodalBCTempl<T, Base>::validParams()
27 : {
28 74523 : return Base::validParams();
29 : }
30 :
31 : template <>
32 : InputParameters
33 14311 : ADNodalBCTempl<RealVectorValue, NodalBCBase>::validParams()
34 : {
35 14311 : InputParameters params = NodalBCBase::validParams();
36 : // The below parameters are useful for vector Nodal BCs
37 14311 : params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
38 14311 : params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
39 14311 : params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
40 14311 : return params;
41 0 : }
42 :
43 : template <>
44 : InputParameters
45 14583 : ADNodalBCTempl<RealVectorValue, ADDirichletBCBase>::validParams()
46 : {
47 14583 : InputParameters params = ADDirichletBCBase::validParams();
48 : // The below parameters are useful for vector Nodal BCs
49 14583 : params.addParam<bool>("set_x_comp", true, "Whether to set the x-component of the variable");
50 14583 : params.addParam<bool>("set_y_comp", true, "Whether to set the y-component of the variable");
51 14583 : params.addParam<bool>("set_z_comp", true, "Whether to set the z-component of the variable");
52 14583 : return params;
53 0 : }
54 :
55 : template <typename T, typename Base>
56 1849 : 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 3698 : _var(*this->mooseVariable()),
66 1849 : _current_node(_var.node()),
67 3698 : _u(_var.adNodalValue()),
68 2401 : _set_components(
69 368 : {std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_x_comp")
70 : : true,
71 368 : std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_y_comp")
72 : : true,
73 184 : std::is_same<T, RealVectorValue>::value ? this->template getParam<bool>("set_z_comp")
74 : : true}),
75 3882 : _undisplaced_assembly(_fe_problem.assembly(_tid, _sys.number()))
76 : {
77 1849 : _subproblem.haveADObjects(true);
78 :
79 1849 : addMooseVariableDependency(this->mooseVariable());
80 1849 : }
81 :
82 : namespace
83 : {
84 : const ADReal &
85 355723 : conversionHelper(const ADReal & value, const unsigned int)
86 : {
87 355723 : return value;
88 : }
89 :
90 : const ADReal &
91 215895 : conversionHelper(const libMesh::VectorValue<ADReal> & value, const unsigned int i)
92 : {
93 215895 : return value(i);
94 : }
95 : }
96 :
97 : template <typename T, typename Base>
98 : template <typename ADResidual>
99 : void
100 370499 : 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 828502 : for (const auto i : index_range(dof_indices))
107 458003 : if (_set_components[i])
108 458003 : setResidual(_sys, raw_value(conversionHelper(residual, i)), dof_indices[i]);
109 370499 : }
110 :
111 : template <typename T, typename Base>
112 : template <typename ADResidual>
113 : void
114 93353 : 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 206968 : for (const auto i : index_range(dof_indices))
121 113615 : 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 227230 : addJacobian(_undisplaced_assembly,
125 154155 : std::array<ADReal, 1>{{conversionHelper(residual, i)}},
126 : std::array<dof_id_type, 1>{{dof_indices[i]}},
127 : /*scaling_factor=*/1);
128 206968 : }
129 :
130 : template <typename T, typename Base>
131 : void
132 358052 : ADNodalBCTempl<T, Base>::computeResidual()
133 : {
134 358052 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
135 358052 : if (dof_indices.empty())
136 0 : return;
137 :
138 358052 : const auto residual = computeQpResidual();
139 :
140 358052 : addResidual(residual, dof_indices);
141 358052 : }
142 :
143 : template <typename T, typename Base>
144 : void
145 80906 : ADNodalBCTempl<T, Base>::computeJacobian()
146 : {
147 80906 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
148 80906 : if (dof_indices.empty())
149 0 : return;
150 :
151 80906 : const auto residual = computeQpResidual();
152 :
153 80906 : addJacobian(residual, dof_indices);
154 80906 : }
155 :
156 : template <typename T, typename Base>
157 : void
158 12447 : ADNodalBCTempl<T, Base>::computeResidualAndJacobian()
159 : {
160 12447 : const std::vector<dof_id_type> & dof_indices = _var.dofIndices();
161 12447 : if (dof_indices.empty())
162 0 : return;
163 :
164 12447 : const auto residual = computeQpResidual();
165 :
166 12447 : addResidual(residual, dof_indices);
167 12447 : addJacobian(residual, dof_indices);
168 12447 : }
169 :
170 : template <typename T, typename Base>
171 : void
172 83850 : 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 83850 : if (jvar_num == _var.number())
176 80906 : computeJacobian();
177 83850 : }
178 :
179 : template <typename T, typename Base>
180 : void
181 371 : ADNodalBCTempl<T, Base>::computeOffDiagJacobianScalar(unsigned int)
182 : {
183 : // scalar coupling will have been included in the all-at-once handling in computeOffDiagJacobian
184 371 : }
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>;
|