Skip to content

Commit

Permalink
Added support for scalar variables in ParsedFunction
Browse files Browse the repository at this point in the history
(closes idaholab#5041)
  • Loading branch information
aeslaughter committed May 14, 2015
1 parent 6e7ed3f commit f81fa6c
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 20 deletions.
12 changes: 11 additions & 1 deletion framework/include/functions/MooseParsedFunctionWrapper.h
Expand Up @@ -48,7 +48,8 @@ class MooseParsedFunctionWrapper
MooseParsedFunctionWrapper(FEProblem & feproblem,
const std::string & function_str,
const std::vector<std::string> & vars,
const std::vector<std::string> & vals);
const std::vector<std::string> & vals,
const THREAD_ID tid = 0);

/**
* Class destruction
Expand Down Expand Up @@ -103,9 +104,18 @@ class MooseParsedFunctionWrapper
/// Vector of pointers to PP values
std::vector<Real *> _pp_vals;

/// Stores the relative location of variables (in _vars) that are connected to Postprocessors
std::vector<unsigned int> _scalar_index;

/// Vector of pointers to PP values
std::vector<Real *> _scalar_vals;

/// Vector of pointers to the variables in libMesh::ParsedFunction
std::vector<Real *> _addr;

/// The thread id passed from owning Function object
const THREAD_ID _tid;

/**
* Initialization method that prepares the vars and vals for use
* by the libMesh::ParsedFunction object allocated in the constructor
Expand Down
5 changes: 5 additions & 0 deletions framework/src/base/FEProblem.C
Expand Up @@ -401,11 +401,16 @@ void FEProblem::initialSetup()
_user_objects(EXEC_CUSTOM)[i].initialSetup();
}

// Initialize scalars so they are properly sized for use as input into ParsedFunctions
for (THREAD_ID tid = 0; tid < n_threads; tid++)
reinitScalars(tid);

// Call the initialSetup methods for functions
for (unsigned int i=0; i<n_threads; i++)
for (std::map<std::string, MooseSharedPointer<Function> >::iterator vit = _functions[i].begin(); vit != _functions[i].end(); ++vit)
vit->second->initialSetup();


if (!_app.isRecovering())
{
for (unsigned int i = 0; i < n_threads; i++)
Expand Down
8 changes: 7 additions & 1 deletion framework/src/functions/MooseParsedFunction.C
Expand Up @@ -65,5 +65,11 @@ void
MooseParsedFunction::initialSetup()
{
if (_function_ptr == NULL)
_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _value, _vars, _vals);
{
THREAD_ID tid = 0;
if (isParamValid("_tid"))
tid = getParam<THREAD_ID>("_tid");

_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _value, _vars, _vals, tid);
}
}
36 changes: 31 additions & 5 deletions framework/src/functions/MooseParsedFunctionWrapper.C
Expand Up @@ -17,21 +17,25 @@
MooseParsedFunctionWrapper::MooseParsedFunctionWrapper(FEProblem & feproblem,
const std::string & function_str,
const std::vector<std::string> & vars,
const std::vector<std::string> & vals) :
const std::vector<std::string> & vals,
const THREAD_ID tid) :
_feproblem(feproblem),
_function_str(function_str),
_vars(vars),
_vals_input(vals)
_vals_input(vals),
_tid(tid)
{
// Initialize (prepares Postprocessor values)
initialize();

// Create the libMesh::ParsedFunction
_function_ptr = new ParsedFunction<Real,RealGradient>(_function_str, &_vars, &_vals);

// Loop through the Postprocessor variables and point the libMesh::ParsedFunction to the PostprocessorValue
// Loop through the Postprocessor and Scalar variables and point the libMesh::ParsedFunction to the PostprocessorValue
for (unsigned int i = 0; i < _pp_index.size(); ++i)
_addr.push_back(&_function_ptr->getVarAddress(_vars[_pp_index[i]]));
for (unsigned int i = 0; i < _scalar_index.size(); ++i)
_addr.push_back(&_function_ptr->getVarAddress(_vars[_scalar_index[i]]));
}

MooseParsedFunctionWrapper::~MooseParsedFunctionWrapper()
Expand Down Expand Up @@ -108,16 +112,35 @@ MooseParsedFunctionWrapper::initialize()
// Case when a Postprocessor is found by the name given in the input values
if (_feproblem.hasPostprocessor(_vals_input[i]))
{
// The PP value
Real & pp_val = _feproblem.getPostprocessorValue(_vals_input[i]);

// Store a pointer to the Postprocessor value
_pp_vals.push_back(&_feproblem.getPostprocessorValue(_vals_input[i]));
_pp_vals.push_back(&pp_val);

// Store the value for passing to the the libMesh::ParsedFunction
_vals.push_back(_feproblem.getPostprocessorValue(_vals_input[i]));
_vals.push_back(pp_val);

// Store the location of this variable
_pp_index.push_back(i);
}

// Case when a scalar variable is bound by the naem given in the input vales
else if (_feproblem.hasScalarVariable(_vals_input[i]))
{
// The scalar variable
Real & scalar_val = _feproblem.getScalarVariable(_tid, _vals_input[i]).sln()[0];

// Store a pointer to the scalar value
_scalar_vals.push_back(&scalar_val);

// Store the value for passing to the the libMesh::ParsedFunction
_vals.push_back(scalar_val);

// Store the location of this variable
_scalar_index.push_back(i);
}

// Case when a Real is supplied, convert std::string to Real
else
{
Expand All @@ -135,4 +158,7 @@ MooseParsedFunctionWrapper::update()
{
for (unsigned int i = 0; i < _pp_index.size(); ++i)
(*_addr[i]) = (*_pp_vals[i]);

for (unsigned int i = 0; i < _scalar_index.size(); ++i)
(*_addr[i]) = (*_scalar_vals[i]);
}
8 changes: 6 additions & 2 deletions framework/src/functions/MooseParsedGradFunction.C
Expand Up @@ -68,9 +68,13 @@ MooseParsedGradFunction::vectorValue(Real /*t*/, const Point & /*p*/)
void
MooseParsedGradFunction::initialSetup()
{
THREAD_ID tid = 0;
if (isParamValid("_tid"))
tid = getParam<THREAD_ID>("_tid");
if (_function_ptr == NULL)
_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _value, _vars, _vals);
_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _value, _vars, _vals, tid);
if (_grad_function_ptr == NULL)
_grad_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _grad_value, _vars, _vals);
_grad_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _grad_value, _vars, _vals, tid);
}
8 changes: 7 additions & 1 deletion framework/src/functions/MooseParsedVectorFunction.C
Expand Up @@ -56,5 +56,11 @@ void
MooseParsedVectorFunction::initialSetup()
{
if (_function_ptr == NULL)
_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _vector_value, _vars, _vals);
{
THREAD_ID tid = 0;
if (isParamValid("_tid"))
tid = getParam<THREAD_ID>("_tid");
_function_ptr = new MooseParsedFunctionWrapper(_pfb_feproblem, _vector_value, _vars, _vals, tid);
}
}
Binary file added test/tests/functions/parsed/gold/scalar_out.e
Binary file not shown.
83 changes: 83 additions & 0 deletions test/tests/functions/parsed/scalar.i
@@ -0,0 +1,83 @@
[Mesh]
type = GeneratedMesh
dim = 2
nx = 10
ny = 10
[]

[Variables]
[./u]
[../]
[]

[AuxVariables]
[./scalar]
family = SCALAR
initial_condition = 0
[../]
[]

[Kernels]
[./diff]
type = CoefDiffusion
variable = u
coef = 0.1
[../]
[./time]
type = TimeDerivative
variable = u
[../]
[]

[AuxScalarKernels]
[./scalar_aux]
type = FunctionScalarAux
variable = scalar
function = func
[../]
[]

[BCs]
[./left]
type = FunctionDirichletBC
variable = u
boundary = left
function = left_bc
[../]
[./right]
type = DirichletBC
variable = u
boundary = right
value = 1
[../]
[]

[Functions]
[./left_bc]
type = ParsedFunction
value = s
vals = scalar
vars = s
[../]
[./func]
type = ParsedFunction
value = t
[../]
[]

[Executioner]
# Preconditioned JFNK (default)
type = Transient
num_steps = 5
solve_type = PJFNK
petsc_options_iname = '-pc_type -pc_hypre_type'
petsc_options_value = 'hypre boomeramg'
[]

[Outputs]
output_initial = true
exodus = true
print_linear_residuals = true
print_perf_log = true
[]

27 changes: 17 additions & 10 deletions test/tests/functions/parsed/tests
Expand Up @@ -4,15 +4,22 @@
input = 'steady.i'
exodiff = 'steady_out.e'
[../]
[./transient]
type = 'Exodiff'
input = 'mms_transient_coupled.i'
exodiff = 'mms_transient_coupled_out.e'
max_threads = 1 # Diffs with threads
[../]
[./vector]
type = 'Exodiff'
input = 'vector_function.i'
exodiff = 'vector_function_out.e'
[./transient]
type = 'Exodiff'
input = 'mms_transient_coupled.i'
exodiff = 'mms_transient_coupled_out.e'
max_threads = 1 # Diffs with threads
[../]
[./vector]
type = 'Exodiff'
input = 'vector_function.i'
exodiff = 'vector_function_out.e'
[../]

[./scalar]
# Test the use of scalar variables within a ParsedFunction
type = Exodiff
input = scalar.i
exodiff = 'scalar_out.e'
[../]
[]

0 comments on commit f81fa6c

Please sign in to comment.