NekScalarValue

Description

The NekScalarValue class sends a scalar value between NekRS and MOOSE. This can be used to control NekRS simulations using MOOSE's Controls system or stochastically perturb NekRS simulations using the MOOSE stochastic tools module. Passing a number can also be used for much more general purposes (anywhere that a scalar value appears in NekRS's .udf or .oudf files).

Example Input File Syntax

Below is an example input file that defines two scalar transfers that we will use to control a NekRS boundary condition from MOOSE using the Controls system.

[Problem<<<{"href": "../../syntax/Problem/index.html"}>>>]
  type = NekRSProblem
  casename<<<{"description": "Case name for the NekRS input files; this is <case> in <case>.par, <case>.udf, <case>.oudf, and <case>.re2."}>>> = 'pyramid'
  n_usrwrk_slots<<<{"description": "Number of slots to allocate in nrs->usrwrk to hold fields either related to coupling (which will be populated by Cardinal), or other custom usages, such as a distance-to-wall calculation"}>>> = 1

  [ScalarTransfers<<<{"href": "../../syntax/Problem/ScalarTransfers/index.html"}>>>]
    [scalar1]
      type = NekScalarValue<<<{"description": "Transfers a scalar value into NekRS"}>>>
      direction<<<{"description": "Direction in which to send data"}>>> = to_nek
      usrwrk_slot<<<{"description": "When 'direction = to_nek', the slot in the usrwrk array to write the incoming data"}>>> = 0
    []
    [scalar2]
      type = NekScalarValue<<<{"description": "Transfers a scalar value into NekRS"}>>>
      direction<<<{"description": "Direction in which to send data"}>>> = to_nek
      usrwrk_slot<<<{"description": "When 'direction = to_nek', the slot in the usrwrk array to write the incoming data"}>>> = 0
    []
  []
[]
(test/tests/transfers/nek_scalar_value/nek.i)

We will control the value in each of these parameters using a RealFunctionControl, a MOOSE object that lets us define a scalar value using a function. Here, we will use a simple constant value function, which changes value partway through the simulation.

[Controls<<<{"href": "../../syntax/Controls/index.html"}>>>]
  [func_control]
    type = RealFunctionControl<<<{"description": "Sets the value of a 'Real' input parameters to the value of a provided function.", "href": "../controls/RealFunctionControl.html"}>>>
    parameter<<<{"description": "The input parameter(s) to control. Specify a single parameter name and all parameters in all objects matching the name will be updated"}>>> = 'Problem/ScalarTransfers/scalar1/value'
    function<<<{"description": "The function to use for controlling the specified parameter."}>>> = 'val'
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'timestep_begin'
  []
  [func_control2]
    type = RealFunctionControl<<<{"description": "Sets the value of a 'Real' input parameters to the value of a provided function.", "href": "../controls/RealFunctionControl.html"}>>>
    parameter<<<{"description": "The input parameter(s) to control. Specify a single parameter name and all parameters in all objects matching the name will be updated"}>>> = 'Problem/ScalarTransfers/scalar2/value'
    function<<<{"description": "The function to use for controlling the specified parameter."}>>> = 'val2'
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'timestep_begin'
  []
[]

[Functions<<<{"href": "../../syntax/Functions/index.html"}>>>]
  [val]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../functions/MooseParsedFunction.html"}>>>
    expression<<<{"description": "The user defined function."}>>> = 'if (t > 1, 200.0, 100.0)'
  []
  [val2]
    type = ParsedFunction<<<{"description": "Function created by parsing a string", "href": "../functions/MooseParsedFunction.html"}>>>
    expression<<<{"description": "The user defined function."}>>> = 'if (t > 1, 400.0, 300.0)'
  []
[]
(test/tests/transfers/nek_scalar_value/nek.i)

When running the input file, you will then see a table like the following print:


-------------------
| Slot | MOOSE quantity |          How to Access (.oudf)          |         How to Access (.udf)          |
-----------------------------------------------------------------------------------------------------------
|    0 | scalar1        | bc->usrwrk[0 * bc->fieldOffset + 0]     | nrs->usrwrk[0 * nrs->fieldOffset + 0] |
|    0 | scalar2        | bc->usrwrk[0 * bc->fieldOffset + 1]     | nrs->usrwrk[0 * nrs->fieldOffset + 1] |
|    1 | unused         | bc->usrwrk[1 * bc->fieldOffset+bc->idM] | nrs->usrwrk[1 * nrs->fieldOffset + n] |
|    2 | unused         | bc->usrwrk[2 * bc->fieldOffset+bc->idM] | nrs->usrwrk[2 * nrs->fieldOffset + n] |
|    3 | unused         | bc->usrwrk[3 * bc->fieldOffset+bc->idM] | nrs->usrwrk[3 * nrs->fieldOffset + n] |
|    4 | unused         | bc->usrwrk[4 * bc->fieldOffset+bc->idM] | nrs->usrwrk[4 * nrs->fieldOffset + n] |
|    5 | unused         | bc->usrwrk[5 * bc->fieldOffset+bc->idM] | nrs->usrwrk[5 * nrs->fieldOffset + n] |
|    6 | unused         | bc->usrwrk[6 * bc->fieldOffset+bc->idM] | nrs->usrwrk[6 * nrs->fieldOffset + n] |
-----------------------------------------------------------------------------------------------------------

Suppose we want to use these two scalar values to set a Dirichlet temperature boundary condition in NekRS. We would simply follow the instructions for the .oudf, and do:

void scalarDirichletConditions(bcData *bc)
{
  // note: when running with Cardinal, Cardinal will allocate the usrwrk
  // array. If running with NekRS standalone (e.g. nrsmpi), you need to
  // replace the usrwrk with some other value or allocate it youself from
  // the udf and populate it with values.
  if (bc->id == 5)
    bc->s = bc->usrwrk[0 * bc->fieldOffset + 0]; // this is the value of scalar1
  else if (bc->id == 6)
    bc->s = bc->usrwrk[0 * bc->fieldOffset + 1]; // this is the value of scalar2
}

void scalarNeumannConditions(bcData *bc)
{
  bc->flux = 0.0;
}
(test/tests/transfers/nek_scalar_value/pyramid.oudf)

Input Parameters

  • directionDirection in which to send data

    C++ Type:MooseEnum

    Options:to_nek, from_nek

    Controllable:No

    Description:Direction in which to send data

Required Parameters

  • output_postprocessorName of the postprocessor to output the value sent into NekRS

    C++ Type:PostprocessorName

    Unit:(no unit assumed)

    Controllable:No

    Description:Name of the postprocessor to output the value sent into NekRS

  • scaling1Multiplier on the value passed into NekRS

    Default:1

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:No

    Description:Multiplier on the value passed into NekRS

  • usrwrk_slotWhen 'direction = to_nek', the slot in the usrwrk array to write the incoming data

    C++ Type:unsigned int

    Controllable:No

    Description:When 'direction = to_nek', the slot in the usrwrk array to write the incoming data

  • value0Scalar value to pass into NekRS

    Default:0

    C++ Type:double

    Unit:(no unit assumed)

    Controllable:Yes

    Description:Scalar value to pass into NekRS

Optional Parameters

  • control_tagsAdds user-defined labels for accessing object parameters via control logic.

    C++ Type:std::vector<std::string>

    Controllable:No

    Description:Adds user-defined labels for accessing object parameters via control logic.

  • enableTrueSet the enabled status of the MooseObject.

    Default:True

    C++ Type:bool

    Controllable:No

    Description:Set the enabled status of the MooseObject.

Advanced Parameters

Input Files