diff --git a/framework/include/materials/FunctorADConverter.h b/framework/include/materials/FunctorADConverter.h new file mode 100644 index 000000000000..322728fe2d3a --- /dev/null +++ b/framework/include/materials/FunctorADConverter.h @@ -0,0 +1,27 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#pragma once + +#include "FunctorMaterial.h" + +/** + * This material converts regular functors to AD functors and AD functors to regular functors + */ +template +class FunctorADConverterTempl : public FunctorMaterial +{ +public: + static InputParameters validParams(); + + FunctorADConverterTempl(const InputParameters & parameters); +}; + +typedef FunctorADConverterTempl FunctorADConverter; +typedef FunctorADConverterTempl VectorFunctorADConverter; diff --git a/framework/include/materials/PiecewiseByBlockFunctorMaterial.h b/framework/include/materials/PiecewiseByBlockFunctorMaterial.h index c4228cbe27ff..765ad2b4e227 100644 --- a/framework/include/materials/PiecewiseByBlockFunctorMaterial.h +++ b/framework/include/materials/PiecewiseByBlockFunctorMaterial.h @@ -12,7 +12,7 @@ #include "FunctorMaterial.h" /** - * Defines a material property that defined by another functor (possibly constant) on each block, + * Defines a functor material property by another functor (possibly constant) on each block, * discontinuous at interfaces */ template diff --git a/framework/src/materials/FunctorADConverter.C b/framework/src/materials/FunctorADConverter.C new file mode 100644 index 000000000000..01300871f8df --- /dev/null +++ b/framework/src/materials/FunctorADConverter.C @@ -0,0 +1,110 @@ +//* This file is part of the MOOSE framework +//* https://www.mooseframework.org +//* +//* All rights reserved, see COPYRIGHT for full restrictions +//* https://github.com/idaholab/moose/blob/master/COPYRIGHT +//* +//* Licensed under LGPL 2.1, please see LICENSE for details +//* https://www.gnu.org/licenses/lgpl-2.1.html + +#include "FunctorADConverter.h" + +#include "metaphysicl/raw_type.h" + +registerMooseObject("MooseApp", FunctorADConverter); +registerMooseObject("MooseApp", VectorFunctorADConverter); + +template +InputParameters +FunctorADConverterTempl::validParams() +{ + InputParameters params = FunctorMaterial::validParams(); + params.addClassDescription( + "Converts regular functors to AD functors and " + " AD functors to regular functors"); + params.addParam>( + "reg_props_in", + "The names of the regular functors to convert to AD functors"); + params.addParam>("ad_props_out", + "The names of the output AD functors"); + params.addParam>( + "ad_props_in", + "The names of the AD functors to convert to regular functors"); + params.addParam>("reg_props_out", + "The names of the output regular functors"); + return params; +} + +template +FunctorADConverterTempl::FunctorADConverterTempl(const InputParameters & parameters) + : FunctorMaterial(parameters) +{ + auto reg_props_in = getParam>("reg_props_in"); + auto ad_props_out = getParam>("ad_props_out"); + auto ad_props_in = getParam>("ad_props_in"); + auto reg_props_out = getParam>("reg_props_out"); + + // Check input sizes + if (reg_props_in.size() != ad_props_out.size()) + paramError("ad_props_out", + "The number of output AD functors must match the number of input regular " + "functors, which is " + std::to_string(reg_props_in.size())); + + if (ad_props_in.size() != reg_props_out.size()) + paramError("reg_props_out", + "The number of output regular functors must match the number of input AD " + "functors, which is " + std::to_string(ad_props_in.size())); + + // Check input names for overlaps, before possibly hitting a harder to + // interpret error at functor definition + for (const auto i : make_range(reg_props_in.size())) + for (const auto j : make_range(reg_props_in.size())) + if (reg_props_in[i] == ad_props_out[j]) + paramError("reg_props_in", + "Functor names may not overlap between reg_props_in and ad_props_out"); + + for (const auto i : make_range(reg_props_in.size())) + for (const auto j : make_range(ad_props_in.size())) + if (reg_props_in[i] == reg_props_out[j]) + paramError("reg_props_in", + "Functor names may not overlap between reg_props_in and reg_props_out"); + + for (const auto i : make_range(ad_props_in.size())) + for (const auto j : make_range(ad_props_in.size())) + if (ad_props_in[i] == reg_props_out[j]) + paramError("ad_props_in", + "Functor names may not overlap between ad_props_in and reg_props_out"); + + for (const auto i : make_range(ad_props_in.size())) + for (const auto j : make_range(reg_props_in.size())) + if (ad_props_in[i] == ad_props_out[j]) + paramError("ad_props_in", + "Functor names may not overlap between ad_props_in and ad_props_out"); + + // Define the AD functors + for (const auto i : make_range(reg_props_in.size())) + { + const auto & reg_functor = &getFunctor(reg_props_in[i]); + const auto & ad_prop = &declareFunctorProperty::type>(ad_props_out[i]); + ad_prop->setFunctor( + _mesh, + blockIDs(), + [reg_functor](const auto & r, const auto & t) -> typename Moose::ADType::type { + return (*reg_functor)(r, t); }); + } + + // Define the regular functors + for (const auto i : make_range(ad_props_in.size())) + { + const auto & ad_functor = &getFunctor::type>(ad_props_in[i]); + const auto & reg_prop = &declareFunctorProperty(reg_props_out[i]); + reg_prop->setFunctor( + _mesh, + blockIDs(), + [ad_functor](const auto & r, const auto & t) -> T { + return MetaPhysicL::raw_value((*ad_functor)(r, t)); }); + } +} + +template class FunctorADConverterTempl; +template class FunctorADConverterTempl; diff --git a/framework/src/materials/MaterialConverter.C b/framework/src/materials/MaterialConverter.C index 74d8d771f6a4..10b687a65d63 100644 --- a/framework/src/materials/MaterialConverter.C +++ b/framework/src/materials/MaterialConverter.C @@ -23,7 +23,7 @@ MaterialConverterTempl::validParams() { InputParameters params = Material::validParams(); params.addClassDescription( - "Converts regular material properties to AD properties and visa versa"); + "Converts regular material properties to AD properties and vice versa"); params.addParam>( "reg_props_in", "The names of the regular material properties to convert to AD properties"); params.addParam>("ad_props_out", @@ -33,7 +33,7 @@ MaterialConverterTempl::validParams() params.addParam>("reg_props_out", "The names of the output regular properties"); params.addParam( - "intra_convert", false, "Whether to intra convert, e.g. regular->regular, ad->ad"); + "intra_convert", false, "Whether to allow intra conversion, e.g. regular->regular, ad->ad"); return params; } diff --git a/test/tests/materials/functor_properties/ad_conversion/1d_dirichlet.i b/test/tests/materials/functor_properties/ad_conversion/1d_dirichlet.i new file mode 100644 index 000000000000..d78f71a24390 --- /dev/null +++ b/test/tests/materials/functor_properties/ad_conversion/1d_dirichlet.i @@ -0,0 +1,77 @@ +[Mesh] + type = GeneratedMesh + dim = 1 + nx = 10 + xmax = 2 +[] + +[Variables] + [v] + type = MooseVariableFVReal + [] +[] + +[AuxVariables] + [sink] + type = MooseVariableFVReal + [] +[] + +[ICs] + [sink] + type = FunctionIC + variable = sink + function = 'x^3' + [] +[] + + +[FVKernels] + [diff] + type = FVDiffusion + variable = v + coeff = 1 + [] + [sink] + type = FVFunctorElementalKernel + variable = v + functor_name = 'ad_sink' + [] +[] + +[FVBCs] + [bounds] + type = FVDirichletBC + variable = v + boundary = 'left right' + value = 0 + [] +[] + +[Materials] + [converter_to_regular] + type = FunctorADConverter + ad_props_in = 'sink' + reg_props_out = 'regular_sink_0' + [] + # Just to change the name + [functor] + type = GenericFunctorMaterial + prop_names = 'regular_sink_1' + prop_values = 'regular_sink_0' + [] + [converter_to_ad] + type = FunctorADConverter + reg_props_in = 'regular_sink_1' + ad_props_out = 'ad_sink' + [] +[] + +[Executioner] + type = Steady + solve_type = 'NEWTON' +[] + +[Outputs] + exodus = true +[] diff --git a/test/tests/materials/functor_properties/ad_conversion/gold/1d_dirichlet_out.e b/test/tests/materials/functor_properties/ad_conversion/gold/1d_dirichlet_out.e new file mode 100644 index 000000000000..13e9ed455bb3 Binary files /dev/null and b/test/tests/materials/functor_properties/ad_conversion/gold/1d_dirichlet_out.e differ diff --git a/test/tests/materials/functor_properties/ad_conversion/tests b/test/tests/materials/functor_properties/ad_conversion/tests new file mode 100644 index 000000000000..a9cc5a120e42 --- /dev/null +++ b/test/tests/materials/functor_properties/ad_conversion/tests @@ -0,0 +1,11 @@ +[Tests] + design = FunctorADConverter.md + issues = '' + [exo] + type = Exodiff + ad_indexing_type = 'global' + input = 1d_dirichlet.i + exodiff = 1d_dirichlet_out.e + requirement = 'The system shall be able to convert functors from AD to regular and vice versa.' + [] +[]