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 DC temporary
22 * @param FC temporary
23 * @param[in ] sstr surface flux
24 * @param[in ] bstr bottom flux
25 * @param[in ] z_r z coordinates at rho points
26 * @param[in ] pm 1/dx
27 * @param[in ] pn 1/dy
28 * @param[in ] iic which time step we're on
29 * @param[in ] ntfirst what is the first time step?
30 * @param[in ] nnew index of time step to update
31 * @param[in ] nstp index of last time step
32 * @param[in ] nrhs index of RHS component
33 * @param[in ] N number of vertical levels
34 * @param[in ] lambda weighting coefficient for the newest (implicit) time step derivatives
35 * @param[in ] dt_lev time step at this level
36 */
37
38void
39REMORA::prestep_diffusion (const Box& vel_bx, const Box& gbx,
40 const int ioff, const int joff,
41 const Array4<Real >& vel,
42 const Array4<Real const>& vel_old,
43 const Array4<Real >& rvel,
44 const Array4<Real const>& Hz,
45 const Array4<Real const>& Akv,
46 const Array4<Real >& DC,
47 const Array4<Real >& FC,
48 const Array4<Real const>& sstr,
49 const Array4<Real const>& bstr,
50 const Array4<Real const>& z_r,
51 const Array4<Real const>& pm,
52 const Array4<Real const>& pn,
53 const int iic, const int ntfirst, const int nnew, int nstp, int nrhs, int N,
54 const Real lambda, const Real dt_lev)
55{
56
57 BoxArray ba_gbxvel = intersect(BoxArray(vel_bx), gbx);
58 AMREX_ASSERT((ba_gbxvel.size() == 1));
59 Box gbxvel = ba_gbxvel[0];
60
61 //
62 // Weighting coefficient for the newest (implicit) time step derivatives
63 // using either a Crank-Nicolson implicit scheme (lambda=0.5_rt) or a
64 // backward implicit scheme (lambda=1.0_rt).
65 //
66
67 Real oml_dt = dt_lev*(1.0_rt-lambda);
68 //N is one less than ROMS
69
70 // Except the commented out part means lambda is always 1.0_rt
71 if (verbose > 1) {
72 amrex::Print() << "in update_vel_3d with box " << vel_bx << std::endl;
73 Print() << "vel old " << Box(vel_old) << std::endl;
74 Print() << "Akv " << Box(Akv) << std::endl;
75 }
76 ParallelFor(vel_bx,
77 [=] AMREX_GPU_DEVICE (int i, int j, int k)
78 {
79 if(k+1<=N&&k>=0)
80 {
81 Real cff = 1.0_rt / ( z_r(i,j,k+1)+z_r(i-ioff,j-joff,k+1)
82 -z_r(i,j,k )-z_r(i-ioff,j-joff,k ));
83 FC(i,j,k) = oml_dt * cff * (vel_old(i,j,k+1,nstp)-vel_old(i,j,k,nstp)) *
84 (Akv(i,j,k) +Akv(i-ioff,j-joff,k));
85 }
86 else if (k==-1)
87 {
88 FC(i,j,-1) = dt_lev*bstr(i,j,0);
89 }
90 else if (k==N)
91 {
92 FC(i,j, N) = dt_lev*sstr(i,j,0);
93 }
94
95 DC(i,j,k) = 0.25_rt * dt_lev * (pm(i,j,0)+pm(i-ioff,j-joff,0))
96 * (pn(i,j,0)+pn(i-ioff,j-joff,0));
97 });
98
99 ParallelFor(gbxvel,
100 [=] AMREX_GPU_DEVICE (int i, int j, int k)
101 {
102 Real cff3=dt_lev*(1.0_rt-lambda);
103 Real cff1 = 0.0_rt, cff2 = 0.0_rt, cff4;
104
105 int indx=0; //nrhs-3
106
107 if (iic==ntfirst)
108 {
109 if (k+1<=N && k>=1)
110 {
111 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
112 cff2=FC(i,j,k)-FC(i,j,k-1);
113 vel(i,j,k,nnew)=cff1+cff2;
114 }
115 else if(k==0)
116 {
117 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
118 cff2=FC(i,j,k)-dt_lev*bstr(i,j,0);
119 vel(i,j,k,nnew)=cff1+cff2;
120 }
121 else if(k==N)
122 {
123 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
124 cff2=dt_lev*sstr(i,j,0)-FC(i,j,k-1); //or: -FC(i,j,k-1)+dt_lev*sstr(i,j,0);
125 vel(i,j,k,nnew)=cff1+cff2;
126 }
127
128 } else if(iic==ntfirst+1) {
129
130 if (k<N && k>0) {
131 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
132 cff2=FC(i,j,k)-FC(i,j,k-1);
133 }
134 else if(k==0) {
135 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
136 cff2=FC(i,j,k)-dt_lev*bstr(i,j,0);
137 }
138 else if(k==N) {
139 cff1=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
140 cff2=dt_lev*sstr(i,j,0)-FC(i,j,k-1); //or: -FC(i,j,k-1)+dt_lev*sstr(i,j,0);
141 }
142
143 cff3=0.5_rt*DC(i,j,k);
144
145 if (ioff==0&&joff==0) {
146 vel(i,j,k,nnew)=cff1 + cff2;
147 } else {
148 indx=nrhs ? 0 : 1;
149 Real r_swap= rvel(i,j,k,indx);
150 rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
151 rvel(i,j,k,nrhs) = r_swap;
152 vel(i,j,k,nnew)=cff1- cff3*rvel(i,j,k,indx)+ cff2;
153 }
154 } else {
155 cff1 = 5.0_rt/12.0_rt;
156 cff2 = 16.0_rt/12.0_rt;
157 if (k==0) {
158 cff3=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
159 cff4=FC(i,j,k)-dt_lev*bstr(i,j,0);
160 //cff4=FC(i,j,k)-FC(i,j,k-1);//-bustr(i,j,0);
161
162 } else if (k == N) {
163 cff3=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
164 cff4=dt_lev*sstr(i,j,0)-FC(i,j,k-1);
165
166 } else {
167 cff3=vel_old(i,j,k,nstp)*0.5_rt*(Hz(i,j,k)+Hz(i-ioff,j-joff,k));
168 cff4=FC(i,j,k)-FC(i,j,k-1);
169 }
170
171 if (ioff==0 && joff==0) {
172 vel(i,j,k,nnew) = cff3 + cff4;
173 } else {
174 indx=nrhs ? 0 : 1;
175 Real r_swap= rvel(i,j,k,indx);
176 rvel(i,j,k,indx) = rvel(i,j,k,nrhs);
177 rvel(i,j,k,nrhs) = r_swap;
178
179 vel(i,j,k,nnew) = cff3 + DC(i,j,k)*(cff1*rvel(i,j,k,nrhs)-
180 cff2*rvel(i,j,k,indx))+cff4;
181 rvel(i,j,k,nrhs) = 0.0_rt;
182 }
183 }
184 });
185}
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 > &DC, 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:1248