HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
TimeRK.c
Go to the documentation of this file.
1 
6 #include <basic.h>
7 #if defined (HAVE_CUDA)
8 #include <arrayfunctions_gpu.h>
9 #else
10 #include <arrayfunctions.h>
11 #endif
12 #include <simulation_object.h>
13 #include <timeintegration.h>
14 #include <time.h>
15 #include <math.h>
16 
35 int TimeRK(void *ts )
36 {
37  TimeIntegration* TS = (TimeIntegration*) ts;
40  int ns, stage, i, nsims = TS->nsims;
41 
42 #if defined(HAVE_CUDA)
43  if (sim[0].solver.use_gpu) {
44 
45  /* Calculate stage values */
46  for (stage = 0; stage < params->nstages; stage++) {
47 
48  double stagetime = TS->waqt + params->c[stage]*TS->dt;
49 
50  for (ns = 0; ns < nsims; ns++) {
51  gpuArrayCopy1D( sim[ns].solver.gpu_u,
52  (TS->gpu_U + stage*TS->u_size_total + TS->u_offsets[ns]),
53  (TS->u_sizes[ns]) );
54 
55  }
56 
57  for (i = 0; i < stage; i++) {
58  gpuArrayAXPY( TS->gpu_Udot + i*TS->u_size_total,
59  (TS->dt * params->A[stage*params->nstages+i]),
60  TS->gpu_U + stage*TS->u_size_total,
61  TS->u_size_total );
62 
63  }
64 
65  for (ns = 0; ns < nsims; ns++) {
66  if (sim[ns].solver.PreStage) {
67  fprintf(stderr,"ERROR in TimeRK(): Call to solver->PreStage() commented out!\n");
68  return 1;
69 // sim[ns].solver.PreStage( stage,
70 // (TS->gpu_U),
71 // &(sim[ns].solver),
72 // &(sim[ns].mpi),
73 // stagetime ); CHECKERR(ierr);
74  }
75  }
76 
77  for (ns = 0; ns < nsims; ns++) {
78  if (sim[ns].solver.PostStage) {
79  sim[ns].solver.PostStage( (TS->gpu_U + stage*TS->u_size_total + TS->u_offsets[ns]),
80  &(sim[ns].solver),
81  &(sim[ns].mpi),
82  stagetime);
83  }
84  }
85 
86  for (ns = 0; ns < nsims; ns++) {
87  TS->RHSFunction( (TS->gpu_Udot + stage*TS->u_size_total + TS->u_offsets[ns]),
88  (TS->gpu_U + stage*TS->u_size_total + TS->u_offsets[ns]),
89  &(sim[ns].solver),
90  &(sim[ns].mpi),
91  stagetime );
92  }
93 
95 
96  for (ns = 0; ns < nsims; ns++) {
97  gpuArrayCopy1D( sim[ns].solver.StageBoundaryIntegral,
98  (TS->gpu_BoundaryFlux + stage*TS->bf_size_total + TS->bf_offsets[ns]),
99  TS->bf_sizes[ns] );
100 
101  }
102 
103  }
104 
105  /* Step completion */
106  for (stage = 0; stage < params->nstages; stage++) {
107 
108  for (ns = 0; ns < nsims; ns++) {
109  gpuArrayAXPY( (TS->gpu_Udot + stage*TS->u_size_total + TS->u_offsets[ns]),
110  (TS->dt * params->b[stage]),
111  (sim[ns].solver.gpu_u),
112  (TS->u_sizes[ns]) );
113  gpuArrayAXPY( (TS->gpu_BoundaryFlux + stage*TS->bf_size_total + TS->bf_offsets[ns]),
114  (TS->dt * params->b[stage]),
115  (sim[ns].solver.StepBoundaryIntegral),
116  (TS->bf_sizes[ns]) );
117 
118  }
119 
120  }
121 
122  } else {
123 #endif
124 
125  /* Calculate stage values */
126  for (stage = 0; stage < params->nstages; stage++) {
127 
128  double stagetime = TS->waqt + params->c[stage]*TS->dt;
129 
130  for (ns = 0; ns < nsims; ns++) {
131  _ArrayCopy1D_( sim[ns].solver.u,
132  (TS->U[stage] + TS->u_offsets[ns]),
133  (TS->u_sizes[ns]) );
134  }
135 
136  for (i = 0; i < stage; i++) {
137  _ArrayAXPY_( TS->Udot[i],
138  (TS->dt * params->A[stage*params->nstages+i]),
139  TS->U[stage],
140  TS->u_size_total );
141  }
142 
143  for (ns = 0; ns < nsims; ns++) {
144  if (sim[ns].solver.PreStage) {
145  fprintf(stderr,"ERROR in TimeRK(): Call to solver->PreStage() commented out!\n");
146  return 1;
147  // sim[ns].solver.PreStage( stage,
148  // (TS->U),
149  // &(sim[ns].solver),
150  // &(sim[ns].mpi),
151  // stagetime ); CHECKERR(ierr);
152  }
153  }
154 
155  for (ns = 0; ns < nsims; ns++) {
156  if (sim[ns].solver.PostStage) {
157  sim[ns].solver.PostStage( (TS->U[stage] + TS->u_offsets[ns]),
158  &(sim[ns].solver),
159  &(sim[ns].mpi),
160  stagetime); CHECKERR(ierr);
161  }
162  }
163 
164  for (ns = 0; ns < nsims; ns++) {
165  TS->RHSFunction( (TS->Udot[stage] + TS->u_offsets[ns]),
166  (TS->U[stage] + TS->u_offsets[ns]),
167  &(sim[ns].solver),
168  &(sim[ns].mpi),
169  stagetime);
170  }
171 
172  _ArraySetValue_(TS->BoundaryFlux[stage], TS->bf_size_total, 0.0);
173  for (ns = 0; ns < nsims; ns++) {
174  _ArrayCopy1D_( sim[ns].solver.StageBoundaryIntegral,
175  (TS->BoundaryFlux[stage] + TS->bf_offsets[ns]),
176  TS->bf_sizes[ns] );
177  }
178 
179  }
180 
181  /* Step completion */
182  for (stage = 0; stage < params->nstages; stage++) {
183 
184  for (ns = 0; ns < nsims; ns++) {
185  _ArrayAXPY_( (TS->Udot[stage] + TS->u_offsets[ns]),
186  (TS->dt * params->b[stage]),
187  (sim[ns].solver.u),
188  (TS->u_sizes[ns]) );
189  _ArrayAXPY_( (TS->BoundaryFlux[stage] + TS->bf_offsets[ns]),
190  (TS->dt * params->b[stage]),
191  (sim[ns].solver.StepBoundaryIntegral),
192  (TS->bf_sizes[ns]) );
193  }
194 
195  }
196 
197 #if defined(HAVE_CUDA)
198  }
199 #endif
200 
201  return 0;
202 }
203 
Structure of variables/parameters and function pointers for time integration.
Contains function definitions for common array operations on GPU.
#define CHECKERR(ierr)
Definition: basic.h:18
Structure defining a simulation.
double * u
Definition: hypar.h:116
Some basic definitions and macros.
Contains function declarations for time integration.
Simulation object.
void gpuArrayAXPY(const double *, double, double *, int)
int(* RHSFunction)(double *, double *, void *, void *, double)
void gpuArraySetValue(double *, int, double)
#define _ArrayAXPY_(x, a, y, size)
double * gpu_u
Definition: hypar.h:459
#define _ArraySetValue_(x, size, value)
int TimeRK(void *ts)
Definition: TimeRK.c:35
int(* PostStage)(double *, void *, void *, double)
Definition: hypar.h:336
double * StepBoundaryIntegral
Definition: hypar.h:384
Structure containing the parameters for an explicit Runge-Kutta method.
void * msti
Definition: hypar.h:366
#define _ArrayCopy1D_(x, y, size)
Contains macros and function definitions for common array operations.
void gpuArrayCopy1D(const double *, double *, int)