|
svMultiPhysics
|
Fourier interpolation of time dependent data. More...
#include <FourierInterpolation.h>
Public Member Functions | |
| FourierInterpolation ()=default | |
| Default constructor. | |
| void | distribute (const CmMod &cm_mod, const cmType &cm) |
| Distribute the data to all parallel processes. | |
| Vector< double > | value (double time) const |
| Return the interpolated value at a given time. | |
| std::pair< Vector< double >, Vector< double > > | value_and_derivative (double time) const |
| Return the interpolated value and its time derivative at a given time. | |
Data member access. | |
| bool | defined () const |
| Return whether this object has been initialized. | |
| unsigned int | get_n_components () const |
| Get the dimension of the data interpolated by this object. | |
| unsigned int | get_n_fourier_coefficients () const |
| Get the number of Fourier coefficients used by this object. | |
| double | get_linear_trend_initial_value (unsigned int component) const |
| Get the initial value of the linear trend part for one component. | |
| double | get_linear_trend_slope (unsigned int component) const |
| Get the slope of the linear trend part for one component. | |
| double | get_coefficient_real (unsigned int component, unsigned int frequency) const |
| Get the real part of the Fourier coefficients for one component. | |
| double | get_coefficient_imaginary (unsigned int component, unsigned int frequency) const |
| Get the imaginary part of the Fourier coefficients for one component. | |
Static Public Member Functions | |
| static FourierInterpolation | from_time_series (const unsigned int n_fourier_coefficients, const Vector< double > ×, const Array< double > &values, bool use_ramp) |
| Construct a FourierInterpolation from a time series. | |
| static FourierInterpolation | from_time_series_file (const std::string &file_name, unsigned int n_components, bool use_ramp) |
| Read a time series from file and return the corresponding instance of FourierInterpolation. | |
| static FourierInterpolation | from_fourier_coefficients (const Vector< double > &linear_trend_initial_values, const Vector< double > &linear_trend_slopes, const Array< double > &fourier_coefficients_real, const Array< double > &fourier_coefficients_imaginary, double initial_time, double period) |
| Construct a FourierInterpolation from Fourier coefficients. | |
| static FourierInterpolation | from_fourier_coefficients_file (const std::string &file_name, unsigned int n_components) |
| Read Fourier coefficients from file and return the corresponding FourierInterpolation instance. | |
Fourier interpolation of time dependent data.
This class implements interpolation of time dependent data through either a Fourier series or a linear clamped ramp. Which of the two is used is determined by the boolean member variable use_ramp.
In what follows, let \(\{t_i, \mathbf{v}_i\}_{i=0}^{N-1}\) be the interpolated time series, and \(T = t_{N-1} - t_0\) be the period of the time series. The time series is assumed to be ordered, i.e. \(t_i < t_{i+1}\) for all \(i\).
The FourierInterpolation class is not meant to be constructed directly, but rather through one of the static methods from_time_series, from_time_series_file, from_fourier_coefficients, or from_fourier_coefficients_file.
If data is only read from the master rank in a parallel setting, the method distribute can be used to broadcast the data to all ranks.
Once the object has been constructed, the interpolated value at a given time can be obtained through the method value, and the interpolated value and its time derivative can be obtained through the method value_and_derivative.
This gives rise to a periodic interpolation, with period \(T\). Let \(M\) be the user-defined number of Fourier modes. The interpolated value at time \(t\) is given by
\[ \begin{aligned} \tilde{\mathbf{v}}(t) &= \underbrace{\mathbf{q}_i + \mathbf{q}_s \tau(t)}_{\text{linear trend}} + \underbrace{ \sum_{k=0}^{M-1} \left( \mathbf{c}_k^{\text{real}} \cos\left(\frac{2 \pi k \tau(t)}{T}\right) - \mathbf{c}_k^{\text{imag}} \sin\left(\frac{2 \pi k \tau(t)}{T}\right) \right) }_{\text{Fourier series}} \\ \tau(t) &= (t - t_0)\;\text{mod}\;T \end{aligned} \]
The coefficients of the linear trend and Fourier series are determined from the input time series as follows:
\[ \begin{aligned} \mathbf{q}_i &= \mathbf{v}_0 \\ \mathbf{q}_s &= \frac{\mathbf{v}_{N-1} - \mathbf{v}_0}{T} \\ \mathbf{c}_0^{\text{real}} &= \frac{1}{2T} \sum_{i=0}^{N-2} (\hat{t}_{i+1} - \hat{t}_i) (\hat{\mathbf{v}}_{i+1} + \hat{\mathbf{v}}_i) \\ \mathbf{c}_0^{\text{imag}} &= 0 \\ \mathbf{c}_k^{\text{real}} &= \frac{T}{2 \pi^2 k^2} \sum_{i=0}^{N-2} \frac{\hat{\mathbf{v}}_{i+1} - \hat{\mathbf{v}}_i} {\hat{t}_{i+1} - \hat{t}_i} \left( \cos\left(\frac{2 \pi k \hat{t}_{i+1}}{T}\right) - \cos\left(\frac{2 \pi k \hat{t}_i}{T}\right) \right) \\ \mathbf{c}_k^{\text{imag}} &= \frac{T}{2 \pi^2 k^2} -\sum_{i=0}^{N-2} \frac{\hat{\mathbf{v}}_{i+1} - \hat{\mathbf{v}}_i} {\hat{t}_{i+1} - \hat{t}_i} \left( \sin\left(\frac{2 \pi k \hat{t}_{i+1}}{T}\right) - \sin\left(\frac{2 \pi k \hat{t}_i}{T}\right) \right) \end{aligned} \]
The quantities \(\hat{t}_i\) and \(\hat{\mathbf{v}}_i\) are the time and value series after subtracting the linear trend:
\[ \begin{aligned} \hat{t}_i &= t_i - t_0 \\ \hat{\mathbf{v}}_i &= \mathbf{v}_i - \mathbf{q}_i - \mathbf{q}_s \hat{t}_i \end{aligned} \]
The interpolated value is equal to \(\mathbf{v}_0\) until time \(t_0\), then it follows a linear ramp from \(\mathbf{v}_0\) to \(\mathbf{v}_{N-1}\) at \(t_{N-1}\), and then it remains constant at \(\mathbf{v}_{N-1}\) for all times greater than \(t_{N-1}\). Notice in particular that this interpolation is not periodic.
The interpolated value is given by
\[ \tilde{\mathbf{v}}(t) = \begin{cases} \mathbf{v}_0 & t < t_0 \\ \mathbf{v}_0 + \frac{\mathbf{v}_{N-1} - \mathbf{v}_0}{t_{N-1} - t_0} (t - t_0) & t_0 \leq t < t_{N-1} \\ \mathbf{v}_{N-1} & t \geq t_{N-1} \end{cases} \]
This is equivalent to only taking the linear trend part of the Fourier series interpolation, and clamping the time to the interval \([t_0, t_{N-1}]\).
|
default |
Default constructor.
This constructor is not meant to be used directly, and is only here to facilitate storing objects of this type in STL containers. The object constructed this way is not initialized and will not be usable until it is assigned to a valid FourierInterpolation instance. Use the static methods from_time_series, from_time_series_file, from_fourier_coefficients, or from_fourier_coefficients_file to construct a valid instance.
| bool FourierInterpolation::defined | ( | ) | const |
Return whether this object has been initialized.
Distribute the data to all parallel processes.
Broadcasts the data contained in this object from the master rank to all other ranks. This is necessary if only the master rank initializes the object (e.g. by reading its data from a file), but all ranks need to use it.
| [in] | cm_mod | The communication module to use for the broadcast. |
| [in] | cm | The communicator to use for the broadcast. |
|
static |
Construct a FourierInterpolation from Fourier coefficients.
This method bypasses the computation of the Fourier coefficients from a time series, and construct the instance directly from precomputed coefficients.
This construction method always sets use_ramp to false, and therefore always constructs a periodic interpolation.
| [in] | linear_trend_initial_values | The initial values \(\mathbf{q}_i\) of the linear trend part of the interpolation, with one entry for each component. |
| [in] | linear_trend_slopes | The slopes \(\mathbf{q}_s\) of the linear trend part of the interpolation, with one entry for each component. |
| [in] | fourier_coefficients_real | The real part \(\mathbf{c}_k^\text{real}\) of the Fourier interpolation. This is a 2D array, for which the first index selects the component and the second index selects the Fourier mode. |
| [in] | fourier_coefficients_imaginary | The imaginary part \(\mathbf{c}_k^\text{imag}\) of the Fourier interpolation. This is a 2D array, for which the first index selects the component and the second index selects the Fourier mode. |
| [in] | initial_time | The initial time \(t_0\) of the interpolation. |
| [in] | period | The period \(T\) of the interpolation. |
|
static |
Read Fourier coefficients from file and return the corresponding FourierInterpolation instance.
The input file is expected to have the following format:
where c_r and c_i are the real and imaginary parts of the Fourier coefficients.
| [in] | file_name | The name of the file to read. An exception will be thrown if the file cannot be opened. |
| [in] | n_components | The number of components of the data to be interpolated. This is used to check the correctness of the file format, and an exception will be thrown if the check fails. |
|
static |
Construct a FourierInterpolation from a time series.
| [in] | n_fourier_coefficients | The number \(M\) of Fourier modes to use in the interpolation. |
| [in] | times | The time points \(t_i\) of the time series. It must be a vector in strictly ascending order, and an exception will be thrown otherwise. |
| [in] | values | The values \(\mathbf{v}_i\) of the time series. It must be a 2D array with one row for each component and one column for each time point. The number of columns must match the size of times, and an exception will be thrown otherwise. |
| [in] | use_ramp | Whether to use a ramp function for the interpolation. See the general class documentation for the precise meaning of this choice. |
|
static |
Read a time series from file and return the corresponding instance of FourierInterpolation.
The input file is expected to have the following format:
| [in] | file_name | The name of the file to read. An exception will be thrown if the file cannot be opened. |
| [in] | n_components | The number of components of the data to be interpolated. If any row in the file does not have this number of entries (plus one entry for the time), an exception will be thrown. |
| [in] | use_ramp | Whether to use a ramp function for the interpolation. See the general class documentation for the precise meaning of this choice. If this parameter is set to true, then the number of Fourier coefficients in the file will be ignored, and the time points except the first and last will have no effect. |
| double FourierInterpolation::get_coefficient_imaginary | ( | unsigned int | component, |
| unsigned int | frequency | ||
| ) | const |
Get the imaginary part of the Fourier coefficients for one component.
| double FourierInterpolation::get_coefficient_real | ( | unsigned int | component, |
| unsigned int | frequency | ||
| ) | const |
Get the real part of the Fourier coefficients for one component.
| double FourierInterpolation::get_linear_trend_initial_value | ( | unsigned int | component | ) | const |
Get the initial value of the linear trend part for one component.
| double FourierInterpolation::get_linear_trend_slope | ( | unsigned int | component | ) | const |
Get the slope of the linear trend part for one component.
| unsigned int FourierInterpolation::get_n_components | ( | ) | const |
Get the dimension of the data interpolated by this object.
| unsigned int FourierInterpolation::get_n_fourier_coefficients | ( | ) | const |
Get the number of Fourier coefficients used by this object.
| Vector< double > FourierInterpolation::value | ( | double | time | ) | const |
Return the interpolated value at a given time.
Refer to the general class documentation for details on how the returned value is computed.
| [in] | time | The time at which to evaluate the interpolation. |
| std::pair< Vector< double >, Vector< double > > FourierInterpolation::value_and_derivative | ( | double | time | ) | const |
Return the interpolated value and its time derivative at a given time.
Refer to the general class documentation for details on how the returned value is computed.
| [in] | time | The time at which to evaluate the interpolation. |