REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_prestep_diffusion.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/**
6 * Called from prestep. The tracer update is a bit different from the u,v updates so we test
7 * for it, but checking if ioff=0 and joff=0. In some cases, though, we
8 * can recover the tracer update from the generic one by setting those indices.
9 * Setting icc and ntfirst identically for the tracers should be equivalent
10 * to setting ioff=0 and joff=0
11 *
12 * @param[in ] vel_bx tile box
13 * @param[in ] gbx grown tile box
14 * @param[in ] ioff offset in x direction
15 * @param[in ] joff offset in y direction
16 * @param[ out] vel velocity or scalar to update
17 * @param[in ] vel_old velocity or scalar at last time
18 * @param[inout] rvel velocity or scalar RHS
19 * @param[in ] Hz vertical cell height
20 * @param[in ] Akv vertical viscosity coefficient
21 * @param FC temporary
22 * @param[in ] sstr surface flux
23 * @param[in ] bstr bottom flux
24 * @param[in ] z_r z coordinates at rho points
25 * @param[in ] pm 1/dx
26 * @param[in ] pn 1/dy
27 * @param[in ] iic which time step we're on
28 * @param[in ] ntfirst what is the first time step?
29 * @param[in ] nnew index of time step to update
30 * @param[in ] nstp index of last time step
31 * @param[in ] nrhs index of RHS component
32 * @param[in ] N number of vertical levels
33 * @param[in ] lambda weighting coefficient for the newest (implicit) time step derivatives
34 * @param[in ] dt_lev time step at this level
35 */
36
37void
38REMORA::prestep_diffusion (const Box& vel_bx, const Box& gbx,
39 const int ioff, const int joff,
40 const Array4<Real >& vel,
41 const Array4<Real const>& vel_old,
42 const Array4<Real >& rvel,
43 const Array4<Real const>& Hz,
44 const Array4<Real const>& Akv,
45 const Array4<Real >& FC,
46 const Array4<Real const>& sstr,
47 const Array4<Real const>& bstr,
48 const Array4<Real const>& z_r,
49 const Array4<Real const>& pm,
50 const Array4<Real const>& pn,
51 const int iic, const int ntfirst, const int nnew, int nstp, int nrhs, int N,
52 const Real lambda, const Real dt_lev)
53{
54 BL_PROFILE("REMORA::prestep_diffusion()");
55
56 BoxArray ba_gbxvel = intersect(BoxArray(vel_bx), gbx);
57 AMREX_ASSERT((ba_gbxvel.size() == 1));
58 Box gbxvel = ba_gbxvel[0];
59
60 //
61 // Weighting coefficient for the newest (implicit) time step derivatives
62 // using either a Crank-Nicolson implicit scheme (lambda=0.5_rt) or a
63 // backward implicit scheme (lambda=1.0_rt).
64 //
65
66 Real oml_dt = dt_lev*(1.0_rt-lambda);
67 //N is one less than ROMS
68
69 // Except the commented out part means lambda is always 1.0_rt
70 if (verbose > 1) {
71 amrex::Print() << "in update_vel_3d with box " << vel_bx << std::endl;
72 Print() << "vel old " << Box(vel_old) << std::endl;
73 Print() << "Akv " << Box(Akv) << std::endl;
74 }
75 ParallelFor(grow(surroundingNodes(vel_bx,2),IntVect(0,0,-1)),
76 [=] AMREX_GPU_DEVICE (int i, int j, int k)
77 {
78 Real cff = 1.0_rt / ( z_r(i,j,k)+z_r(i-ioff,j-joff,k)
79 -z_r(i,j,k-1)-z_r(i-ioff,j-joff,k-1));
80 FC(i,j,k) = oml_dt * cff * (vel_old(i,j,k,nstp)-vel_old(i,j,k-1,nstp)) *
81 (Akv(i,j,k) +Akv(i-ioff,j-joff,k));
82 });
83 ParallelFor(makeSlab(vel_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int ) {
84 FC(i,j,0) = dt_lev*bstr(i,j,0);
85 FC(i,j, N+1) = dt_lev*sstr(i,j,0);
86 });
87
88 if (iic==ntfirst || (ioff==0 and joff==0)) {
89 ParallelFor(gbxvel,
90 [=] AMREX_GPU_DEVICE (int i, int j, int k)
91 {
92 Real cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
93 Real cff2=FC(i,j,k+1)-FC(i,j,k);
94 vel(i,j,k,nnew)=cff1+cff2;
95 });
96 } else if (iic==ntfirst+1) {
97 ParallelFor(gbxvel,
98 [=] AMREX_GPU_DEVICE (int i, int j, int k)
99 {
100 Real cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
101 Real cff2=FC(i,j,k+1)-FC(i,j,k);
102 Real DC = 0.25_rt * dt_lev * (pm(i,j,0)+pm(i-ioff,j-joff,0))
103 * (pn(i,j,0)+pn(i-ioff,j-joff,0));
104 Real cff3 = DC * 0.5_rt;
105 int indx=nrhs ? 0 : 1;
106 Real r_swap= rvel(i,j,k,indx);
107 rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
108 rvel(i,j,k,nrhs) = r_swap;
109 vel(i,j,k,nnew)=cff1- cff3*rvel(i,j,k,indx)+ cff2;
110 });
111 } else {
112 ParallelFor(gbxvel,
113 [=] AMREX_GPU_DEVICE (int i, int j, int k)
114 {
115 Real cff1 = 5.0_rt/12.0_rt;
116 Real cff2 = 16.0_rt/12.0_rt;
117 Real cff3=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
118 Real cff4=FC(i,j,k+1)-FC(i,j,k);
119 Real DC = 0.25_rt * dt_lev * (pm(i,j,0)+pm(i-ioff,j-joff,0))
120 * (pn(i,j,0)+pn(i-ioff,j-joff,0));
121
122 int indx=nrhs ? 0 : 1;
123 Real r_swap= rvel(i,j,k,indx);
124 rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
125 rvel(i,j,k,nrhs) = r_swap;
126
127 vel(i,j,k,nnew) = cff3 + DC*(cff1*rvel(i,j,k,nrhs)-
128 cff2*rvel(i,j,k,indx))+cff4;
129 rvel(i,j,k,nrhs) = 0.0_rt;
130 });
131 }
132}
void prestep_diffusion(const amrex::Box &bx, const amrex::Box &gbx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &vel, const amrex::Array4< amrex::Real const > &vel_old, const amrex::Array4< amrex::Real > &rvel, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &Akv, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &sstr, const amrex::Array4< amrex::Real const > &bstr, const amrex::Array4< amrex::Real const > &z_r, const amrex::Array4< amrex::Real const > &pm, const amrex::Array4< amrex::Real const > &pn, const int iic, const int ntfirst, const int nnew, int nstp, int nrhs, int N, const amrex::Real lambda, const amrex::Real dt_lev)
Update velocities or tracers with diffusion/viscosity as the last part of the prestep.
static int verbose
Verbosity level of output.
Definition REMORA.H:1306