REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_rhs_uv_2d.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/**
6 * @param[in ] xbx Box for operations on x-velocity
7 * @param[in ] ybx Box for operations on y-velocity
8 * @param[in ] ubar barotropic x-velocity
9 * @param[in ] vbar barotropic y-velocity
10 * @param[inout] rhs_ubar RHS for barotropic x-velocity
11 * @param[inout] rhs_vbar RHS for barotropic y-velocity
12 * @param[in ] DUon u-volume flux (barotropic)
13 * @param[in ] DVom v-volume flux (barotropic)
14 * @param[in ] krhs index of rhs component
15 */
16void
17REMORA::rhs_uv_2d (const Box& xbx, const Box& ybx,
18 const Array4<Real const>& ubar,
19 const Array4<Real const>& vbar,
20 const Array4<Real >& rhs_ubar ,
21 const Array4<Real >& rhs_vbar,
22 const Array4<Real const>& DUon,
23 const Array4<Real const>& DVom,
24 const int krhs)
25{
26 const Box& domain = geom[0].Domain();
27 const auto dlo = amrex::lbound(domain);
28 const auto dhi = amrex::ubound(domain);
29
30 GeometryData const& geomdata = geom[0].data();
31 bool is_periodic_in_x = geomdata.isPeriodic(0);
32 bool is_periodic_in_y = geomdata.isPeriodic(1);
33
34 int ncomp = 1;
35 Vector<BCRec> bcrs_x(ncomp);
36 Vector<BCRec> bcrs_y(ncomp);
37 amrex::setBC(xbx,domain,BCVars::xvel_bc,0,1,domain_bcs_type,bcrs_x);
38 amrex::setBC(ybx,domain,BCVars::yvel_bc,0,1,domain_bcs_type,bcrs_y);
39
40 //
41 // Scratch space
42 //
43 FArrayBox fab_UFx(growLo(xbx,0,1),1,amrex::The_Async_Arena()); fab_UFx.template setVal<RunOn::Device>(0.);
44 FArrayBox fab_UFe(growHi(xbx,1,1),1,amrex::The_Async_Arena()); fab_UFe.template setVal<RunOn::Device>(0.);
45 FArrayBox fab_VFe(growLo(ybx,1,1),1,amrex::The_Async_Arena()); fab_VFe.template setVal<RunOn::Device>(0.);
46 FArrayBox fab_VFx(growHi(ybx,0,1),1,amrex::The_Async_Arena()); fab_VFx.template setVal<RunOn::Device>(0.);
47
48 auto UFx=fab_UFx.array();
49 auto UFe=fab_UFe.array();
50 auto VFx=fab_VFx.array();
51 auto VFe=fab_VFe.array();
52
53 auto uv_hadv_scheme = solverChoice.uv_Hadv_scheme;
54
55 if (uv_hadv_scheme == AdvectionScheme::upstream3) {
56 // *************************************************************
57 // UPDATING U
58 // *************************************************************
59
60 // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
61 //
62 // xbx is the x-face-centered box on which we update ubar (with rhs_ubar) [ 0:nx , 0:ny-1] (1,0,0) x-faces
63 // to do so requires UFx on [-1:nx , 0:ny-1] (0,0,0) cc
64 // which requires ubar on [-2:nx+2, 0:ny-1] (1,0,0) x-faces
65 // and requires DUon on [-2:nx+2, 0:ny-1] (1,0,0) x-faces
66 // to do so requires UFe on [ 0:nx , 0:ny ] (1,1,0) xy-nodes
67 // which requires ubar on [ 0:nx ,-2:ny+1] (1,0,0) x-faces
68 // and requires DVom on [-2:nx+1, 0:ny-1] (0,1,0) y-faces
69
70 //
71 // Define UFx, the x-fluxes at cell centers for updating u
72 // (Note that grow arguments are (bx, dir, ng)
73 //
74 ParallelFor(growLo(xbx,0,1),
75 [=] AMREX_GPU_DEVICE (int i, int j, int )
76 {
77 Real uxx_i = ubar(i-1,j,0,krhs)-2.0_rt*ubar(i ,j,0,krhs)+ubar(i+1,j,0,krhs);
78 Real uxx_ip1 = ubar(i ,j,0,krhs)-2.0_rt*ubar(i+1,j,0,krhs)+ubar(i+2,j,0,krhs);
79
80 Real Huxx_i = DUon(i-1,j,0)-2.0_rt*DUon(i ,j,0)+DUon(i+1,j,0);
81 Real Huxx_ip1 = DUon(i ,j,0)-2.0_rt*DUon(i+1,j,0)+DUon(i+2,j,0);
82
83 if (i == dlo.x && !is_periodic_in_x) {
84 uxx_i = uxx_ip1;
85 Huxx_i = Huxx_ip1;
86 }
87 else if (i == dhi.x && !is_periodic_in_x) {
88 uxx_ip1 = uxx_i;
89 Huxx_ip1 = Huxx_i;
90 }
91
92 Real cff=1.0_rt/6.0_rt;
93 Real ubar_avg = ubar(i ,j,0,krhs)+ubar(i+1,j,0,krhs);
94
95 UFx(i,j,0)=0.25_rt*(ubar_avg-cff*(uxx_i+uxx_ip1)) * (DUon(i,j,0)+ DUon(i+1,j,0)-cff*(Huxx_i+ Huxx_ip1));
96 });
97
98 //
99 // Define UFe, the y-fluxes at nodes for updating u
100 //
101 ParallelFor(growHi(xbx,1,1),
102 [=] AMREX_GPU_DEVICE (int i, int j, int )
103 {
104 //should not include grow cells
105 Real uee_j = ubar(i,j-1,0,krhs)-2.0_rt*ubar(i,j ,0,krhs)+ubar(i,j+1,0,krhs);
106 Real uee_jm1 = ubar(i,j-2,0,krhs)-2.0_rt*ubar(i,j-1,0,krhs)+ubar(i,j ,0,krhs);
107
108 Real Hvxx_i = DVom(i-1,j,0)-2.0_rt*DVom(i ,j,0)+DVom(i+1,j,0);
109 Real Hvxx_im1 = DVom(i-2,j,0)-2.0_rt*DVom(i-1,j,0)+DVom(i ,j,0);
110
111 if (j == dlo.y and !is_periodic_in_y) {
112 uee_jm1 = uee_j;
113 } else if (j == dhi.y+1 and !is_periodic_in_y) {
114 uee_j = uee_jm1;
115 }
116
117 Real cff=1.0_rt/6.0_rt;
118 Real cff1=ubar(i,j ,0,krhs)+ubar(i,j-1,0,krhs);
119 Real cff2=DVom(i,j,0)+DVom(i-1,j,0);
120
121 UFe(i,j,0)=0.25_rt*(cff1-(uee_j+uee_jm1)*cff)*
122 (cff2-cff*(Hvxx_i+Hvxx_im1));
123 });
124 } else if (uv_hadv_scheme == AdvectionScheme::centered2) {
125 ParallelFor(growLo(xbx,0,1),
126 [=] AMREX_GPU_DEVICE (int i, int j, int )
127 {
128 UFx(i,j,0) = 0.25_rt * (DUon(i,j,0)+DUon(i+1,j,0)) * (ubar(i,j,0,krhs)+ubar(i+1,j,0,krhs));
129 });
130
131 ParallelFor(growHi(xbx,1,1),
132 [=] AMREX_GPU_DEVICE (int i, int j, int )
133 {
134 UFe(i,j,0) = 0.25_rt * (DVom(i,j,0)+DVom(i-1,j,0)) * (ubar(i,j,0,krhs)+ubar(i,j-1,0,krhs));
135 });
136 }
137
138 //
139 // Add in horizontal advection.
140 //
141 ParallelFor(makeSlab(xbx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
142 {
143 Real cff1=UFx(i,j ,0)-UFx(i-1,j,0);
144 Real cff2=UFe(i,j+1,0)-UFe(i ,j,0);
145
146 rhs_ubar(i,j,0) -= (cff1 + cff2);
147 });
148
149 if (uv_hadv_scheme == AdvectionScheme::upstream3) {
150 // *************************************************************
151 // UPDATING V
152 // *************************************************************
153
154 // Think of the cell-centered box as [ 0:nx-1, 0:ny-1] (0,0,0) cc
155 //
156 // ybx is the y-face-centered box on which we update vbar (with rhs_vbar) [ 0:nx-1, 0:ny ] (1,0,0) y-faces
157 // to do so requires VFe on [ 0:nx-1,-1:ny ] (1,1,0) xy-nodes
158 // which requires vbar on [ 0:nx-1,-2:ny+2] (1,0,0) y-faces
159 // and requires DVom on [ 0:nx-1,-2:ny+2] (0,1,0) x-faces
160 // to do so requires VFx on [ 0:nx , 0:ny ] (0,0,0) cc
161 // which requires vbar on [-2:nx+1, 0:ny ] (1,0,0) y-faces
162 // and requires DUon on [ 0:nx-1,-2:ny+1] (0,0,0) y-faces
163
164 // Grow ybx by one in high x-direction
165 ParallelFor(growHi(ybx,0,1),
166 [=] AMREX_GPU_DEVICE (int i, int j, int )
167 {
168 Real cff=1.0_rt/6.0_rt;
169 Real vxx_i = vbar(i-1,j,0,krhs)-2.0_rt*vbar(i ,j,0,krhs)+vbar(i+1,j,0,krhs);
170 Real vxx_im1 = vbar(i-2,j,0,krhs)-2.0_rt*vbar(i-1,j,0,krhs)+vbar(i ,j,0,krhs);
171
172 Real Huee_j = DUon(i,j-1,0)-2.0_rt*DUon(i,j ,0)+DUon(i,j+1,0);
173 Real Huee_jm1 = DUon(i,j-2,0)-2.0_rt*DUon(i,j-1,0)+DUon(i,j ,0);
174
175 if (i == dlo.x and !is_periodic_in_x) {
176 vxx_im1 = vxx_i;
177 } else if (i == dhi.x + 1 and !is_periodic_in_x) {
178 vxx_i = vxx_im1;
179 }
180
181 Real cff1=vbar(i ,j,0,krhs)+vbar(i-1,j,0,krhs);
182 Real cff2=DUon(i,j,0)+DUon(i,j-1,0);
183
184 VFx(i,j,0)=0.25_rt*(cff1-(vxx_i + vxx_im1)*cff)* (cff2-cff*(Huee_j+ Huee_jm1));
185 });
186
187 ParallelFor(growLo(ybx,1,1),
188 [=] AMREX_GPU_DEVICE (int i, int j, int)
189 {
190 Real vee_j = vbar(i,j-1,0,krhs)-2.0_rt*vbar(i,j ,0,krhs)+vbar(i,j+1,0,krhs);
191 Real vee_jp1 = vbar(i,j ,0,krhs)-2.0_rt*vbar(i,j+1,0,krhs)+vbar(i,j+2,0,krhs);
192
193 Real Hvee_j = DVom(i,j-1,0)-2.0_rt*DVom(i,j ,0)+DVom(i,j+1,0);
194 Real Hvee_jp1 = DVom(i,j ,0)-2.0_rt*DVom(i,j+1,0)+DVom(i,j+2,0);
195
196 if (j == dlo.y and !is_periodic_in_y) {
197 vee_j = vee_jp1;
198 Hvee_j = Hvee_jp1;
199 }
200 else if (j == dhi.y and !is_periodic_in_y) {
201 vee_jp1 = vee_j;
202 Hvee_jp1 = Hvee_j;
203 }
204
205 Real cff=1.0_rt/6.0_rt;
206 Real cff1=vbar(i,j ,0,krhs)+vbar(i,j+1,0,krhs);
207
208 VFe(i,j,0) = 0.25_rt * (cff1-(vee_j + vee_jp1)*cff) * (DVom(i,j ,0)+ DVom(i,j+1,0) -
209 cff * (Hvee_j+ Hvee_jp1));
210 });
211 } else if (uv_hadv_scheme == AdvectionScheme::centered2) {
212 ParallelFor(growHi(ybx,0,1),
213 [=] AMREX_GPU_DEVICE (int i, int j, int )
214 {
215 VFx(i,j,0) = 0.25_rt * (DUon(i,j,0) + DUon(i,j-1,0))*(vbar(i,j,0,krhs)+vbar(i-1,j,0,krhs));
216 });
217 ParallelFor(growLo(ybx,1,1),
218 [=] AMREX_GPU_DEVICE (int i, int j, int )
219 {
220 VFe(i,j,0) = 0.25_rt * (DVom(i,j,0) + DVom(i,j+1,0))*(vbar(i,j,0,krhs)+vbar(i,j+1,0,krhs));
221 });
222 }
223
224 ParallelFor(makeSlab(ybx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int)
225 {
226 Real cff1=VFx(i+1,j,0)-VFx(i ,j,0);
227 Real cff2=VFe(i ,j,0)-VFe(i,j-1,0);
228
229 rhs_vbar(i,j,0) -= (cff1 + cff2);
230 });
231
232}
void rhs_uv_2d(const amrex::Box &xbx, const amrex::Box &ybx, const amrex::Array4< amrex::Real const > &uold, const amrex::Array4< amrex::Real const > &vold, const amrex::Array4< amrex::Real > &ru, const amrex::Array4< amrex::Real > &rv, const amrex::Array4< amrex::Real const > &Duon, const amrex::Array4< amrex::Real const > &Dvom, const int nrhs)
RHS terms for 2D momentum.
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
Definition REMORA.H:1120
static SolverChoice solverChoice
Container for algorithmic choices.
Definition REMORA.H:1221
AdvectionScheme uv_Hadv_scheme