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

Initializes the WENO-type schemes. More...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arrayfunctions_gpu.h>
#include <interpolation.h>
#include <mpivars.h>
#include <hypar.h>

Go to the source code of this file.

Functions

int WENOFifthOrderInitializeWeights (double *const, double *const, double *const, const int *const, int, void *, void *)
 
int WENOFifthOrderCalculateWeights (double *, double *, double *, int, void *, void *)
 
int WENOFifthOrderCalculateWeightsChar (double *, double *, double *, int, void *, void *)
 
int gpuWENOFifthOrderCalculateWeights (double *, double *, double *, int, void *, void *)
 
int WENOInitialize (void *s, void *m, char *scheme, char *type)
 

Detailed Description

Initializes the WENO-type schemes.

Author
Debojyoti Ghosh, Youngdae Kim

Definition in file WENOInitialize.c.

Function Documentation

◆ WENOFifthOrderInitializeWeights()

int WENOFifthOrderInitializeWeights ( double *const  a_w1,
double *const  a_w2,
double *const  a_w3,
const int *const  a_offset,
int  dir,
void *  s,
void *  m 
)

This function initializes the arrays to store the nonlinear weights for fifth order WENO-type schemes to their optimal values (i.e. values of the weights for a perfectly smooth solution). 5th order methods need three weights at each grid interface.

Notes:

  • The three weights at all the grid interfaces along all the dimensions are stored in three big arrays (WENOParameters::w1, WENOParameters::w2, WENOParameters::w3), one for each weight.
  • This function initializes the values for the spatial dimension given by the input dir.
  • offset indicates the location in WENOParameters::w1,WENOParameters::w2, and WENOParameters::w3 from where the chunk of memory with the weights for the spatial dimension dir starts.
  • This chunk of memory (1D array) represents a multidimensional array of the following size: 4 X (number of interfaces) X (number of solution components HyPar::nvars). The factor 4 comes from the fact that the array stores weights for the interpolation of left-biased flux function, left-biased solution, right-biased flux function, and right-biased solution, one after the other, in this order.
  • The weights are initialized to their optimal values so that, if no limiting is specified (WENOParameters::no_limiting = 1), then no further computation of weights are required.
Parameters
a_w1Weight array
a_w2Weight array
a_w3Weight array
a_offsetOffset array
dirSpatial dimension
sSolver object of type HyPar
mMPI object of type MPIVariables

Definition at line 33 of file WENOFifthOrderInitializeWeights.c.

41 {
42  HyPar *solver = (HyPar*) s;
43  WENOParameters *weno = (WENOParameters*) solver->interp;
44  MPIVariables *mpi = (MPIVariables*) m;
45  int done;
46  double *ww1, *ww2, *ww3;
47 
48 
49  int ndims = solver->ndims;
50  int nvars = solver->nvars;
51  int *dim = solver->dim_local;
52 
53  /* calculate dimension offset */
54  int offset = a_offset[dir];
55 
56  /* create index and bounds for the outer loop, i.e., to loop over all 1D lines along
57  dimension "dir" */
58  int indexI[ndims], index_outer[ndims], bounds_outer[ndims], bounds_inter[ndims];
59  _ArrayCopy1D_(dim,bounds_outer,ndims); bounds_outer[dir] = 1;
60  _ArrayCopy1D_(dim,bounds_inter,ndims); bounds_inter[dir] += 1;
61 
62  /* calculate weights for a left-biased interpolation */
63  ww1 = a_w1 + offset;
64  ww2 = a_w2 + offset;
65  ww3 = a_w3 + offset;
66  done = 0; _ArraySetValue_(index_outer,ndims,0);
67  while (!done) {
68  _ArrayCopy1D_(index_outer,indexI,ndims);
69  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
70  int p, v;
71  _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
72  for (v=0; v<nvars; v++) {
73  /* optimal weights*/
74  double c1, c2, c3;
75  if (!strcmp(solver->spatial_scheme_hyp,_FIFTH_ORDER_CRWENO_)) {
76  if ( ((mpi->ip[dir] == 0 ) && (indexI[dir] == 0 ))
77  || ((mpi->ip[dir] == mpi->iproc[dir]-1) && (indexI[dir] == dim[dir])) ) {
78  /* Use WENO5 at the physical boundaries */
82  } else {
83  /* CRWENO5 at the interior points */
87  }
88  } else {
89  /* WENO5 and HCWENO5 */
93  }
94 
95  /* save the weights */
96  *(ww1+p*nvars+v) = c1;
97  *(ww2+p*nvars+v) = c2;
98  *(ww3+p*nvars+v) = c3;
99  }
100  }
101  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
102  }
103 
104  ww1 = a_w1 + weno->size + offset;
105  ww2 = a_w2 + weno->size + offset;
106  ww3 = a_w3 + weno->size + offset;
107  done = 0; _ArraySetValue_(index_outer,ndims,0);
108  while (!done) {
109  _ArrayCopy1D_(index_outer,indexI,ndims);
110  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
111  int p, v;
112  _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
113  for (v=0; v<nvars; v++) {
114 
115  /* optimal weights*/
116  double c1, c2, c3;
117  if (!strcmp(solver->spatial_scheme_hyp,_FIFTH_ORDER_CRWENO_)) {
118  if ( ((mpi->ip[dir] == 0 ) && (indexI[dir] == 0 ))
119  || ((mpi->ip[dir] == mpi->iproc[dir]-1) && (indexI[dir] == dim[dir])) ) {
120  /* Use WENO5 at the physical boundaries */
124  } else {
125  /* CRWENO5 at the interior points */
129  }
130  } else {
131  /* WENO5 and HCWENO5 */
135  }
136 
137  /* save the weights */
138  *(ww1+p*nvars+v) = c1;
139  *(ww2+p*nvars+v) = c2;
140  *(ww3+p*nvars+v) = c3;
141  }
142  }
143  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
144  }
145 
146  /* calculate weights for a right-biased interpolation */
147  ww1 = a_w1 + 2*weno->size + offset;
148  ww2 = a_w2 + 2*weno->size + offset;
149  ww3 = a_w3 + 2*weno->size + offset;
150  done = 0; _ArraySetValue_(index_outer,ndims,0);
151  while (!done) {
152  _ArrayCopy1D_(index_outer,indexI,ndims);
153  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
154  int p, v;
155  _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
156  for (v=0; v<nvars; v++) {
157 
158  /* optimal weights*/
159  double c1, c2, c3;
160  if (!strcmp(solver->spatial_scheme_hyp,_FIFTH_ORDER_CRWENO_)) {
161  if ( ((mpi->ip[dir] == 0 ) && (indexI[dir] == 0 ))
162  || ((mpi->ip[dir] == mpi->iproc[dir]-1) && (indexI[dir] == dim[dir])) ) {
163  /* Use WENO5 at the physical boundaries */
167  } else {
168  /* CRWENO5 at the interior points */
172  }
173  } else {
174  /* WENO5 and HCWENO5 */
178  }
179 
180  /* save the weights */
181  *(ww1+p*nvars+v) = c1;
182  *(ww2+p*nvars+v) = c2;
183  *(ww3+p*nvars+v) = c3;
184  }
185  }
186  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
187  }
188 
189  ww1 = a_w1 + 2*weno->size + weno->size + offset;
190  ww2 = a_w2 + 2*weno->size + weno->size + offset;
191  ww3 = a_w3 + 2*weno->size + weno->size + offset;
192  done = 0; _ArraySetValue_(index_outer,ndims,0);
193  while (!done) {
194  _ArrayCopy1D_(index_outer,indexI,ndims);
195  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
196  int p, v;
197  _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
198  for (v=0; v<nvars; v++) {
199 
200  /* optimal weights*/
201  double c1, c2, c3;
202  if (!strcmp(solver->spatial_scheme_hyp,_FIFTH_ORDER_CRWENO_)) {
203  if ( ((mpi->ip[dir] == 0 ) && (indexI[dir] == 0 ))
204  || ((mpi->ip[dir] == mpi->iproc[dir]-1) && (indexI[dir] == dim[dir])) ) {
205  /* Use WENO5 at the physical boundaries */
209  } else {
210  /* CRWENO5 at the interior points */
214  }
215  } else {
216  /* WENO5 and HCWENO5 */
220  }
221 
222  /* save the weights */
223  *(ww1+p*nvars+v) = c1;
224  *(ww2+p*nvars+v) = c2;
225  *(ww3+p*nvars+v) = c3;
226  }
227  }
228  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
229  }
230 
231  return(0);
232 }
#define _CRWENO_OPTIMAL_WEIGHT_1_
int nvars
Definition: hypar.h:29
#define _WENO_OPTIMAL_WEIGHT_2_
#define _CRWENO_OPTIMAL_WEIGHT_2_
int ndims
Definition: hypar.h:26
#define _CRWENO_OPTIMAL_WEIGHT_3_
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
char spatial_scheme_hyp[_MAX_STRING_SIZE_]
Definition: hypar.h:84
#define _WENO_OPTIMAL_WEIGHT_1_
#define _ArrayIndex1D_(N, imax, i, ghost, index)
Structure of variables/parameters needed by the WENO-type scheme.
#define _ArraySetValue_(x, size, value)
int * dim_local
Definition: hypar.h:37
void * interp
Definition: hypar.h:362
#define _ArrayIncrementIndex_(N, imax, i, done)
#define _FIFTH_ORDER_CRWENO_
Definition: interpolation.h:28
#define _WENO_OPTIMAL_WEIGHT_3_
Structure of MPI-related variables.
#define _ArrayCopy1D_(x, y, size)

◆ WENOFifthOrderCalculateWeights()

int WENOFifthOrderCalculateWeights ( double *  fC,
double *  uC,
double *  x,
int  dir,
void *  s,
void *  m 
)

Compute the nonlinear weights for 5th order WENO-type schemes. This function is a wrapper that calls the appropriate function, depending on the type of WENO weights.

Parameters
fCArray of cell-centered values of the function \({\bf f}\left({\bf u}\right)\)
uCArray of cell-centered values of the solution \({\bf u}\)
xGrid coordinates
dirSpatial dimension along which to interpolation
sObject of type HyPar containing solver-related variables
mObject of type MPIVariables containing MPI-related variables

Definition at line 40 of file WENOFifthOrderCalculateWeights.c.

48 {
49  HyPar *solver = (HyPar*) s;
50  WENOParameters *weno = (WENOParameters*) solver->interp;
51  MPIVariables *mpi = (MPIVariables*) m;
52 
53  int ret;
54 
55  if (weno->yc) ret = WENOFifthOrderCalculateWeightsYC (fC,uC,x,dir,solver,mpi);
56  else if (weno->borges) ret = WENOFifthOrderCalculateWeightsZ (fC,uC,x,dir,solver,mpi);
57  else if (weno->mapped) ret = WENOFifthOrderCalculateWeightsM (fC,uC,x,dir,solver,mpi);
58  else ret = WENOFifthOrderCalculateWeightsJS (fC,uC,x,dir,solver,mpi);
59 
60  return ret;
61 }
static int WENOFifthOrderCalculateWeightsZ(double *, double *, double *, int, void *, void *)
static int WENOFifthOrderCalculateWeightsM(double *, double *, double *, int, void *, void *)
static int WENOFifthOrderCalculateWeightsJS(double *, double *, double *, int, void *, void *)
static int WENOFifthOrderCalculateWeightsYC(double *, double *, double *, int, void *, void *)
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
Structure of variables/parameters needed by the WENO-type scheme.
void * interp
Definition: hypar.h:362
Structure of MPI-related variables.

◆ WENOFifthOrderCalculateWeightsChar()

int WENOFifthOrderCalculateWeightsChar ( double *  fC,
double *  uC,
double *  x,
int  dir,
void *  s,
void *  m 
)

Compute the nonlinear weights for 5th order WENO-type schemes. This function is a wrapper that calls the appropriate function, depending on the type of WENO weights.

Parameters
fCArray of cell-centered values of the function \({\bf f}\left({\bf u}\right)\)
uCArray of cell-centered values of the solution \({\bf u}\)
xGrid coordinates
dirSpatial dimension along which to interpolation
sObject of type HyPar containing solver-related variables
mObject of type MPIVariables containing MPI-related variables

Definition at line 66 of file WENOFifthOrderCalculateWeights.c.

74 {
75  HyPar *solver = (HyPar*) s;
76  WENOParameters *weno = (WENOParameters*) solver->interp;
77  MPIVariables *mpi = (MPIVariables*) m;
78 
79  if (weno->yc) return(WENOFifthOrderCalculateWeightsCharYC (fC,uC,x,dir,solver,mpi));
80  else if (weno->borges) return(WENOFifthOrderCalculateWeightsCharZ (fC,uC,x,dir,solver,mpi));
81  else if (weno->mapped) return(WENOFifthOrderCalculateWeightsCharM (fC,uC,x,dir,solver,mpi));
82  else return(WENOFifthOrderCalculateWeightsCharJS (fC,uC,x,dir,solver,mpi));
83 }
static int WENOFifthOrderCalculateWeightsCharJS(double *, double *, double *, int, void *, void *)
static int WENOFifthOrderCalculateWeightsCharZ(double *, double *, double *, int, void *, void *)
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
static int WENOFifthOrderCalculateWeightsCharM(double *, double *, double *, int, void *, void *)
static int WENOFifthOrderCalculateWeightsCharYC(double *, double *, double *, int, void *, void *)
Structure of variables/parameters needed by the WENO-type scheme.
void * interp
Definition: hypar.h:362
Structure of MPI-related variables.

◆ gpuWENOFifthOrderCalculateWeights()

int gpuWENOFifthOrderCalculateWeights ( double *  ,
double *  ,
double *  ,
int  ,
void *  ,
void *   
)

◆ WENOInitialize()

int WENOInitialize ( void *  s,
void *  m,
char *  scheme,
char *  type 
)

This function initializes the WENO-type methods.

  • Sets the parameters to default values.
  • Reads in the parameters from optional input file "weno.inp", if available.
  • Allocates memory for and initializes the nonlinear weights used by WENO-type schemes.
Parameters
sSolver object of type HyPar
mMPI object of type MPIVariables
schemeName of scheme
typeType of interpolation

Definition at line 34 of file WENOInitialize.c.

40 {
41  HyPar *solver = (HyPar*) s;
42  MPIVariables *mpi = (MPIVariables*) m;
43  WENOParameters *weno = (WENOParameters*) solver->interp;
44 
45  static int count = 0;
46 
47  int nvars = solver->nvars;
48  int ndims = solver->ndims;
49 
50  /* default parameters */
51  weno->mapped = 0;
52  weno->borges = 0;
53  weno->yc = 0;
54  weno->no_limiting = 0;
55  weno->eps = 1e-6;
56  weno->p = 2.0;
57 
58  weno->rc = 0.3;
59  weno->xi = 0.001;
60  weno->tol = 1e-16;
61 
62  if (!mpi->rank) {
63  FILE *in;
64  int ferr;
65  in = fopen("weno.inp","r");
66  if (!in) printf("Warning: File weno.inp not found. Using default parameters for WENO5/CRWENO5/HCWENO5 scheme.\n");
67  else {
68  if (!count) printf("Reading WENO parameters from weno.inp.\n");
69  char word[_MAX_STRING_SIZE_];
70  ferr = fscanf(in,"%s",word); if (ferr != 1) return(1);
71  if (!strcmp(word, "begin")){
72  while (strcmp(word, "end")){
73  ferr = fscanf(in,"%s",word); if (ferr != 1) return(1);
74  if (!strcmp(word,"mapped" )) { ferr = fscanf(in,"%d" ,&weno->mapped ); if (ferr != 1) return(1); }
75  else if (!strcmp(word,"borges" )) { ferr = fscanf(in,"%d" ,&weno->borges ); if (ferr != 1) return(1); }
76  else if (!strcmp(word,"yc" )) { ferr = fscanf(in,"%d" ,&weno->yc ); if (ferr != 1) return(1); }
77  else if (!strcmp(word,"no_limiting")) { ferr = fscanf(in,"%d" ,&weno->no_limiting); if (ferr != 1) return(1); }
78  else if (!strcmp(word,"epsilon" )) { ferr = fscanf(in,"%lf",&weno->eps ); if (ferr != 1) return(1); }
79  else if (!strcmp(word,"p" )) { ferr = fscanf(in,"%lf",&weno->p ); if (ferr != 1) return(1); }
80  else if (!strcmp(word,"rc" )) { ferr = fscanf(in,"%lf",&weno->rc ); if (ferr != 1) return(1); }
81  else if (!strcmp(word,"xi" )) { ferr = fscanf(in,"%lf",&weno->xi ); if (ferr != 1) return(1); }
82  else if (!strcmp(word,"tol" )) { ferr = fscanf(in,"%lf",&weno->tol ); if (ferr != 1) return(1); }
83  else if (strcmp(word,"end")) {
84  char useless[_MAX_STRING_SIZE_];
85  ferr = fscanf(in,"%s",useless); if (ferr != 1) return(ferr);
86  printf("Warning: keyword %s in file \"weno.inp\" with value %s not ",word,useless);
87  printf("recognized or extraneous. Ignoring.\n");
88  }
89  }
90  } else {
91  fprintf(stderr,"Error: Illegal format in file \"weno.inp\".\n");
92  return(1);
93  }
94  fclose(in);
95  }
96  }
97 
98  int integer_data[4];
99  double real_data[5];
100  if (!mpi->rank) {
101  integer_data[0] = weno->mapped;
102  integer_data[1] = weno->borges;
103  integer_data[2] = weno->yc;
104  integer_data[3] = weno->no_limiting;
105  real_data[0] = weno->eps;
106  real_data[1] = weno->p;
107  real_data[2] = weno->rc;
108  real_data[3] = weno->xi;
109  real_data[4] = weno->tol;
110  }
111  MPIBroadcast_integer(integer_data,4,0,&mpi->world);
112  MPIBroadcast_double (real_data ,5,0,&mpi->world);
113 
114  weno->mapped = integer_data[0];
115  weno->borges = integer_data[1];
116  weno->yc = integer_data[2];
117  weno->no_limiting = integer_data[3];
118  weno->eps = real_data [0];
119  weno->p = real_data [1];
120  weno->rc = real_data [2];
121  weno->xi = real_data [3];
122  weno->tol = real_data [4];
123 
124  /* WENO weight calculation is hard-coded for p=2, so return error if p != 2 in
125  * user input file, so that there's no confusion */
126  if (weno->p != 2.0) {
127  if (!mpi->rank && !count) printf("Warning from WENOInitialize(): \"p\" parameter is 2.0. Any other value will be ignored!\n");
128  }
129 
130  weno->offset = NULL;
131  weno->w1 = NULL;
132  weno->w2 = NULL;
133  weno->w3 = NULL;
134 
135  weno->offset = (int*) calloc (ndims,sizeof(int));
136  int dir,d;
137  for (dir=0; dir<ndims; dir++) {
138  weno->offset[dir] = 0;
139  for (d=0; d<dir; d++) {
140  int size = nvars, i;
141  for (i=0; i<ndims; i++)
142  size *= ( i==d ? solver->dim_local[i]+1 : solver->dim_local[i] );
143  weno->offset[dir] += size;
144  }
145  }
146 
147  int total_size = 0;
148  for (d=0; d<ndims; d++) {
149  int size = nvars, i;
150  for (i=0; i<ndims; i++)
151  size *= ( i==d ? solver->dim_local[i]+1 : solver->dim_local[i] );
152  total_size += size;
153  }
154  weno->size = total_size;
155 
156  if ((!strcmp(type,_CHARACTERISTIC_)) && (nvars > 1))
158  else {
159 #if defined(HAVE_CUDA)
160  if (solver->use_gpu) {
162  } else {
163 #endif
165 #if defined(HAVE_CUDA)
166  }
167 #endif
168  }
169 
170  /* initialize WENO weights to their optimal values */
171  double* tmp_w1 = (double*) calloc (4*total_size,sizeof(double));
172  double* tmp_w2 = (double*) calloc (4*total_size,sizeof(double));
173  double* tmp_w3 = (double*) calloc (4*total_size,sizeof(double));
174  for (d=0; d<ndims; d++) WENOFifthOrderInitializeWeights( tmp_w1,
175  tmp_w2,
176  tmp_w3,
177  weno->offset,
178  d,
179  solver,
180  mpi);
181  count++;
182 
183 #if defined(HAVE_CUDA)
184  if (solver->use_gpu) {
185  //gpuMalloc((void**)&weno->gpu_offset, solver->ndims*sizeof(int));
186  gpuMalloc((void**)&weno->w1, 4*total_size*sizeof(double));
187  gpuMalloc((void**)&weno->w2, 4*total_size*sizeof(double));
188  gpuMalloc((void**)&weno->w3, 4*total_size*sizeof(double));
189 
190  //gpuMemcpy(weno->gpu_offset, weno->offset, solver->ndims*sizeof(int), gpuMemcpyHostToDevice);
191  gpuMemcpy(weno->w1, tmp_w1, 4*total_size*sizeof(double), gpuMemcpyHostToDevice);
192  gpuMemcpy(weno->w2, tmp_w2, 4*total_size*sizeof(double), gpuMemcpyHostToDevice);
193  gpuMemcpy(weno->w3, tmp_w3, 4*total_size*sizeof(double), gpuMemcpyHostToDevice);
194  } else {
195 #endif
196  weno->w1 = (double*) calloc (4*total_size,sizeof(double));
197  weno->w2 = (double*) calloc (4*total_size,sizeof(double));
198  weno->w3 = (double*) calloc (4*total_size,sizeof(double));
199 
200  _ArrayCopy1D_(tmp_w1, weno->w1, 4*total_size);
201  _ArrayCopy1D_(tmp_w2, weno->w2, 4*total_size);
202  _ArrayCopy1D_(tmp_w3, weno->w3, 4*total_size);
203 #if defined(HAVE_CUDA)
204  }
205 #endif
206 
207  free(tmp_w1);
208  free(tmp_w2);
209  free(tmp_w3);
210 
211  return 0;
212 }
int WENOFifthOrderCalculateWeights(double *, double *, double *, int, void *, void *)
int WENOFifthOrderCalculateWeightsChar(double *, double *, double *, int, void *, void *)
int nvars
Definition: hypar.h:29
int MPIBroadcast_integer(int *, int, int, void *)
Definition: MPIBroadcast.c:23
#define _CHARACTERISTIC_
Definition: interpolation.h:33
int ndims
Definition: hypar.h:26
int(* SetInterpLimiterVar)(double *, double *, double *, int, void *, void *)
Definition: hypar.h:234
int MPIBroadcast_double(double *, int, int, void *)
Definition: MPIBroadcast.c:9
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
void gpuMalloc(void **, size_t)
#define _MAX_STRING_SIZE_
Definition: basic.h:14
MPI_Comm world
Structure of variables/parameters needed by the WENO-type scheme.
int * dim_local
Definition: hypar.h:37
void * interp
Definition: hypar.h:362
int WENOFifthOrderInitializeWeights(double *const, double *const, double *const, const int *const, int, void *, void *)
void gpuMemcpy(void *, const void *, size_t, enum gpuMemcpyKind)
int gpuWENOFifthOrderCalculateWeights(double *, double *, double *, int, void *, void *)
Structure of MPI-related variables.
int use_gpu
Definition: hypar.h:449
#define _ArrayCopy1D_(x, y, size)