HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
TimeRK.c File Reference

Explicit Runge-Kutta method. More...

#include <basic.h>
#include <arrayfunctions_gpu.h>
#include <simulation_object.h>
#include <timeintegration.h>
#include <time.h>
#include <math.h>

Go to the source code of this file.

Functions

int TimeRK (void *ts)
 

Detailed Description

Explicit Runge-Kutta method.

Author
Debojyoti Ghosh, Youngdae Kim

Definition in file TimeRK.c.

Function Documentation

◆ TimeRK()

int TimeRK ( void *  ts)

Advance the ODE given by

\begin{equation} \frac{d{\bf u}}{dt} = {\bf F} \left({\bf u}\right) \end{equation}

by one time step of size HyPar::dt using the forward Euler method given by

\begin{align} {\bf U}^{\left(i\right)} &= {\bf u}_n + \Delta t \sum_{j=1}^{i-1} a_{ij} {\bf F}\left({\bf U}^{\left(j\right)}\right), \\ {\bf u}_{n+1} &= {\bf u}_n + \Delta t \sum_{i=1}^s b_{i} {\bf F}\left({\bf U}^{\left(i\right)}\right), \end{align}

where the subscript represents the time level, the superscripts represent the stages, \(\Delta t\) is the time step size HyPar::dt, and \({\bf F}\left({\bf u}\right)\) is computed by TimeIntegration::RHSFunction. The Butcher tableaux coefficients are \(a_{ij}\) (ExplicitRKParameters::A) and \(b_i\) (ExplicitRKParameters::b).

Note: In the code TimeIntegration::Udot is equivalent to \({\bf F}\left({\bf u}\right)\).

Parameters
tsObject of type TimeIntegration

Definition at line 35 of file TimeRK.c.

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 }
Structure of variables/parameters and function pointers for time integration.
#define CHECKERR(ierr)
Definition: basic.h:18
Structure defining a simulation.
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)
#define _ArraySetValue_(x, size, value)
int(* PostStage)(double *, void *, void *, double)
Definition: hypar.h:336
Structure containing the parameters for an explicit Runge-Kutta method.
void * msti
Definition: hypar.h:366
#define _ArrayCopy1D_(x, y, size)
void gpuArrayCopy1D(const double *, double *, int)