REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_update_massflux_3d.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/**
6 * @param[in ] bx box on which to update
7 * @param[in ] ioff offset in x-direction
8 * @param[in ] joff offset in y-direction
9 * @param[inout] phi u or v
10 * @param[inout] phibar ubar or vbar
11 * @param[inout] Hphi phi-volume flux
12 * @param[in ] Hz vertical cell height
13 * @param[in ] pm_or_pn pm or pn
14 * @param[in ] Dphi_avg1 DU_avg1 or DV_avg1
15 * @param[in ] Dphi_avg2 DU_avg2 or DV_avg2
16 * @param DC temporary
17 * @param FC temporary
18 * @param[in ] msk land-sea mask
19 * @param[in ] nnew component of velocity
20 */
21void
23 const int ioff, const int joff,
24 const Array4<Real >& phi,
25 const Array4<Real >& phibar,
26 const Array4<Real >& Hphi,
27 const Array4<Real const>& Hz,
28 const Array4<Real const>& pm_or_pn,
29 const Array4<Real const>& Dphi_avg1,
30 const Array4<Real const>& Dphi_avg2,
31 const Array4<Real >& DC,
32 const Array4<Real >& FC,
33 const Array4<Real const>& msk,
34 const int nnew)
35{
36 const Box& domain = geom[0].Domain();
37 const auto dlo = amrex::lbound(domain);
38 const auto dhi = amrex::ubound(domain);
39
40 GeometryData const& geomdata = geom[0].data();
41 bool is_periodic_in_x = geomdata.isPeriodic(0);
42 bool is_periodic_in_y = geomdata.isPeriodic(1);
43
44 int ncomp = 1;
45 Vector<BCRec> bcrs_x(ncomp);
46 Vector<BCRec> bcrs_y(ncomp);
47 amrex::setBC(bx,domain,BCVars::xvel_bc,0,1,domain_bcs_type,bcrs_x);
48 amrex::setBC(bx,domain,BCVars::yvel_bc,0,1,domain_bcs_type,bcrs_y);
49
50 auto N = Geom(0).Domain().size()[2]-1; // Number of vertical "levs" aka, NZ
51
52 auto bxD=bx;
53 auto bx_g1z=bx;
54 bxD.makeSlab(2,0);
55 bx_g1z.grow(IntVect(0,0,1));
56
57 FArrayBox fab_CF(bxD,1,amrex::The_Async_Arena()); fab_CF.template setVal<RunOn::Device>(0.);
58 auto CF=fab_CF.array();
59
60 //Copied depth of water column calculation from DepthStretchTransform
61 //Compute thicknesses of U-boxes DC(i,j,0:N-1), total depth of the water column DC(i,j,-1)
62
63 //This takes advantage of Hz being an extra grow cell size
64 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
65 {
66 Real om_v_or_on_u = 2.0_rt / (pm_or_pn(i,j,0) + pm_or_pn(i-ioff,j-joff,0));
67
68 DC(i,j,k) = 0.5_rt * om_v_or_on_u * (Hz(i,j,k)+Hz(i-ioff,j-joff,k));
69 });
70
71 ParallelFor(bxD, [=] AMREX_GPU_DEVICE (int i, int j, int )
72 {
73 for (int k=0; k<=N; k++) {
74 DC(i,j,-1) += DC(i,j,k);
75 CF(i,j,0) += DC(i,j,k) * phi(i,j,k,nnew);
76 }
77
78 DC(i,j,-1) = 1.0_rt / DC(i,j,-1);
79 CF(i,j,0) = DC(i,j,-1) * (CF(i,j,0) - Dphi_avg1(i,j,0));
80
81 for (int k=0; k<=N; k++) {
82 if (i == dlo.x-joff && !is_periodic_in_x) {
83 phi(i,j,k,nnew) -= CF(i,j,0);
84 phi(i,j,k,nnew) *= msk(i,j,0);
85 } else if (i == dhi.x+1 && !is_periodic_in_x) {
86 phi(i,j,k,nnew) -= CF(i,j,0);
87 phi(i,j,k,nnew) *= msk(i,j,0);
88 } else if (j == dlo.y-ioff && !is_periodic_in_y) {
89 phi(i,j,k,nnew) -= CF(i,j,0);
90 phi(i,j,k,nnew) *= msk(i,j,0);
91 } else if (j == dhi.y+1 && !is_periodic_in_y) {
92 phi(i,j,k,nnew) -= CF(i,j,0);
93 phi(i,j,k,nnew) *= msk(i,j,0);
94 }
95 }
96
97 for (int k=0; k<=N; k++) {
98 Hphi(i,j,k) = 0.5_rt * (Hphi(i,j,k)+phi(i,j,k,nnew)*DC(i,j,k));
99 FC(i,j,0) += Hphi(i,j,k);
100 } // k
101
102 FC(i,j,0) = DC(i,j,-1)*(FC(i,j,0)-Dphi_avg2(i,j,0));
103 });
104
105 ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
106 {
107 Hphi(i,j,k) -= DC(i,j,k)*FC(i,j,0);
108 });
109
110 ParallelFor(bxD, [=] AMREX_GPU_DEVICE(int i, int j, int )
111 {
112 phibar(i,j,0,0) = DC(i,j,-1) * Dphi_avg1(i,j,0);
113 phibar(i,j,0,1) = phibar(i,j,0,0);
114 });
115
116}
amrex::Vector< amrex::BCRec > domain_bcs_type
vector (over BCVars) of BCRecs
Definition REMORA.H:1120
void update_massflux_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real > &phibar, const amrex::Array4< amrex::Real > &Hphi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real const > &pm_or_pn, const amrex::Array4< amrex::Real const > &Dphi1, const amrex::Array4< amrex::Real const > &Dphi2, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real const > &msk, const int nnew)
Correct mass flux.