TURTLE
|
Holds field data, performs FFTs and HDF5 I/O operations. More...
#include <field.hpp>
Public Member Functions | |
field (const int nx, const int ny, const int nz, const MPI_Comm COMM_TO_USE, const unsigned FFTW_PLAN_RIGOR=DEFAULT_FFTW_FLAG) | |
~field () noexcept(false) | |
int | io (const std::string fname, const std::string field_name, const int iteration, const bool read=true) |
int | io_database (const std::string fname, const std::string field_name, const int toffset, const bool read=true) |
int | write_0slice (const hid_t group, const std::string field_name, const int iteration) |
int | write_filtered (const std::string fname, const std::string field_name, const int iteration, const int nx, const int ny, const int nz) |
int | io_binary (const std::string fname, const int iteration, const bool read=true) |
void | dft () |
void | ift () |
void | normalize () |
void | symmetrize () |
Enforce Hermitian symmetry (fast and reasonable) | |
void | symmetrize_FFT () |
Enforce Hermitian symmetry (slow, reference) | |
void | symmetrize_alternate () |
Enforce Hermitian symmetry (unoptimized, amplitude-aware) | |
void | Hermitian_reflect () |
void | compute_rspace_xincrement_stats (const int xcells, const hid_t group, const std::string dset_name, const hsize_t toffset, const std::vector< double > max_estimate, field< rnumber, be, fc > *tmp_field=NULL) |
void | compute_rspace_stats (const hid_t group, const std::string dset_name, const hsize_t toffset, const std::vector< double > max_estimate, const unsigned int maximum_moment=9) |
Compute statistics (real-space representation) | |
double | compute_CFL_velocity () |
Compute CFL velocity. | |
void | compute_rspace_zaverage (const hid_t group, const std::string dset_name, const hsize_t toffset) |
int | get_nx () const |
int | get_ny () const |
int | get_nz () const |
rnumber *__restrict__ | get_rdata () |
const rnumber *__restrict__ | get_rdata () const |
fftw_interface< rnumber >::complex *__restrict__ | get_cdata () |
fftw_interface< rnumber >::complex *__restrict__ | get_cdata () const |
rnumber & | rval (ptrdiff_t rindex, unsigned int component=0) |
const rnumber & | rval (ptrdiff_t rindex, unsigned int component=0) const |
rnumber & | rval (ptrdiff_t rindex, int comp1, int comp0) |
rnumber & | cval (ptrdiff_t cindex, int imag) |
rnumber & | cval (ptrdiff_t cindex, int component, int imag) |
rnumber & | cval (ptrdiff_t cindex, int comp1, int comp0, int imag) |
field< rnumber, be, fc > & | operator= (const typename fftw_interface< rnumber >::complex *__restrict__ source) |
field< rnumber, be, fc > & | operator= (const rnumber *__restrict__ source) |
field< rnumber, be, fc > & | operator= (const rnumber value) |
field< rnumber, be, fc > & | operator= (const field< rnumber, be, fc > &src) |
template<kspace_dealias_type dt> | |
void | compute_stats (kspace< be, dt > *kk, const hid_t group, const std::string dset_name, const hsize_t toffset, const double max_estimate) |
Compute field statistics. | |
template<kspace_dealias_type dt> | |
double | L2norm (kspace< be, dt > *kk) |
void | impose_zero_mode () |
template<class func_type > | |
void | RLOOP_simd (func_type expression) |
template<class func_type > | |
void | RLOOP (func_type expression) |
ptrdiff_t | get_cindex (ptrdiff_t xindex, ptrdiff_t yindex, ptrdiff_t zindex) |
ptrdiff_t | get_rindex (ptrdiff_t xindex, ptrdiff_t yindex, ptrdiff_t zindex) const |
ptrdiff_t | get_rindex_from_global (const ptrdiff_t in_global_x, const ptrdiff_t in_global_y, const ptrdiff_t in_global_z) const |
int | print_plan (const std::string preamble) |
Static Public Member Functions | |
static constexpr int | get_number_of_components (void) |
Data Fields | |
hsize_t | npoints |
bool | real_space_representation |
int | myrank |
int | nprocs |
MPI_Comm | comm |
field_layout< fc > * | clayout |
field_layout< fc > * | rlayout |
field_layout< fc > * | rmemlayout |
fftw_interface< rnumber >::many_plan | c2r_plan |
fftw_interface< rnumber >::many_plan | r2c_plan |
unsigned | fftw_plan_rigor |
hid_t | rnumber_H5T |
hid_t | cnumber_H5T |
Static Public Attributes | |
static constexpr int | number_of_components = ncomp(fc) |
Private Attributes | |
rnumber *__restrict__ | data |
Holds field data, performs FFTs and HDF5 I/O operations.
The purpose of this class is to manage memory for field data, create/destroy FFT plans for them, and compute HDF5 input/output operations.
FFTW recommendations are to create different plans for different arrays, hence the plans are member variables. All plans are for in-place transforms, since even with out-of-place transforms there are no guarantees that input data is not messed up by an inverse FFT, so there's no point in wasting the memory.
field< rnumber, be, fc >::field | ( | const int | nx, |
const int | ny, | ||
const int | nz, | ||
const MPI_Comm | COMM_TO_USE, | ||
const unsigned | FFTW_PLAN_RIGOR = DEFAULT_FFTW_FLAG ) |
field< rnumber, be, fc >::~field | ( | ) |
double field< rnumber, be, fc >::compute_CFL_velocity | ( | ) |
Compute CFL velocity.
For the CFL condition we need a specific "maximum" norm of the velocity field.
\[ \| u \|_{CFL} \equiv \max_{\mathbf{x}}\left(\sum_{i=1,2,3}\big(|u_i(\mathbf{x})|\big)\right) \]
void field< rnumber, be, fc >::compute_rspace_stats | ( | const hid_t | group, |
const std::string | dset_name, | ||
const hsize_t | toffset, | ||
const std::vector< double > | max_estimate, | ||
const unsigned int | maximum_moment = 9 ) |
Compute statistics (real-space representation)
void field< rnumber, be, fc >::compute_rspace_xincrement_stats | ( | const int | xcells, |
const hid_t | group, | ||
const std::string | dset_name, | ||
const hsize_t | toffset, | ||
const std::vector< double > | max_estimate, | ||
field< rnumber, be, fc > * | tmp_field = NULL ) |
void field< rnumber, be, fc >::compute_rspace_zaverage | ( | const hid_t | group, |
const std::string | dset_name, | ||
const hsize_t | toffset ) |
template void field< rnumber, be, fc >::compute_stats< SMOOTH > | ( | kspace< be, dt > * | kk, |
const hid_t | group, | ||
const std::string | dset_name, | ||
const hsize_t | toffset, | ||
const double | max_estimate ) |
Compute field statistics.
compute_rspace_stats
, as well as cospectrum
This means that there will be a Fourier transform performed at some point.compute_rspace_stats
: if the field is a vector field, the maximum estimate for the field magnitude is multiplied by sqrt(3). This is a naive attempt to account for the fact that the magnitude is larger than any 1 of the 3 components.
|
inline |
|
inline |
|
inline |
void field< rnumber, be, fc >::dft | ( | ) |
|
inline |
|
inline |
|
inline |
|
inlinestaticconstexpr |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
void field< rnumber, be, fc >::Hermitian_reflect | ( | ) |
void field< rnumber, be, fc >::ift | ( | ) |
|
inline |
int field< rnumber, be, fc >::io | ( | const std::string | fname, |
const std::string | field_name, | ||
const int | iteration, | ||
const bool | read = true ) |
int field< rnumber, be, fc >::io_binary | ( | const std::string | fname, |
const int | iteration, | ||
const bool | read = true ) |
int field< rnumber, be, fc >::io_database | ( | const std::string | fname, |
const std::string | field_name, | ||
const int | toffset, | ||
const bool | read = true ) |
template double field< rnumber, be, fc >::L2norm< SMOOTH > | ( | kspace< be, dt > * | kk | ) |
void field< rnumber, be, fc >::normalize | ( | ) |
field< rnumber, be, fc > & field< rnumber, be, fc >::operator= | ( | const field< rnumber, be, fc > & | src | ) |
field< rnumber, be, fc > & field< rnumber, be, fc >::operator= | ( | const rnumber *__restrict__ | source | ) |
field< rnumber, be, fc > & field< rnumber, be, fc >::operator= | ( | const rnumber | value | ) |
field< rnumber, be, fc > & field< rnumber, be, fc >::operator= | ( | const typename fftw_interface< rnumber >::complex *__restrict__ | source | ) |
int field< rnumber, be, fc >::print_plan | ( | const std::string | preamble | ) |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
void field< rnumber, be, fc >::symmetrize | ( | ) |
Enforce Hermitian symmetry (fast and reasonable)
TurTLE uses real-to-complex and complex-to-real FFTW transforms, because the equations are PDEs of real-valued fields. Hermitian symmetry means that Fourier-transformed real valued fields must respect the equation \(\hat f(-\mathbf{k}) = {\hat f}^*(\mathbf{k})\).
FFTW enforces this property mainly by only storing the positive half of the Fourier grid for the fastest array component. In TurTLE's case, this means \( k_x \). For the \( k_x = 0 \) plane, the symmetry must be enforced.
This method uses an arithmetic mean of the \( (0, k_y, k_z)\) mode and the conjugate of the \((0, -k_y, -k_z) \) mode to generate the desired values. The method is fast (other than the required MPI communications).
Note: the method is adequate either in cases where deviations from Hermitian symmetry are small, or in cases where deviations from correct physics is irrelevant. In practice: initial condition fields may be strongly perturbed by the application of this method, but they are unphysical anyway; during the quasistationary regime of some simulation, the method is applied regularly to all relevant fields, and deviations are expected to be small, i.e. effect on PDE approximations is negligible.
void field< rnumber, be, fc >::symmetrize_alternate | ( | ) |
Enforce Hermitian symmetry (unoptimized, amplitude-aware)
TurTLE uses real-to-complex and complex-to-real FFTW transforms, because the equations are PDEs of real-valued fields. Hermitian symmetry means that Fourier-transformed real valued fields must respect the equation \(\hat f(-\mathbf{k}) = {\hat f}^*(\mathbf{k})\).
FFTW enforces this property mainly by only storing the positive half of the Fourier grid for the fastest array component. In TurTLE's case, this means \( k_x \). For the \( k_x = 0 \) plane, the symmetry must be enforced.
This method is an alternative to the default arithmetic mean method, meant to be used in special circumstances where it is important to retain the exact amplitude of modes. Rather than an arithmetic mean, here we compute the amplitudes and phases for the \((0, k_y, k_z)\) and \((0, -k_y, -k_z)\) modes. We then compute a mean amplitude as the square root of the product of the two amplitudes, and a mean phase as the arithmetic mean of the two phases. When this method is applied to a field with fixed amplitudes, but random phases, it should preserve the spectrum of the initial field exactly.
void field< rnumber, be, fc >::symmetrize_FFT | ( | ) |
Enforce Hermitian symmetry (slow, reference)
TurTLE uses real-to-complex and complex-to-real FFTW transforms, because the equations are PDEs of real-valued fields. Hermitian symmetry means that Fourier-transformed real valued fields must respect the equation \(\hat f(-\mathbf{k}) = {\hat f}^*(\mathbf{k})\).
FFTW enforces this property mainly by only storing the positive half of the Fourier grid for the fastest array component. In TurTLE's case, this means \( k_x \). For the \( k_x = 0 \) plane, the symmetry must be enforced.
This method uses a pair of backwards-forwards FFTs, which leads to FFTW effectively imposing Hermitian symmetry. It should be used as a reference implementation to calibrate against in the general case.
int field< rnumber, be, fc >::write_0slice | ( | const hid_t | group, |
const std::string | field_name, | ||
const int | iteration ) |
int field< rnumber, be, fc >::write_filtered | ( | const std::string | fname, |
const std::string | field_name, | ||
const int | iteration, | ||
const int | nx, | ||
const int | ny, | ||
const int | nz ) |
set up counts and offsets x is easy, since only positive modes are present
three options for y: this->starts[0] <= ny/2 ny / 2 < this->starts[0] +this->clayout->subsizes[0] < this->sizes[0] - ny/2 this->starts[0] >= this->sizes[0] - ny/2 we don't care about saving the ny/2 mode, because of symmetry
for z, we need to take into account that there are both positive and negative modes
fftw_interface<rnumber>::many_plan field< rnumber, be, fc >::c2r_plan |
field_layout<fc>* field< rnumber, be, fc >::clayout |
hid_t field< rnumber, be, fc >::cnumber_H5T |
MPI_Comm field< rnumber, be, fc >::comm |
MPI communicator this fields lives in.
|
private |
data array
unsigned field< rnumber, be, fc >::fftw_plan_rigor |
int field< rnumber, be, fc >::myrank |
hsize_t field< rnumber, be, fc >::npoints |
total number of grid points. Useful for normalization.
int field< rnumber, be, fc >::nprocs |
basic MPI information.
|
staticconstexpr |
fftw_interface<rnumber>::many_plan field< rnumber, be, fc >::r2c_plan |
bool field< rnumber, be, fc >::real_space_representation |
true
if field is in real space representation.
field_layout<fc> * field< rnumber, be, fc >::rlayout |
field_layout<fc> * field< rnumber, be, fc >::rmemlayout |
hid_t field< rnumber, be, fc >::rnumber_H5T |