From e15819ac14c8cd604fed9d4b36bce1473493da99 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Thu, 16 Jan 2020 16:51:44 -0700 Subject: [PATCH] FFT buffer base class template (#401) --- include/userobjects/FFTBufferBase.h | 63 +++++++++++ include/userobjects/FFTWBufferBase.h | 42 ++++++++ src/userobjects/FFTBufferBase.C | 152 +++++++++++++++++++++++++++ src/userobjects/FFTWBufferBase.C | 77 ++++++++++++++ 4 files changed, 334 insertions(+) create mode 100644 include/userobjects/FFTBufferBase.h create mode 100644 include/userobjects/FFTWBufferBase.h create mode 100644 src/userobjects/FFTBufferBase.C create mode 100644 src/userobjects/FFTWBufferBase.C diff --git a/include/userobjects/FFTBufferBase.h b/include/userobjects/FFTBufferBase.h new file mode 100644 index 00000000..75b8e696 --- /dev/null +++ b/include/userobjects/FFTBufferBase.h @@ -0,0 +1,63 @@ +/**********************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ +/* */ +/* Copyright 2017 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/**********************************************************************/ + +#pragma once + +#include "GeneralUserObject.h" + +template +class FFTBufferBase; + +/** + * Generic FFT interleaved data buffer base class + */ +template +class FFTBufferBase : public GeneralUserObject +{ +public: + FFTBufferBase(const InputParameters & parameters); + + virtual void initialize() {} + virtual void execute() {} + virtual void finalize() {} + + // transforms + virtual void forward() = 0; + virtual void backward() = 0; + + // data access + const T & operator[](std::size_t i) const { return _buffer[i]; } + T & operator[](std::size_t i) { return _buffer[i]; } + + // size buffer + virtual void resize(); + void resize(std::size_t ni); + void resize(std::size_t ni, std::size_t nj); + void resize(std::size_t ni, std::size_t nj, std::size_t nk); + +protected: + /// get the addres of the first data element of the ith object in the bufefr + Real * start(std::size_t i); + + /// get the number of transforms required for type T + std::size_t howMany() const; + + std::size_t _dim; + + std::size_t _ni; + std::size_t _nj; + std::size_t _nk; + + std::vector _buffer; + + /// pointer to the start of the data + Real * _start; + + /// stride in units of double size + std::ptrdiff_t _stride; +}; diff --git a/include/userobjects/FFTWBufferBase.h b/include/userobjects/FFTWBufferBase.h new file mode 100644 index 00000000..e790d357 --- /dev/null +++ b/include/userobjects/FFTWBufferBase.h @@ -0,0 +1,42 @@ +/**********************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ +/* */ +/* Copyright 2017 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/**********************************************************************/ +#ifdef FFTW3_ENABLED + +#pragma once + +#include "FFTBufferBase.h" + +#include "fftw3.h" + +template +class FFTWBufferBase; + +/** + * FFTW specific interleaved data buffer base class + */ +template +class FFTWBufferBase : public FFTBufferBase +{ +public: + FFTWBufferBase(const InputParameters & parameters); + ~FFTWBufferBase(); + + // transforms + virtual void forward(); + virtual void backward(); + + // resize buffer + void resize() override; + +protected: + /// FFTW plans + fftw_plan _forward_plan; + fftw_plan _backward_plan; +}; + +#endif diff --git a/src/userobjects/FFTBufferBase.C b/src/userobjects/FFTBufferBase.C new file mode 100644 index 00000000..6f7cbce8 --- /dev/null +++ b/src/userobjects/FFTBufferBase.C @@ -0,0 +1,152 @@ +/**********************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ +/* */ +/* Copyright 2017 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/**********************************************************************/ +#include "FFTBufferBase.h" +#include "MooseTypes.h" +#include "RankTwoTensor.h" +#include "RankThreeTensor.h" +#include "RankFourTensor.h" + +// template <> +// InputParameters +// validParams() +// { +// InputParameters params = validParams(); +// params.addClassDescription(""); +// return params; +// } + +template +FFTBufferBase::FFTBufferBase(const InputParameters & parameters) : GeneralUserObject(parameters) +{ +} + +template +void +FFTBufferBase::resize() +{ + if (sizeof(Real) != sizeof(double)) + mooseError("Invalid Real type size"); + _buffer.resize(_ni * _nj * _nk); + + // redo plan / pointers + auto istart = start(0); + std::ptrdiff_t istride = reinterpret_cast(start(1)) - reinterpret_cast(istart); + if (istride % sizeof(Real) != 0) + mooseError("Invalid data alignment"); + istride /= sizeof(Real); +} + +template +void +FFTBufferBase::resize(std::size_t ni) +{ + _ni = ni; + _nj = 1; + _nk = 1; + _dim = 1; + resize(); +} + +template +void +FFTBufferBase::resize(std::size_t ni, std::size_t nj) +{ + _ni = ni; + _nj = nj; + _nk = 1; + _dim = 2; + resize(); +} + +template +void +FFTBufferBase::resize(std::size_t ni, std::size_t nj, std::size_t nk) +{ + _ni = ni; + _nj = nj; + _nk = nk; + _dim = 3; + resize(); +} + +template <> +Real * +FFTBufferBase::start(std::size_t i) +{ + return &_buffer[i]; +} + +template <> +Real * +FFTBufferBase::start(std::size_t i) +{ + return &_buffer[i](0); +} + +template <> +Real * +FFTBufferBase::start(std::size_t i) +{ + return &_buffer[i](0, 0); +} + +template <> +Real * +FFTBufferBase::start(std::size_t i) +{ + return &_buffer[i](0, 0, 0); +} + +template <> +Real * +FFTBufferBase::start(std::size_t i) +{ + return &_buffer[i](0, 0, 0, 0); +} + +template <> +std::size_t +FFTBufferBase::howMany() const +{ + return 1; +} + +template <> +std::size_t +FFTBufferBase::howMany() const +{ + return LIBMESH_DIM; +} + +template <> +std::size_t +FFTBufferBase::howMany() const +{ + return LIBMESH_DIM * LIBMESH_DIM; +} + +template <> +std::size_t +FFTBufferBase::howMany() const +{ + return LIBMESH_DIM * LIBMESH_DIM * LIBMESH_DIM; +} + +template <> +std::size_t +FFTBufferBase::howMany() const +{ + return LIBMESH_DIM * LIBMESH_DIM * LIBMESH_DIM * LIBMESH_DIM; +} + +// explicit instantiation +template class FFTBufferBase; +template class FFTBufferBase; +template class FFTBufferBase; +template class FFTBufferBase; +template class FFTBufferBase; diff --git a/src/userobjects/FFTWBufferBase.C b/src/userobjects/FFTWBufferBase.C new file mode 100644 index 00000000..0c017b61 --- /dev/null +++ b/src/userobjects/FFTWBufferBase.C @@ -0,0 +1,77 @@ +/**********************************************************************/ +/* DO NOT MODIFY THIS HEADER */ +/* MAGPIE - Mesoscale Atomistic Glue Program for Integrated Execution */ +/* */ +/* Copyright 2017 Battelle Energy Alliance, LLC */ +/* ALL RIGHTS RESERVED */ +/**********************************************************************/ +#ifdef FFTW3_ENABLED + +#include "FFTWBufferBase.h" +#include "MooseTypes.h" +#include "RankTwoTensor.h" +#include "RankThreeTensor.h" +#include "RankFourTensor.h" + +template +FFTWBufferBase::FFTWBufferBase(const InputParameters & parameters) + : FFTBufferBase(parameters), _forward_plan(nullptr), _backward_plan(nullptr) +{ +} + +template +FFTWBufferBase::~FFTWBufferBase() +{ + // destroy FFTW plans + if (_forward_plan) + fftw_destroy_plan(_forward_plan); + if (_backward_plan) + fftw_destroy_plan(_backward_plan); +} + +template +void +FFTWBufferBase::forward() +{ + // execute plan + if (_forward_plan) + fftw_execute(_forward_plan); + else + mooseError("No forward plan created"); +} + +template +void +FFTWBufferBase::backward() +{ + // execute plan + if (_backward_plan) + fftw_execute(_backward_plan); + else + mooseError("No backward plan created"); +} + +template +void +FFTWBufferBase::resize() +{ + // call parent class to rezize data bufefr + FFTBufferBase::resize(); + + // destroy FFTW plans + if (_forward_plan) + fftw_destroy_plan(_forward_plan); + if (_backward_plan) + fftw_destroy_plan(_backward_plan); + + // create new plans using _start, _stride, and howMany() +} + +// explicit instantiation +template class FFTWBufferBase; +template class FFTWBufferBase; +template class FFTWBufferBase; +template class FFTWBufferBase; +template class FFTWBufferBase; + +#endif