Skip to content

Commit 257b7f5

Browse files
committed
Further generify ConservativeAdvection
1 parent 5aca218 commit 257b7f5

File tree

5 files changed

+101
-44
lines changed

5 files changed

+101
-44
lines changed

framework/include/kernels/ConservativeAdvection.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#pragma once
1111

1212
#include "GenericKernel.h"
13+
#include "libmesh/dense_vector.h"
1314

1415
/**
1516
* Advection of the variable by the velocity provided by the user.
@@ -47,13 +48,13 @@ class ConservativeAdvectionTempl : public GenericKernel<is_ad>
4748
const enum class UpwindingType { none, full } _upwinding;
4849

4950
/// Nodal value of u, used for full upwinding
50-
const VariableValue & _u_nodal;
51+
const GenericVariableValue<is_ad> & _u_nodal;
5152

5253
/// In the full-upwind scheme, whether a node is an upwind node
5354
std::vector<bool> _upwind_node;
5455

5556
/// In the full-upwind scheme d(total_mass_out)/d(variable_at_node_i)
56-
std::vector<Real> _dtotal_mass_out;
57+
std::vector<GenericReal<is_ad>> _dtotal_mass_out;
5758

5859
/// Returns - _grad_test * velocity
5960
GenericReal<is_ad> negSpeedQp() const;
@@ -62,6 +63,10 @@ class ConservativeAdvectionTempl : public GenericKernel<is_ad>
6263
void fullUpwind(JacRes res_or_jac);
6364

6465
usingGenericKernelMembers;
66+
67+
private:
68+
/// A container for holding the local residuals
69+
libMesh::DenseVector<GenericReal<is_ad>> _my_local_re;
6570
};
6671

6772
typedef ConservativeAdvectionTempl<false> ConservativeAdvection;

framework/include/variables/MooseVariableField.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ class MooseVariableField : public MooseVariableFieldBase,
363363
virtual const MooseArray<libMesh::Number> & dofValuesDuDotDotDu() const = 0;
364364
virtual const MooseArray<libMesh::Number> & dofValuesDuDotDotDuNeighbor() const = 0;
365365

366+
template <bool is_ad>
367+
const MooseArray<GenericReal<is_ad>> & genericDofValues() const;
368+
366369
/**
367370
* tag values getters
368371
*/
@@ -399,6 +402,24 @@ class MooseVariableField : public MooseVariableFieldBase,
399402
mutable ADReal _ad_real_dummy = 0;
400403
};
401404

405+
template <>
406+
template <>
407+
const MooseArray<Real> & MooseVariableField<Real>::genericDofValues<false>() const;
408+
template <>
409+
template <>
410+
const MooseArray<Real> & MooseVariableField<RealVectorValue>::genericDofValues<false>() const;
411+
template <>
412+
template <>
413+
const MooseArray<Real> & MooseVariableField<RealEigenVector>::genericDofValues<false>() const;
414+
415+
template <typename OutputType>
416+
template <bool is_ad>
417+
const MooseArray<GenericReal<is_ad>> &
418+
MooseVariableField<OutputType>::genericDofValues() const
419+
{
420+
return adDofValues();
421+
}
422+
402423
#define usingMooseVariableFieldMembers \
403424
usingMooseVariableFieldBaseMembers; \
404425
using MooseVariableField<OutputType>::_time_integrator; \

framework/src/kernels/ConservativeAdvection.C

Lines changed: 47 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "ConservativeAdvection.h"
1111
#include "SystemBase.h"
1212

13+
using namespace libMesh;
14+
1315
registerMooseObject("MooseApp", ConservativeAdvection);
1416
registerMooseObject("MooseApp", ADConservativeAdvection);
1517

@@ -70,7 +72,7 @@ ConservativeAdvectionTempl<is_ad>::ConservativeAdvectionTempl(const InputParamet
7072
: _u),
7173
_upwinding(
7274
this->template getParam<MooseEnum>("upwinding_type").template getEnum<UpwindingType>()),
73-
_u_nodal(_var.dofValues()),
75+
_u_nodal(_var.template genericDofValues<is_ad>()),
7476
_upwind_node(0),
7577
_dtotal_mass_out(0)
7678
{
@@ -115,9 +117,9 @@ ConservativeAdvectionTempl<false>::computeQpJacobian()
115117
return negSpeedQp() * _phi[_j][_qp];
116118
}
117119

118-
template <bool is_ad>
120+
template <>
119121
Real
120-
ConservativeAdvectionTempl<is_ad>::computeQpJacobian()
122+
ConservativeAdvectionTempl<true>::computeQpJacobian()
121123
{
122124
mooseError("Internal error, should never get here when using AD");
123125
return 0.0;
@@ -162,80 +164,85 @@ ConservativeAdvectionTempl<is_ad>::fullUpwind(JacRes res_or_jac)
162164

163165
// Even if we are computing the Jacobian we still need to compute the outflow from each node to
164166
// see which nodes are upwind and which are downwind
165-
prepareVectorTag(this->_assembly, _var.number());
167+
_my_local_re.resize(_var.dofIndices().size());
166168

167-
if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
169+
if (!is_ad && (res_or_jac == JacRes::CALCULATE_JACOBIAN))
168170
prepareMatrixTag(this->_assembly, _var.number(), _var.number());
169171

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
173175
_upwind_node.resize(num_nodes);
174176
for (_i = 0; _i < num_nodes; ++_i)
175177
{
176178
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);
179181
}
180182

181183
// 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;
184186
if (res_or_jac == JacRes::CALCULATE_JACOBIAN)
185187
_dtotal_mass_out.assign(num_nodes, 0.0);
186188

187-
for (unsigned int n = 0; n < num_nodes; ++n)
189+
for (const auto n : make_range(num_nodes))
188190
{
189191
if (_upwind_node[n])
190192
{
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);
206209
}
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
209212
}
210213

211214
// Conserve mass over all phases by proportioning the total_mass_out mass to the inflow nodes,
212215
// 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))
215217
if (!_upwind_node[n]) // downwind node
216218
{
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;
221224
}
222-
}
223225

224226
// Add the result to the residual and jacobian
225227
if (res_or_jac == JacRes::CALCULATE_RESIDUAL)
226228
{
227-
accumulateTaggedLocalResidual();
229+
this->addResiduals(this->_assembly, _my_local_re, _var.dofIndices(), _var.scalingFactor());
228230

229231
if (this->_has_save_in)
230232
{
231233
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
232234
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());
234236
}
235237
}
236238

237239
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+
}
239246
}
240247

241248
template class ConservativeAdvectionTempl<false>;

framework/src/variables/MooseVariableField.C

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,30 @@ MooseVariableField<OutputType>::isVector() const
9595
return std::is_same<OutputType, RealVectorValue>::value;
9696
}
9797

98+
template <>
99+
template <>
100+
const MooseArray<Real> &
101+
MooseVariableField<Real>::genericDofValues<false>() const
102+
{
103+
return dofValues();
104+
}
105+
106+
template <>
107+
template <>
108+
const MooseArray<Real> &
109+
MooseVariableField<RealVectorValue>::genericDofValues<false>() const
110+
{
111+
return dofValues();
112+
}
113+
114+
template <>
115+
template <>
116+
const MooseArray<Real> &
117+
MooseVariableField<RealEigenVector>::genericDofValues<false>() const
118+
{
119+
mooseError("genericDofValues not implemented for array variables");
120+
}
121+
98122
template class MooseVariableField<Real>;
99123
template class MooseVariableField<RealVectorValue>;
100124
template class MooseVariableField<RealEigenVector>;

test/tests/kernels/conservative_advection/tests

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
type = RunException
99
input = no_upwinding_1D.i
1010
detail = 'by throwing an error when no velocity is given,'
11-
expect_err = "Either velocity_variable or velocity_material must be specificied, not both, nor velocity."
11+
expect_err = "Either velocity_variable or velocity_material must be specified"
1212
[]
1313
[ad_no_velocity]
1414
type = RunException
1515
input = ad_no_upwinding_1D.i
1616
detail = 'by throwing an error when no velocity is given when using AD,'
17-
expect_err = "Either velocity_variable or velocity_material must be specificied, not both, nor velocity."
17+
expect_err = "Either velocity_variable or velocity_material must be specified"
1818
[]
1919
[deprecated_velocity]
2020
type = RunException

0 commit comments

Comments
 (0)