Skip to content

Commit 4ff3845

Browse files
committed
double buffered real to complex transform (idaholab#401)
1 parent 8aabb42 commit 4ff3845

File tree

4 files changed

+107
-222
lines changed

4 files changed

+107
-222
lines changed

include/userobjects/FFTBufferBase.h

+24-31
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,24 @@
88

99
#pragma once
1010

11+
#include "ComplexTypes.h"
1112
#include "ElementUserObject.h"
13+
#include "FFTData.h"
1214

1315
template <typename T>
1416
class FFTBufferBase;
1517

1618
#define usingFFTBufferBaseMembers \
1719
using ElementUserObject::_perf_graph; \
1820
using FFTBufferBase<T>::_dim; \
19-
using FFTBufferBase<T>::_grid; \
20-
using FFTBufferBase<T>::_buffer; \
21-
using FFTBufferBase<T>::_start; \
22-
using FFTBufferBase<T>::_stride; \
21+
using FFTBufferBase<T>::_real_space_grid; \
22+
using FFTBufferBase<T>::_reciprocal_space_grid; \
23+
using FFTBufferBase<T>::_real_space_data; \
24+
using FFTBufferBase<T>::_reciprocal_space_data; \
25+
using FFTBufferBase<T>::_real_space_data_start; \
26+
using FFTBufferBase<T>::_reciprocal_space_data_start; \
27+
using FFTBufferBase<T>::_real_space_data_stride; \
28+
using FFTBufferBase<T>::_reciprocal_space_data_stride; \
2329
using FFTBufferBase<T>::_how_many
2430

2531
/**
@@ -28,6 +34,8 @@ class FFTBufferBase;
2834
template <typename T>
2935
class FFTBufferBase : public ElementUserObject
3036
{
37+
using ComplexT = typename ComplexType<T>::type;
38+
3139
public:
3240
static InputParameters validParams();
3341

@@ -43,31 +51,20 @@ class FFTBufferBase : public ElementUserObject
4351
virtual void backward() = 0;
4452
///@}
4553

46-
///@{ data access by index
47-
const T & operator[](std::size_t i) const { return _buffer[i]; }
48-
T & operator[](std::size_t i) { return _buffer[i]; }
49-
///@}
54+
///@{ buffer access
55+
FFTData<T> & realSpace() { return _real_space_data; }
56+
FFTData<ComplexT> & reciprocalSpace() { return _reciprocal_space_data; }
57+
const FFTData<T> & realSpace() const { return _real_space_data; }
58+
const FFTData<ComplexT> & reciprocalSpace() const { return _reciprocal_space_data; }
5059

51-
///@{ data access by location
60+
///@{ real space data access by location
5261
const T & operator()(const Point & p) const;
5362
T & operator()(const Point & p);
5463
///@}
5564

56-
///@{ convenience math operators
57-
FFTBufferBase<T> & operator+=(FFTBufferBase<T> const & rhs);
58-
FFTBufferBase<T> & operator-=(FFTBufferBase<T> const & rhs);
59-
FFTBufferBase<T> & operator*=(FFTBufferBase<Real> const & rhs);
60-
FFTBufferBase<T> & operator/=(FFTBufferBase<Real> const & rhs);
61-
FFTBufferBase<T> & operator*=(Real rhs);
62-
FFTBufferBase<T> & operator/=(Real rhs);
63-
///@}
64-
6565
/// return the number of grid cells along each dimension without padding
6666
const std::vector<int> & grid() const { return _grid; }
6767

68-
/// return the number of proper grid cells without padding
69-
const std::size_t & size() const { return _grid_size; }
70-
7168
/// return the buffer dimension
7269
const unsigned int & dim() const { return _dim; }
7370

@@ -79,12 +76,6 @@ class FFTBufferBase : public ElementUserObject
7976
}
8077

8178
protected:
82-
/// get the addres of the first data element of the ith object in the bufefr
83-
Real * start(std::size_t i);
84-
85-
/// get the number of transforms required for type T
86-
std::size_t howMany() const;
87-
8879
///@{ mesh data
8980
MooseMesh & _mesh;
9081
unsigned int _dim;
@@ -103,15 +94,17 @@ class FFTBufferBase : public ElementUserObject
10394
Real _cell_volume;
10495

10596
///@{ FFT data buffer and unpadded number of grid cells
106-
std::vector<T> _buffer;
107-
std::size_t _grid_size;
97+
FFTData<T> _real_space_data;
98+
FFTData<ComplexT> _reciprocal_space_data;
10899
///@}
109100

110101
/// pointer to the start of the data
111-
Real * _start;
102+
Real * _real_space_data_start;
103+
Complex * _reciprocal_space_data_start;
112104

113105
/// stride in units of double size
114-
std::ptrdiff_t _stride;
106+
std::ptrdiff_t _real_space_data_stride;
107+
std::ptrdiff_t _reciprocal_space_data_stride;
115108

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

src/executioners/SpectralExecutionerBase.C

+27-20
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,22 @@ SpectralExecutionerBase::execute()
5757
_fe_problem.advanceState();
5858

5959
// back and forth test
60-
auto & c = getFFTBuffer<Real>("c");
61-
c.forward();
62-
auto & R = getFFTBuffer<RealVectorValue>("R");
63-
R.forward();
60+
auto & c_buffer = getFFTBuffer<Real>("c");
61+
auto c = c_buffer.realSpace();
62+
c_buffer.forward();
63+
64+
auto & R_buffer = getFFTBuffer<RealVectorValue>("R");
65+
auto R = R_buffer.realSpace();
66+
R_buffer.forward();
6467

6568
// gradient test
66-
auto & u = getFFTBuffer<Real>("u");
67-
u.forward();
68-
auto & grad_u = getFFTBuffer<RealVectorValue>("grad_u");
69-
kVectorMultiply(u, grad_u);
69+
auto & u_buffer = getFFTBuffer<Real>("u");
70+
auto u = u_buffer.realSpace();
71+
u_buffer.forward();
72+
73+
auto & grad_u_buffer = getFFTBuffer<RealVectorValue>("grad_u");
74+
auto grad_u = grad_u_buffer.realSpace();
75+
kVectorMultiply(u_buffer, grad_u_buffer);
7076

7177
_time_step = 1;
7278
_fe_problem.execute(EXEC_FINAL);
@@ -75,14 +81,15 @@ SpectralExecutionerBase::execute()
7581
_fe_problem.advanceState();
7682

7783
// back and forth test
78-
c.backward();
79-
R.backward();
84+
c_buffer.backward();
85+
R_buffer.backward();
8086
R /= 10000.0;
8187
c /= 10000.0;
8288

8389
// gradient test
84-
u.backward();
85-
grad_u.backward();
90+
u_buffer.backward();
91+
grad_u_buffer.backward();
92+
8693
u /= 10000.0;
8794
grad_u /= 100.0;
8895

@@ -93,23 +100,24 @@ SpectralExecutionerBase::execute()
93100
}
94101

95102
void
96-
SpectralExecutionerBase::kVectorMultiply(const FFTBufferBase<Real> & in,
97-
FFTBufferBase<RealVectorValue> & out) const
103+
SpectralExecutionerBase::kVectorMultiply(const FFTBufferBase<Real> & in_buffer,
104+
FFTBufferBase<RealVectorValue> & out_buffer) const
98105
{
106+
mooseAssert(in_buffer.dim() == out_buffer.dim(), "Buffer dimensions must be equal");
107+
108+
const FFTData<Complex> & in = in_buffer.reciprocalSpace();
109+
FFTData<ComplexVectorValue> & out = out_buffer.reciprocalSpace();
99110
mooseAssert(in.size() == out.size(), "Buffer sizes must be equal");
100-
mooseAssert(in.dim() == out.dim(), "Buffer dimensions must be equal");
101111

102-
const auto & grid = in.grid();
103-
switch (in.dim())
112+
const auto & grid = in_buffer.grid();
113+
switch (in_buffer.dim())
104114
{
105115
case 1:
106116
{
107117
const int ni = grid[0];
108118
for (int i = 0; i < ni; ++i)
109119
{
110120
out[i](0) = in[i] * i;
111-
out[i](1) = 0.0;
112-
out[i](2) = 0.0;
113121
}
114122
return;
115123
}
@@ -124,7 +132,6 @@ SpectralExecutionerBase::kVectorMultiply(const FFTBufferBase<Real> & in,
124132
{
125133
out[index](0) = in[index] * i;
126134
out[index](1) = in[index] * j;
127-
out[index](2) = 0.0;
128135
index++;
129136
}
130137
return;

0 commit comments

Comments
 (0)