|
10 | 10 | #include "ConservativeAdvection.h" |
11 | 11 | #include "SystemBase.h" |
12 | 12 |
|
| 13 | +using namespace libMesh; |
| 14 | + |
13 | 15 | registerMooseObject("MooseApp", ConservativeAdvection); |
14 | 16 | registerMooseObject("MooseApp", ADConservativeAdvection); |
15 | 17 |
|
@@ -70,7 +72,7 @@ ConservativeAdvectionTempl<is_ad>::ConservativeAdvectionTempl(const InputParamet |
70 | 72 | : _u), |
71 | 73 | _upwinding( |
72 | 74 | this->template getParam<MooseEnum>("upwinding_type").template getEnum<UpwindingType>()), |
73 | | - _u_nodal(_var.dofValues()), |
| 75 | + _u_nodal(_var.template genericDofValues<is_ad>()), |
74 | 76 | _upwind_node(0), |
75 | 77 | _dtotal_mass_out(0) |
76 | 78 | { |
@@ -115,9 +117,9 @@ ConservativeAdvectionTempl<false>::computeQpJacobian() |
115 | 117 | return negSpeedQp() * _phi[_j][_qp]; |
116 | 118 | } |
117 | 119 |
|
118 | | -template <bool is_ad> |
| 120 | +template <> |
119 | 121 | Real |
120 | | -ConservativeAdvectionTempl<is_ad>::computeQpJacobian() |
| 122 | +ConservativeAdvectionTempl<true>::computeQpJacobian() |
121 | 123 | { |
122 | 124 | mooseError("Internal error, should never get here when using AD"); |
123 | 125 | return 0.0; |
@@ -162,80 +164,85 @@ ConservativeAdvectionTempl<is_ad>::fullUpwind(JacRes res_or_jac) |
162 | 164 |
|
163 | 165 | // Even if we are computing the Jacobian we still need to compute the outflow from each node to |
164 | 166 | // see which nodes are upwind and which are downwind |
165 | | - prepareVectorTag(this->_assembly, _var.number()); |
| 167 | + _my_local_re.resize(_var.dofIndices().size()); |
166 | 168 |
|
167 | | - if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
| 169 | + if (!is_ad && (res_or_jac == JacRes::CALCULATE_JACOBIAN)) |
168 | 170 | prepareMatrixTag(this->_assembly, _var.number(), _var.number()); |
169 | 171 |
|
170 | | - // Compute the outflux from each node and store in _local_re |
171 | | - // If _local_re is positive at the node, mass (or whatever the Variable represents) is flowing out |
172 | | - // of the node |
| 172 | + // Compute the outflux from each node and store in _my_local_re |
| 173 | + // If _my_local_re is positive at the node, mass (or whatever the Variable represents) is flowing |
| 174 | + // out of the node |
173 | 175 | _upwind_node.resize(num_nodes); |
174 | 176 | for (_i = 0; _i < num_nodes; ++_i) |
175 | 177 | { |
176 | 178 | for (_qp = 0; _qp < this->_qrule->n_points(); _qp++) |
177 | | - _local_re(_i) += this->_JxW[_qp] * this->_coord[_qp] * MetaPhysicL::raw_value(negSpeedQp()); |
178 | | - _upwind_node[_i] = (_local_re(_i) >= 0.0); |
| 179 | + _my_local_re(_i) += this->_JxW[_qp] * this->_coord[_qp] * negSpeedQp(); |
| 180 | + _upwind_node[_i] = (MetaPhysicL::raw_value(_my_local_re(_i)) >= 0.0); |
179 | 181 | } |
180 | 182 |
|
181 | 183 | // Variables used to ensure mass conservation |
182 | | - Real total_mass_out = 0.0; |
183 | | - Real total_in = 0.0; |
| 184 | + GenericReal<is_ad> total_mass_out = 0.0; |
| 185 | + GenericReal<is_ad> total_in = 0.0; |
184 | 186 | if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
185 | 187 | _dtotal_mass_out.assign(num_nodes, 0.0); |
186 | 188 |
|
187 | | - for (unsigned int n = 0; n < num_nodes; ++n) |
| 189 | + for (const auto n : make_range(num_nodes)) |
188 | 190 | { |
189 | 191 | if (_upwind_node[n]) |
190 | 192 | { |
191 | | - if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
192 | | - { |
193 | | - if (_test.size() == _phi.size()) |
194 | | - /* u at node=n depends only on the u at node=n, by construction. For |
195 | | - * linear-lagrange variables, this means that Jacobian entries involving the derivative |
196 | | - * will only be nonzero for derivatives wrt variable at node=n. Hence the |
197 | | - * (n, n) in the line below. The above "if" statement catches other variable types |
198 | | - * (eg constant monomials) |
199 | | - */ |
200 | | - _local_ke(n, n) += _local_re(n); |
201 | | - |
202 | | - _dtotal_mass_out[n] += _local_ke(n, n); |
203 | | - } |
204 | | - _local_re(n) *= _u_nodal[n]; |
205 | | - total_mass_out += _local_re(n); |
| 193 | + if constexpr (!is_ad) |
| 194 | + if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
| 195 | + { |
| 196 | + if (_test.size() == _phi.size()) |
| 197 | + /* u at node=n depends only on the u at node=n, by construction. For |
| 198 | + * linear-lagrange variables, this means that Jacobian entries involving the derivative |
| 199 | + * will only be nonzero for derivatives wrt variable at node=n. Hence the |
| 200 | + * (n, n) in the line below. The above "if" statement catches other variable types |
| 201 | + * (eg constant monomials) |
| 202 | + */ |
| 203 | + _local_ke(n, n) += _my_local_re(n); |
| 204 | + |
| 205 | + _dtotal_mass_out[n] += _local_ke(n, n); |
| 206 | + } |
| 207 | + _my_local_re(n) *= _u_nodal[n]; |
| 208 | + total_mass_out += _my_local_re(n); |
206 | 209 | } |
207 | | - else // downwind node |
208 | | - total_in -= _local_re(n); // note the -= means the result is positive |
| 210 | + else // downwind node |
| 211 | + total_in -= _my_local_re(n); // note the -= means the result is positive |
209 | 212 | } |
210 | 213 |
|
211 | 214 | // Conserve mass over all phases by proportioning the total_mass_out mass to the inflow nodes, |
212 | 215 | // weighted by their local_re values |
213 | | - for (unsigned int n = 0; n < num_nodes; ++n) |
214 | | - { |
| 216 | + for (const auto n : make_range(num_nodes)) |
215 | 217 | if (!_upwind_node[n]) // downwind node |
216 | 218 | { |
217 | | - if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
218 | | - for (_j = 0; _j < _phi.size(); _j++) |
219 | | - _local_ke(n, _j) += _local_re(n) * _dtotal_mass_out[_j] / total_in; |
220 | | - _local_re(n) *= total_mass_out / total_in; |
| 219 | + if constexpr (!is_ad) |
| 220 | + if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
| 221 | + for (_j = 0; _j < _phi.size(); _j++) |
| 222 | + _local_ke(n, _j) += _my_local_re(n) * _dtotal_mass_out[_j] / total_in; |
| 223 | + _my_local_re(n) *= total_mass_out / total_in; |
221 | 224 | } |
222 | | - } |
223 | 225 |
|
224 | 226 | // Add the result to the residual and jacobian |
225 | 227 | if (res_or_jac == JacRes::CALCULATE_RESIDUAL) |
226 | 228 | { |
227 | | - accumulateTaggedLocalResidual(); |
| 229 | + this->addResiduals(this->_assembly, _my_local_re, _var.dofIndices(), _var.scalingFactor()); |
228 | 230 |
|
229 | 231 | if (this->_has_save_in) |
230 | 232 | { |
231 | 233 | Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx); |
232 | 234 | for (const auto & var : this->_save_in) |
233 | | - var->sys().solution().add_vector(_local_re, var->dofIndices()); |
| 235 | + var->sys().solution().add_vector(MetaPhysicL::raw_value(_my_local_re), var->dofIndices()); |
234 | 236 | } |
235 | 237 | } |
236 | 238 |
|
237 | 239 | if (res_or_jac == JacRes::CALCULATE_JACOBIAN) |
238 | | - accumulateTaggedLocalMatrix(); |
| 240 | + { |
| 241 | + if constexpr (is_ad) |
| 242 | + this->addJacobian(this->_assembly, _my_local_re, _var.dofIndices(), _var.scalingFactor()); |
| 243 | + else |
| 244 | + accumulateTaggedLocalMatrix(); |
| 245 | + } |
239 | 246 | } |
240 | 247 |
|
241 | 248 | template class ConservativeAdvectionTempl<false>; |
|
0 commit comments