From 670f857740cd82b8367a1269820c7e5b74840f65 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Tue, 15 Oct 2024 16:42:05 -0600 Subject: [PATCH 1/8] Add support for time derivatives of nodal dofs --- .../include/variables/MooseLinearVariableFV.h | 1 + framework/include/variables/MooseVariableData.h | 13 +++++++++++++ framework/include/variables/MooseVariableDataFV.h | 13 +++++++++++++ framework/include/variables/MooseVariableFE.h | 15 ++++++++------- framework/include/variables/MooseVariableFV.h | 11 ++++++++--- framework/include/variables/MooseVariableField.h | 5 +++++ framework/src/interfaces/Coupleable.C | 14 ++++++++++---- framework/src/variables/MooseLinearVariableFV.C | 7 +++++++ framework/src/variables/MooseVariableDataFV.C | 4 ++-- 9 files changed, 67 insertions(+), 16 deletions(-) diff --git a/framework/include/variables/MooseLinearVariableFV.h b/framework/include/variables/MooseLinearVariableFV.h index fcfe967582e4..437a13dc74fe 100644 --- a/framework/include/variables/MooseLinearVariableFV.h +++ b/framework/include/variables/MooseLinearVariableFV.h @@ -404,6 +404,7 @@ class MooseLinearVariableFV : public MooseVariableField [[noreturn]] virtual const MooseArray & adDofValues() const override; [[noreturn]] virtual const MooseArray & adDofValuesNeighbor() const override; + [[noreturn]] virtual const MooseArray & adDofValuesDot() const override; [[noreturn]] virtual const dof_id_type & nodalDofIndex() const override final; [[noreturn]] virtual const dof_id_type & nodalDofIndexNeighbor() const override final; diff --git a/framework/include/variables/MooseVariableData.h b/framework/include/variables/MooseVariableData.h index 60478194d3ee..be2062e5381e 100644 --- a/framework/include/variables/MooseVariableData.h +++ b/framework/include/variables/MooseVariableData.h @@ -428,6 +428,11 @@ class MooseVariableData : public MooseVariableDataBase */ const MooseArray & adDofValues() const; + /** + * Return the AD time derivative values + */ + const MooseArray & adDofValuesDot() const; + /////////////////////////////// Increment stuff /////////////////////////////////////// /** @@ -726,6 +731,14 @@ MooseVariableData::adDofValues() const return _ad_dof_values; } +template +const MooseArray & +MooseVariableData::adDofValuesDot() const +{ + _need_ad = _need_ad_u_dot = true; + return _ad_dofs_dot; +} + template const typename Moose::ADType::type & MooseVariableData::adNodalValue() const diff --git a/framework/include/variables/MooseVariableDataFV.h b/framework/include/variables/MooseVariableDataFV.h index 83bce9314717..86595927db29 100644 --- a/framework/include/variables/MooseVariableDataFV.h +++ b/framework/include/variables/MooseVariableDataFV.h @@ -259,6 +259,11 @@ class MooseVariableDataFV : public MooseVariableDataBase, public Mes */ const MooseArray & adDofValues() const; + /** + * Return the AD dof time derivatives + */ + const MooseArray & adDofValuesDot() const; + /////////////////////////////// Increment stuff /////////////////////////////////////// /** @@ -473,6 +478,14 @@ MooseVariableDataFV::adDofValues() const return _ad_dof_values; } +template +const MooseArray & +MooseVariableDataFV::adDofValuesDot() const +{ + _need_ad = _need_ad_u_dot = true; + return _ad_dofs_dot; +} + template inline bool MooseVariableDataFV::safeToComputeADUDot() const diff --git a/framework/include/variables/MooseVariableFE.h b/framework/include/variables/MooseVariableFE.h index 800cc8d8fddd..2d5807b18b73 100644 --- a/framework/include/variables/MooseVariableFE.h +++ b/framework/include/variables/MooseVariableFE.h @@ -594,15 +594,9 @@ class MooseVariableFE : public MooseVariableField const MooseArray & dofValuesDuDotDotDu() const override; const MooseArray & dofValuesDuDotDotDuNeighbor() const override; - /** - * Return the AD dof values - */ const MooseArray & adDofValues() const override; - - /** - * Return the AD neignbor dof values - */ const MooseArray & adDofValuesNeighbor() const override; + const MooseArray & adDofValuesDot() const override; /** * Compute and store incremental change in solution at QPs based on increment_vec @@ -844,6 +838,13 @@ MooseVariableFE::adDofValuesNeighbor() const return _neighbor_data->adDofValues(); } +template +inline const MooseArray & +MooseVariableFE::adDofValuesDot() const +{ + return _element_data->adDofValuesDot(); +} + template inline const typename Moose::ADType::type & MooseVariableFE::adNodalValue() const diff --git a/framework/include/variables/MooseVariableFV.h b/framework/include/variables/MooseVariableFV.h index 2e092d306e40..6084c33d6482 100644 --- a/framework/include/variables/MooseVariableFV.h +++ b/framework/include/variables/MooseVariableFV.h @@ -423,11 +423,9 @@ class MooseVariableFV : public MooseVariableField const MooseArray & dofValuesDuDotDotDu() const override; const MooseArray & dofValuesDuDotDotDuNeighbor() const override; - /// Returns the AD dof values. const MooseArray & adDofValues() const override; - - /// Returns the AD neighbor dof values const MooseArray & adDofValuesNeighbor() const override; + const MooseArray & adDofValuesDot() const override; /// Note: const monomial is always the case - higher order solns are /// reconstructed - so this is simpler func than FE equivalent. @@ -732,6 +730,13 @@ MooseVariableFV::adDofValuesNeighbor() const return _neighbor_data->adDofValues(); } +template +inline const MooseArray & +MooseVariableFV::adDofValuesDot() const +{ + return _element_data->adDofValuesDot(); +} + template typename MooseVariableFV::ValueType MooseVariableFV::evaluate(const ElemArg & elem_arg, const StateArg & state) const diff --git a/framework/include/variables/MooseVariableField.h b/framework/include/variables/MooseVariableField.h index f304ff0e23d5..16e418cc6000 100644 --- a/framework/include/variables/MooseVariableField.h +++ b/framework/include/variables/MooseVariableField.h @@ -168,6 +168,11 @@ class MooseVariableField : public MooseVariableFieldBase, */ virtual const MooseArray & adDofValuesNeighbor() const = 0; + /** + * Return the AD time derivatives at dofs + */ + virtual const MooseArray & adDofValuesDot() const = 0; + ///@{ /** * Methods for retrieving values of variables at the nodes in a MooseArray for AuxKernelBase diff --git a/framework/src/interfaces/Coupleable.C b/framework/src/interfaces/Coupleable.C index 9f65edb897b1..4286c326ae2d 100644 --- a/framework/src/interfaces/Coupleable.C +++ b/framework/src/interfaces/Coupleable.C @@ -2207,12 +2207,18 @@ Coupleable::adCoupledDot(const std::string & var_name, unsigned int comp) const return *getADDefaultValue(var_name); checkFuncType(var_name, VarType::Dot, FuncAge::Curr); - if (_c_nodal) - mooseError("Not implemented"); - if (!_coupleable_neighbor) + { + if (_c_nodal) + return var->adDofValuesDot(); return var->adUDot(); - return var->adUDotNeighbor(); + } + else + { + if (_c_nodal) + mooseError("AD neighbor nodal dof dot implemented"); + return var->adUDotNeighbor(); + } } const ADVariableValue & diff --git a/framework/src/variables/MooseLinearVariableFV.C b/framework/src/variables/MooseLinearVariableFV.C index 54b5fd0a7df5..ce2439d34d22 100644 --- a/framework/src/variables/MooseLinearVariableFV.C +++ b/framework/src/variables/MooseLinearVariableFV.C @@ -851,6 +851,13 @@ MooseLinearVariableFV::adDofValuesNeighbor() const adError(); } +template +const MooseArray & +MooseLinearVariableFV::adDofValuesDot() const +{ + adError(); +} + template const dof_id_type & MooseLinearVariableFV::nodalDofIndex() const diff --git a/framework/src/variables/MooseVariableDataFV.C b/framework/src/variables/MooseVariableDataFV.C index 6dd13a0c526d..a43d4007a865 100644 --- a/framework/src/variables/MooseVariableDataFV.C +++ b/framework/src/variables/MooseVariableDataFV.C @@ -50,9 +50,9 @@ MooseVariableDataFV::MooseVariableDataFV(const MooseVariableFV Date: Tue, 15 Oct 2024 17:36:17 -0600 Subject: [PATCH 2/8] Add some generic ad/noAD routines for time derivatives in coupleable API Add a test material to test those refs #18178 --- framework/include/interfaces/Coupleable.h | 22 +++++++++++++++ framework/src/interfaces/Coupleable.C | 28 +++++++++++++++++++ .../include/materials/CoupledValuesMaterial.h | 22 +++++++++------ test/src/materials/CoupledValuesMaterial.C | 27 +++++++++++------- 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/framework/include/interfaces/Coupleable.h b/framework/include/interfaces/Coupleable.h index f48712bafc84..9f0a52465f90 100644 --- a/framework/include/interfaces/Coupleable.h +++ b/framework/include/interfaces/Coupleable.h @@ -241,6 +241,28 @@ class Coupleable const GenericVariableValue & coupledGenericDofValue(const std::string & var_name, unsigned int comp = 0) const; + /** + * Returns time derivative of a coupled variable for use in templated automatic differentiation + * classes + * @param var_name Name of coupled variable + * @param comp Component number for vector of coupled variables + * @return Reference to a GenericVariableValue for the coupled variable time derivative + */ + template + const GenericVariableValue & coupledGenericDot(const std::string & var_name, + unsigned int comp = 0) const; + + /** + * Returns the second time derivative of a coupled variable for use in templated automatic + * differentiation classes + * @param var_name Name of coupled variable + * @param comp Component number for vector of coupled variables + * @return Reference to a GenericVariableValue for the coupled variable second time derivative + */ + template + const GenericVariableValue & coupledGenericDotDot(const std::string & var_name, + unsigned int comp = 0) const; + /** * Returns value of a coupled lower-dimensional variable * @param var_name Name of coupled variable diff --git a/framework/src/interfaces/Coupleable.C b/framework/src/interfaces/Coupleable.C index 4286c326ae2d..dc9ded1932af 100644 --- a/framework/src/interfaces/Coupleable.C +++ b/framework/src/interfaces/Coupleable.C @@ -1168,6 +1168,20 @@ Coupleable::coupledDotDot(const std::string & var_name, unsigned int comp) const } } +template <> +const GenericVariableValue & +Coupleable::coupledGenericDotDot(const std::string & var_name, unsigned int comp) const +{ + return coupledDotDot(var_name, comp); +} + +template <> +const GenericVariableValue & +Coupleable::coupledGenericDotDot(const std::string & var_name, unsigned int comp) const +{ + return adCoupledDotDot(var_name, comp); +} + const VariableValue & Coupleable::coupledDotOld(const std::string & var_name, unsigned int comp) const { @@ -2693,6 +2707,20 @@ Coupleable::adCoupledDots(const std::string & var_name) const return coupledVectorHelper(var_name, func); } +template <> +const GenericVariableValue & +Coupleable::coupledGenericDot(const std::string & var_name, unsigned int comp) const +{ + return coupledDot(var_name, comp); +} + +template <> +const GenericVariableValue & +Coupleable::coupledGenericDot(const std::string & var_name, unsigned int comp) const +{ + return adCoupledDot(var_name, comp); +} + // Explicit instantiations template const Real & Coupleable::getDefaultNodalValue(const std::string & var_name, diff --git a/test/include/materials/CoupledValuesMaterial.h b/test/include/materials/CoupledValuesMaterial.h index fe5cb690afdd..213d52c02c0b 100644 --- a/test/include/materials/CoupledValuesMaterial.h +++ b/test/include/materials/CoupledValuesMaterial.h @@ -14,27 +14,33 @@ /** * A material that couples variables values and stores them into material property * This makes sure that everything is properly resized and can be indexed into. + * @tparam whether to use the AD version, retrieving AD values from variables and storing them in + * AD material properties, or not */ -class CoupledValuesMaterial : public Material +template +class CoupledValuesMaterialTempl : public Material { public: static InputParameters validParams(); - CoupledValuesMaterial(const InputParameters & parameters); + CoupledValuesMaterialTempl(const InputParameters & parameters); protected: virtual void computeQpProperties() override; - const VariableValue & _value; - const VariableValue & _dot; - const VariableValue & _dot_dot; + const GenericVariableValue & _value; + const GenericVariableValue & _dot; + const GenericVariableValue & _dot_dot; const VariableValue & _dot_du; const VariableValue & _dot_dot_du; const std::string & _var_name; - MaterialProperty & _value_prop; - MaterialProperty & _dot_prop; - MaterialProperty & _dot_dot_prop; + GenericMaterialProperty & _value_prop; + GenericMaterialProperty & _dot_prop; + GenericMaterialProperty & _dot_dot_prop; MaterialProperty & _dot_du_prop; MaterialProperty & _dot_dot_du_prop; }; + +typedef CoupledValuesMaterialTempl CoupledValuesMaterial; +typedef CoupledValuesMaterialTempl ADCoupledValuesMaterial; diff --git a/test/src/materials/CoupledValuesMaterial.C b/test/src/materials/CoupledValuesMaterial.C index 4898834fb680..03f7f19345e1 100644 --- a/test/src/materials/CoupledValuesMaterial.C +++ b/test/src/materials/CoupledValuesMaterial.C @@ -10,34 +10,38 @@ #include "CoupledValuesMaterial.h" registerMooseObject("MooseTestApp", CoupledValuesMaterial); +registerMooseObject("MooseTestApp", ADCoupledValuesMaterial); +template InputParameters -CoupledValuesMaterial::validParams() +CoupledValuesMaterialTempl::validParams() { InputParameters params = Material::validParams(); params.addRequiredCoupledVar("variable", "Coupled variable"); return params; } -CoupledValuesMaterial::CoupledValuesMaterial(const InputParameters & parameters) +template +CoupledValuesMaterialTempl::CoupledValuesMaterialTempl(const InputParameters & parameters) : Material(parameters), - _value(coupledValue("variable")), - _dot(coupledDot("variable")), - _dot_dot(coupledDotDot("variable")), + _value(coupledGenericValue("variable")), + _dot(coupledGenericDot("variable")), + _dot_dot(coupledGenericDotDot("variable")), + // We dont have a generic override for this, and we don't need one yet _dot_du(coupledDotDu("variable")), _dot_dot_du(coupledDotDotDu("variable")), - _var_name(getVar("variable", 0)->name()), - _value_prop(declareProperty(_var_name + "_value")), - _dot_prop(declareProperty(_var_name + "_dot")), - _dot_dot_prop(declareProperty(_var_name + "_dot_dot")), + _value_prop(declareGenericProperty(_var_name + "_value")), + _dot_prop(declareGenericProperty(_var_name + "_dot")), + _dot_dot_prop(declareGenericProperty(_var_name + "_dot_dot")), _dot_du_prop(declareProperty(_var_name + "_dot_du")), _dot_dot_du_prop(declareProperty(_var_name + "_dot_dot_du")) { } +template void -CoupledValuesMaterial::computeQpProperties() +CoupledValuesMaterialTempl::computeQpProperties() { _value_prop[_qp] = _value[_qp]; _dot_prop[_qp] = _dot[_qp]; @@ -45,3 +49,6 @@ CoupledValuesMaterial::computeQpProperties() _dot_du_prop[_qp] = _dot_du[_qp]; _dot_dot_du_prop[_qp] = _dot_dot_du[_qp]; } + +template class CoupledValuesMaterialTempl; +template class CoupledValuesMaterialTempl; From 6b87965ba7e43c81ca68f06b38f7b4f6974547f2 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Tue, 15 Oct 2024 18:37:08 -0600 Subject: [PATCH 3/8] Fix central difference AD 2nd time derivative refs #18178 --- framework/src/timeintegrators/CentralDifference.C | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/framework/src/timeintegrators/CentralDifference.C b/framework/src/timeintegrators/CentralDifference.C index a3cfb30eff89..75058aba1ad0 100644 --- a/framework/src/timeintegrators/CentralDifference.C +++ b/framework/src/timeintegrators/CentralDifference.C @@ -46,6 +46,10 @@ CentralDifference::computeADTimeDerivatives(ADReal & ad_u_dot, const dof_id_type & dof, ADReal & ad_u_dotdot) const { + // Seeds ad_u_dotdot with _ad_dof_values and associated derivatives provided via ad_u_dot from + // MooseVariableData + ad_u_dotdot = ad_u_dot; + computeTimeDerivativeHelper(ad_u_dot, ad_u_dotdot, _solution_old(dof), _solution_older(dof)); } From 6019458b1d72eba13039260f536bf494587d41d7 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Tue, 15 Oct 2024 18:37:58 -0600 Subject: [PATCH 4/8] Add a test for testing new AD dot routines in coupleable --- .../interfaces/coupleable/coupled_dots.i | 78 +++++++++++++++++++ .../coupleable/gold/coupled_dots_out.csv | 5 ++ test/tests/interfaces/coupleable/tests | 8 ++ 3 files changed, 91 insertions(+) create mode 100644 test/tests/interfaces/coupleable/coupled_dots.i create mode 100644 test/tests/interfaces/coupleable/gold/coupled_dots_out.csv diff --git a/test/tests/interfaces/coupleable/coupled_dots.i b/test/tests/interfaces/coupleable/coupled_dots.i new file mode 100644 index 000000000000..b7e92a7c9620 --- /dev/null +++ b/test/tests/interfaces/coupleable/coupled_dots.i @@ -0,0 +1,78 @@ +[Mesh] + [gmg] + type = GeneratedMeshGenerator + dim = 1 + nx = 2 + [] +[] + +[Functions] + [linear] + type = ParsedFunction + expression = 'x + 10*t + 2*t*t' + [] +[] + +[AuxVariables] + [base] + family = MONOMIAL + order = CONSTANT + [] +[] + +[AuxKernels] + [base_aux] + type = FunctionAux + function = 'linear' + variable = 'base' + [] +[] + +[Executioner] + type = Transient + num_steps = 3 + + [TimeIntegrator] + type = CentralDifference + [] +[] + +[Problem] + solve = false + +[] + +[Materials] + [coupled] + type = CoupledValuesMaterial + variable = 'base' + [] + [ad_coupled] + type = ADCoupledValuesMaterial + variable = 'base' + declare_suffix = 'ad' + [] +[] + +[Postprocessors] + [dot] + type = ElementAverageMaterialProperty + mat_prop = 'base_dot' + [] + [dot_dot] + type = ElementAverageMaterialProperty + mat_prop = 'base_dot_dot' + [] + [ad_dot] + type = ADElementAverageMaterialProperty + mat_prop = 'base_dot_ad' + [] + [ad_dot_dot] + type = ADElementAverageMaterialProperty + mat_prop = 'base_dot_dot_ad' + [] +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/interfaces/coupleable/gold/coupled_dots_out.csv b/test/tests/interfaces/coupleable/gold/coupled_dots_out.csv new file mode 100644 index 000000000000..59c1dcbd7151 --- /dev/null +++ b/test/tests/interfaces/coupleable/gold/coupled_dots_out.csv @@ -0,0 +1,5 @@ +time,ad_dot,ad_dot_dot,dot,dot_dot +0,0,0,0,0 +1,6.25,12.5,6.25,12.5 +2,14.25,3.5,14.25,3.5 +3,18,4,18,4 diff --git a/test/tests/interfaces/coupleable/tests b/test/tests/interfaces/coupleable/tests index 76778a3fd4f8..ff0d0dda0ac6 100644 --- a/test/tests/interfaces/coupleable/tests +++ b/test/tests/interfaces/coupleable/tests @@ -23,4 +23,12 @@ exodiff = 'array_coupling_by_name_out.e' requirement = 'The system shall be able to couple an array variable with its name directly through the coupling interface.' [] + [time_derivative_coupling] + design = 'Coupleable.md' + issues = '#28' + type = CSVDiff + input = 'coupled_dots.i' + csvdiff = 'coupled_dots_out.csv' + requirement = 'The system shall be able to retrieve the time derivatives of variables through the coupling interface.' + [] [] From 50196c4745e12b5a9c6412540876c81abaf803c0 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Tue, 15 Oct 2024 19:17:52 -0600 Subject: [PATCH 5/8] Add templating to test AD/nonAD versions of some coupleable APIs --- test/include/auxkernels/DotCouplingAux.h | 11 +++++++---- test/src/auxkernels/DotCouplingAux.C | 19 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/test/include/auxkernels/DotCouplingAux.h b/test/include/auxkernels/DotCouplingAux.h index d3df4f912a42..37284755b72b 100644 --- a/test/include/auxkernels/DotCouplingAux.h +++ b/test/include/auxkernels/DotCouplingAux.h @@ -14,16 +14,19 @@ /** * Couples in the time derivatives of a NL variable */ -class DotCouplingAux : public AuxKernel +template +class DotCouplingAuxTempl : public AuxKernel { public: static InputParameters validParams(); - DotCouplingAux(const InputParameters & parameters); - virtual ~DotCouplingAux(); + DotCouplingAuxTempl(const InputParameters & parameters); protected: virtual Real computeValue(); - const VariableValue & _v_dot; + const GenericVariableValue & _v_dot; }; + +typedef DotCouplingAuxTempl DotCouplingAux; +typedef DotCouplingAuxTempl ADDotCouplingAux; diff --git a/test/src/auxkernels/DotCouplingAux.C b/test/src/auxkernels/DotCouplingAux.C index 3a4a3644e229..5bc7fc7416d5 100644 --- a/test/src/auxkernels/DotCouplingAux.C +++ b/test/src/auxkernels/DotCouplingAux.C @@ -10,9 +10,11 @@ #include "DotCouplingAux.h" registerMooseObject("MooseTestApp", DotCouplingAux); +registerMooseObject("MooseTestApp", ADDotCouplingAux); +template InputParameters -DotCouplingAux::validParams() +DotCouplingAuxTempl::validParams() { InputParameters params = AuxKernel::validParams(); params.addRequiredCoupledVar("v", "Coupled variable"); @@ -20,15 +22,18 @@ DotCouplingAux::validParams() return params; } -DotCouplingAux::DotCouplingAux(const InputParameters & parameters) - : AuxKernel(parameters), _v_dot(coupledDot("v")) +template +DotCouplingAuxTempl::DotCouplingAuxTempl(const InputParameters & parameters) + : AuxKernel(parameters), _v_dot(coupledGenericDot("v")) { } -DotCouplingAux::~DotCouplingAux() {} - +template Real -DotCouplingAux::computeValue() +DotCouplingAuxTempl::computeValue() { - return _v_dot[_qp]; + return MetaPhysicL::raw_value(_v_dot[_qp]); } + +template class DotCouplingAuxTempl; +template class DotCouplingAuxTempl; From bd578c23fcac00adbbce7adf2578fdb9ca661488 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Tue, 15 Oct 2024 19:32:23 -0600 Subject: [PATCH 6/8] Add a test for new AD routines in coupleable for nodal variables refs #28867 --- .../coupleable/coupled_dots_nodal.i | 73 +++++++++++++++++++ .../gold/coupled_dots_nodal_out.csv | 5 ++ test/tests/interfaces/coupleable/tests | 8 ++ 3 files changed, 86 insertions(+) create mode 100644 test/tests/interfaces/coupleable/coupled_dots_nodal.i create mode 100644 test/tests/interfaces/coupleable/gold/coupled_dots_nodal_out.csv diff --git a/test/tests/interfaces/coupleable/coupled_dots_nodal.i b/test/tests/interfaces/coupleable/coupled_dots_nodal.i new file mode 100644 index 000000000000..ce53aa902687 --- /dev/null +++ b/test/tests/interfaces/coupleable/coupled_dots_nodal.i @@ -0,0 +1,73 @@ +[Mesh] + [gmg] + type = GeneratedMeshGenerator + dim = 1 + nx = 2 + [] +[] + +[Functions] + [linear] + type = ParsedFunction + expression = 'x + 10*t + 2*t*t' + [] +[] + +[Variables] + [base] + [] +[] + +[Kernels] + [time] + type = TimeDerivative + variable = base + [] + [source] + type = BodyForce + variable = base + function = linear + [] +[] + +[AuxVariables] + [first] + [] + [first_from_ad] + [] +[] + +[AuxKernels] + [set_first] + type = DotCouplingAux + variable = first + v = base + [] + [set_first_from_AD] + type = ADDotCouplingAux + variable = first_from_ad + v = base + [] +[] + +[Executioner] + type = Transient + num_steps = 3 +[] + +[Postprocessors] + [dot] + type = AverageNodalVariableValue + variable = 'first' + [] + [ad_dot] + type = AverageNodalVariableValue + variable = 'first_from_ad' + [] + # Ideally we would test the second derivative here, but it's not implemented yet for nodal variables + # through the coupleable API +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/interfaces/coupleable/gold/coupled_dots_nodal_out.csv b/test/tests/interfaces/coupleable/gold/coupled_dots_nodal_out.csv new file mode 100644 index 000000000000..7414f3487e83 --- /dev/null +++ b/test/tests/interfaces/coupleable/gold/coupled_dots_nodal_out.csv @@ -0,0 +1,5 @@ +time,ad_dot,dot +0,0,0 +1,12.5,12.5 +2,28.500000186692,28.500000186692 +3,48.49999979484,48.49999979484 diff --git a/test/tests/interfaces/coupleable/tests b/test/tests/interfaces/coupleable/tests index ff0d0dda0ac6..39b1e0a491fa 100644 --- a/test/tests/interfaces/coupleable/tests +++ b/test/tests/interfaces/coupleable/tests @@ -31,4 +31,12 @@ csvdiff = 'coupled_dots_out.csv' requirement = 'The system shall be able to retrieve the time derivatives of variables through the coupling interface.' [] + [time_derivative_coupling_nodal] + design = 'Coupleable.md' + issues = '#28' + type = CSVDiff + input = 'coupled_dots_nodal.i' + csvdiff = 'coupled_dots_nodal_out.csv' + requirement = 'The system shall be able to retrieve the time derivatives of nodal variables through the coupling interface.' + [] [] From 4ced19920b412a0f0ef5549f8d07928791e2b7c9 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Wed, 16 Oct 2024 09:44:51 -0600 Subject: [PATCH 7/8] Add support for elemental AD time derivatives for auxvariables (using nonAD version) Add support for nodal AD time derivatives, with errors for unsupported cases closes #28859 refs #28867 --- .../include/variables/MooseVariableData.h | 3 ++ framework/src/variables/MooseVariableData.C | 29 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/framework/include/variables/MooseVariableData.h b/framework/include/variables/MooseVariableData.h index be2062e5381e..173f20b60789 100644 --- a/framework/include/variables/MooseVariableData.h +++ b/framework/include/variables/MooseVariableData.h @@ -736,6 +736,9 @@ const MooseArray & MooseVariableData::adDofValuesDot() const { _need_ad = _need_ad_u_dot = true; + if (!_time_integrator) + // See explanation in adUDot() body + _need_u_dot = true; return _ad_dofs_dot; } diff --git a/framework/src/variables/MooseVariableData.C b/framework/src/variables/MooseVariableData.C index 181c9b46d503..50e670a70e43 100644 --- a/framework/src/variables/MooseVariableData.C +++ b/framework/src/variables/MooseVariableData.C @@ -1149,7 +1149,7 @@ template <> void MooseVariableData::computeMonomialValues() { - // Fixeme: will think of optimization later + // FIXME: will think of optimization later computeValues(); } @@ -1271,12 +1271,16 @@ MooseVariableData::computeAD(const unsigned int num_dofs, const unsi } if (_need_ad_u_dot && !_time_integrator) + { for (MooseIndex(nqp) qp = 0; qp < nqp; ++qp) { _ad_u_dot[qp] = _u_dot[qp]; if (_need_ad_u_dotdot) _ad_u_dotdot[qp] = _u_dotdot[qp]; } + for (unsigned int i = 0; i < num_dofs; i++) + _ad_dofs_dot[i] = _dof_values_dot[i]; + } if (_need_ad_grad_u_dot && !_time_integrator) for (MooseIndex(nqp) qp = 0; qp < nqp; ++qp) @@ -1785,6 +1789,11 @@ MooseVariableData::fetchADDoFValues() libmesh_assert(n); _ad_dof_values.resize(n); + if (_need_ad_u_dot) + _ad_dofs_dot.resize(n); + if (_need_ad_u_dotdot) + _ad_dofs_dotdot.resize(n); + const bool do_derivatives = ADReal::do_derivatives && _sys.number() == _subproblem.currentNlSysNum(); @@ -1794,6 +1803,24 @@ MooseVariableData::fetchADDoFValues() if (do_derivatives) Moose::derivInsert(_ad_dof_values[i].derivatives(), _dof_indices[i], 1.); assignADNodalValue(_ad_dof_values[i], i); + + if (_need_ad_u_dot) + { + if (_time_integrator && _time_integrator->dt()) + { + _ad_dofs_dot[i] = _ad_dof_values[i]; + _time_integrator->computeADTimeDerivatives(_ad_dofs_dot[i], + _dof_indices[i], + _need_ad_u_dotdot ? _ad_dofs_dotdot[i] + : _ad_real_dummy); + } + // Executing something with a time derivative at initial should not put a NaN + else if (_time_integrator && !_time_integrator->dt()) + _ad_dofs_dot[i] = 0; + else + mooseError("AD nodal time derivatives not implemented for variables without a time " + "integrator (auxiliary variables)"); + } } } From 937efad857a0eb51bf3fb5166bf84b8b61916ed5 Mon Sep 17 00:00:00 2001 From: Guillaume Giudicelli Date: Thu, 31 Oct 2024 12:46:57 -0600 Subject: [PATCH 8/8] Address Alex's review - fix error msg - rename routine Co-authored-by: Alex Lindsay --- framework/include/variables/MooseVariableData.h | 4 ++-- framework/src/interfaces/Coupleable.C | 2 +- framework/src/variables/MooseVariableData.C | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/include/variables/MooseVariableData.h b/framework/include/variables/MooseVariableData.h index 173f20b60789..33917bae8820 100644 --- a/framework/include/variables/MooseVariableData.h +++ b/framework/include/variables/MooseVariableData.h @@ -429,7 +429,7 @@ class MooseVariableData : public MooseVariableDataBase const MooseArray & adDofValues() const; /** - * Return the AD time derivative values + * Return the AD time derivative values of degrees of freedom */ const MooseArray & adDofValuesDot() const; @@ -458,7 +458,7 @@ class MooseVariableData : public MooseVariableDataBase * for nodal basis families */ void assignADNodalValue(const ADReal & value, const unsigned int & component); - void fetchADDoFValues(); + void fetchADNodalValues(); const FEType & _fe_type; diff --git a/framework/src/interfaces/Coupleable.C b/framework/src/interfaces/Coupleable.C index dc9ded1932af..db3a10da2f40 100644 --- a/framework/src/interfaces/Coupleable.C +++ b/framework/src/interfaces/Coupleable.C @@ -2230,7 +2230,7 @@ Coupleable::adCoupledDot(const std::string & var_name, unsigned int comp) const else { if (_c_nodal) - mooseError("AD neighbor nodal dof dot implemented"); + mooseError("AD neighbor nodal dof dot not implemented"); return var->adUDotNeighbor(); } } diff --git a/framework/src/variables/MooseVariableData.C b/framework/src/variables/MooseVariableData.C index 50e670a70e43..3d1ce8e87688 100644 --- a/framework/src/variables/MooseVariableData.C +++ b/framework/src/variables/MooseVariableData.C @@ -1775,7 +1775,7 @@ MooseVariableData::computeNodalValues() assignNodalValue(); if (_need_ad) - fetchADDoFValues(); + fetchADNodalValues(); } else zeroSizeDofValues(); @@ -1783,7 +1783,7 @@ MooseVariableData::computeNodalValues() template void -MooseVariableData::fetchADDoFValues() +MooseVariableData::fetchADNodalValues() { auto n = _dof_indices.size(); libmesh_assert(n); @@ -1826,7 +1826,7 @@ MooseVariableData::fetchADDoFValues() template <> void -MooseVariableData::fetchADDoFValues() +MooseVariableData::fetchADNodalValues() { mooseError("I do not know how to support AD with array variables"); }