accelerInt  v0.1
arnoldi.h
Go to the documentation of this file.
1 
11 #ifndef ARNOLDI_H
12 #define ARNOLDI_H
13 
14 #include <string.h>
15 
16 #include "header.h"
17 #include "phiAHessenberg.h"
19 #include "sparse_multiplier.h"
20 #include "solver_options.h"
21 #include "solver_props.h"
22 
23 //#define EXACT_KRYLOV
24 
26 static int index_list[23] = {1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 17, 21, 27, 34, 42, 53, 67, 84, 106, 133, 167, 211, 265};
27 
29 
45 static inline
46 int arnoldi(const double scale, const int p, const double h, const double* A, const double* v, const double* sc, double* beta, double* Vm, double* Hm, double* phiHm)
47 {
48  //the temporary work array
49  double w[NSP];
50 
51  //first place A*fy in the Vm matrix
52  *beta = normalize(v, Vm);
53 
54  double store = 0;
55  int index = 0;
56  int j = 0;
57  double err = 2.0;
58 
59  while(err > 1.0)
60  {
61 
62  for (; j < index_list[index] && j + p < STRIDE; j++)
63  {
64  sparse_multiplier(A, &Vm[j * NSP], w);
65  for (int i = 0; i <= j; i++)
66  {
67  Hm[j * STRIDE + i] = dotproduct(w, &Vm[i * NSP]);
68  scale_subtract(Hm[j * STRIDE + i], &Vm[i * NSP], w);
69  }
70  Hm[j * STRIDE + j + 1] = two_norm(w);
71  if (fabs(Hm[j * STRIDE + j + 1]) < ATOL)
72  {
73  //happy breakdown
74  j++;
75  break;
76  }
77  scale_mult(1.0 / Hm[j * STRIDE + j + 1], w, &Vm[(j + 1) * NSP]);
78  }
79 #ifndef CONST_TIME_STEP
80  if (j + p >= STRIDE)
81  return j;
82 #else
83  if (j + p >= STRIDE)
84  j = STRIDE - p - 1;
85 #endif
86  index++;
87  //resize Hm to be mxm, and store Hm(m, m + 1) for later
88  store = Hm[(j - 1) * STRIDE + j];
89  Hm[(j - 1) * STRIDE + j] = 0.0;
90 
91  //0. fill potentially non-empty memory first
92  memset(&Hm[j * STRIDE], 0, (j + 2) * sizeof(double));
93 
94  //get error
95  //1. Construct augmented Hm (fill in identity matrix)
96  Hm[(j) * STRIDE] = 1.0;
97 
98  for (int i = 1; i < p; i++)
99  {
100  //0. fill potentially non-empty memory first
101  memset(&Hm[(j + i) * STRIDE], 0, (j + i + 2) * sizeof(double));
102  Hm[(j + i) * STRIDE + (j + i - 1)] = 1.0;
103  }
104 
105 #ifdef RB43
106  //2. Get phiHm
107  int info = expAc_variable (j + p, Hm, h * scale, phiHm);
108 #elif EXP4
109  //2. Get phiHm
110  int info = phiAc_variable (j + p, Hm, h * scale, phiHm);
111 #endif
112  if (info != 0)
113  {
114  return -info;
115  }
116 
117  //3. Get error
118  err = h * (*beta) * fabs(store * phiHm[(j) * STRIDE + (j) - 1]) * sc_norm(&Vm[(j) * NSP], sc);
119 
120  //restore Hm(m, m + 1)
121  Hm[(j - 1) * STRIDE + j] = store;
122  //restore real Hm (NOTE: untested in RB43)
123  Hm[(j) * STRIDE] = 0.0;
124 
125 #if defined(LOG_OUTPUT) && defined(EXACT_KRYLOV)
126  //kill the error such that we will continue
127  //and greatly reduce the subspace approximation error
128  if (index_list[index] + p < STRIDE && fabs(Hm[(j - 1) * STRIDE + j]) >= ATOL)
129  {
130  err = 10;
131  }
132 #endif
133 #ifdef CONST_TIME_STEP
134  if (j == STRIDE - p - 1)
135  break;
136 #endif
137 
138  }
139 
140  return j;
141 }
142 
143 #endif
__device__ double dotproduct(const double *__restrict__ w, const double *__restrict__ Vm)
Performs the dot product of the w (NSP x 1) vector with the given subspace vector (NSP x 1) ...
__device__ void scale_subtract(const double s, const double *__restrict__ Vm, double *__restrict__ w)
Subtracts Vm scaled by s from w.
An example header file that defines system size and other required methods for integration of the van...
int expAc_variable(const int m, const double *A, const double c, double *phiA)
Compute the zeroth order Phi (exponential) matrix function. This is the regular matrix exponential...
Header definition for Jacobian vector multiplier, used in exponential integrators.
#define NSP
The IVP system size.
Definition: header.cuh:20
#define STRIDE
the matrix dimensions
A file generated by Scons that specifies various options to the solvers.
__device__ void scale_mult(const double s, const double *__restrict__ w, double *__restrict__ Vm)
Sets Vm to s * w.
int phiAc_variable(const int m, const double *A, const double c, double *phiA)
Compute the first order Phi (exponential) matrix function.
__device__ double normalize(const double *__restrict__ v, double *__restrict__ v_out)
Normalize the input vector using a 2-norm.
Header for Matrix exponential (phi) methods.
void sparse_multiplier(const double *A, const double *Vm, double *w)
Implements Jacobian \ vector multiplication in sparse (or unrolled) form.
#define ATOL
__device__ void scale(const double *__restrict__ y0, const double *__restrict__ y1, double *__restrict__ sc)
Get scaling for weighted norm.
simple convenience file to include the correct solver properties file
static int index_list[23]
The list of indicies to check the Krylov projection error at.
Definition: arnoldi.h:26
static int arnoldi(const double scale, const int p, const double h, const double *A, const double *v, const double *sc, double *beta, double *Vm, double *Hm, double *phiHm)
Runs the arnoldi iteration to calculate the Krylov projection.
Definition: arnoldi.h:46
__device__ double sc_norm(const double *__restrict__ nums, const double *__restrict__ sc)
Perform weighted norm.
Implementation of various linear algebra functions needed in the exponential integrators.
__device__ double two_norm(const double *__restrict__ v)
Computes and returns the two norm of a vector.