Skip to content

Commit

Permalink
Add a functor material property converter between AD and regular
Browse files Browse the repository at this point in the history
  • Loading branch information
GiudGiud committed Dec 3, 2021
1 parent 51445a1 commit 663c57c
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 3 deletions.
27 changes: 27 additions & 0 deletions 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 <typename T>
class FunctorADConverterTempl : public FunctorMaterial
{
public:
static InputParameters validParams();

FunctorADConverterTempl(const InputParameters & parameters);
};

typedef FunctorADConverterTempl<Real> FunctorADConverter;
typedef FunctorADConverterTempl<RealVectorValue> VectorFunctorADConverter;
Expand Up @@ -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 <bool is_ad>
Expand Down
110 changes: 110 additions & 0 deletions 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 <typename T>
InputParameters
FunctorADConverterTempl<T>::validParams()
{
InputParameters params = FunctorMaterial::validParams();
params.addClassDescription(
"Converts regular functors to AD functors and "
" AD functors to regular functors");
params.addParam<std::vector<std::string>>(
"reg_props_in",
"The names of the regular functors to convert to AD functors");
params.addParam<std::vector<std::string>>("ad_props_out",
"The names of the output AD functors");
params.addParam<std::vector<std::string>>(
"ad_props_in",
"The names of the AD functors to convert to regular functors");
params.addParam<std::vector<std::string>>("reg_props_out",
"The names of the output regular functors");
return params;
}

template <typename T>
FunctorADConverterTempl<T>::FunctorADConverterTempl(const InputParameters & parameters)
: FunctorMaterial(parameters)
{
auto reg_props_in = getParam<std::vector<std::string>>("reg_props_in");
auto ad_props_out = getParam<std::vector<std::string>>("ad_props_out");
auto ad_props_in = getParam<std::vector<std::string>>("ad_props_in");
auto reg_props_out = getParam<std::vector<std::string>>("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<T>(reg_props_in[i]);
const auto & ad_prop = &declareFunctorProperty<typename Moose::ADType<T>::type>(ad_props_out[i]);
ad_prop->setFunctor(
_mesh,
blockIDs(),
[reg_functor](const auto & r, const auto & t) -> typename Moose::ADType<T>::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<typename Moose::ADType<T>::type>(ad_props_in[i]);
const auto & reg_prop = &declareFunctorProperty<T>(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<Real>;
template class FunctorADConverterTempl<RealVectorValue>;
4 changes: 2 additions & 2 deletions framework/src/materials/MaterialConverter.C
Expand Up @@ -23,7 +23,7 @@ MaterialConverterTempl<T>::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<std::vector<std::string>>(
"reg_props_in", "The names of the regular material properties to convert to AD properties");
params.addParam<std::vector<std::string>>("ad_props_out",
Expand All @@ -33,7 +33,7 @@ MaterialConverterTempl<T>::validParams()
params.addParam<std::vector<std::string>>("reg_props_out",
"The names of the output regular properties");
params.addParam<bool>(
"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;
}

Expand Down
@@ -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
[]
Binary file not shown.
11 changes: 11 additions & 0 deletions 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.'
[]
[]

0 comments on commit 663c57c

Please sign in to comment.