From 0aca3999091e4ad37b3106953d3536e5439daae4 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Mon, 20 Jan 2020 16:24:08 -0700 Subject: [PATCH] Initial conditions (#401) --- include/userobjects/FFTBufferBase.h | 22 +++++-- src/userobjects/FFTBufferBase.C | 95 +++++++++++++++++++++++------ 2 files changed, 93 insertions(+), 24 deletions(-) diff --git a/include/userobjects/FFTBufferBase.h b/include/userobjects/FFTBufferBase.h index b328fe43..2ff31511 100644 --- a/include/userobjects/FFTBufferBase.h +++ b/include/userobjects/FFTBufferBase.h @@ -8,7 +8,7 @@ #pragma once -#include "GeneralUserObject.h" +#include "ElementUserObject.h" template class FFTBufferBase; @@ -17,7 +17,7 @@ class FFTBufferBase; * Generic FFT interleaved data buffer base class */ template -class FFTBufferBase : public GeneralUserObject +class FFTBufferBase : public ElementUserObject { public: static InputParameters validParams(); @@ -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 @@ -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 _moose_variable; + + /// cache the howMany value + const std::size_t _how_many; }; diff --git a/src/userobjects/FFTBufferBase.C b/src/userobjects/FFTBufferBase.C index 44d77ce6..b004930b 100644 --- a/src/userobjects/FFTBufferBase.C +++ b/src/userobjects/FFTBufferBase.C @@ -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 -// template <> -// InputParameters -// validParams() -// { -// InputParameters params = validParams(); -// params.addClassDescription(""); -// return params; -// } - template InputParameters FFTBufferBase::validParams() { - InputParameters params = GeneralUserObject::validParams(); + InputParameters params = ElementUserObject::validParams(); params.addClassDescription("Fourier transform data buffer object."); params.addRangeCheckedParam>( "grid", "grid > 0", "Number of grid cells in each dimension to compute " "the FFT on (can be omitted when using MyTRIMMesh)"); - params.addParam( - "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("execute_on") = EXEC_INITIAL; + return params; } template FFTBufferBase::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( @@ -56,6 +56,12 @@ FFTBufferBase::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>("grid"); if (_grid.size() != _dim) @@ -72,10 +78,24 @@ FFTBufferBase::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("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) @@ -98,6 +118,41 @@ FFTBufferBase::FFTBufferBase(const InputParameters & parameters) istride /= sizeof(Real); } +template <> +void +FFTBufferBase::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 +const T & +FFTBufferBase::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 +T & +FFTBufferBase::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::start(std::size_t i)