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

3rd order MUSCL scheme with Koren's limiter (component-wise application to vectors) More...

#include <stdio.h>
#include <stdlib.h>
#include <basic.h>
#include <arrayfunctions.h>
#include <mathfunctions.h>
#include <interpolation.h>
#include <mpivars.h>
#include <hypar.h>

Go to the source code of this file.

Macros

#define _MINIMUM_GHOSTS_   2
 

Functions

int Interp1PrimThirdOrderMUSCL (double *fI, double *fC, double *u, double *x, int upw, int dir, void *s, void *m, int uflag)
 3rd order MUSCL scheme with Koren's limiter (component-wise) on a uniform grid More...
 

Detailed Description

3rd order MUSCL scheme with Koren's limiter (component-wise application to vectors)

Author
Debojyoti Ghosh

Definition in file Interp1PrimThirdOrderMUSCL.c.

Macro Definition Documentation

◆ _MINIMUM_GHOSTS_

#define _MINIMUM_GHOSTS_   2

Minimum number of ghost points required for this interpolation method.

Definition at line 24 of file Interp1PrimThirdOrderMUSCL.c.

Function Documentation

◆ Interp1PrimThirdOrderMUSCL()

int Interp1PrimThirdOrderMUSCL ( double *  fI,
double *  fC,
double *  u,
double *  x,
int  upw,
int  dir,
void *  s,
void *  m,
int  uflag 
)

3rd order MUSCL scheme with Koren's limiter (component-wise) on a uniform grid

Computes the interpolated values of the first primitive of a function \({\bf f}\left({\bf u}\right)\) at the interfaces from the cell-centered values of the function using the 3rd order MUSCL scheme with Koren's limiter on a uniform grid. The first primitive is defined as a function \({\bf h}\left({\bf u}\right)\) that satisfies:

\begin{equation} {\bf f}\left({\bf u}\left(x\right)\right) = \frac{1}{\Delta x} \int_{x-\Delta x/2}^{x+\Delta x/2} {\bf h}\left({\bf u}\left(\zeta\right)\right)d\zeta, \end{equation}

where \(x\) is the spatial coordinate along the dimension of the interpolation. This function computes numerical approximation \(\hat{\bf f}_{j+1/2} \approx {\bf h}_{j+1/2}\) as: using the 3rd order MUSCL scheme with Koren's limiter as follows:

\begin{equation} \hat{\bf f}_{j+1/2} = {\bf f}_{j-1} + \phi \left[\frac{1}{3}\left({\bf f}_j-{\bf f}_{j-1}\right) + \frac{1}{6}\left({\bf f}_{j-1}-{\bf f}_{j-2}\right)\right] \end{equation}

where

\begin{equation} \phi = \frac {3\left({\bf f}_j-{\bf f}_{j-1}\right)\left({\bf f}_{j-1}-{\bf f}_{j-2}\right) + \epsilon} {2\left[\left({\bf f}_j-{\bf f}_{j-1}\right)-\left({\bf f}_{j-1}-{\bf f}_{j-2}\right)\right]^2 + 3\left({\bf f}_j-{\bf f}_{j-1}\right)\left({\bf f}_{j-1}-{\bf f}_{j-2}\right) + \epsilon}. \end{equation}

and \(\epsilon\) is a small constant (typically \(10^{-3}\)).

Implementation Notes:

  • The scalar interpolation method is applied to the vector function in a component-wise manner.
  • The method described above corresponds to a left-biased interpolation. The corresponding right-biased interpolation can be obtained by reflecting the equations about interface j+1/2.
  • The function computes the interpolant for the entire grid in one call. It loops over all the grid lines along the interpolation direction and carries out the 1D interpolation along these grid lines.
  • Location of cell-centers and cell interfaces along the spatial dimension of the interpolation is shown in the following figure:
    chap1_1Ddomain.png

Function arguments:

Argument Type Explanation ------—
fI double* Array to hold the computed interpolant at the grid interfaces. This array must have the same layout as the solution, but with no ghost points. Its size should be the same as u in all dimensions, except dir (the dimension along which to interpolate) along which it should be larger by 1 (number of interfaces is 1 more than the number of interior cell centers).
fC double* Array with the cell-centered values of the flux function \({\bf f}\left({\bf u}\right)\). This array must have the same layout and size as the solution, with ghost points.
u double* The solution array \({\bf u}\) (with ghost points). If the interpolation is characteristic based, this is needed to compute the eigendecomposition. For a multidimensional problem, the layout is as follows: u is a contiguous 1D array of size (nvars*dim[0]*dim[1]*...*dim[D-1]) corresponding to the multi-dimensional solution, with the following ordering - nvars, dim[0], dim[1], ..., dim[D-1], where nvars is the number of solution components (HyPar::nvars), dim is the local size (HyPar::dim_local), D is the number of spatial dimensions.
x double* The grid array (with ghost points). This is used only by non-uniform-grid interpolation methods. For multidimensional problems, the layout is as follows: x is a contiguous 1D array of size (dim[0]+dim[1]+...+dim[D-1]), with the spatial coordinates along dim[0] stored from 0,...,dim[0]-1, the spatial coordinates along dim[1] stored along dim[0],...,dim[0]+dim[1]-1, and so forth.
upw int Upwinding direction: if positive, a left-biased interpolant will be computed; if negative, a right-biased interpolant will be computed. If the interpolation method is central, then this has no effect.
dir int Spatial dimension along which to interpolate (eg: 0 for 1D; 0 or 1 for 2D; 0,1 or 2 for 3D)
s void* Solver object of type HyPar: the following variables are needed - HyPar::ghosts, HyPar::ndims, HyPar::nvars, HyPar::dim_local.
m void* MPI object of type MPIVariables: this is needed only by compact interpolation method that need to solve a global implicit system across MPI ranks.
uflag int A flag indicating if the function being interpolated \({\bf f}\) is the solution itself \({\bf u}\) (if 1, \({\bf f}\left({\bf u}\right) \equiv {\bf u}\)).

Reference:

  • van Leer, B., Towards the Ultimate Conservative Difference Scheme. 2: Monotonicity and Conservation Combined in a Second-Order Scheme, J. of Comput. Phys., 14 (4), 1974, pp.361-370, http://dx.doi.org/10.1016/0021-9991(74)90019-9
  • Koren, B., A Robust Upwind Discretization Method for Advection, Diffusion and Source Terms, Centrum voor Wiskunde en Informatica, Amsterdam, 1993
Parameters
fIArray of interpolated function values at the interfaces
fCArray of cell-centered values of the function \({\bf f}\left({\bf u}\right)\)
uArray of cell-centered values of the solution \({\bf u}\)
xGrid coordinates
upwUpwind direction (left or right biased)
dirSpatial dimension along which to interpolation
sObject of type HyPar containing solver-related variables
mObject of type MPIVariables containing MPI-related variables
uflagFlag to indicate if \(f(u) \equiv u\), i.e, if the solution is being reconstructed

Definition at line 75 of file Interp1PrimThirdOrderMUSCL.c.

86 {
87  HyPar *solver = (HyPar*) s;
88  MUSCLParameters *muscl = (MUSCLParameters*) solver->interp;
89 
90  int ghosts = solver->ghosts;
91  int ndims = solver->ndims;
92  int nvars = solver->nvars;
93  int *dim = solver->dim_local;
94 
95  /* define some constants */
96  double one_third = 1.0/3.0;
97  double one_sixth = 1.0/6.0;
98 
99  /* create index and bounds for the outer loop, i.e., to loop over all 1D lines along
100  dimension "dir" */
101  int indexC[ndims], indexI[ndims], index_outer[ndims], bounds_outer[ndims], bounds_inter[ndims];
102  _ArrayCopy1D_(dim,bounds_outer,ndims); bounds_outer[dir] = 1;
103  _ArrayCopy1D_(dim,bounds_inter,ndims); bounds_inter[dir] += 1;
104  int N_outer; _ArrayProduct1D_(bounds_outer,ndims,N_outer);
105 
106  int i;
107  if (upw > 0) {
108 #pragma omp parallel for schedule(auto) default(shared) private(i,index_outer,indexC,indexI)
109  for (i=0; i<N_outer; i++) {
110  _ArrayIndexnD_(ndims,i,bounds_outer,index_outer,0);
111  _ArrayCopy1D_(index_outer,indexC,ndims);
112  _ArrayCopy1D_(index_outer,indexI,ndims);
113  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
114  int p; _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
115  int qm1,qm2,qp1,v;
116  indexC[dir] = indexI[dir]-2; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qm2);
117  indexC[dir] = indexI[dir]-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qm1);
118  indexC[dir] = indexI[dir] ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qp1);
119  for (v=0; v<nvars; v++) {
120  /* Defining stencil points */
121  double m2, m1, p1;
122  m2 = fC[qm2*nvars+v];
123  m1 = fC[qm1*nvars+v];
124  p1 = fC[qp1*nvars+v];
125 
126  double fdiff = p1 - m1;
127  double bdiff = m1 - m2;
128  double limit = (3*fdiff*bdiff + muscl->eps)
129  / (2*(fdiff-bdiff)*(fdiff-bdiff) + 3*fdiff*bdiff + muscl->eps);
130 
131  fI[p*nvars+v] = m1 + limit * (one_third*fdiff + one_sixth*bdiff);
132  }
133  }
134  }
135  } else {
136 #pragma omp parallel for schedule(auto) default(shared) private(i,index_outer,indexC,indexI)
137  for (i=0; i<N_outer; i++) {
138  _ArrayIndexnD_(ndims,i,bounds_outer,index_outer,0);
139  _ArrayCopy1D_(index_outer,indexC,ndims);
140  _ArrayCopy1D_(index_outer,indexI,ndims);
141  for (indexI[dir] = 0; indexI[dir] < dim[dir]+1; indexI[dir]++) {
142  int p; _ArrayIndex1D_(ndims,bounds_inter,indexI,0,p);
143  int qm1,qp1,qp2,v;
144  indexC[dir] = indexI[dir]-1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qm1);
145  indexC[dir] = indexI[dir] ; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qp1);
146  indexC[dir] = indexI[dir]+1; _ArrayIndex1D_(ndims,dim,indexC,ghosts,qp2);
147  for (v=0; v<nvars; v++) {
148  /* Defining stencil points */
149  double m1, p1, p2;
150  m1 = fC[qm1*nvars+v];
151  p1 = fC[qp1*nvars+v];
152  p2 = fC[qp2*nvars+v];
153 
154  double fdiff = p2 - p1;
155  double bdiff = p1 - m1;
156  double limit = (3*fdiff*bdiff + muscl->eps)
157  / (2*(fdiff-bdiff)*(fdiff-bdiff) + 3*fdiff*bdiff + muscl->eps);
158 
159  fI[p*nvars+v] = p1 - limit * (one_third*fdiff + one_sixth*bdiff);
160  }
161  }
162  }
163  }
164 
165  return(0);
166 }
int nvars
Definition: hypar.h:29
#define _ArrayIndexnD_(N, index, imax, i, ghost)
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)
int * dim_local
Definition: hypar.h:37
void * interp
Definition: hypar.h:362
Structure of variables/parameters needed by the MUSCL scheme.
int ghosts
Definition: hypar.h:52
#define _ArrayCopy1D_(x, y, size)
#define _ArrayProduct1D_(x, size, p)