Langevin C++ source
Loading...
Searching...
No Matches
sim_dplangevin_private.cpp
Go to the documentation of this file.
1
5
6#include "sim_dplangevin.hpp"
7
8double round(const double value, const int n_decimals) {
9 const double multiplier = std::pow(10, n_decimals);
10 return std::round(value * multiplier) / multiplier;
11}
12
13
16{
17 int n_epochs;
18 double t;
19 for (
20 n_epochs=0, t=0;
21 t<p.t_final;
22 t=round(t+p.dt, n_decimals), n_epochs++
23 ) {}
24 return n_epochs+1;
25}
26
28{
29 switch (p.integration_method)
30 {
31 case (IntegrationMethod::RUNGE_KUTTA):
33 return true;
34 case (IntegrationMethod::EULER):
36 return true;
37 default:
38 return false;
39 }
40}
41
42bool SimDP::integrate(const int n_next_epochs)
43{
44 // Check a further n_next_epochs won't exceed total permitted steps
45 if (t_epochs.size() < i_next_epoch+n_next_epochs)
46 {
47 std::cout << "Too many epochs: "
48 << t_epochs.size()
49 << " < "
50 << i_next_epoch+n_next_epochs
51 << std::endl;
52 return false;
53 }
54
55 // Perform (possibly another another) n_next_epochs integration steps
56 int i;
57 double t;
58 // For the very first epoch, record mean density right now
59 if (i_next_epoch==1) {
60 dpLangevin->apply_boundary_conditions(p, 0);
61 mean_densities[0] = dpLangevin->get_mean_density();
64 }
65 // Loop over integration steps.
66 // Effectively increment epoch counter and add to Δt to time counter
67 // so that both point the state *after* each integration step is complete.
68 // In so doing, we will record t_epochs.size() + 1 total integration steps.
69 for (
71 i<i_next_epoch+n_next_epochs;
72 t=round(t+p.dt, n_decimals), i++
73 )
74 {
75 // Reapply boundary conditions prior to integrating
76 dpLangevin->apply_boundary_conditions(p, i);
77 // Perform a single integration over Δt
79 // Record this epoch
80 t_epochs[i] = t;
81 mean_densities[i] = dpLangevin->get_mean_density();
84 };
85 // Set epoch and time counters to point to *after* the last integration step
86 i_next_epoch = i;
87 t_next_epoch = t;
88 return true;
89}
90
92{
93 py_array_t epochs_array(n_epochs);
94 auto epochs_proxy = epochs_array.mutable_unchecked();
95 for (auto i=0; i<n_epochs; i++)
96 {
97 epochs_proxy(i) = t_epochs[i];
98 };
99 pyarray_t_epochs = epochs_array;
100 return true;
101}
102
104{
105 py_array_t mean_densities_array(n_epochs);
106 auto mean_densities_proxy = mean_densities_array.mutable_unchecked();
107 for (auto i=0; i<n_epochs; i++)
108 {
109 mean_densities_proxy(i) = mean_densities[i];
110 };
111 pyarray_mean_densities = mean_densities_array;
112 return true;
113}
114
116{
117 if (not (p.n_cells == p.n_x * p.n_y * p.n_z))
118 {
119 std::cout << "prep_density: grid size problem" << std::endl;
120 return false;
121 }
122 // Assume we're working with a <=2d grid for now
123 py_array_t density_array({p.n_x, p.n_y});
124 auto density_proxy = density_array.mutable_unchecked();
125 for (auto i=0; i<p.n_cells; i++)
126 {
127 int x = i % p.n_x;
128 int y = i / p.n_x;
129 density_proxy(x, y) = dpLangevin->get_density_grid_value(i);
130 };
131 pyarray_density = density_array;
132 return true;
133}
void integrate_rungekutta(rng_t &rng)
Runge-Kutta + stochastic integration + grid update.
void integrate_euler(rng_t &rng)
Explicit Euler + stochastic integration + grid update.
int i_current_epoch
Index of current epoch aka time step.
int i_next_epoch
Index of next epoch aka time step.
Parameters p
Model simulation parameters.
py_array_t pyarray_t_epochs
Python-compatible array of epochs time-series.
dbl_vec_t mean_densities
Vector time-series of grid-averaged field density values.
int count_epochs() const
Count upcoming number of epochs by running a dummy time-stepping loop.
bool choose_integrator()
Chooses function implementing either Runge-Kutta or Euler integration methods.
double t_next_epoch
Time of next epoch.
void(DPLangevin::* integrator)(rng_t &)
Integrator: either a Runge-Kutta or an Euler method.
bool pyprep_mean_densities()
Generate a Python-compatible version of the mean densities time-series vector.
int n_epochs
Total number of simulation time steps aka "epochs".
dbl_vec_t t_epochs
Vector time-series of epochs.
py_array_t pyarray_density
Python-compatible array of current density grid.
py_array_t pyarray_mean_densities
Python-compatible array of mean density time-series.
bool pyprep_t_epochs()
Generate a Python-compatible version of the epochs time-series vector.
int n_decimals
Truncation number of decimal places when summing Δt.
DPLangevin * dpLangevin
Instance of DP Langevin integrator class (pointer to instance)
bool pyprep_density_grid()
Generate a Python-compatible version of the current density grid.
rng_t * rng
Random number generation function (Mersenne prime) (pointer to RNG)
bool integrate(const int n_next_epochs)
Perform Dornic-type integration of the DP Langevin equation for n_next_epochs
double t_current_epoch
Time of current epoch.
py::array_t< double, py::array::c_style > py_array_t
Type for Python arrays of doubles.
Class that manages simulation of DPLangevin equation.