Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions framework/doc/content/source/mfem/functions/MFEMParsedFunction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# MFEMParsedFunction

!if! function=hasCapability('mfem')

## Summary

!syntax description /Functions/MFEMParsedFunction

## Overview

`MFEMParsedFunction` is responsible for parsing expressions that, in addition
to being scalar functions of position and time, can also depend on scalar
coefficients, including any scalar variables, postprocessors, material
properties or functions specified by the user.

The input parameters are those of [ParsedFunction](/MooseParsedFunction.md)
and provide the same flexibility. Note that, in the context of MFEM problems,
a scalar variable is a real-valued scalar field, not (necessarily) a constant
over the entire domain as elsewhere in MOOSE.

## Example Input File Syntax

!listing test/tests/mfem/functions/parsed_function_source.i block=Functions

!syntax parameters /Functions/MFEMParsedFunction

!syntax inputs /Functions/MFEMParsedFunction

!syntax children /Functions/MFEMParsedFunction

!if-end!

!else
!include mfem/mfem_warning.md
36 changes: 36 additions & 0 deletions framework/include/mfem/functions/MFEMParsedCoefficient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* 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

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "FunctionParserUtils.h"

/**
* Scalar coefficient that, given a set of scalar (possibly, but not necessarily, gridfunction)
* coefficients u, v, w, ..., and a scalar, parsed function f, returns f(u, v, w, ..., x, y, z, t)
*/
class MFEMParsedCoefficient : public mfem::Coefficient
{
private:
const std::vector<std::reference_wrapper<mfem::Coefficient>> & _coefficients;
const FunctionParserUtils<false>::SymFunctionPtr & _sym_function;
mfem::Array<mfem::real_t> _vals;
mfem::Vector _transip;

public:
MFEMParsedCoefficient(const unsigned & arity,
const std::vector<std::reference_wrapper<mfem::Coefficient>> & coefs,
const FunctionParserUtils<false>::SymFunctionPtr & sym_function);

mfem::real_t Eval(mfem::ElementTransformation & T, const mfem::IntegrationPoint & ip) override;
};

#endif
43 changes: 43 additions & 0 deletions framework/include/mfem/functions/MFEMParsedFunction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* 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

#ifdef MOOSE_MFEM_ENABLED

#pragma once

#include "MooseParsedFunction.h"
#include "FunctionParserUtils.h"
#include "MFEMProblem.h"

/**
* Scalar, parsed function of position, time, and any number of scalar problem coefficients,
* including any scalar variables, postprocessors, material properties or functions
*/
class MFEMParsedFunction : public MooseParsedFunction, public FunctionParserUtils<false>
{
public:
static InputParameters validParams();

MFEMParsedFunction(const InputParameters & parameters);
virtual ~MFEMParsedFunction() = default;

void initialSetup() override;

protected:
/// reference to the MFEMProblem instance
MFEMProblem & _mfem_problem;
/// function parser object
SymFunctionPtr _sym_function;
/// coordinate and time variable names
const std::vector<std::string> _xyzt;
/// vector of references to the scalar coefficients used in the function
std::vector<std::reference_wrapper<mfem::Coefficient>> _coefficients;
};

#endif
38 changes: 38 additions & 0 deletions framework/src/mfem/functions/MFEMParsedCoefficient.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* 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

#ifdef MOOSE_MFEM_ENABLED

#include "MFEMParsedCoefficient.h"

MFEMParsedCoefficient::MFEMParsedCoefficient(
const unsigned & arity,
const std::vector<std::reference_wrapper<mfem::Coefficient>> & coefficients,
const FunctionParserUtils<false>::SymFunctionPtr & sym_function)
: _coefficients(coefficients), _sym_function(sym_function), _vals(arity), _transip(3)
{
}

mfem::real_t
MFEMParsedCoefficient::Eval(mfem::ElementTransformation & T, const mfem::IntegrationPoint & ip)
{
for (unsigned i = 0; i < _coefficients.size(); i++)
_vals[i] = _coefficients[i].get().Eval(T, ip);

T.Transform(ip, _transip);

for (int i = 0; i < 3; i++)
_vals[_coefficients.size() + i] = i < _transip.Size() ? _transip(i) : 0.;

_vals[_coefficients.size() + 3] = GetTime();

return _sym_function->Eval(_vals.GetData());
}

#endif
53 changes: 53 additions & 0 deletions framework/src/mfem/functions/MFEMParsedFunction.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//* This file is part of the MOOSE framework
//* https://mooseframework.inl.gov
//*
//* 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

#ifdef MOOSE_MFEM_ENABLED

#include "MFEMParsedFunction.h"
#include "MFEMParsedCoefficient.h"

registerMooseObject("MooseApp", MFEMParsedFunction);

InputParameters
MFEMParsedFunction::validParams()
{
InputParameters params = MooseParsedFunction::validParams();
params += FunctionParserUtils<false>::validParams();
params.addClassDescription("Parses scalar function of position, time and scalar "
"problem coefficients (including scalar variables).");
return params;
}

MFEMParsedFunction::MFEMParsedFunction(const InputParameters & parameters)
: MooseParsedFunction(parameters),
FunctionParserUtils(parameters),
_mfem_problem(static_cast<MFEMProblem &>(_pfb_feproblem)),
_sym_function(std::make_shared<SymFunction>()),
_xyzt({"x", "y", "z", "t"})
{
// variable symbols the function depends on (including position and time)
std::string symbols = MooseUtils::stringJoin({_vars.begin(), _vars.end()}, ",");
symbols += (symbols.empty() ? "" : ",") + MooseUtils::stringJoin(_xyzt, ",");

// setup parsed function
parsedFunctionSetup(_sym_function, _value, symbols, {}, {}, comm());

// create MFEMParsedCoefficient
_mfem_problem.getCoefficients().declareScalar<MFEMParsedCoefficient>(
name(), _vars.size() + _xyzt.size(), _coefficients, _sym_function);
}

void
MFEMParsedFunction::initialSetup()
{
for (const auto i : index_range(_vars))
_coefficients.push_back(_mfem_problem.getCoefficients().getScalarCoefficient(_vals[i]));
}

#endif
2 changes: 1 addition & 1 deletion framework/src/mfem/problem/MFEMProblem.C
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ MFEMProblem::addFunction(const std::string & type,
}
});
}
else
else if ("MFEMParsedFunction" != type)
{
mooseWarning("Could not identify whether function ",
type,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
time,error
0,0
1,0.21586854778503
113 changes: 113 additions & 0 deletions test/tests/mfem/functions/parsed_function_source.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
[Mesh]
type = MFEMMesh
file = ../mesh/hinomaru.e
[]

[Problem]
type = MFEMProblem
[]

[FESpaces]
[H1FESpace]
type = MFEMScalarFESpace
fec_type = H1
fec_order = FIRST
[]
[]

[Variables]
[variable]
type = MFEMVariable
fespace = H1FESpace
[]
[]

[ICs]
[ic]
type = MFEMScalarIC
variable = variable
coefficient = material
[]
[]

[BCs]
[bc]
type = MFEMScalarDirichletBC
variable = variable
boundary = skin
[]
[]

[FunctorMaterials]
[material]
type = MFEMGenericFunctorMaterial
prop_names = material
prop_values = -100
[]
[]

[Functions]
[r]
type = ParsedFunction
expression = hypot(x,y)
[]
[p]
type = ParsedFunction
expression = atan2(y,x)
[]
[source]
type = MFEMParsedFunction
expression = v*sin(w*p)
symbol_names = 'p w v'
symbol_values = 'p 4 variable'
[]
[solution]
type = MFEMParsedFunction
expression = if(r<=1,-c*sin(w*p)*(r^w-r^2)/(w^2-4),0)
symbol_names = 'r p w c'
symbol_values = 'r p 4 material'
[]
[]

[Kernels]
[diff]
type = MFEMDiffusionKernel
variable = variable
[]
[source]
type = MFEMDomainLFKernel
variable = variable
coefficient = source
block = wire
[]
[]

[Preconditioner]
[boomeramg]
type = MFEMHypreBoomerAMG
[]
[]

[Solver]
type = MFEMHyprePCG
preconditioner = boomeramg
l_tol = 1e-16
[]

[Executioner]
type = MFEMSteady
device = cpu
[]

[Postprocessors]
[error]
type = MFEML2Error
variable = variable
function = solution
[]
[]

[Outputs]
csv = true
file_base = OutputData/ParsedFunctionSource
[]
13 changes: 13 additions & 0 deletions test/tests/mfem/functions/tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Tests]
[MFEMParsedFunction]
type = CSVDiff
input = parsed_function_source.i
csvdiff = OutputData/ParsedFunctionSource.csv
design = 'MFEMParsedFunction.md'
issues = '#31145'
requirement = 'The system shall have the ability to parse non-linear functions of problem variables'
capabilities = 'mfem'
compute_devices = 'cpu cuda'
recover = false
[]
[]