47 int integrate (
const double t_start,
const double t_end,
const double pr,
double* y) {
50 #ifdef CONST_TIME_STEP 51 double h = t_end - t_start;
53 double h = fmin(1.0e-8, t_end - t_start);
70 #ifdef LOG_KRYLOV_AND_STEPSIZES 75 int len = strlen(f_name);
76 char out_name[len + 17];
77 sprintf(out_name,
"log/%s-kry-log.txt", f_name);
78 logFile = fopen(out_name,
"a");
80 char out_reject_name[len + 23];
81 sprintf(out_reject_name,
"log/%s-kry-reject.txt", f_name);
85 rFile = fopen(out_reject_name,
"a");
99 double A[
NSP *
NSP] = {0.0};
106 double savedActions[
NSP * 5];
108 while ((t < t_end) && (t + h > t)) {
130 for (
int i = 0; i <
NSP; ++i) {
131 gy[i] = fy[i] - gy[i];
136 int m =
arnoldi(0.5, 1, h, A, fy, sc, &beta, Vm, Hm, phiHm);
137 if (m + 1 >=
STRIDE || m < 0)
162 dydt(t, pr, temp, &savedActions[
NSP]);
166 for (
int i = 0; i <
NSP; ++i) {
167 temp[i] = savedActions[
NSP + i] - f_temp[i] - gy[i];
176 int m1 =
arnoldi(1.0, 4, h, A, temp, sc, &beta, Vm, Hm, phiHm);
177 if (m1 + 4 >=
STRIDE || m1 < 0)
189 const double* in[5] = {&phiHm[(m1 + 2) *
STRIDE], &phiHm[(m1 + 3) *
STRIDE], &phiHm[m1 *
STRIDE], savedActions, y};
190 double* out[3] = {&savedActions[
NSP], &savedActions[2 *
NSP], temp};
191 double scale_vec[3] = {beta / (h * h), beta / (h * h * h), beta};
197 dydt(t, pr, temp, &savedActions[3 *
NSP]);
201 for (
int i = 0; i <
NSP; ++i) {
202 temp[i] = savedActions[3 *
NSP + i] - f_temp[i] - gy[i];
207 int m2 =
arnoldi(1.0, 4, h, A, temp, sc, &beta, Vm, Hm, phiHm);
208 if (m2 + 4 >=
STRIDE || m2 < 0)
217 out[0] = &savedActions[3 *
NSP];
218 out[1] = &savedActions[4 *
NSP];
219 in[0] = &phiHm[(m2 + 2) *
STRIDE];
220 in[1] = &phiHm[(m2 + 3) *
STRIDE];
221 scale_vec[0] = beta / (h * h);
222 scale_vec[1] = beta / (h * h * h);
227 for (
int i = 0; i <
NSP; ++i) {
229 y1[i] = y[i] + savedActions[i] + 16.0 * savedActions[
NSP + i] - 48.0 * savedActions[2 *
NSP + i] + -2.0 * savedActions[3 *
NSP + i] + 12.0 * savedActions[4 *
NSP + i];
231 temp[i] = 48.0 * savedActions[2 *
NSP + i] - 12.0 * savedActions[4 *
NSP + i];
235 #ifndef CONST_TIME_STEP 237 scale (y, y1, f_temp);
241 h_new = pow(err, -1.0 /
ORD);
246 #ifdef LOG_KRYLOV_AND_STEPSIZES 247 fprintf (logFile,
"%.15le\t%.15le\t%.15le\t%d\t%d\t%d\n", t, h, err, m, m1, m2);
250 memcpy(sc, f_temp,
NSP *
sizeof(
double));
253 h_new = fmin(h_new, (h / h_old) * pow((err_old / (err * err)), (1.0 /
ORD)));
256 h_new = h * fmax(fmin(0.9 * h_new, 8.0), 0.2);
260 for (
int i = 0; i <
NSP; ++i) {
267 err_old = fmax(1.0e-2, err);
273 h_new = fmin(h, h_new);
275 h = fmin(h_new, t_end - t);
280 #ifdef LOG_KRYLOV_AND_STEPSIZES 281 fprintf (rFile,
"%.15le\t%.15le\t%.15le\t%d\t%d\t%d\n", t, h, err, m, m1, m2);
285 h_new = h * fmax(fmin(0.9 * h_new, 8.0), 0.2);
286 h_new = fmin(h_new, t_end - t);
294 for (
int i = 0; i <
NSP; ++i) {
303 #ifdef LOG_KRYLOV_AND_STEPSIZES
Contains header definitions for the RHS function for the van der Pol example.
__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 EC_consecutive_steps
Maximum number of consecutive internal timesteps with error reached.
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 ...
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.
const char * solver_name()
Returns a descriptive solver name.
__device__ void matvec_n_by_m_scale_special2(const int m, const double *__restrict__ scale, const double *__restrict__ A, double *const __restrict__ *V, double *__restrict__ *Av)
Matrix-vector multiplication of a matrix sized NSPxM and a vector of size Mx1 scaled by a specified f...
#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.
Various macros controlling behaviour of EXPRB43 algorithm.
__device__ void scale(const double *__restrict__ y0, const double *__restrict__ y1, double *__restrict__ sc)
Get scaling for weighted norm.
__device__ void matvec_m_by_m_plusequal(const int m, const double *const __restrict__ A, const double *const __restrict__ V, double *const __restrict__ Av)
Matrix-vector plus equals for a matrix of size MxM and vector of size Mx1. That is, it returns (A + I) * v.
__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
__device__ void matvec_n_by_m_scale_special(const int m, const double *__restrict__ scale, const double *__restrict__ A, double *const __restrict__ *V, double *__restrict__ *Av)
Matrix-vector multiplication of a matrix sized NSPxM and a vector of size Mx1 scaled by a specified f...
#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.
__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.