File: cosine.gfs

package info (click to toggle)
gerris 20131206%2Bdfsg-21
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 14,252 kB
  • sloc: ansic: 66,595; sh: 15,922; f90: 1,513; makefile: 1,150; fortran: 696; python: 493; awk: 104; lisp: 89; xml: 27
file content (217 lines) | stat: -rw-r--r-- 7,582 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# Title: Advection of a cosine bell around the sphere
#
# Description:
#
# This test case was suggested by Williamson et
# al. \cite{williamson92} (Problem \#1). A "cosine bell" initial
# concentration is given by
# $$
# h(\lambda,\theta)=(h_0/2)(1+\cos(\pi r/R))
# $$
# if $r<R$ and 0 otherwise, with $R=1/3$ and
# $$
# r=\arccos[\sin\theta_c\sin\theta+\cos\theta_c\cos\theta\cos(\lambda-\lambda_c)]
# $$
# the great circle distance between longitude, latitude
# $(\lambda,\theta)$ and the center initially taken as
# $(\lambda_c,\theta_c)=(3\pi/2,0)$.
#
# The advection velocity field corresponds to solid-body rotation at an
# angle $\alpha$ to the polar axis of the spherical coordinate
# system. It is given by the streamfunction
# $$
# \psi=-u_0(\sin\theta\cos\alpha-\cos\lambda\cos\theta\sin\alpha)
# $$
#
# The cosine bell field is rotated once around the sphere and should
# come back exactly to its original position. The difference between
# the initial and final fields is a measure of the accuracy of the
# advection scheme coupled with the spherical coordinate mapping (the
# "conformal expanded spherical cube" metric in our case).
#
# For the "spherical cube" metric, two angles are considered: 45
# degrees which rotates the cosine bell above four of the eight "poles"
# of the mapping and 90 degrees which avoids the poles entirely. Mass
# is conserved to within machine accuracy in either case.
#
# The mesh is adapted dynamically according to the gradient of tracer
# concentration.
#
# \begin{figure}[htbp] 
# \caption{\label{solution45}Tracer field after one rotation around the
# sphere with $\alpha=45^\circ$ (red). Reference solution
# (green). Zero level contour line (blue). Equivalent static
# resolutions (a) $16\times 16\times 6$. (b) $32\times 32\times
# 6$. (c) $64\times 64\times 6$. (d) $128\times 128\times 6$.}
# \begin{center}
# \begin{tabular}{cc}
# (a) \includegraphics[width=0.45\hsize]{isolines-4-45.eps} &
# (b) \includegraphics[width=0.45\hsize]{isolines-5-45.eps} \\
# (c) \includegraphics[width=0.45\hsize]{isolines-6-45.eps} &
# (d) \includegraphics[width=0.45\hsize]{isolines-7-45.eps}
# \end{tabular}
# \end{center}
# \end{figure}
#
# \begin{figure}[htbp] 
# \caption{\label{solution90}Tracer field after one rotation around the
# sphere with $\alpha=90^\circ$ (red). Reference solution
# (green). Zero level contour line (blue). Equivalent static
# resolutions (a) $16\times 16\times 6$. (b) $32\times 32\times
# 6$. (c) $64\times 64\times 6$. (d) $128\times 128\times 6$.}
# \begin{center}
# \begin{tabular}{cc}
# (a) \includegraphics[width=0.45\hsize]{isolines-4-90.eps} &
# (b) \includegraphics[width=0.45\hsize]{isolines-5-90.eps} \\
# (c) \includegraphics[width=0.45\hsize]{isolines-6-90.eps} &
# (d) \includegraphics[width=0.45\hsize]{isolines-7-90.eps}
# \end{tabular}
# \end{center}
# \end{figure}
#
# \begin{figure}[htbp] 
# \caption{\label{error}Relative error norms (as defined in
# \cite{williamson92}) as functions of spatial resolution. The results
# of Rossmanith \cite{rossmanith2006} using a gnomonic spherical cube
# metric and a different 2nd-order advection scheme are also
# reproduced for comparison. (a) $\alpha=45^\circ$. (b)
# $\alpha=90^\circ$.}
# \begin{center}
# \begin{tabular}{c}
# (a) \includegraphics[width=0.7\hsize]{order-45.eps} \\
# (b) \includegraphics[width=0.7\hsize]{order-90.eps}
# \end{tabular}
# \end{center}
# \end{figure}
#
# \begin{figure}[htbp] 
# \caption{\label{error-t}Maximum relative errors as functions of
# time. (a) $\alpha=45^\circ$. (b) $\alpha=90^\circ$.}
# \begin{center}
# \begin{tabular}{c}
# (a) \includegraphics[width=0.7\hsize]{error-45.eps} \\
# (b) \includegraphics[width=0.7\hsize]{error-90.eps}
# \end{tabular}
# \end{center}
# \end{figure}
#
# Author: St\'ephane Popinet
# Command: sh cosine.sh
# Version: 091029
# Required files: cosine.sh isolines.gfv reference.gfv zero.gfv error-45.ref error-90.ref rossmanith45 rossmanith90
# Running time: 6 minutes
# Generated files: isolines-4-45.eps isolines-5-90.eps isolines-7-45.eps order-90.eps isolines-4-90.eps isolines-6-45.eps isolines-7-90.eps isolines-5-45.eps isolines-6-90.eps order-45.eps error-90.eps error-45.eps
#
Define U0 (2.*M_PI)

6 12 GfsAdvection GfsBox GfsGEdge {} {
  PhysicalParams { L = 2.*M_PI/4. }
  MetricCubed M LEVEL

  # Use alternative implementation
  # MetricCubed1 M
  # MapFunction {
  #     x = atan2 (X, Z)*180./M_PI
  #     y = asin (CLAMP(Y,-1.,1.))*180./M_PI
  # }

  Time { end = 1 }
  Refine LEVEL
  VariableTracer T { 
      gradient = gfs_center_gradient 
      cfl = 1
  }
  Global {
      #define DTR (M_PI/180.)
      double lambda1 (double lambda, double theta, double lambdap, double thetap) {
	  /* eq. (8) */
	  return atan2 (cos (theta)*sin (lambda - lambdap),
	                cos (theta)*sin (thetap)*cos (lambda - lambdap) - 
                        cos (thetap)* sin (theta));
      }
      double theta1 (double lambda, double theta, double lambdap, double thetap) {
	  /* eq. (9) */
	  return asin (sin (theta)*sin (thetap) + cos (theta)*cos (thetap)*cos (lambda - lambdap));
      }
      double bell (double lambda, double theta, double lc, double tc) {
	  double h0 = 1.;
	  double R = 1./3.;
	  double r = acos (sin(tc)*sin(theta) + cos (tc)*cos (theta)*cos (lambda - lc));
	  return r >= R ? 0. : (h0/2.)*(1. + cos (M_PI*r/R));
      }
      double bell_moving (double lambda, double theta, double t) {
	  double lambda2 = lambda1 (lambda, theta, M_PI, M_PI/2. - ALPHA*DTR);
	  double theta2 = theta1 (lambda, theta, M_PI, M_PI/2. - ALPHA*DTR);
	  double lc = 3.*M_PI/2. - U0*t, tc = 0.;
	  return bell (lambda2, theta2, lc, tc);
      }      
  }
  Init {} { T = bell_moving(x*DTR,y*DTR,0) }
  VariableStreamFunction Psi -U0*(sin (y*DTR)*cos (DTR*ALPHA) - cos (x*DTR)*cos (y*DTR)*sin (DTR*ALPHA))
  AdaptGradient { istep = 1 } { cmax = 1e-4 maxlevel = LEVEL } T
  OutputTime { istep = 10 } stderr
#  OutputSimulation { istep = 10 } stdout
  OutputSimulation { start = end } end-LEVEL-ALPHA.gfs
  OutputErrorNorm { istep = 1 } { awk '{ print LEVEL,$3,$5,$7,$9}' > error-LEVEL-ALPHA } { v = T } {
      s = bell_moving(x*DTR,y*DTR,t)
      v = E
      relative = 1
  }
  OutputScalarSum { istep = 1 } t-LEVEL-ALPHA { v = T }
  OutputScalarSum { istep = 1 } area-LEVEL-ALPHA { v = 1 }
  EventScript { start = end } {
      ( cat isolines.gfv
        echo "Save isolines.gnu { format = Gnuplot }"
        echo "Clear"
        cat reference.gfv
        echo "Save reference.gnu { format = Gnuplot }"
	echo "Clear"
        cat zero.gfv
        echo "Save zero.gnu { format = Gnuplot }"
      ) | gfsview-batch2D end-LEVEL-ALPHA.gfs
      cat <<EOF | gnuplot
        set term postscript eps lw 2 18 color
        set output 'isolines-LEVEL-ALPHA.eps'
        set size ratio -1
        set xlabel 'Longitude'
        set ylabel 'Latitude'
        unset key
        plot [60:120][-30:30]'isolines.gnu' w l, 'reference.gnu' w l, 'zero.gnu' w l
EOF
      fixbb isolines-LEVEL-ALPHA.eps
      rm -f isolines.gnu reference.gnu zero.gnu

      # check mass conservation
      if awk '
        BEGIN { min = 1000.; max = -1000.; }{ 
          if ($5 < min) min = $5; 
          if ($5 > max) max = $5; 
        }
        END {
          if (max - min != 0.)
            exit (1);
        }' < t-LEVEL-ALPHA; then
	  exit 0
      else
	  exit $GFS_STOP
      fi
  }
}
GfsBox {}
GfsBox {}
GfsBox {}
GfsBox {}
GfsBox {}
GfsBox {}
1 2 right
2 3 top
3 4 right
4 5 top
5 6 right
6 1 top
1 3 top left
3 5 top left
5 1 top left
2 6 bottom right
4 2 bottom right
6 4 bottom right