From 100a63d7cf132a409a719ac603628a1484c367cd Mon Sep 17 00:00:00 2001 From: rhaas Date: Tue, 13 Aug 2013 14:56:28 +0000 Subject: GRHydro: add templated (yay\!) PPM routine; can do old ppm, but for MHD, hot, cold whatever From: Christian Ott git-svn-id: http://svn.einsteintoolkit.org/cactus/EinsteinEvolve/GRHydro/trunk@573 c83d129a-5a75-4d5a-9c4d-ed3a5855bf45 --- src/GRHydro_PPM.cc | 414 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/make.code.defn | 1 + 2 files changed, 415 insertions(+) create mode 100644 src/GRHydro_PPM.cc diff --git a/src/GRHydro_PPM.cc b/src/GRHydro_PPM.cc new file mode 100644 index 0000000..e1f426f --- /dev/null +++ b/src/GRHydro_PPM.cc @@ -0,0 +1,414 @@ +#include +#include +#include "cctk.h" +#include "cctk_Parameters.h" +#include "cctk_Arguments.h" +#include "cctk_Functions.h" +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +using namespace std; + +/* + Cases that must be considered: + * basic hydro + * hydro + temperature + ye + * hydro + ye + * basic mhd + * mhd + temperature + ye + * mhd + ye + * mppm (not supported right now) + * not supporting trivial_rp + * with or without divergence cleaning + */ + + +static inline void steep(const double *restrict x, + const double *restrict dx, + double *restrict dmx, + const int i) { + if ( (x[i+1] - x[i]) * (x[i]-x[i-1]) > 0.0 ) { + dmx[i] = copysign(1.0,dx[i]) * MIN(fabs(dx[i]), + MIN(2.0*fabs(x[i]-x[i-1]), + 2.0*fabs(x[i+1]-x[i]))); + } else { + dmx[i] = 0.0; + } +} + +static inline double approx_at_cell_interface(double* a, const int i) { + return 7.0/12.0*(a[i]+a[i+1]) - 1.0/12.0*(a[i-1]+a[i+2]); +} + +static inline void monotonize(double* restrict xminus, + const double* restrict x, + double* restrict xplus, + const int i) { + + if ( !(xplus[i]==x[i] && x[i]==xminus[i]) + && ( (xplus[i]-x[i])*(x[i]-xminus[i]) <= 0.0 ) ) + { + xminus[i] = x[i]; + xplus[i] = x[i]; + } else if( 6.0 * (xplus[i]-xminus[i]) * + (x[i]-0.5*(xplus[i]+xminus[i])) > + (xplus[i]-xminus[i])*(xplus[i]-xminus[i]) ) + { + xminus[i] = 3.0*x[i]-2.0*xplus[i]; + } else if( 6.0 * (xplus[i]-xminus[i]) * + (x[i]-0.5*(xplus[i]+xminus[i])) < + -(xplus[i]-xminus[i])*(xplus[i]-xminus[i]) ) + { + xplus[i] = 3.0*x[i]-2.0*xminus[i]; + } + + return; +} + + + +template +static void ppm1d_cxx(const int nx, + const double dx, + const double* restrict rho, + const double* restrict velx, + const double* restrict vely, + const double* restrict velz, + const double* restrict eps, + const double* restrict press, + const double* restrict temp, + const double* restrict ye, + const double* restrict Bvcx, + const double* restrict Bvcy, + const double* restrict Bvcz, + const double* restrict psidc, + double* restrict rhominus, + double* restrict velxminus, + double* restrict velyminus, + double* restrict velzminus, + double* restrict epsminus, + double* restrict tempminus, + double* restrict yeminus, + double* restrict Bvcxminus, + double* restrict Bvcyminus, + double* restrict Bvczminus, + double* restrict psidcminus, + double* restrict rhoplus, + double* restrict velxplus, + double* restrict velyplus, + double* restrict velzplus, + double* restrict epsplus, + double* restrict tempplus, + double* restrict yeplus, + double* restrict Bvcxplus, + double* restrict Bvcyplus, + double* restrict Bvczplus, + double* restrict psidcplus) +{ + DECLARE_CCTK_PARAMETERS; + + double drho[nx], dpress[nx], deps[nx], d2rho[nx]; + double dmrho[nx], dmeps[nx]; + double dmtemp[nx], dmye[nx]; + double dtemp[nx], dye[nx]; + double dvelx[nx], dvely[nx], dvelz[nx]; + double dmvelx[nx], dmvely[nx], dmvelz[nx]; + double dBvcx[nx], dBvcy[nx], dBvcz[nx], dpsidc[nx]; + double dmBvcx[nx], dmBvcy[nx], dmBvcz[nx], dmpsidc[nx]; + double tilde_flatten[nx]; + + const double onesixth = 1.0/6.0; + + // Average slopes delta_m(a). See (1.7) of Colella and Woodward, p.178 + // This is the expression for an even grid. + for(int i=1;i < nx-1;i++) { + drho[i] = 0.5 * (rho[i+1]-rho[i-1]); + d2rho[i] = rho[i+1] - 2.0 * rho[i] + rho[i-1]; + dpress[i] = (press[i+1]-press[i-1]); + deps[i] = 0.5 * (eps[i+1]-eps[i-1]); + dvelx[i] = 0.5 * (velx[i+1]-velx[i-1]); + dvely[i] = 0.5 * (vely[i+1]-vely[i-1]); + dvelz[i] = 0.5 * (velz[i+1]-velz[i-1]); + if(do_ye) { + if(do_temp) { + dtemp[i] = 0.5 * (temp[i+1]-temp[i-1]); + } + dye[i] = 0.5 * (ye[i+1]-ye[i-1]); + } + if(do_mhd) { + dBvcx[i] = 0.5 * (Bvcx[i+1]-Bvcx[i-1]); + dBvcy[i] = 0.5 * (Bvcy[i+1]-Bvcy[i-1]); + dBvcz[i] = 0.5 * (Bvcz[i+1]-Bvcz[i-1]); + if(dc_flag) { + dpsidc[i] = 0.5 * (psidc[i+1]-psidc[i-1]); + } + } + } + + // Steepened slope. See (1.8) of Colella and Woodward, p.178 + for(int i=1;i 0.0) ) + { + etatilde = (rho[i-2] - rho[i+2] + 4.0 * drho[i]) / (drho[i] * 12.0); + } + double eta = MAX(0.0, MIN(1.0, ppm_eta1 * (etatilde - ppm_eta2))); + if (ppm_k0 * fabs(drho[i]) * MIN(press[i-1],press[i+1]) + < fabs(dpress[i]) * MIN(rho[i-1], rho[i+1])) + { + eta = 0.0; + } + rhominus[i] = rhominus[i] * (1.0 - eta) + + (rho[i-1] + 0.5 * dmrho[i-1]) * eta; + rhoplus[i] = rhoplus[i] * (1.0 - eta) + + (rho[i+1] - 0.5 * dmrho[i+1]) * eta; + } + } + + // flattening + for(int i=2;i ppm_epsilon * MIN(press[i-1],press[i+1])) + && (dvel < 0.0) ) + { + w = 1.0; + } + if (fabs(dpress2) < ppm_small) + { + tilde_flatten[i] = 1.0; + } + else + { + tilde_flatten[i] = MAX(0.0, 1.0 - w * MAX(0.0, + ppm_omega2 * (dpress[i] / dpress2 - ppm_omega1))); + } + } + + for(int i=2;i +#define INSTANTIATE(do_temp,do_ye,do_mhd,dc_flag,do_ppm_detect) \ +template static void ppm1d_cxx(const int nx, \ + const double dx, \ + const double* restrict rho, \ + const double* restrict velx, \ + const double* restrict vely, \ + const double* restrict velz, \ + const double* restrict eps, \ + const double* restrict press, \ + const double* restrict temp, \ + const double* restrict ye, \ + const double* restrict Bvcx, \ + const double* restrict Bvcy, \ + const double* restrict Bvcz, \ + const double* restrict psidc, \ + double* restrict rhominus, \ + double* restrict velxminus, \ + double* restrict velyminus, \ + double* restrict velzminus, \ + double* restrict epsminus, \ + double* restrict tempminus, \ + double* restrict yeminus, \ + double* restrict Bvcxminus, \ + double* restrict Bvcyminus, \ + double* restrict Bvczminus, \ + double* restrict psidcminus, \ + double* restrict rhoplus, \ + double* restrict velxplus, \ + double* restrict velyplus, \ + double* restrict velzplus, \ + double* restrict epsplus, \ + double* restrict tempplus, \ + double* restrict yeplus, \ + double* restrict Bvcxplus, \ + double* restrict Bvcyplus, \ + double* restrict Bvczplus, \ + double* restrict psidcplus); + +//template template + + +// first stuff without MHD +INSTANTIATE(false,false,false,false,false) +INSTANTIATE(false,false,false,false,true) +// do_temp can only be true of do_ye is also true +INSTANTIATE(true,true,false,false,false) +INSTANTIATE(true,true,false,false,true) +// but do_ye can be true and do_temp can be false +INSTANTIATE(false,true,false,false,false) +INSTANTIATE(false,true,false,false,true) + +// with MHD, but dc_flag false +INSTANTIATE(false,false,true,false,false) +INSTANTIATE(false,false,true,false,true) +// do_temp can only be true of do_ye is also true +INSTANTIATE(true,true,true,false,false) +INSTANTIATE(true,true,true,false,true) +// but do_ye can be true and do_temp can be false +INSTANTIATE(false,true,true,false,false) +INSTANTIATE(false,true,true,false,true) + +// with MHD, dc_flag true +INSTANTIATE(false,false,true,true,false) +INSTANTIATE(false,false,true,true,true) +// do_temp can only be true of do_ye is also true +INSTANTIATE(true,true,true,true,false) +INSTANTIATE(true,true,true,true,true) +// but do_ye can be true and do_temp can be false +INSTANTIATE(false,true,true,true,false) +INSTANTIATE(false,true,true,true,true) diff --git a/src/make.code.defn b/src/make.code.defn index 527713e..21181df 100644 --- a/src/make.code.defn +++ b/src/make.code.defn @@ -82,6 +82,7 @@ SRCS = Utils.F90 \ Con2Prim_fortran_interfaces.F90 \ Con2PrimM_fortran_interfaces.F90 \ GRHydro_Prim2Con.c \ + GRHydro_PPM.cc \ GRHydro_Wrappers.F90 # Subdirectories containing source files -- cgit v1.2.3