HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
secondderivative.h File Reference

Definitions for the functions computing the second derivative. More...

Go to the source code of this file.

Macros

#define _SECOND_ORDER_CENTRAL_   "2"
 
#define _FOURTH_ORDER_CENTRAL_   "4"
 

Functions

int SecondDerivativeSecondOrderCentral (double *, double *, int, void *, void *)
 
int SecondDerivativeFourthOrderCentral (double *, double *, int, void *, void *)
 
int SecondDerivativeSecondOrderCentralNoGhosts (double *, double *, int, int, int *, int, int, void *)
 

Detailed Description

Definitions for the functions computing the second derivative.

Author
Debojyoti Ghosh

Definition in file secondderivative.h.

Macro Definition Documentation

◆ _SECOND_ORDER_CENTRAL_

#define _SECOND_ORDER_CENTRAL_   "2"

Second order central scheme

Definition at line 10 of file secondderivative.h.

◆ _FOURTH_ORDER_CENTRAL_

#define _FOURTH_ORDER_CENTRAL_   "4"

Fourth order central scheme

Definition at line 12 of file secondderivative.h.

Function Documentation

◆ SecondDerivativeSecondOrderCentral()

int SecondDerivativeSecondOrderCentral ( double *  D2f,
double *  f,
int  dir,
void *  s,
void *  m 
)

Second order approximation to the second derivative (note: not divided by square of grid spacing).

Computes the second-order finite-difference approximation to the second derivative (Note: not divided by the grid spacing):

\begin{equation} \left(\partial^2 f\right)_i = f_{i-1} - 2f_i + f_{i+1} \end{equation}

where \(i\) is the grid index along the spatial dimension of the derivative.

Notes:

  • The second derivative is computed at the grid points or the cell centers.
  • Though the array D2f includes ghost points, the second derivative is not computed at these locations. Thus, array elements corresponding to the ghost points contain undefined values.
  • D2f and f are 1D arrays containing the function and its computed derivatives on a multi- dimensional grid. The derivative along the specified dimension dir is computed by looping through all grid lines along dir.
Parameters
D2fArray to hold the computed second derivative (with ghost points) (same size and layout as f)
fArray containing the grid point function values whose first derivative is to be computed (with ghost points)
dirThe spatial dimension along which the derivative is computed
sSolver object of type HyPar
mMPI object of type MPIVariables

Definition at line 34 of file SecondDerivativeSecondOrder.c.

43 {
44  HyPar *solver = (HyPar*) s;
45  int i, v;
46 
47  int ghosts = solver->ghosts;
48  int ndims = solver->ndims;
49  int nvars = solver->nvars;
50  int *dim = solver->dim_local;
51 
52 
53  if ((!D2f) || (!f)) {
54  fprintf(stderr, "Error in SecondDerivativeSecondOrder(): input arrays not allocated.\n");
55  return(1);
56  }
57  if (ghosts < _MINIMUM_GHOSTS_) {
58  fprintf(stderr, "Error in SecondDerivativeSecondOrder(): insufficient number of ghosts.\n");
59  return(1);
60  }
61 
62  /* create index and bounds for the outer loop, i.e., to loop over all 1D lines along
63  dimension "dir" */
64  int indexC[ndims], index_outer[ndims], bounds_outer[ndims];
65  _ArrayCopy1D_(dim,bounds_outer,ndims); bounds_outer[dir] = 1;
66 
67  int done = 0; _ArraySetValue_(index_outer,ndims,0);
68  while (!done) {
69  _ArrayCopy1D_(index_outer,indexC,ndims);
70  for (i = 0; i < dim[dir]; i++) {
71  int qL, qC, qR;
72  indexC[dir] = i-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qL);
73  indexC[dir] = i ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qC);
74  indexC[dir] = i+1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qR);
75  for (v=0; v<nvars; v++) D2f[qC*nvars+v] = f[qL*nvars+v]-2*f[qC*nvars+v]+f[qR*nvars+v];
76  }
77  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
78  }
79 
80  return(0);
81 }
int nvars
Definition: hypar.h:29
int ndims
Definition: hypar.h:26
#define _MINIMUM_GHOSTS_
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _ArrayIndex1D_(N, imax, i, ghost, index)
#define _ArraySetValue_(x, size, value)
int * dim_local
Definition: hypar.h:37
#define _ArrayIncrementIndex_(N, imax, i, done)
int ghosts
Definition: hypar.h:52
#define _ArrayCopy1D_(x, y, size)

◆ SecondDerivativeFourthOrderCentral()

int SecondDerivativeFourthOrderCentral ( double *  D2f,
double *  f,
int  dir,
void *  s,
void *  m 
)

Fourth order approximation to the second derivative (note: not divided by square of grid spacing).

Computes the fourth-order finite-difference approximation to the second derivative (Note: not divided by the grid spacing):

\begin{equation} \left(\partial^2 f\right)_i = -\frac{1}{12}f_{i-2} + \frac{4}{3}f_{i-1} - \frac{15}{6}f_i + \frac{4}{3}f_{i+1} - \frac{1}{12}f_{i+2} \end{equation}

where \(i\) is the grid index along the spatial dimension of the derivative.

Notes:

  • The second derivative is computed at the grid points or the cell centers.
  • Though the array D2f includes ghost points, the second derivative is not computed at these locations. Thus, array elements corresponding to the ghost points contain undefined values.
  • D2f and f are 1D arrays containing the function and its computed derivatives on a multi- dimensional grid. The derivative along the specified dimension dir is computed by looping through all grid lines along dir.
Parameters
D2fArray to hold the computed second derivative (with ghost points) (same size and layout as f)
fArray containing the grid point function values whose first derivative is to be computed (with ghost points)
dirThe spatial dimension along which the derivative is computed
sSolver object of type HyPar
mMPI object of type MPIVariables

Definition at line 34 of file SecondDerivativeFourthOrder.c.

43 {
44  HyPar *solver = (HyPar*) s;
45  int i, v;
46 
47  int ghosts = solver->ghosts;
48  int ndims = solver->ndims;
49  int nvars = solver->nvars;
50  int *dim = solver->dim_local;
51 
52  static double one_twelve = 1.0/12.0;
53 
54  if ((!D2f) || (!f)) {
55  fprintf(stderr, "Error in SecondDerivativeFourthOrder(): input arrays not allocated.\n");
56  return(1);
57  }
58  if (ghosts < _MINIMUM_GHOSTS_) {
59  fprintf(stderr, "Error in SecondDerivativeFourthOrder(): insufficient number of ghosts.\n");
60  return(1);
61  }
62 
63  /* create index and bounds for the outer loop, i.e., to loop over all 1D lines along
64  dimension "dir" */
65  int indexC[ndims], index_outer[ndims], bounds_outer[ndims];
66  _ArrayCopy1D_(dim,bounds_outer,ndims); bounds_outer[dir] = 1;
67 
68  int done = 0; _ArraySetValue_(index_outer,ndims,0);
69  while (!done) {
70  _ArrayCopy1D_(index_outer,indexC,ndims);
71  for (i = 0; i < dim[dir]; i++) {
72  int qm2, qm1, qC, qp1, qp2;
73  indexC[dir] = i-2; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qm2);
74  indexC[dir] = i-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qm1);
75  indexC[dir] = i ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qC );
76  indexC[dir] = i+1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qp1);
77  indexC[dir] = i+2; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qp2);
78  for (v=0; v<nvars; v++)
79  D2f[qC*nvars+v] = (-f[qm2*nvars+v]+16*f[qm1*nvars+v]-30*f[qC*nvars+v]+16*f[qp1*nvars+v]-f[qp2*nvars+v])*one_twelve;
80  }
81  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
82  }
83 
84  return(0);
85 }
int nvars
Definition: hypar.h:29
#define _MINIMUM_GHOSTS_
int ndims
Definition: hypar.h:26
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _ArrayIndex1D_(N, imax, i, ghost, index)
#define _ArraySetValue_(x, size, value)
int * dim_local
Definition: hypar.h:37
#define _ArrayIncrementIndex_(N, imax, i, done)
int ghosts
Definition: hypar.h:52
#define _ArrayCopy1D_(x, y, size)

◆ SecondDerivativeSecondOrderCentralNoGhosts()

int SecondDerivativeSecondOrderCentralNoGhosts ( double *  D2f,
double *  f,
int  dir,
int  ndims,
int *  dim,
int  ghosts,
int  nvars,
void *  m 
)

Second order approximation to the second derivative (note: not divided by square of grid spacing).

Computes the second-order finite-difference approximation to the second derivative (Note: not divided by the grid spacing):

\begin{equation} \left(\partial^2 f\right)_i = f_{i-1} - 2f_i + f_{i+1} \end{equation}

where \(i\) is the grid index along the spatial dimension of the derivative.

Notes:

  • The second derivative is computed at the grid points or the cell centers.
  • Though the array D2f must include the same number of ghost points as the array f (including 0), the second derivative is not computed at these locations. Thus, array elements corresponding to the ghost points contain undefined values.
  • D2f and f are serialized 1D arrays containing the function and its computed derivatives on a multi-dimensional grid. The derivative along the specified dimension dir is computed by looping through all grid lines along dir.
  • Biased stencils are used at the physical boundaries and ghost point values of f are not used. So this function can be used when the ghost values at physical boundaries are not filled. The ghost values at internal (MPI) boundaries are still needed.
Parameters
D2fArray to hold the computed second derivative (with ghost points) (same size and layout as f)
fArray containing the grid point function values whose second derivative is to be computed (with ghost points)
dirThe spatial dimension along which the derivative is computed
ndimsNumber of spatial/coordinate dimensions
dimLocal dimensions
ghostsNumber of ghost points
nvarsNumber of vector components at each grid points
mMPI object of type MPIContext

Definition at line 39 of file SecondDerivativeSecondOrderNoGhosts.c.

49 {
50  MPIContext* mpi = (MPIContext*) m;
51  int i, v;
52 
53  if ((!D2f) || (!f)) {
54  fprintf(stderr, "Error in SecondDerivativeSecondOrder(): input arrays not allocated.\n");
55  return(1);
56  }
57  if (ghosts < _MINIMUM_GHOSTS_) {
58  fprintf(stderr, "Error in SecondDerivativeSecondOrderNoGhosts(): insufficient number of ghosts.\n");
59  return(1);
60  }
61 
62  /* create index and bounds for the outer loop, i.e., to loop over all 1D lines along
63  dimension "dir" */
64  int indexC[ndims], index_outer[ndims], bounds_outer[ndims];
65  _ArrayCopy1D_(dim,bounds_outer,ndims); bounds_outer[dir] = 1;
66 
67  int done = 0; _ArraySetValue_(index_outer,ndims,0);
68  while (!done) {
69  _ArrayCopy1D_(index_outer,indexC,ndims);
70  for (i = 0; i < dim[dir]; i++) {
71  int qL, qC, qR;
72  indexC[dir] = i-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qL);
73  indexC[dir] = i ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qC);
74  indexC[dir] = i+1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qR);
75  for (v=0; v<nvars; v++) D2f[qC*nvars+v] = f[qL*nvars+v]-2*f[qC*nvars+v]+f[qR*nvars+v];
76  }
77  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
78  }
79 
80  if (mpi->ip[dir] == 0) {
81  /* left physical boundary: overwrite the leftmost value with biased finite-difference */
82  int done = 0; _ArraySetValue_(index_outer,ndims,0);
83  while (!done) {
84  _ArrayCopy1D_(index_outer,indexC,ndims);
85  i = 0;
86  int qC, qR, qR2, qR3;
87  indexC[dir] = i ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qC);
88  indexC[dir] = i+1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qR);
89  indexC[dir] = i+2; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qR2);
90  indexC[dir] = i+3; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qR3);
91  for (v=0; v<nvars; v++) D2f[qC*nvars+v] = 2*f[qC*nvars+v]-5*f[qR*nvars+v]+4*f[qR2*nvars+v]-f[qR3*nvars+v];
92  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
93  }
94  }
95 
96  if (mpi->ip[dir] == (mpi->iproc[dir]-1)) {
97  /* right physical boundary: overwrite the rightmost value with biased finite-difference */
98  int done = 0; _ArraySetValue_(index_outer,ndims,0);
99  while (!done) {
100  _ArrayCopy1D_(index_outer,indexC,ndims);
101  i = dim[dir]-1;
102  int qL3, qL2, qL, qC;
103  indexC[dir] = i-3; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qL3);
104  indexC[dir] = i-2; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qL2);
105  indexC[dir] = i-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qL);
106  indexC[dir] = i ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qC);
107  for (v=0; v<nvars; v++) D2f[qC*nvars+v] = 2*f[qC*nvars+v]-5*f[qL*nvars+v]+4*f[qL2*nvars+v]-f[qL3*nvars+v];
108  _ArrayIncrementIndex_(ndims,bounds_outer,index_outer,done);
109  }
110  }
111 
112 
113  return 0;
114 }
#define _ArrayIndex1D_(N, imax, i, ghost, index)
#define _ArraySetValue_(x, size, value)
#define _ArrayIncrementIndex_(N, imax, i, done)
Structure of MPI-related variables.
#define _ArrayCopy1D_(x, y, size)