REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_vert_visc_3d.cpp
Go to the documentation of this file.
1#include <REMORA.H>
2
3using namespace amrex;
4
5/**
6 * @param[in ] phi_bx box to update on
7 * @param[in ] ioff x-direction offset
8 * @param[in ] joff y-direction offset
9 * @param[inout] phi velocity (u or v)
10 * @param[in ] Hz vertical height of cells
11 * @param Hzk temporary
12 * @param AK temporary
13 * @param[in ] Akv vertical viscosity coefficient
14 * @param BC temporary
15 * @param DC temporary
16 * @param FC temporary
17 * @param CF temporary
18 * @param[in ] nnew index of time step to update
19 * @param[in ] N number of vertical levels
20 * @param[in ] dt_lev time step at this refinement level
21 */
22void
23REMORA::vert_visc_3d (const Box& phi_bx, const int ioff, const int joff,
24 const Array4<Real >& phi,
25 const Array4<Real const>& Hz,
26 const Array4<Real >& Hzk,
27 const Array4<Real >& AK,
28 const Array4<Real const>& Akv,
29 const Array4<Real >& BC,
30 const Array4<Real >& DC,
31 const Array4<Real >& FC,
32 const Array4<Real >& CF,
33 const int nnew, const int N, const Real dt_lev)
34{
35 BL_PROFILE("REMORA::vert_visc_3d()");
36 //
37 // Put Hzk on the x- or y-face as appropriate, or leave on cell center for tracers
38 //
39 if (verbose > 1)
40 amrex::Print() << "updating on box in vert_visc_3d: " << phi_bx << std::endl;
41
42 ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
43 {
44 Hzk(i,j,k)=0.5_rt*(Hz(i-ioff,j-joff,k)+Hz(i,j,k));
45 });
46
47 //
48 // Put Akv on the x- or y-face as appropriate, or leave on cell center for tracers
49 //
50 ParallelFor(surroundingNodes(phi_bx,2), [=] AMREX_GPU_DEVICE (int i, int j, int k)
51 {
52 AK(i,j,k) = 0.5_rt * (Akv(i-ioff,j-joff,k)+Akv(i,j,k));
53 });
54
55 Gpu::streamSynchronize();
56#ifdef AMREX_USE_GPU
57 Gpu::synchronize();
58#else
59#endif
60 /////////////////// This and the following loop is the first non-matching thing that affects plotfile comparison for cuda
61 // NOTE: vertical viscosity term for tracers is identical except AK=Akt
62 const Real sixth = 1.0_rt / 6.0_rt;
63 const Real third = 1.0_rt / 3.0_rt;
64
65 ParallelFor(makeSlab(phi_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
66 {
67 DC(i,j,0) = 0.0_rt;
68 FC(i,j,0) = 0.0_rt;
69 CF(i,j,0) = 0.0_rt;
70 });
71
72 ParallelFor(makeSlab(phi_bx,2,0), N, [=] AMREX_GPU_DEVICE (int i, int j, int , int kk)
73 {
74 int k = kk+1;
75 //
76 // Use conservative, parabolic spline reconstruction of vertical
77 // viscosity derivatives. Then, time step vertical viscosity term
78 // implicitly by solving a tridiagonal system.
79 //
80 const Real oHzkm1 = 1.0_rt/ Hzk(i,j,k-1);
81 const Real oHz = 1.0_rt/ Hzk(i,j,k);
82 //const Real oHzkp1 = 1.0_rt/ Hzk(i,j,k+1);
83
84 FC(i,j,k) = sixth * Hzk(i,j,k-1) - dt_lev * AK(i,j,k-1) / Hzk(i,j,k-1);
85 CF(i,j,k) = sixth * Hzk(i,j,k ) - dt_lev * AK(i,j,k+1) / Hzk(i,j,k );
86
87 BC(i,j,k) = third * (Hzk(i,j,k-1) + Hzk(i,j,k )) + dt_lev * AK(i,j,k) * (oHzkm1 + oHz);
88 Real cff = 1.0_rt / (BC(i,j,k) - FC(i,j,k) * CF(i,j,k-1));
89 CF(i,j,k) *= cff;
90 DC(i,j,k) = cff * (phi(i,j,k ,nnew) - phi(i,j,k-1,nnew) - FC(i,j,k)*DC(i,j,k-1));
91 });
92#ifdef AMREX_USE_GPU
93 Gpu::synchronize();
94#else
95#endif
96 Gpu::streamSynchronize();
97 ParallelFor(makeSlab(phi_bx,2,0), [=] AMREX_GPU_DEVICE (int i, int j, int )
98 {
99 DC(i,j,N+1) = 0.0_rt;
100 for(int k=N; k>=1; k--) {
101 //
102 // Backward substitution.
103 //
104 DC(i,j,k) -= CF(i,j,k)*DC(i,j,k+1);
105 }
106 });
107
108#ifdef AMREX_USE_GPU
109 Gpu::synchronize();
110#endif
111
112 ParallelFor(surroundingNodes(phi_bx,2), [=] AMREX_GPU_DEVICE (int i, int j, int k)
113 {
114 DC(i,j,k) *= AK(i,j,k);
115 });
116
117 ParallelFor(phi_bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
118 {
119 const Real oHz = 1.0_rt/ Hzk(i,j,k);
120 Real cff = dt_lev*oHz*(DC(i,j,k+1)-DC(i,j,k));
121 phi(i,j,k) += cff;
122 });
123}
void vert_visc_3d(const amrex::Box &bx, const int ioff, const int joff, const amrex::Array4< amrex::Real > &phi, const amrex::Array4< amrex::Real const > &Hz, const amrex::Array4< amrex::Real > &Hzk, const amrex::Array4< amrex::Real > &AK, const amrex::Array4< amrex::Real const > &Akv, const amrex::Array4< amrex::Real > &BC, const amrex::Array4< amrex::Real > &DC, const amrex::Array4< amrex::Real > &FC, const amrex::Array4< amrex::Real > &CF, const int nnew, const int N, const amrex::Real dt_lev)
Calculate effects of vertical viscosity or diffusivity.
static int verbose
Verbosity level of output.
Definition REMORA.H:1306