REMORA
Regional Modeling of Oceans Refined Adaptively
Loading...
Searching...
No Matches
REMORA_set_weights.cpp
Go to the documentation of this file.
1#include <cmath>
2#include <REMORA_DataStruct.H>
3#include <REMORA.H>
5
6using namespace amrex;
7
8/**
9 * @param[in ] lev level to operate on
10 */
11void REMORA::set_weights (int /*lev*/) {
12
13 Real gamma, scale;
14 Real wsum, shift, cff;
15
16 // ndtfast is the REMORA member, guaranteed positive by ReadParameters.
17
18 //From mod_scalars
19 Real Falpha = two;
20 Real Fbeta = Real(4.0);
21 Real Fgamma = Real(0.284);
22
23 vec_weight1.resize(2*ndtfast+1);
24 vec_weight2.resize(2*ndtfast+1);
25
26 auto weight1 = vec_weight1.dataPtr();
27 auto weight2 = vec_weight2.dataPtr();
28
29//
30//=======================================================================
31// Compute time-averaging filter for barotropic fields.
32//=======================================================================
33//
34// Initialize both sets of weights to zero.
35//
36 nfast=0;
37 for(int i=1;i<=2*ndtfast;i++) {
38 weight1[i-1]=zero;
39 weight2[i-1]=zero;
40 }
41//
42//-----------------------------------------------------------------------
43// Power-law shape filters.
44//-----------------------------------------------------------------------
45//
46// The power-law shape filters are given by:
47//
48// F(xi)=xi^Falpha*(1-xi^Fbeta)-Fgamma*xi
49//
50// where xi=scale*i/ndtfast; and scale, Falpha, Fbeta, Fgamma, and
51// normalization are chosen to yield the correct zeroth-order
52// (normalization), first-order (consistency), and second-order moments,
53// resulting in overall second-order temporal accuracy for time-averaged
54// barotropic motions resolved by baroclinic time step.
55//
57 ((Falpha+two)*(Falpha+Fbeta+two)*Real(ndtfast));
58 //
59 // Find center of gravity of the primary weighting shape function and
60 // iteratively adjust "scale" to place the centroid exactly at
61 // "ndtfast".
62 //
63 gamma = Fgamma*max(zero, one-Real(10.0)/Real(ndtfast));
64
65 for (int iter=1;iter<=16;iter++) {
66 nfast=0;
67 for(int i=1;i<=2*ndtfast;i++) {
68 cff=scale*Real(i);
69
71
72 if (weight1[i-1] > zero) {
73 nfast=i;
74 }
75
76 if ( (nfast>0) && (weight1[i-1] < zero) ) {
77 weight1[i-1] = zero;
78 }
79 }
80 wsum = zero;
81 shift = zero;
82 for(int i=1;i<=nfast;i++) {
83 wsum=wsum+weight1[i-1];
84 shift=shift+weight1[i-1]*Real(i);
85 }
86 scale *= shift/(wsum*Real(ndtfast));
87 }
88//
89//-----------------------------------------------------------------------
90// Post-processing of primary weights.
91//-----------------------------------------------------------------------
92//
93// Although it is assumed that the initial settings of the primary
94// weights has its center of gravity "reasonably close" to NDTFAST,
95// it may be not so according to the discrete rules of integration.
96// The following procedure is designed to put the center of gravity
97// exactly to NDTFAST by computing mismatch (NDTFAST-shift) and
98// applying basically an upstream advection of weights to eliminate
99// the mismatch iteratively. Once this procedure is complete primary
100// weights are normalized.
101//
102// Find center of gravity of the primary weights and subsequently
103// calculate the mismatch to be compensated.
104//
105 for (int iter=1;iter<=ndtfast;iter++) {
106 wsum = zero;
107 shift = zero;
108 for(int i=1;i<=nfast;i++) {
109 wsum=wsum+weight1[i-1];
110 shift=shift+Real(i)*weight1[i-1];
111 }
113 cff=Real(ndtfast)-shift;
114 //
115 // Apply advection step using either whole, or fractional shifts.
116 // Notice that none of the four loops here is reversible.
117 //
118 if (cff > one) {
119 nfast=nfast+1;
120 for (int i=nfast;i>=2;i--) {
121 weight1[i-1]=weight1[i-1-1];
122 }
123 weight1[1-1] = zero;
124 } else if (cff> zero) {
125 wsum=one-cff;
126 for (int i=nfast;i>=2;i--) {
127 weight1[i-1]=wsum*weight1[i-1]+cff*weight1[i-1-1];
128 }
129 weight1[1-1]=wsum*weight1[1-1];
130 } else if (cff < Real(-1.0)) {
131 nfast=nfast-1;
132 for (int i=1;i<=nfast;i++) {
133 weight1[i-1]=weight1[i+1-1];
134 }
135 weight1[nfast+1-1] = zero;
136 } else if (cff < zero) {
137 wsum=one+cff;
138 for (int i=1;i<=nfast-1;i++) {
139 weight1[i-1]=wsum*weight1[i-1]-cff*weight1[i+1-1];
140 }
142 }
143 }
144
145 // Set SECONDARY weights assuming that backward Euler time step is used
146 // for free surface. Notice that array weight2[i] is assumed to
147 // have all-zero status at entry in this segment of code.
148 for(int j=1;j<=nfast;j++) {
149 cff=weight1[j-1];
150 for(int i=1;i<=j;i++) {
151 weight2[i-1]=weight2[i-1]+cff;
152 }
153 }
154
155 //
156 // Normalize both set of weights.
157 //
158 wsum = zero;
159 cff = zero;
160 for(int i=1;i<=nfast;i++) {
161 wsum=wsum+weight1[i-1];
162 cff=cff+weight2[i-1];
163 }
164
165 wsum = one / wsum;
166 cff = one / cff;
167
168 for(int i=1;i<=nfast;i++) {
169 weight1[i-1]=wsum*weight1[i-1];
170 weight2[i-1]=cff*weight2[i-1];
171 }
172}
constexpr amrex::Real two
constexpr amrex::Real one
constexpr amrex::Real zero
mf_h setVal(geomdata.ProbHi(2))
int nfast
Number of fast steps to take.
Definition REMORA.H:1675
amrex::Vector< amrex::Real > vec_weight2
Weights for calculating avg2 in 2D advance.
Definition REMORA.H:628
amrex::Vector< amrex::Real > vec_weight1
Weights for calculating avg1 in 2D advance.
Definition REMORA.H:626
static int ndtfast
User specified, number of barotropic steps per baroclinic step.
Definition REMORA.H:1673
void set_weights(int lev)
Set weights for averaging 3D variables to 2D.