Skip to content

Commit 75e4c83

Browse files
authored
Merge pull request #31613 from Giannis95/Giannis95/MFEMInnerCrossProductAux
Add two MFEM auxkernels for L2-averaged inner and cross product of two source (par)gridfucntions projected onto an MFEM AuxVariable
2 parents 7323e92 + c7d5559 commit 75e4c83

File tree

23 files changed

+33033
-1
lines changed

23 files changed

+33033
-1
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# MFEMCrossProductAux
2+
3+
!if! function=hasCapability('mfem')
4+
5+
## Summary
6+
7+
!syntax description /AuxKernels/MFEMCrossProductAux
8+
9+
## Overview
10+
11+
AuxKernel for calculating the cross product of two vector fields and projecting onto an L2 vector finite element space mfem auxvariable.
12+
13+
!equation
14+
s(x)(u\times v), \,\,\,
15+
16+
where $u$ and $v$ are the two vector fields and $s(x)$ is an optional scaling.
17+
18+
## Example Input File Syntax
19+
20+
!listing mfem/auxkernels/crossproduct.i block=/AuxKernels
21+
22+
!syntax parameters /AuxKernels/MFEMCrossProductAux
23+
24+
!syntax inputs /AuxKernels/MFEMCrossProductAux
25+
26+
!syntax children /AuxKernels/MFEMCrossProductAux
27+
28+
!if-end!
29+
30+
!else
31+
!include mfem/mfem_warning.md
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# MFEMDotProductAux
2+
3+
!if! function=hasCapability('mfem')
4+
5+
## Summary
6+
7+
!syntax description /AuxKernels/MFEMDotProductAux
8+
9+
## Overview
10+
11+
AuxKernel for calculating the inner product of two vector fields and projecting onto an L2 finite element space mfem auxvariable.
12+
13+
!equation
14+
s u\cdot v, \,\,\,
15+
16+
where $u$ and $v$ are the two fields and $s(x)$ is an optional scaling.
17+
18+
## Example Input File Syntax
19+
20+
!listing mfem/kernels/curlcurl.i block=/AuxKernels
21+
22+
!syntax parameters /AuxKernels/MFEMDotProductAux
23+
24+
!syntax inputs /AuxKernels/MFEMDotProductAux
25+
26+
!syntax children /AuxKernels/MFEMDotProductAux
27+
28+
!if-end!
29+
30+
!else
31+
!include mfem/mfem_warning.md
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//* This file is part of the MOOSE framework
2+
//* https://mooseframework.inl.gov
3+
//*
4+
//* All rights reserved, see COPYRIGHT for full restrictions
5+
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6+
//*
7+
//* Licensed under LGPL 2.1, please see LICENSE for details
8+
//* https://www.gnu.org/licenses/lgpl-2.1.html
9+
10+
#ifdef MOOSE_MFEM_ENABLED
11+
#pragma once
12+
13+
#include "MFEMAuxKernel.h"
14+
#include "mfem.hpp"
15+
16+
/**
17+
* Project s(x) * (U x V) onto a vector MFEM auxvariable.
18+
*
19+
* Notes:
20+
* - Currently supports only interior DOFs (no shared/constrained DOFs).
21+
* - Enforces 3D: mesh dimension and all involved vdim must be 3.
22+
*/
23+
class MFEMCrossProductAux : public MFEMAuxKernel
24+
{
25+
public:
26+
static InputParameters validParams();
27+
28+
MFEMCrossProductAux(const InputParameters & parameters);
29+
~MFEMCrossProductAux() override = default;
30+
31+
void execute() override;
32+
33+
protected:
34+
/// Names of vector sources
35+
const VariableName _u_var_name;
36+
const VariableName _v_var_name;
37+
38+
/// References to the vector ParGridFunctions
39+
const mfem::ParGridFunction & _u_var;
40+
const mfem::ParGridFunction & _v_var;
41+
/// Scaling factor applied on the resulting field
42+
const mfem::real_t _scale_factor;
43+
44+
/// Coefficient wrappers
45+
mfem::VectorGridFunctionCoefficient _u_coef;
46+
mfem::VectorGridFunctionCoefficient _v_coef;
47+
mfem::VectorCrossProductCoefficient _cross_uv;
48+
mfem::ConstantCoefficient _scale_c;
49+
50+
///Final coefficient that applies the scale factor to the crossproduct
51+
mfem::ScalarVectorProductCoefficient _final_coef;
52+
};
53+
54+
#endif // MOOSE_MFEM_ENABLED
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//* This file is part of the MOOSE framework
2+
//* https://mooseframework.inl.gov
3+
//*
4+
//* All rights reserved, see COPYRIGHT for full restrictions
5+
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6+
//*
7+
//* Licensed under LGPL 2.1, please see LICENSE for details
8+
//* https://www.gnu.org/licenses/lgpl-2.1.html
9+
10+
#ifdef MOOSE_MFEM_ENABLED
11+
#pragma once
12+
13+
#include "MFEMAuxKernel.h"
14+
#include "mfem.hpp"
15+
16+
/**
17+
* Project s(x) * (U . V) onto a scalar MFEM auxvariable.
18+
*
19+
* Notes:
20+
* - Currently supports only interior DOFs (no shared/constrained DOFs).
21+
* - The target variable's FE Space must be L2.
22+
*/
23+
class MFEMDotProductAux : public MFEMAuxKernel
24+
{
25+
public:
26+
static InputParameters validParams();
27+
28+
MFEMDotProductAux(const InputParameters & parameters);
29+
~MFEMDotProductAux() override = default;
30+
31+
void execute() override;
32+
33+
protected:
34+
/// Names of vector sources
35+
const VariableName _u_var_name;
36+
const VariableName _v_var_name;
37+
38+
/// References to the vector ParGridFunctions
39+
const mfem::ParGridFunction & _u_var;
40+
const mfem::ParGridFunction & _v_var;
41+
const mfem::real_t _scale_factor;
42+
43+
/// Coefficient wrappers
44+
mfem::VectorGridFunctionCoefficient _u_coef;
45+
mfem::VectorGridFunctionCoefficient _v_coef;
46+
mfem::InnerProductCoefficient _dot_uv;
47+
mfem::ConstantCoefficient _scale_c;
48+
49+
///Final coefficient that applies the scale factor to the inner product
50+
mfem::ProductCoefficient _final_coef;
51+
};
52+
53+
#endif // MOOSE_MFEM_ENABLED

framework/include/mfem/fespaces/MFEMScalarFESpace.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class MFEMScalarFESpace : public MFEMSimplifiedFESpace
3434
private:
3535
/// Name of the family of finite element collections to use
3636
const std::string _fec_type;
37+
/// Name of the map types VALUE OR INTEGRAL to use (meaningful only for L2)
38+
const std::string _fec_map;
3739
};
3840

3941
#endif

framework/include/mfem/fespaces/MFEMVectorFESpace.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class MFEMVectorFESpace : public MFEMSimplifiedFESpace
3737

3838
/// The number of vector components in the reference space.
3939
const int _range_dim;
40+
41+
/// Name of the map types VALUE or INTEGRAL to use (meaningful only for L2)
42+
const std::string _fec_map;
4043
};
4144

4245
#endif
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//* This file is part of the MOOSE framework
2+
//* https://mooseframework.inl.gov
3+
//*
4+
//* All rights reserved, see COPYRIGHT for full restrictions
5+
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6+
//*
7+
//* Licensed under LGPL 2.1, please see LICENSE for details
8+
//* https://www.gnu.org/licenses/lgpl-2.1.html
9+
10+
#ifdef MOOSE_MFEM_ENABLED
11+
12+
#include "MFEMCrossProductAux.h"
13+
#include "MFEMProblem.h"
14+
#include "mfem.hpp"
15+
16+
registerMooseObject("MooseApp", MFEMCrossProductAux);
17+
18+
InputParameters
19+
MFEMCrossProductAux::validParams()
20+
{
21+
InputParameters params = MFEMAuxKernel::validParams();
22+
params.addClassDescription("Projects s(x) * (U x V) onto a vector MFEM auxvariable");
23+
params.addRequiredParam<VariableName>("first_source_vec", "Vector MFEMVariable U (vdim=3)");
24+
params.addRequiredParam<VariableName>("second_source_vec", "Vector MFEMVariable V (vdim=3)");
25+
params.addParam<mfem::real_t>(
26+
"scale_factor", 1.0, "Constant multiplier applied to the cross product");
27+
return params;
28+
}
29+
30+
MFEMCrossProductAux::MFEMCrossProductAux(const InputParameters & parameters)
31+
: MFEMAuxKernel(parameters),
32+
_u_var_name(getParam<VariableName>("first_source_vec")),
33+
_v_var_name(getParam<VariableName>("second_source_vec")),
34+
_u_var(*getMFEMProblem().getProblemData().gridfunctions.Get(_u_var_name)),
35+
_v_var(*getMFEMProblem().getProblemData().gridfunctions.Get(_v_var_name)),
36+
_scale_factor(getParam<mfem::real_t>("scale_factor")),
37+
_u_coef(&_u_var),
38+
_v_coef(&_v_var),
39+
_cross_uv(_u_coef, _v_coef),
40+
_scale_c(_scale_factor),
41+
_final_coef(_scale_c, _cross_uv)
42+
{
43+
// Check the target variable type and dimensions
44+
mfem::ParFiniteElementSpace * fes = _result_var.ParFESpace();
45+
const int mesh_dim = fes->GetMesh()->Dimension();
46+
47+
// Enforce 3D cross product
48+
if (mesh_dim != 3)
49+
mooseError("MFEMCrossProductAux requires a 3D mesh (Dimension == 3).");
50+
51+
if (fes->GetVDim() != 3)
52+
mooseError("MFEMCrossProductAux requires AuxVariable to have vdim == 3.");
53+
54+
// Must be L2
55+
if (!dynamic_cast<const mfem::L2_FECollection *>(fes->FEColl()))
56+
mooseError("MFEMCrossProductAux requires the target variable to use L2_FECollection.");
57+
58+
// Must have no shared/constrained DOFs (pure interior DOFs)
59+
if (fes->GetTrueVSize() != fes->GetVSize())
60+
mooseError("MFEMCrossProductAux currently supports only L2 spaces with interior DOFs "
61+
"(no shared/constrained DOFs).");
62+
}
63+
64+
void
65+
MFEMCrossProductAux::execute()
66+
{
67+
68+
// MFEM element projection for L2
69+
_result_var = 0.0;
70+
_result_var.ProjectCoefficient(_final_coef);
71+
}
72+
73+
#endif // MOOSE_MFEM_ENABLED
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//* This file is part of the MOOSE framework
2+
//* https://mooseframework.inl.gov
3+
//*
4+
//* All rights reserved, see COPYRIGHT for full restrictions
5+
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6+
//*
7+
//* Licensed under LGPL 2.1, please see LICENSE for details
8+
//* https://www.gnu.org/licenses/lgpl-2.1.html
9+
10+
#ifdef MOOSE_MFEM_ENABLED
11+
12+
#include "MFEMDotProductAux.h"
13+
#include "MFEMProblem.h"
14+
15+
registerMooseObject("MooseApp", MFEMDotProductAux);
16+
17+
InputParameters
18+
MFEMDotProductAux::validParams()
19+
{
20+
InputParameters params = MFEMAuxKernel::validParams();
21+
params.addClassDescription("Project s(x) * (U . V) onto a scalar MFEM auxvariable.");
22+
params.addRequiredParam<VariableName>("first_source_vec", "Vector MFEMVariable U");
23+
params.addRequiredParam<VariableName>("second_source_vec", "Vector MFEMVariable V");
24+
params.addParam<mfem::real_t>(
25+
"scale_factor", 1.0, "Constant multiplier applied to the dot product");
26+
return params;
27+
}
28+
29+
MFEMDotProductAux::MFEMDotProductAux(const InputParameters & parameters)
30+
: MFEMAuxKernel(parameters),
31+
_u_var_name(getParam<VariableName>("first_source_vec")),
32+
_v_var_name(getParam<VariableName>("second_source_vec")),
33+
_u_var(*getMFEMProblem().getProblemData().gridfunctions.Get(_u_var_name)),
34+
_v_var(*getMFEMProblem().getProblemData().gridfunctions.Get(_v_var_name)),
35+
_scale_factor(getParam<mfem::real_t>("scale_factor")),
36+
_u_coef(&_u_var),
37+
_v_coef(&_v_var),
38+
_dot_uv(_u_coef, _v_coef),
39+
_scale_c(_scale_factor),
40+
_final_coef(_scale_c, _dot_uv)
41+
{
42+
// Must be L2
43+
mfem::ParFiniteElementSpace * fes = _result_var.ParFESpace();
44+
if (!dynamic_cast<const mfem::L2_FECollection *>(fes->FEColl()))
45+
paramError("variable", "The target variable must use L2_FECollection.");
46+
47+
// Must have no shared/constrained DOFs
48+
if (fes->GetTrueVSize() != fes->GetVSize())
49+
mooseError("MFEMDotProductAux currently supports only L2 spaces with interior DOFs (no "
50+
"shared/constrained DOFs).");
51+
}
52+
53+
void
54+
MFEMDotProductAux::execute()
55+
{
56+
// Project into the scalar aux result variable per element projection for L2
57+
_result_var = 0.0;
58+
_result_var.ProjectCoefficient(_final_coef);
59+
}
60+
61+
#endif // MOOSE_MFEM_ENABLED

framework/src/mfem/fespaces/MFEMScalarFESpace.C

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ MFEMScalarFESpace::validParams()
2828
basis_types,
2929
"Specifies the basis used for scalar elements. H1 spaces require a closed basis "
3030
"(GaussLobatto Positive ClosedUniform Serendipity ClosedGL)");
31+
MooseEnum fec_maps("VALUE INTEGRAL", "VALUE", true);
32+
params.addParam<MooseEnum>(
33+
"fec_map",
34+
fec_maps,
35+
"Specify the FE map type used VALUE or INTEGRAL (meaningful for L2 only)");
3136

3237
return params;
3338
}
3439

3540
MFEMScalarFESpace::MFEMScalarFESpace(const InputParameters & parameters)
36-
: MFEMSimplifiedFESpace(parameters), _fec_type(getParam<MooseEnum>("fec_type"))
41+
: MFEMSimplifiedFESpace(parameters),
42+
_fec_type(getParam<MooseEnum>("fec_type")),
43+
_fec_map(getParam<MooseEnum>("fec_map"))
3744
{
3845
}
3946

@@ -48,6 +55,10 @@ MFEMScalarFESpace::getFECName() const
4855
// This is to get around an MFEM bug (to be removed in #31525)
4956
basis = (basis == "@G" || basis == "_T0") ? "" : basis;
5057

58+
if (_fec_map == "INTEGRAL")
59+
return "L2Int" + basis + "_" + std::to_string(getProblemDim()) + "D_P" +
60+
std::to_string(_fec_order);
61+
5162
return _fec_type + basis + "_" + std::to_string(getProblemDim()) + "D_P" +
5263
std::to_string(_fec_order);
5364
}

framework/src/mfem/fespaces/MFEMVectorFESpace.C

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ MFEMVectorFESpace::validParams()
4444
"(the default) means it will be the same as the problem dimension. "
4545
"Note that MFEM does not currently support 2D vectors in 1D space "
4646
"for ND and RT elements.");
47+
MooseEnum fec_maps("VALUE INTEGRAL", "VALUE", true);
48+
params.addParam<MooseEnum>(
49+
"fec_map",
50+
fec_maps,
51+
"Specify the FE map type used VALUE or INTEGRAL (meaningful for L2 only)");
52+
4753
return params;
4854
}
4955

@@ -88,6 +94,11 @@ MFEMVectorFESpace::getFECName() const
8894
// This is to get around an MFEM bug (to be removed in #31525)
8995
basis = (basis == "@Gg" || basis == "@G" || basis == "_T0") ? "" : basis;
9096

97+
if (_fec_map == "INTEGRAL" && _fec_type == "L2")
98+
{
99+
return "L2Int" + basis + "_" + std::to_string(pdim) + "D_P" + std::to_string(_fec_order);
100+
}
101+
91102
return actual_type + basis + "_" + std::to_string(pdim) + "D_P" + std::to_string(_fec_order);
92103
}
93104

0 commit comments

Comments
 (0)