∇-Nabla: Numerical Analysis BAsed LAnguage

∇-Nabla: Numerical Analysis BAsed LAnguage

nablaLulesh-512.png pnnnt-512.png nablaSethi-512.png monai-512.png nablaDDFV-512.png nablaMNLDDFV-512.png nablaCoMD-512.png nablaSPH-512.png

∇ Monai

This ∇ mini-app solves the tsunami runup Monai valley benchmark from the NOAA (National Oceanic and Atmospheric Administration) center for tsunami research. http://nctr.pmel.noaa.gov/benchmark/Laboratory/Laboratory_MonaiValley/index.html

with ℝ²,cartesian;

const  π = acos(-1.0); 
const  D2R = π/180.0; // degrees ⇒ radians
const  EarthMeridionalRadius = 6367449.0;
const  D2M = EarthMeridionalRadius*D2R; // degrees ⇒ meters
const  G = 9.80665; // AccelerationDueToGravity m/s²

 deg_to_r( θ){ return θ*D2R; }
 lat_to_m( δy){ return δy*D2M; }
 lon_to_m( δx,  δy){ return δx*D2M*cos(δy*D2R); }

options{
   NX                    = 32;      // Number of inner X cells
   NY                    = 32;      // Number of inner Y cells
   LENGTH                = 1.0;
   X_EDGE_ELEMS          = NX+2;    // Inner + Fictitious X cells
   Y_EDGE_ELEMS          = NY+2;    // Inner + Fictitious Y cells
   option_λ              = 1.e-4;
   option_stoptime       = 60.0;
   option_max_iterations = 32;
   option_epsd           = 1.0e-9;
   option_δt             = 0.0025;
};

cells{
   h,hn,hnp; // height
   x,dx,inv_dx,y,dy,inv_dy;
   d,d_hn; // depth
   un,vn,unp,vnp; // velocities
   deqh,deqh_dx,deqh_dy;
   coef_gradx_h,coef_grady_h;
   fc;       // Coriolis force
};

global{
   xmin,xmax, ymin,ymax;
   dmax,dxmax,dymax;
   dx_lon, dy_lat;
   chk,chkH,chkU,chkV;
};

// Geometry: X, Y and Z Beach + Island
 cells @ -19.99 { x=0.0;  nodes x+=coord.x; x*=¼*option_λ;}
 cells @ -19.99 { y=0.0;  nodes y+=coord.y; y*=¼*option_λ;}
 cells @ -19.99 {
   i = x/option_λ;
   j = y/option_λ;
   islnd = ½*expf(-32.0*π²*((i-½)²+(j-½)²));
   beach =(2.0/3.0)*expf(-4.0*π*((i-1.0)²+0.1*(j-1.0)²));
  d -= islnd + beach - ¼;
  }

// Analytical inlet functions
 inlet(const  τ){ return -exp(-((-10.0+τ)²/(4.0*π)))*sin*τ)/(12.0*π); }

// Geometry Min Max & Coriolis Force
 cells xmin <?= x @ -17;
 cells xmax >?= x @ -17;
 cells ymin <?= y @ -17;
 cells ymax >?= y @ -17;

dxLon @ -15 { dx_lon = (xmax-xmin)/(NX-1);}
dyLat @ -15 { dy_lat = (ymax-ymin)/(NY-1);}

 cells @ -13 { dx = lon_to_m(dx_lon,y);}
 cells @ -13 { dy = lat_to_m(dy_lat);}

 cells dxmax >?= dx @ -11;
 cells dymax >?= dy @ -11;
 cells @ -11 { inv_dx = 1.0/dx; }
 cells @ -11 { inv_dy = 1.0/dy; }
 cells @ -11 { coef_gradx_h = option_δt*G/dx; }
 cells @ -11 { coef_grady_h = option_δt*G/dy; }

 cells space_scheme_init_coriolis @ -11 {
   T_SIDEREAL = 86164.1;
   ΩT = 2.0*π/T_SIDEREAL;
   dΩt = 2.0*ΩT;
  fc = dΩt*sin(deg_to_r(y));
}

// Depth Init
 cells dmax >?= d @ -17;
 outer west cells @ -13 { d=d[→];}
 cells @ -11,+1 { d_hn = d + hn; }

// CFL & δt
ini_δt @ -8 { δt=½*option_δt; }

time_scheme_assert_δt_vs_cfl @ -7 {
   cgmax = √(G*dmax);
   idxmx = 1.0/dxmax;
   idymx = 1.0/dymax;
   cfl = fmax(δt*cgmax*idxmx, δt*cgmax*idymx);
  assert(δt<cfl);
}

set_δt @ -1 { δt=2.0*δt; }

// Velocity U Init
 own inner cells nlsw1_eqU @ -4,+2 {
   tv = ¼*(vn[↓]+vn[↘]+vn+vn[→]);
   ul = (un>0.0)?un:un[→];
   ur = (un>0.0)?un[←]:un;
   uu = (tv>0.0)?un:un[↑];
   ud = (tv>0.0)?un[↓]:un;
   tu1 = un*(ul-ur);
   tu2 = tv*(uu-ud);
   thu = G*(hn[→]-hn);
   tfc = -tv*fc;
   dequ = (tu1+thu)*inv_dx + tu2*inv_dy + tfc;
  unp = un - δt*dequ;
  }

 inner cells ini_update_un @ -3,+3 { un = unp; }

// Velocitu V Init
 own inner cells nlsw1_eqV @ -4,+2 {
   tu = ¼*(un[←]+un+un[↖]+un[↑]);
   vl = (tu>0)?vn:vn[→];
   vr = (tu>0)?vn[←]:vn;
   vu = (vn>0)?vn:vn[↑];
   vd = (vn>0)?vn[↓]:vn;
   tv1 = tu*(vl-vr);
   tv2 = vn*(vu-vd);
   thv = G*(hn[↑]-hn);
   tfc = tu*fc;
   deqv = tv1*inv_dx + (tv2+thv)*inv_dy + tfc;
  vnp = vn - δt*deqv;
  }

 inner cells ini_update_vn @ -3,+3 { vn = vnp; }

time_init @ 0 { if (time==0) time=δt; }

// Compute loop ]0.0,+∞[
// Iteration
model_iterate @ 1 if (0==(iteration%32)) {
  printf("\n[ %d ] t=%.5fs",iteration,time);
 }

// Quit test
test4quit @ 1 if (iteration==option_max_iterations) { exit; }


// Height Compute loop
 own inner cells @ 1.2 {
  const  dhr=(un>0.0)?d_hn:d_hn[→];
  const  dhl=(un[←]>0.0)?d_hn[←]:d_hn;
  deqh_dx = (un*dhr-un[←]*dhl)*inv_dx;
}

 own inner cells @ 1.2 {
   dhu=(vn>0.0)?d_hn:d_hn[↑];
   dhd=(vn[↓]>0.0)?d_hn[↓]:d_hn;
  deqh_dy = (vn*dhu-vn[↓]*dhd)*inv_dy;
}

 own inner cells @ 1.22 { deqh = deqh_dx + deqh_dy; }
 inner cells @ 1.23 { hnp = hn - δt*deqh; }
 inner cells @ 1.3 { hn = hnp; }

// HN read INLETs
 outer west cells @ 7 { hn=inlet(time); }

// HN Boundaries
 outer ~west cells @ 7 {  outer south face hn=hn[↑]; }
 outer ~west cells @ 7 {  outer north face hn=hn[↓]; }

// H for output
 cells @ 9 { h=hn; }

// Velocity U
 own inner cells uRunup @ 2.2 {
   dr = d[→];
   hnr = hn[→];
   dhnr = d_hn[→];
   ε = option_epsd;
   coef_grad_h = coef_gradx_h;
   dhnIe = d_hn < ε;
   dorh = dhnr<ε or hnr<-d;
   uadh = unp<0.0 and hnr>hn;
   dIe = dhnr < ε;
   hid = hn < -dr;
   hsr = hn>hnr;
  unp=(dhnIe and dorh)?0.0:(dhnIe and uadh)?unp-coef_grad_h*(hn+dr):unp;
   ft = !dIe and unp>0.0;
  unp=(dIe and hid)?0.0;
  unp+=(dIe and unp>0.0 and hsr)?coef_grad_h*(hnr+d):0.0;
  unp+=(ft and -d>hnr)?coef_grad_h*(hnr+d):0.0;
  unp-=(ft and -dr>hn)?coef_grad_h*(hn+dr):0.0;
}

// UN Boundaries
 outer west cells @ -8.7,7.2 { un = hn * √(G/d); }
 outer cells @ 7.2 {  outer south faces un=un[↑]; }
 outer cells @ 7.2 {  outer north faces un=un[↓]; }

// Velocity V
 own inner cells vRunup @ 2.2 {
   du = d[↑];
   hnu = hn[↑];
   dhnu = d_hn[↑];
   ε = option_epsd;
   coef_grad_h = coef_grady_h;
   dorh = dhnu<ε or hnu<-d;
   vorh = vnp<0.0 and hnu>hn;
   dhnuIε = dhnu<ε;
   hnIdu = hn<-du;
  vnp=(d_hn<ε and dorh)?0.0:(d_hn<ε and vorh)?vnp-coef_grad_h*(hn+du):vnp;
   ft = (!dhnuIε) and vnp>0.0;
  vnp=(dhnuIε and hnIdu)?0.0;
  vnp+=(dhnuIε and vnp>0.0 and hn>hnu)?coef_grad_h*(hnu+d):0.0;
  vnp+=(ft and -d>hnu)?coef_grad_h*(hnu+d):0.0;
  vnp-=(ft and -du>hn)?coef_grad_h*(hn+du):0.0;
}

// VN Boundaries
 outer cells @ 7.2 {  outer west faces vn=vn[→]; }
 inner north cells @ 7.3 { vn=0.0; }

camierjs@nabla-lang.org,