Skip to content

Commit

Permalink
Initial conditions (idaholab#401)
Browse files Browse the repository at this point in the history
  • Loading branch information
dschwen authored and recuero committed Apr 29, 2020
1 parent 4d02241 commit b13c26e
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 24 deletions.
22 changes: 18 additions & 4 deletions include/userobjects/FFTBufferBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#pragma once

#include "GeneralUserObject.h"
#include "ElementUserObject.h"

template <typename T>
class FFTBufferBase;
Expand All @@ -17,7 +17,7 @@ class FFTBufferBase;
* Generic FFT interleaved data buffer base class
*/
template <typename T>
class FFTBufferBase : public GeneralUserObject
class FFTBufferBase : public ElementUserObject
{
public:
static InputParameters validParams();
Expand All @@ -27,14 +27,22 @@ class FFTBufferBase : public GeneralUserObject
virtual void initialize() {}
virtual void execute() {}
virtual void finalize() {}
virtual void threadJoin(const UserObject &) {}

// transforms
///@{ transforms
virtual void forward() = 0;
virtual void backward() = 0;
///@}

// data access
///@{ data access by index
const T & operator[](std::size_t i) const { return _buffer[i]; }
T & operator[](std::size_t i) { return _buffer[i]; }
///@}

///@{ data access by location
const T & operator()(const Point & p) const;
T & operator()(const Point & p);
///@}

protected:
/// get the addres of the first data element of the ith object in the bufefr
Expand Down Expand Up @@ -70,4 +78,10 @@ class FFTBufferBase : public GeneralUserObject

/// stride in units of double size
std::ptrdiff_t _stride;

/// optional moose sister variabe (to obtain IC from)
std::vector<const VariableValue *> _moose_variable;

/// cache the howMany value
const std::size_t _how_many;
};
95 changes: 75 additions & 20 deletions src/userobjects/FFTBufferBase.C
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,48 @@
/* Copyright 2017 Battelle Energy Alliance, LLC */
/* ALL RIGHTS RESERVED */
/**********************************************************************/

#include "FFTBufferBase.h"
#include "MooseTypes.h"
#include "MyTRIMMesh.h"

#include "MooseTypes.h"
#include "AuxiliarySystem.h"
#include "AllLocalDofIndicesThread.h"
#include "RankTwoTensor.h"
#include "RankThreeTensor.h"
#include "RankFourTensor.h"

#include <type_traits>

// template <>
// InputParameters
// validParams<FFTBufferBase>()
// {
// InputParameters params = validParams<GeneralUserObject>();
// params.addClassDescription("");
// return params;
// }

template <typename T>
InputParameters
FFTBufferBase<T>::validParams()
{
InputParameters params = GeneralUserObject::validParams();
InputParameters params = ElementUserObject::validParams();
params.addClassDescription("Fourier transform data buffer object.");
params.addRangeCheckedParam<std::vector<int>>(
"grid",
"grid > 0",
"Number of grid cells in each dimension to compute "
"the FFT on (can be omitted when using MyTRIMMesh)");
params.addParam<unsigned int>(
"max_h_level", 0, "Further grid refinement to apply when using MyTRIMMesh with adaptivity");
params.addCoupledVar("moose_variable",
"Optional AuxVariable to take the initial condition of the buffer from.");

// make sure we run the object on initial to apply the initial conditions
params.set<ExecFlagEnum>("execute_on") = EXEC_INITIAL;

return params;
}

template <typename T>
FFTBufferBase<T>::FFTBufferBase(const InputParameters & parameters)
: GeneralUserObject(parameters),
: ElementUserObject(parameters),
_mesh(_subproblem.mesh()),
_dim(_mesh.dimension()),
_cell_volume(1.0),
_buffer_size(1)

_buffer_size(1),
_moose_variable(coupledComponents("moose_variable")),
_how_many(howMany())
{
// make sure Real is double
static_assert(
Expand All @@ -56,6 +56,12 @@ FFTBufferBase<T>::FFTBufferBase(const InputParameters & parameters)
// FFT needs a regular grid of values to operate on
if (isParamValid("grid"))
{
// cannot specify a corresponding MOOSE Variable when running mesh-less
if (!_moose_variable.empty())
paramError("moose_variable",
"You cannot specify a corresponding MOOSE Variable when running mesh-less, i.e. "
"using the 'grid' parameter.");

// if valid use the user-supplied sampling grid
_grid = getParam<std::vector<int>>("grid");
if (_grid.size() != _dim)
Expand All @@ -72,10 +78,24 @@ FFTBufferBase<T>::FFTBufferBase(const InputParameters & parameters)
_grid.push_back(mytrim_mesh->getCellCountInDimension(i));
}

// refine grid by max_h_level powers of two
auto max_h_level = getParam<unsigned int>("max_h_level");
for (auto & count : _grid)
count = count << max_h_level;
// check optional coupled MOOSE variable (only for Real valued buffers)
if (!_moose_variable.empty())
{
if (_moose_variable.size() != _how_many)
paramError("moose_variable", "Variable needs to have ", _how_many, " components.");

for (unsigned i = 0; i < _moose_variable.size(); ++i)
{
// check
auto var = getVar("moose_variable", i);
if (var->order() != 0)
paramError("moose_variable", "Variable needs to have CONSTANT order.");
if (var->isNodal())
paramError("moose_variable", "Variable must be elemental.");

_moose_variable[i] = &coupledValue("moose_variable");
}
}

// get mesh extents and calculate space required and estimate spectrum bins
for (unsigned int i = 0; i < _dim; ++i)
Expand All @@ -98,6 +118,41 @@ FFTBufferBase<T>::FFTBufferBase(const InputParameters & parameters)
istride /= sizeof(Real);
}

template <>
void
FFTBufferBase<Real>::execute()
{
// get grid / buffer location
Point centroid = _current_elem->centroid();
std::size_t a = 0;
for (unsigned int i = 0; i < _dim; ++i)
a = a * _grid[i] + std::floor(((centroid(i) - _min_corner(i)) * _grid[i]) / _box_size(i));

// copy solution value from the variables into the buffer
for (unsigned i = 0; i < _moose_variable.size(); ++i)
_start[a * _how_many + i] = (*_moose_variable[i])[0];
}

template <typename T>
const T &
FFTBufferBase<T>::operator()(const Point & p) const
{
std::size_t a = 0;
for (unsigned int i = 0; i < _dim; ++i)
a = a * _grid[i] + std::floor(((p(i) - _min_corner(i)) * _grid[i]) / _box_size(i));
return _buffer[a];
}

template <typename T>
T &
FFTBufferBase<T>::operator()(const Point & p)
{
std::size_t a = 0;
for (unsigned int i = 0; i < _dim; ++i)
a = a * _grid[i] + std::floor(((p(i) - _min_corner(i)) * _grid[i]) / _box_size(i));
return _buffer[a];
}

template <>
Real *
FFTBufferBase<Real>::start(std::size_t i)
Expand Down

0 comments on commit b13c26e

Please sign in to comment.