46 int integrate (
const double t_start,
const double t_end,
const double pr,
double* y) {
49 #ifdef CONST_TIME_STEP 50 double h = t_end - t_start;
52 double h = fmin(1.0e-8, t_end - t_start);
69 #ifdef LOG_KRYLOV_AND_STEPSIZES 74 int len = strlen(f_name);
75 char out_name[len + 17];
76 sprintf(out_name,
"log/%s-kry-log.txt", f_name);
77 logFile = fopen(out_name,
"a");
79 char out_reject_name[len + 23];
80 sprintf(out_reject_name,
"log/%s-kry-reject.txt", f_name);
84 rFile = fopen(out_reject_name,
"a");
91 double A[
NSP *
NSP] = {0.0};
111 while ((t < t_end) && (t + h > t)) {
133 int m =
arnoldi(1.0 / 3.0,
P, h, A, fy, sc, &beta, Vm, Hm, phiHm);
162 for (
int i = 0; i <
NSP; ++i) {
164 f_temp[i] = h * ((-7.0 / 300.0) * k1[i] + (97.0 / 150.0) * k2[i] - (37.0 / 300.0) * k3[i]);
166 k4[i] = y[i] + f_temp[i];
169 dydt (t, pr, k4, temp);
173 for (
int i = 0; i <
NSP; ++i) {
174 k4[i] = temp[i] - fy[i] - k4[i];
178 int m1 =
arnoldi(1.0 / 3.0,
P, h, A, k4, sc, &beta, Vm, Hm, phiHm);
179 if (m1 +
P >=
STRIDE || m1 < 0)
205 for (
int i = 0; i <
NSP; ++i) {
207 f_temp[i] = h * ((59.0 / 300.0) * k1[i] - (7.0 / 75.0) * k2[i] + (269.0 / 300.0) * k3[i] + (2.0 / 3.0) * (k4[i] + k5[i] + k6[i]));
209 k7[i] = y[i] + f_temp[i];
212 dydt (t, pr, k7, temp);
216 for (
int i = 0; i <
NSP; ++i) {
217 k7[i] = temp[i] - fy[i] - k7[i];
220 int m2 =
arnoldi(1.0 / 3.0,
P, h, A, k7, sc, &beta, Vm, Hm, phiHm);
221 if (m2 +
P >=
STRIDE || m2 < 0)
234 for (
int i = 0; i <
NSP; ++i) {
235 y1[i] = y[i] + h * (k3[i] + k4[i] - (4.0 / 3.0) * k5[i] + k6[i] + (1.0 / 6.0) * k7[i]);
238 #ifndef CONST_TIME_STEP 239 scale (y, y1, f_temp);
247 for (
int i = 0; i <
NSP; ++i) {
248 temp[i] = k3[i] - (2.0 / 3.0) * k5[i] + 0.5 * (k6[i] + k7[i] - k4[i]) - (y1[i] - y[i]) / h;
250 err = h *
sc_norm(temp, f_temp);
254 for (
int i = 0; i <
NSP; ++i) {
255 temp[i] = -k1[i] + 2.0 * k2[i] - k4[i] + k7[i] - (y1[i] - y[i]) / h;
258 err = fmax(
EPS, fmin(err, h *
sc_norm(temp, f_temp)));
261 h_new = pow(err, -1.0 /
ORD);
266 #ifdef LOG_KRYLOV_AND_STEPSIZES 267 fprintf (logFile,
"%.15le\t%.15le\t%.15le\t%d\t%d\t%d\n", t, h, err, m, m1, m2);
271 h_new = fmin(h_new, (h / h_old) * pow((err_old / (err * err)), (1.0 /
ORD)));
274 h_new = h * fmax(fmin(0.9 * h_new, 8.0), 0.2);
277 memcpy(sc, f_temp,
NSP *
sizeof(
double));
278 memcpy(y, y1,
NSP *
sizeof(
double));
282 err_old = fmax(1.0e-2, err);
288 h_new = fmin(h, h_new);
290 h = fmin(h_new, t_end - t);
294 #ifdef LOG_KRYLOV_AND_STEPSIZES 295 fprintf (rFile,
"%.15le\t%.15le\t%.15le\t%d\t%d\t%d\n", t, h, err, m, m1, m2);
299 h_new = h * fmax(fmin(0.9 * h_new, 8.0), 0.2);
300 h_new = fmin(h_new, t_end - t);
309 for (
int i = 0; i <
NSP; ++i) {
318 #ifdef LOG_KRYLOV_AND_STEPSIZES Contains header definitions for the RHS function for the van der Pol example.
int integrate(const double t_start, const double t_end, const double pr, double *y)
4th-order exponential integrator function w/ adaptive Kyrlov subspace approximation ...
__device__ void scale_init(const double *__restrict__ y0, double *__restrict__ sc)
Get scaling for weighted norm for the initial timestep (used in krylov process)
#define P
max order of the phi functions (for error estimation)
#define EC_consecutive_steps
Maximum number of consecutive internal timesteps with error reached.
Header definition for Jacobian vector multiplier, used in exponential integrators.
void dydt(const double t, const double mu, const double *__restrict__ y, double *__restrict__ dy)
An implementation of the RHS of the van der Pol equation.
void eval_jacob(const double t, const double pres, const double *cy, double *jac)
Computes a finite difference Jacobian of order FD_ORD of the RHS function dydt at the given pressure ...
#define STRIDE
the matrix dimensions
#define MAX_STEPS
Maximum allowed internal timesteps per integration step.
Various macros controlling behaviour of EXP4 algorithm.
#define EC_success
Successful time step.
__device__ void matvec_n_by_m_scale_add(const int m, const double scale, const double *__restrict__ A, const double *__restrict__ V, double *__restrict__ Av, const double *__restrict__ add)
Matrix-vector multiplication of a matrix sized NSPxM and a vector of size Mx1 scaled by a specified f...
void sparse_multiplier(const double *A, const double *Vm, double *w)
Implements Jacobian \ vector multiplication in sparse (or unrolled) form.
__device__ void matvec_n_by_m_scale_add_subtract(const int m, const double scale, const double *__restrict__ A, const double *V, double *__restrict__ Av, const double *__restrict__ add, const double *__restrict__ sub)
Matrix-vector multiplication of a matrix sized NSPxM and a vector of size Mx1 scaled by a specified f...
__device__ void scale(const double *__restrict__ y0, const double *__restrict__ y1, double *__restrict__ sc)
Get scaling for weighted norm.
#define MAX_CONSECUTIVE_ERRORS
Number of consecutive errors on internal integration steps allowed before exit.
__device__ void matvec_m_by_m(const int m, const double *const __restrict__ A, const double *const __restrict__ V, double *const __restrict__ Av)
Matrix-vector multiplication of a matrix sized MxM and a vector Mx1.
__device__ int arnoldi(const double scale, const int p, const double h, const double *__restrict__ A, const solver_memory *__restrict__ solver, const double *__restrict__ v, double *__restrict__ beta, double *__restrict__ work, cuDoubleComplex *__restrict__ work2)
Runs the arnoldi iteration to calculate the Krylov projection.
Contains a header definition for the van der Pol Jacobian evaluation.
#define ORD
order of embedded methods
#define EC_max_steps_exceeded
Maximum number of internal timesteps exceeded.
__device__ double sc_norm(const double *__restrict__ nums, const double *__restrict__ sc)
Perform weighted norm.
const char * solver_name()
Returns a descriptive solver name.
__device__ void matvec_n_by_m_scale(const int m, const double scale, const double *const __restrict__ A, const double *const __restrict__ V, double *const __restrict__ Av)
Matrix-vector multiplication of a matrix sized NSPxM and a vector of size Mx1 scaled by a specified f...
Header definitions for solver initialization routins.
Implementation of the arnoldi iteration methods.
Implementation of various linear algebra functions needed in the exponential integrators.
#define EC_h_plus_t_equals_h
Timescale reduced such that t + h == t in floating point math.