gphys 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +7414 -0
- data/LICENSE.txt +1 -1
- data/Rakefile +0 -2
- data/doc/derivative/math-doc/document/images.log +385 -0
- data/doc/ep_flux/math-doc/document/images.log +1375 -0
- data/doc/ganalysis/doc/NumRu.html +203 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis.html +931 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/BetaPlane.html +574 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/Fitting.html +576 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/LogP.html +425 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/Met.html +2021 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/MetZ.html +524 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/Planet.html +1047 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG.html +794 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG/Uninitialized.html +215 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG_common.html +603 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere.html +760 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere_common.html +251 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/QG_sphere_div.html +424 -0
- data/doc/ganalysis/doc/NumRu/GAnalysis/SigmaCoord.html +321 -0
- data/doc/ganalysis/doc/NumRu/GGraph.html +334 -0
- data/doc/ganalysis/doc/NumRu/GPhys.html +579 -0
- data/doc/ganalysis/doc/Object.html +210 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/beta_plane_rb.html +60 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/covariance_rb.html +56 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/eof_rb.html +64 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/fitting_rb.html +54 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/histogram_rb.html +58 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/log_p_rb.html +60 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/met_rb.html +60 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/met_z_rb.html +58 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/planet_rb.html +58 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/qg_rb.html +64 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis/sigma_coord_rb.html +56 -0
- data/doc/ganalysis/doc/__/__/lib/numru/ganalysis_rb.html +98 -0
- data/doc/ganalysis/doc/created.rid +13 -0
- data/doc/ganalysis/doc/images/brick.png +0 -0
- data/doc/ganalysis/doc/images/brick_link.png +0 -0
- data/doc/ganalysis/doc/images/bug.png +0 -0
- data/doc/ganalysis/doc/images/bullet_black.png +0 -0
- data/doc/ganalysis/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/ganalysis/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/ganalysis/doc/images/date.png +0 -0
- data/doc/ganalysis/doc/images/find.png +0 -0
- data/doc/ganalysis/doc/images/loadingAnimation.gif +0 -0
- data/doc/ganalysis/doc/images/macFFBgHack.png +0 -0
- data/doc/ganalysis/doc/images/package.png +0 -0
- data/doc/ganalysis/doc/images/page_green.png +0 -0
- data/doc/ganalysis/doc/images/page_white_text.png +0 -0
- data/doc/ganalysis/doc/images/page_white_width.png +0 -0
- data/doc/ganalysis/doc/images/plugin.png +0 -0
- data/doc/ganalysis/doc/images/ruby.png +0 -0
- data/doc/ganalysis/doc/images/tag_green.png +0 -0
- data/doc/ganalysis/doc/images/wrench.png +0 -0
- data/doc/ganalysis/doc/images/wrench_orange.png +0 -0
- data/doc/ganalysis/doc/images/zoom.png +0 -0
- data/doc/ganalysis/doc/index.html +383 -0
- data/doc/ganalysis/doc/js/darkfish.js +118 -0
- data/doc/ganalysis/doc/js/jquery.js +32 -0
- data/doc/ganalysis/doc/js/quicksearch.js +114 -0
- data/doc/ganalysis/doc/js/thickbox-compressed.js +10 -0
- data/doc/ganalysis/doc/rdoc.css +763 -0
- data/ext/numru/gphys/ext_init.c +1 -0
- data/ext/numru/gphys/quad_mesh_sample.c +478 -0
- data/gphys.gemspec +2 -2
- data/lib/numru/dclext.rb +394 -14
- data/lib/numru/derivative.rb +6 -0
- data/lib/numru/ganalysis/qg.rb +6 -4
- data/lib/numru/ggraph.rb +41 -8
- data/lib/numru/gphys/gphys.rb +62 -14
- data/lib/numru/gphys/gphys_io.rb +4 -4
- data/lib/numru/gphys/version.rb +2 -2
- metadata +84 -79
- data/.gitignore +0 -14
- data/TODO_ep_flux +0 -6
- data/gphys-bigmem.gemspec +0 -44
- data/install.rb +0 -130
- data/sample/cira86_to_nc.rb +0 -122
- data/sample/druby_cli1.rb +0 -23
- data/sample/druby_cli2.rb +0 -28
- data/sample/druby_serv1.rb +0 -30
- data/sample/druby_serv2.rb +0 -51
- data/sample/ep_flux/demo_NCEP_1.rb +0 -48
- data/sample/ep_flux/demo_NCEP_2.rb +0 -57
- data/sample/ep_flux/demo_NCEP_3.rb +0 -81
- data/sample/ggraph_latlon_labelling_dr002690.rb +0 -159
- data/sample/ggraph_mapfit-axes_dr002687.rb +0 -131
- data/sample/map_projection.rb +0 -121
- data/sample/ncep_theta_coord.rb +0 -79
- data/test_old/eof_slp.rb +0 -28
- data/test_old/mltbit.dat +0 -0
- data/test_old/test_ep_flux.rb +0 -533
- data/test_old/test_multibitIO.rb +0 -19
data/sample/map_projection.rb
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
=map_projection.rb
|
3
|
-
==USAGE
|
4
|
-
% ruby map_projection.rb [wsn]
|
5
|
-
where wsn is 1,2,3,or 4.
|
6
|
-
PNG files will be dumped if wsn==4.
|
7
|
-
=end
|
8
|
-
|
9
|
-
require 'numru/ggraph'
|
10
|
-
include NumRu
|
11
|
-
|
12
|
-
wsn = ( ARGV[0] ? ARGV[0].to_i : 1 )
|
13
|
-
|
14
|
-
path = '../testdata/T.jan.nc'
|
15
|
-
var = 'T'
|
16
|
-
gp = GPhys::IO.open(path,var)
|
17
|
-
|
18
|
-
DCL.swpset('ldump',true) if wsn == 4
|
19
|
-
DCL.gropn(wsn)
|
20
|
-
DCL.sldiv('t',3,2)
|
21
|
-
DCL.uzfact(1.1)
|
22
|
-
DCL.sgpset('lcntl',false)
|
23
|
-
|
24
|
-
# < defalut: itr==1 >
|
25
|
-
GGraph.set_fig('viewport'=>[0.2,0.8,0.21,0.81])
|
26
|
-
GGraph.tone( gp )
|
27
|
-
DCL.grfrm
|
28
|
-
|
29
|
-
# < map projection >
|
30
|
-
|
31
|
-
GGraph.set_map('vpt_boundary'=>true, 'coast_world'=>true)
|
32
|
-
|
33
|
-
itr=11
|
34
|
-
GGraph.set_fig('itr'=>itr)
|
35
|
-
[ [180.0,0.0,0.0], [180.0,0.0,180.0] ].each do |axis|
|
36
|
-
GGraph.next_fig('map_axis'=>axis)
|
37
|
-
GGraph.tone( gp.cut('lat'=>-70.0..-20.0) )
|
38
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" map_axis=#{axis.inspect}",
|
39
|
-
0.03, 0, 0, 3)
|
40
|
-
|
41
|
-
GGraph.next_fig('map_axis'=>axis, 'map_window'=>[-180.0,180.0,-70.0,-20.0])
|
42
|
-
GGraph.tone( gp.cut('lat'=>-70.0..-20.0) )
|
43
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" map_axis=#{axis.inspect}",
|
44
|
-
0.03, 0, 0, 3)
|
45
|
-
end
|
46
|
-
|
47
|
-
[ [180.0,0.0,90.0], [180.0,0.0,60.0] ].each do |axis|
|
48
|
-
GGraph.next_fig('map_axis'=>axis)
|
49
|
-
GGraph.tone( gp.cut('lat'=>-70.0..-20.0) )
|
50
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" map_axis=#{axis.inspect}",
|
51
|
-
0.03, 0, 0, 3)
|
52
|
-
end
|
53
|
-
|
54
|
-
GGraph.set_map('vpt_boundary'=>false)
|
55
|
-
|
56
|
-
[10,11,12,13,14,15].each do |itr|
|
57
|
-
GGraph.next_fig('itr'=>itr)
|
58
|
-
GGraph.tone( gp )
|
59
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr), 0.03, 0, 0, 3)
|
60
|
-
end
|
61
|
-
|
62
|
-
[20,21,22,23,30,31,32,33].each do |itr|
|
63
|
-
GGraph.next_fig('itr'=>itr)
|
64
|
-
if itr==31 # polar stereo
|
65
|
-
GGraph.next_map('vpt_boundary'=>3)
|
66
|
-
DCL::sgpset('lclip', true)
|
67
|
-
else
|
68
|
-
DCL::sgpset('lclip', false)
|
69
|
-
end
|
70
|
-
GGraph.tone( gp )
|
71
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr), 0.03, 0, 0, 3)
|
72
|
-
|
73
|
-
axis = [135,60,0]
|
74
|
-
GGraph.next_fig('itr'=>itr,'map_axis'=>axis,'map_radius'=>60.0)
|
75
|
-
GGraph.next_map('vpt_boundary'=>3) if itr==31 # polar stereo
|
76
|
-
GGraph.tone( gp.cut('lat'=>0..90) )
|
77
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" map_axis=#{axis.inspect}",
|
78
|
-
0.03, 0, 0, 3)
|
79
|
-
end
|
80
|
-
|
81
|
-
# < cylindrical and mercator; effects of 'map_fit' >
|
82
|
-
|
83
|
-
gpjpn = gp.cut(110..160,10..70,false)
|
84
|
-
|
85
|
-
itr = 10
|
86
|
-
GGraph.next_fig('itr'=>itr)
|
87
|
-
GGraph.tone( gpjpn )
|
88
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+' defaut', 0.03, 0, 0, 3)
|
89
|
-
|
90
|
-
itr = 10
|
91
|
-
GGraph.next_fig('itr'=>itr, 'map_fit'=>false )
|
92
|
-
GGraph.tone( gpjpn )
|
93
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" 'map_fit'=>false", 0.03, 0, 0, 3)
|
94
|
-
|
95
|
-
itr=11
|
96
|
-
GGraph.next_fig('itr'=>itr)
|
97
|
-
GGraph.tone( gpjpn )
|
98
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+' defaut', 0.03, 0, 0, 3)
|
99
|
-
|
100
|
-
GGraph.next_fig('itr'=>itr, 'map_fit'=>true)
|
101
|
-
GGraph.tone( gpjpn)
|
102
|
-
DCL::sgtxzr(0.5, 0.15, DCL::sgtrnl(itr).strip+" 'map_fit'=>true", 0.03, 0, 0, 3)
|
103
|
-
|
104
|
-
itr = 10
|
105
|
-
GGraph.next_fig('itr'=>itr)
|
106
|
-
GGraph.tone( gpjpn, true, 'map_axes'=>true, 'title'=>'itr=10 & map_axes=true' )
|
107
|
-
GGraph.contour( gpjpn, false, 'map_axes'=>true, 'title'=>'itr=10 & map_axes=true' )
|
108
|
-
|
109
|
-
gpjpn2 = gp.cut(110..180,10..70,false)
|
110
|
-
|
111
|
-
itr = 10
|
112
|
-
GGraph.next_fig('itr'=>itr)
|
113
|
-
GGraph.contour( gpjpn2, true, 'map_axes'=>true, 'title'=>'itr=10 & map_axes=true' )
|
114
|
-
|
115
|
-
#itr = 10
|
116
|
-
#GGraph.next_fig('itr'=>itr)
|
117
|
-
#GGraph.vector( gpjpn, gpjpn, true, 'map'=>true, 'title'=>'itr=10 & map_axes=true', 'unit_vect'=>true )
|
118
|
-
|
119
|
-
|
120
|
-
DCL.grcls
|
121
|
-
|
data/sample/ncep_theta_coord.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
# = Sample program to use GPhys#interpolation by using NCEP reanalysis data
|
2
|
-
#
|
3
|
-
# USAGE
|
4
|
-
#
|
5
|
-
# % ruby ncep_theta_coord.rb [data_directory [varname [year [day_of_yr_from0]]]]
|
6
|
-
#
|
7
|
-
# COMMAND-LINE OPTIONS
|
8
|
-
#
|
9
|
-
# * data_directory : directory where the NCEP data situated -- by default
|
10
|
-
# an existing OPeNDAP directory is specified -- so it should work,
|
11
|
-
# though it may be slow for network data transfer.
|
12
|
-
# * others : you can guess -- see the source code.
|
13
|
-
#
|
14
|
-
# DESCRIPTION
|
15
|
-
#
|
16
|
-
# Here are two samples: one is a simple interpolation along a coordinate
|
17
|
-
# and the other is a coordinate transformation from pressure to potential
|
18
|
-
# temperature (isentropic coordinate).
|
19
|
-
|
20
|
-
require "numru/ggraph"
|
21
|
-
include NumRu
|
22
|
-
|
23
|
-
|
24
|
-
dir = ARGV[0] || "http://db-dods.rish.kyoto-u.ac.jp/cgi-bin/nph-dods/ncep/ncep.reanalysis.dailyavgs/pressure"
|
25
|
-
|
26
|
-
vname = ARGV[1] || "uwnd" # name of the variable to be interpolated
|
27
|
-
|
28
|
-
year = ARGV[2] || 2008
|
29
|
-
iday = ( ARGV[3] || 0 ).to_i # day of the year
|
30
|
-
|
31
|
-
|
32
|
-
xsel = 0
|
33
|
-
temp = GPhys::IO.open(dir+"/air.#{year}.nc","air")[xsel,false,2..-1,iday]
|
34
|
-
gp = GPhys::IO.open(dir+"/#{vname}.#{year}.nc",vname)[xsel,false,2..-1,iday]
|
35
|
-
|
36
|
-
prs = temp.axis("level").to_gphys
|
37
|
-
p00 = UNumeric[1000.0, "millibar"]
|
38
|
-
kappa = 2.0 / 7.0
|
39
|
-
pfact = (prs/p00)**(-kappa)
|
40
|
-
|
41
|
-
theta = temp * pfact
|
42
|
-
theta.name = "theta"
|
43
|
-
theta.long_name = "potential theta"
|
44
|
-
|
45
|
-
gp.set_assoc_coords([theta])
|
46
|
-
|
47
|
-
tht_crd = VArray.new( NArray[300.0,350.0, 400.0, 500.0, 700.0, 800.0] ).rename("theta")
|
48
|
-
gp_ontht = gp.interpolate("level"=>tht_crd)
|
49
|
-
|
50
|
-
p_crd = VArray.new( NArray[25.0, 15.0] ).rename("level")
|
51
|
-
p_crd.units = "hPa"
|
52
|
-
gp_onp = gp.interpolate(p_crd) # 1D: same as interpolate("level"=>p_crd)
|
53
|
-
|
54
|
-
DCL.swpset('iwidth',800)
|
55
|
-
DCL.swpset('iheight',800)
|
56
|
-
|
57
|
-
DCL.gropn(1)
|
58
|
-
DCL.sgpset('isub', 96) # control character of subscription: '_' --> '`'
|
59
|
-
DCL.glpset('lmiss',true)
|
60
|
-
DCL.sldiv('y',2,2)
|
61
|
-
|
62
|
-
GGraph::set_fig "itr"=>2
|
63
|
-
|
64
|
-
GGraph::tone_and_contour theta[false],true,"int"=>50
|
65
|
-
GGraph::color_bar
|
66
|
-
|
67
|
-
GGraph::tone_and_contour gp[false],true
|
68
|
-
GGraph::color_bar
|
69
|
-
|
70
|
-
GGraph::set_fig "itr"=>1
|
71
|
-
|
72
|
-
GGraph::tone_and_contour gp_onp[false],true,"keep"=>true
|
73
|
-
GGraph::color_bar
|
74
|
-
|
75
|
-
GGraph::tone_and_contour gp_ontht[false],true,"keep"=>true
|
76
|
-
GGraph::color_bar
|
77
|
-
|
78
|
-
|
79
|
-
DCL.grcls
|
data/test_old/eof_slp.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require "numru/gphys"
|
2
|
-
require "numru/ganalysis"
|
3
|
-
require "numru/ggraph"
|
4
|
-
include NumRu
|
5
|
-
|
6
|
-
slp = GPhys::IO.open("slp.mon.mean.nc","slp") # ftp://ftp.cdc.noaa.gov/Datasets/ncep.reanalysis.derived/surface/slp.mon.mean.nc
|
7
|
-
slp = slp.cut("lat"=>30..90) # 北緯30度以北のデータを使用する
|
8
|
-
slp = slp[{0..-1,4},{0..-1,2},true] # 経度, 緯度について4, 2点おきに読む
|
9
|
-
# 計算時間を速めるため(∴不要)
|
10
|
-
nt = slp.shape[2]
|
11
|
-
mon = NArray.sint(12,nt/12).indgen #=> [ [0,1,..,11], [12,13,..,23], .. ]
|
12
|
-
mon = mon[[0,1,11],true] # [0,1,11]: Jan,Feb,Dec (use [0] to include only Jan)
|
13
|
-
mon = mon.reshape!(mon.total) # to 1D (list of months to use)
|
14
|
-
slp = slp[true,true,mon] # 12,1,2月のデータを切取り
|
15
|
-
|
16
|
-
vec,val = slp.eof("time","norder"=>2) # EOF第2モードまで計算する
|
17
|
-
|
18
|
-
DCL::gropn(4)
|
19
|
-
GGraph.set_fig("itr"=>32)
|
20
|
-
eof = vec[true,true,0]
|
21
|
-
if eof.cut("lat"=>90).mean > 0
|
22
|
-
eof = -eof # 北極における値がが負になるようにする
|
23
|
-
end
|
24
|
-
GGraph.tone(eof, true, "min"=>-7.0, "max"=>7.0)
|
25
|
-
GGraph.contour(eof,false, "min"=>-7.0, "max"=>7.0)
|
26
|
-
GGraph.map("coast_world"=>true)
|
27
|
-
|
28
|
-
DCL::grcls
|
data/test_old/mltbit.dat
DELETED
Binary file
|
data/test_old/test_ep_flux.rb
DELETED
@@ -1,533 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
=test.rb for module NumRu::GPhys::EP_Flux in ep_flux.rb
|
3
|
-
|
4
|
-
==todo
|
5
|
-
* add draw code.
|
6
|
-
=end
|
7
|
-
|
8
|
-
require 'narray'
|
9
|
-
require 'numru/gphys'
|
10
|
-
require 'numru/gphys/ep_flux'
|
11
|
-
require 'getopts' # to use option
|
12
|
-
|
13
|
-
include NumRu
|
14
|
-
include NMath
|
15
|
-
|
16
|
-
########################################################
|
17
|
-
######## Define Test Methods ########
|
18
|
-
|
19
|
-
## -----------------------------------------------------
|
20
|
-
# preparation GPhys objects for test
|
21
|
-
|
22
|
-
def gen_gphys__W_and_Temp_in_z_coordinate(na_u,na_v,na_w,na_t,
|
23
|
-
na_lon,na_lat,na_z)
|
24
|
-
## make GPhys
|
25
|
-
grid = make_grid_in_z(na_lon, na_lat, na_z)
|
26
|
-
gp_u = GPhys.new(grid, make_va_u( na_u ))
|
27
|
-
gp_v = GPhys.new(grid, make_va_v( na_v ))
|
28
|
-
gp_w = GPhys.new(grid, make_va_w( na_w ))
|
29
|
-
gp_t = GPhys.new(grid, make_va_t( na_t ))
|
30
|
-
return gp_u, gp_v, gp_w, gp_t
|
31
|
-
end
|
32
|
-
|
33
|
-
def gen_gphys__W_and_Temp_in_p_coordinate(na_u,na_v,na_w,na_t,
|
34
|
-
na_lon,na_lat,na_p)
|
35
|
-
## make GPhys
|
36
|
-
grid = make_grid_in_p(na_lon, na_lat, na_p)
|
37
|
-
gp_u = GPhys.new(grid, make_va_u( na_u ))
|
38
|
-
gp_v = GPhys.new(grid, make_va_v( na_v ))
|
39
|
-
gp_w = GPhys.new(grid, make_va_w( na_w ))
|
40
|
-
gp_t = GPhys.new(grid, make_va_t( na_t ))
|
41
|
-
return gp_u, gp_v, gp_w, gp_t
|
42
|
-
end
|
43
|
-
|
44
|
-
def gen_gphys__Omega_and_Theta_in_z_coordinate(na_u,na_v,na_omega,na_theta,
|
45
|
-
na_lon,na_lat,na_z)
|
46
|
-
## make GPhys
|
47
|
-
grid = make_grid_in_z(na_lon, na_lat, na_z)
|
48
|
-
gp_u = GPhys.new(grid, make_va_u( na_u ))
|
49
|
-
gp_v = GPhys.new(grid, make_va_v( na_v ))
|
50
|
-
gp_omega = GPhys.new(grid, make_va_omega( na_omega ))
|
51
|
-
gp_theta = GPhys.new(grid, make_va_theta( na_theta ))
|
52
|
-
return gp_u, gp_v, gp_omega, gp_theta
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
def make_grid_in_z(na_lon, na_lat, na_z)
|
57
|
-
va_lon = VArray.new( na_lon,
|
58
|
-
{"long_name"=>"longitude","units"=>"degrees"},
|
59
|
-
"lon" )
|
60
|
-
va_lat = VArray.new( na_lat,
|
61
|
-
{"long_name"=>"latitude","units"=>"degrees"},
|
62
|
-
"lat" )
|
63
|
-
va_z = VArray.new( na_z,
|
64
|
-
{"long_name"=>"altitude","units"=>"m"},
|
65
|
-
"alt" )
|
66
|
-
lon = Axis.new.set_pos(va_lon)
|
67
|
-
lat = Axis.new.set_pos(va_lat)
|
68
|
-
z = Axis.new.set_pos(va_z)
|
69
|
-
return Grid.new(lon, lat, z)
|
70
|
-
end
|
71
|
-
|
72
|
-
def make_grid_in_p(na_lon, na_lat, na_p)
|
73
|
-
va_lon = VArray.new( na_lon,
|
74
|
-
{"long_name"=>"longitude","units"=>"degrees"},
|
75
|
-
"lon" )
|
76
|
-
va_lat = VArray.new( na_lat,
|
77
|
-
{"long_name"=>"latitude","units"=>"degrees"},
|
78
|
-
"lat" )
|
79
|
-
va_p = VArray.new( na_p,
|
80
|
-
{"long_name"=>"pressure","units"=>"mb"},
|
81
|
-
"p" )
|
82
|
-
lon = Axis.new.set_pos(va_lon)
|
83
|
-
lat = Axis.new.set_pos(va_lat)
|
84
|
-
pres = Axis.new.set_pos(va_p)
|
85
|
-
return Grid.new(lon, lat, pres)
|
86
|
-
end
|
87
|
-
|
88
|
-
def make_va_u( na_u )
|
89
|
-
VArray.new( na_u, {"long_name"=>"U","units"=>"m/s"}, "u" )
|
90
|
-
end
|
91
|
-
def make_va_v( na_v )
|
92
|
-
VArray.new( na_v, {"long_name"=>"V","units"=>"m/s"}, "v" )
|
93
|
-
end
|
94
|
-
def make_va_w( na_w )
|
95
|
-
VArray.new( na_w, {"long_name"=>"W","units"=>"m/s"}, "w" )
|
96
|
-
end
|
97
|
-
def make_va_omega( na_omega )
|
98
|
-
VArray.new( na_omega,
|
99
|
-
{"long_name"=>"Omega","units"=>"mb/s"}, "Omega" )
|
100
|
-
end
|
101
|
-
def make_va_t( na_t )
|
102
|
-
VArray.new( na_t, {"long_name"=>"T","units"=>"K"}, "t" )
|
103
|
-
end
|
104
|
-
def make_va_theta( na_theta )
|
105
|
-
VArray.new( na_theta,
|
106
|
-
{"long_name"=>"Theta","units"=>"K"}, "theta" )
|
107
|
-
end
|
108
|
-
|
109
|
-
def gen_na_lon(nlon)
|
110
|
-
NArray.float(nlon).indgen! / (nlon) * 360.0 # [0, ..., (360 - 1/nlon)]
|
111
|
-
end
|
112
|
-
def gen_na_lat(nlat)
|
113
|
-
NArray.float(nlat).indgen! / (nlat - 1) * 180.0 - 90.0 # [90, .., -90]
|
114
|
-
end
|
115
|
-
def gen_na_z1(nz)
|
116
|
-
NArray.sfloat(nz).indgen!/(nz-1)
|
117
|
-
end
|
118
|
-
def gen_na_z2(nz)
|
119
|
-
1000 * 10 ** (-NArray.float(nz).indgen!/(nz-1)) # [1000, .., 100]
|
120
|
-
end
|
121
|
-
|
122
|
-
## -----------------------------------------------------
|
123
|
-
# output method for error check
|
124
|
-
|
125
|
-
def print_error_ratio_max_and_mean(numerical_na, analytical_na)
|
126
|
-
error_ratio = ((numerical_na - analytical_na).abs / ( analytical_na.abs ).max)
|
127
|
-
print " error_ratio max,mean (for each alt):\n"
|
128
|
-
for k in 0...error_ratio.shape[1]
|
129
|
-
printf("%4s%10.5e%4s%10.5e%s", "", error_ratio[true,k,false].max(0),
|
130
|
-
"", error_ratio[true,k,false].mean(0), "\n")
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
|
135
|
-
## -----------------------------------------------------
|
136
|
-
# output method for attribute check
|
137
|
-
|
138
|
-
def show_attr(gp)
|
139
|
-
case gp.data.rank
|
140
|
-
when 1
|
141
|
-
fm = "%-15s%-20s%-10s%s"
|
142
|
-
printf(fm, " <attr_name>", "<data>", "<axis>", "\n")
|
143
|
-
printf(fm, " name", gp.data.name, gp.axis(0).pos.name, "\n")
|
144
|
-
gp.data.att_names.each{|nm|
|
145
|
-
printf(fm, " "+nm, gp.data.get_att(nm).to_s,
|
146
|
-
gp.axis(0).pos.get_att(nm).to_s, "\n")
|
147
|
-
}
|
148
|
-
when 2
|
149
|
-
fm = "%-15s%-20s%-10s%-10s%s"
|
150
|
-
printf(fm, " <attr_name>", "<data>", "<axis_y>", "<axis_z>", "\n")
|
151
|
-
printf(fm, " name", gp.data.name,
|
152
|
-
gp.axis(0).pos.name,
|
153
|
-
gp.axis(1).pos.name,"\n")
|
154
|
-
gp.data.att_names.each{|nm|
|
155
|
-
printf(fm, " "+nm, gp.data.get_att(nm).to_s,
|
156
|
-
gp.axis(0).pos.get_att(nm).to_s,
|
157
|
-
gp.axis(1).pos.get_att(nm).to_s, "\n")
|
158
|
-
}
|
159
|
-
when 3
|
160
|
-
fm = "%-15s%-20s%-10s%-10s%-10s%s"
|
161
|
-
printf(fm, " <attr_name>","<data>","<axis_x>","<axis_y>","<axis_z>", "\n")
|
162
|
-
printf(fm, " name", gp.data.name,
|
163
|
-
gp.axis(0).pos.name,
|
164
|
-
gp.axis(1).pos.name,
|
165
|
-
gp.axis(2).pos.name,"\n")
|
166
|
-
gp.data.att_names.each{|nm|
|
167
|
-
printf(fm, " "+nm, gp.data.get_att(nm).to_s,
|
168
|
-
gp.axis(0).pos.get_att(nm).to_s,
|
169
|
-
gp.axis(1).pos.get_att(nm).to_s,
|
170
|
-
gp.axis(2).pos.get_att(nm).to_s, "\n")
|
171
|
-
}
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
########################################################
|
176
|
-
######## Main Routine ########
|
177
|
-
|
178
|
-
|
179
|
-
#############
|
180
|
-
## check netCDF output flag
|
181
|
-
|
182
|
-
unless getopts('n')
|
183
|
-
print "#{$0}:illegal options. \n"
|
184
|
-
exit 1
|
185
|
-
end
|
186
|
-
if $OPT_n
|
187
|
-
nc_output_flag = true # output test variable as NetCDF.
|
188
|
-
else
|
189
|
-
nc_output_flag = false # not output NetCDF.
|
190
|
-
end
|
191
|
-
|
192
|
-
|
193
|
-
p "##############################################################"
|
194
|
-
p "#### << Section 1 -- test accesor method >> ####"
|
195
|
-
|
196
|
-
# get DEFAULT constants
|
197
|
-
default_h = GPhys::EP_Flux::scale_height
|
198
|
-
default_radius = GPhys::EP_Flux::radius
|
199
|
-
default_rot = GPhys::EP_Flux::rot_period
|
200
|
-
default_g = GPhys::EP_Flux::g_forces
|
201
|
-
default_p00 = GPhys::EP_Flux::p00
|
202
|
-
default_cp = GPhys::EP_Flux::cp
|
203
|
-
default_gas_const = GPhys::EP_Flux::gas_const
|
204
|
-
|
205
|
-
# set module constants
|
206
|
-
GPhys::EP_Flux::scale_height = UNumeric.new(1, "m")
|
207
|
-
GPhys::EP_Flux::radius = UNumeric.new(1, "")
|
208
|
-
GPhys::EP_Flux::rot_period = UNumeric.new(10, "rad/s")
|
209
|
-
GPhys::EP_Flux::g_forces = UNumeric.new(1, "m.s-2")
|
210
|
-
GPhys::EP_Flux::p00 = UNumeric.new(1, "Pa")
|
211
|
-
GPhys::EP_Flux::cp = UNumeric.new(1, "")
|
212
|
-
GPhys::EP_Flux::gas_const = UNumeric.new(1, "")
|
213
|
-
|
214
|
-
# get GIVEN constants
|
215
|
-
h = GPhys::EP_Flux::scale_height
|
216
|
-
radius = GPhys::EP_Flux::radius
|
217
|
-
rot = GPhys::EP_Flux::rot_period
|
218
|
-
g = GPhys::EP_Flux::g_forces
|
219
|
-
p00 = GPhys::EP_Flux::p00
|
220
|
-
cp = GPhys::EP_Flux::cp
|
221
|
-
gas_const = GPhys::EP_Flux::gas_const
|
222
|
-
|
223
|
-
# compare default and given values.
|
224
|
-
fm = "%-15s%15s%17s%s" # format of output
|
225
|
-
|
226
|
-
p "*********** compare default and given values ***********"
|
227
|
-
printf(fm, " <name>", "<default value>", "<given value>","\n")
|
228
|
-
printf(fm, " scale_height", default_h.to_s, h.to_s, "\n")
|
229
|
-
printf(fm, " radius", default_radius.to_s, radius.to_s, "\n")
|
230
|
-
printf(fm, " rot_period", default_rot.to_s, rot.to_s, "\n")
|
231
|
-
printf(fm, " g_forces", default_g.to_s, g.to_s, "\n")
|
232
|
-
printf(fm, " p00", default_p00.to_s, p00.to_s, "\n")
|
233
|
-
printf(fm, " cp", default_cp.to_s, cp.to_s, "\n")
|
234
|
-
printf(fm, " gas_const", default_gas_const.to_s, gas_const.to_s, "\n")
|
235
|
-
|
236
|
-
# test ((<set_constants>)) and ((<get_constants>))
|
237
|
-
GPhys::EP_Flux::set_constants(default_h, default_radius, default_rot,
|
238
|
-
default_g, default_p00, default_cp,
|
239
|
-
default_gas_const)
|
240
|
-
# clean up after tests (backto default values)
|
241
|
-
h, radius, rot, g, p00, cp, gas_const = GPhys::EP_Flux::get_constants
|
242
|
-
p "*** test ((<set_constants>)) and ((<get_constants>)) ***"
|
243
|
-
printf(fm, " <name>", "<set_constants>", "<get_constants>", "\n")
|
244
|
-
printf(fm, " scale_height", default_h.to_s, h.to_s, "\n")
|
245
|
-
printf(fm, " radius", default_radius.to_s, radius.to_s, "\n")
|
246
|
-
printf(fm, " rot_period", default_rot.to_s, rot.to_s, "\n")
|
247
|
-
printf(fm, " g_forces", default_g.to_s, g.to_s, "\n")
|
248
|
-
printf(fm, " p00", default_p00.to_s, p00.to_s, "\n")
|
249
|
-
printf(fm, " cp", default_cp.to_s, cp.to_s, "\n")
|
250
|
-
printf(fm, " gas_const", default_gas_const.to_s, gas_const.to_s, "\n")
|
251
|
-
|
252
|
-
|
253
|
-
p "##############################################################"
|
254
|
-
p "#### << Section 2 -- test deriv method >> ####"
|
255
|
-
|
256
|
-
# preparate for testdata
|
257
|
-
n = 21
|
258
|
-
x = exp(-NArray.sfloat(n).indgen!/(n-1)) # un-uniform grid
|
259
|
-
f = NArray.sfloat(n).indgen!
|
260
|
-
ax = Axis.new.set_pos( VArray.new( x ,
|
261
|
-
{"long_name"=>"longitude", "units"=>"rad"},
|
262
|
-
"lon" ))
|
263
|
-
data = VArray.new( f,
|
264
|
-
{"long_name"=>"temperature", "units"=>"K"},
|
265
|
-
"t" )
|
266
|
-
gp = GPhys.new(Grid.new(ax), data)
|
267
|
-
|
268
|
-
# threepoint_O2nd_deriv
|
269
|
-
dgp_dx = GPhys::EP_Flux::deriv(gp, 0)
|
270
|
-
dgp_dx2 = GPhys::Derivative::threepoint_O2nd_deriv(gp, 0)
|
271
|
-
show_attr(dgp_dx)
|
272
|
-
err = ( dgp_dx.data.val - dgp_dx2.data.val )
|
273
|
-
p err.abs.max
|
274
|
-
|
275
|
-
# cderiv
|
276
|
-
GPhys::EP_Flux::set_deriv_method('cderiv')
|
277
|
-
dgp_dx = GPhys::EP_Flux::deriv(gp, 0)
|
278
|
-
dgp_dx2 = GPhys::Derivative::cderiv(gp, 0)
|
279
|
-
show_attr(dgp_dx)
|
280
|
-
err = ( dgp_dx.data.val - dgp_dx2.data.val )
|
281
|
-
p err.abs.max
|
282
|
-
|
283
|
-
GPhys::EP_Flux::set_deriv_method('cderiv') # backto default method
|
284
|
-
|
285
|
-
p "##############################################################"
|
286
|
-
p "#### << Section 3 -- test calculate method >> ####"
|
287
|
-
|
288
|
-
############
|
289
|
-
## setup for making testdata
|
290
|
-
|
291
|
-
### constants
|
292
|
-
GPhys::EP_Flux::scale_height = UNumeric.new(1, "m")
|
293
|
-
GPhys::EP_Flux::radius = UNumeric.new(1, "m")
|
294
|
-
h, radius, rot, g, = GPhys::EP_Flux::get_constants
|
295
|
-
h = h.val; radius = radius.val; rot = rot.val
|
296
|
-
p00_Pa = GPhys::EP_Flux::p00.val
|
297
|
-
p00 = GPhys::EP_Flux::p00.convert( Units.new("mb") ).val
|
298
|
-
kappa = (GPhys::EP_Flux::gas_const / GPhys::EP_Flux::cp).val
|
299
|
-
|
300
|
-
### make NArray of axis
|
301
|
-
nlon = 100; nlat = 50; nz = 10
|
302
|
-
na_lon = gen_na_lon(nlon)
|
303
|
-
na_lat = gen_na_lat(nlat)
|
304
|
-
na_z = gen_na_z1(nz)
|
305
|
-
na_p = gen_na_z2(nz)
|
306
|
-
na_lambda = PI/180.0*na_lon # convert deg => rad
|
307
|
-
na_phi = PI/180.0*na_lat # convert deg => rad
|
308
|
-
### make NArray of data
|
309
|
-
# make axis term
|
310
|
-
to_3D = NArray.sfloat(nlon, nlat, nz).fill!(1.0)
|
311
|
-
|
312
|
-
sin_lambda = sin(na_lambda).reshape(nlon, 1, 1)
|
313
|
-
cos_phi = cos(na_phi).reshape(1, nlat, 1)
|
314
|
-
sin_phi = sin(na_phi).reshape(1, nlat, 1)
|
315
|
-
tan_phi = sin_phi/cos_phi
|
316
|
-
z = na_z.reshape(1, 1, nz)
|
317
|
-
p = na_p.reshape(1, 1, nz)
|
318
|
-
eddy = ( sin_lambda * cos_phi * to_3D) # common eddy term
|
319
|
-
|
320
|
-
# make each data na in z
|
321
|
-
na_u = 1.0 * eddy + 10 + z
|
322
|
-
na_v = 2.0 * eddy + 20
|
323
|
-
na_w = 3.0 * eddy + 30
|
324
|
-
na_t = 4.0 * eddy + 40
|
325
|
-
na_omega = ( 3.0 * eddy + 30 ) * -p00/h * exp(-z/h)
|
326
|
-
na_theta = ( 4.0 * eddy + 40 ) * exp(kappa*z/h)
|
327
|
-
|
328
|
-
# make each data na in p
|
329
|
-
na_u_p = 1.0 * eddy + 10 + p
|
330
|
-
na_v_p = na_v
|
331
|
-
na_w_p = na_w
|
332
|
-
na_t_p = na_t
|
333
|
-
|
334
|
-
|
335
|
-
p "--------------------------------------------------------------"
|
336
|
-
p "==== pattern 1: W, T in z-coordinate ===="
|
337
|
-
p "--------------------------------------------------------------"
|
338
|
-
|
339
|
-
# generate test GPhys objects.
|
340
|
-
gp_u, gp_v, gp_w, gp_t = \
|
341
|
-
gen_gphys__W_and_Temp_in_z_coordinate(na_u, na_v, na_w, na_t,
|
342
|
-
na_lon, na_lat, na_z)
|
343
|
-
|
344
|
-
# calculate EP Flux, etc.
|
345
|
-
( epflx_y, epflx_z, v_rmean, w_rmean, gp_lat, gp_z,
|
346
|
-
u_mean, theta_mean,
|
347
|
-
uv_dash, vt_dash, uw_dash, dtheta_dz) = \
|
348
|
-
GPhys::EP_Flux::ep_full_sphere(gp_u,gp_v,gp_w,gp_t,true)
|
349
|
-
|
350
|
-
# calculate EP Flux divergence
|
351
|
-
epflx_div = GPhys::EP_Flux::div_sphere(epflx_y, epflx_z)
|
352
|
-
|
353
|
-
# calculate Residual merdional mean circulation
|
354
|
-
strm_rmean = GPhys::EP_Flux::strm_rmean(v_rmean)
|
355
|
-
|
356
|
-
# analytical functions. (these are not smart code.)
|
357
|
-
f = 2*2*PI/rot*sin_phi
|
358
|
-
sig_cos3 = exp( -z/h )*cos_phi**3
|
359
|
-
avort = ( f + (10 + z)/radius*tan_phi )
|
360
|
-
epflx_y_ana = (sig_cos3 * ( h/(10.0*kappa) - 1 )).reshape(nlat,nz)
|
361
|
-
epflx_z_ana = (sig_cos3 * ( avort* h/(10.0*kappa) - 1.5 )).reshape(nlat,nz)
|
362
|
-
u_mean_ana = 10 + na_z.reshape(1,nz)
|
363
|
-
theta_mean_ana = 40 * exp(kappa*na_z.reshape(1,nz)/h)
|
364
|
-
uv_dash_ana = cos(na_phi.reshape(nlat, 1))**2
|
365
|
-
vt_dash_ana = 4* cos(na_phi.reshape(nlat, 1))**2 * exp(kappa*na_z.reshape(1,nz)/h)
|
366
|
-
uw_dash_ana = 1.5 * cos(na_phi.reshape(nlat, 1))**2
|
367
|
-
dtheta_dz_ana = 40 * kappa/h * exp(kappa*na_z.reshape(1,nz)/h)
|
368
|
-
epflx_div_ana = ( exp( -z/h )*(-4)*(cos_phi**2)*sin_phi/radius * ( h/(10.0*kappa) - 1 )).reshape(nlat,nz) \
|
369
|
-
- epflx_z_ana/h + (( exp( -z/h )*( cos_phi**2 *sin_phi) ) / radius * h/(10.0*kappa)).reshape(nlat,nz)
|
370
|
-
v_rmean_ana = 20 + cos(na_phi.reshape(nlat, 1))**2/10/kappa
|
371
|
-
w_rmean_ana = 30 + 3*h*cos(na_phi.reshape(nlat, 1))*sin(na_phi.reshape(nlat, 1))/10/radius/kappa
|
372
|
-
na_zp = p00_Pa*exp(-z/h).reshape(1, nz)
|
373
|
-
strm_rmean_ana = v_rmean_ana * 2 * PI * radius * cos(na_phi.reshape(nlat, 1)) * (na_zp - na_zp[-1])/g.val + v_rmean_ana[-1] * PI * radius * cos(na_phi.reshape(nlat, 1)) * na_zp[-1]/g.val
|
374
|
-
|
375
|
-
|
376
|
-
### check_precision_and_attribute
|
377
|
-
["epflx_y", "epflx_z", "v_rmean", "w_rmean", "u_mean", "theta_mean",
|
378
|
-
"uv_dash", "vt_dash", "uw_dash", "dtheta_dz", "epflx_div", "strm_rmean"].each { |gp_nm|
|
379
|
-
gp = eval(gp_nm) # ex. "epflx_y" => epflx_y
|
380
|
-
gp_ana = eval(gp_nm+"_ana") # ex. "epflx_y" => epflx_y_na
|
381
|
-
title = gp.data.get_att("long_name").to_s
|
382
|
-
p "***************** #{title} *****************"
|
383
|
-
show_attr(gp)
|
384
|
-
print_error_ratio_max_and_mean(gp.data.val, gp_ana)
|
385
|
-
}
|
386
|
-
|
387
|
-
p "--------------------------------------------------------------"
|
388
|
-
p "==== pattern 2: Omega, Theta in z-coordinate ===="
|
389
|
-
p "--------------------------------------------------------------"
|
390
|
-
|
391
|
-
gp_u, gp_v, gp_omega, gp_theta = \
|
392
|
-
gen_gphys__Omega_and_Theta_in_z_coordinate(na_u, na_v, na_omega, na_theta,
|
393
|
-
na_lon, na_lat, na_z)
|
394
|
-
( epflx_y, epflx_z, v_rmean, w_rmean, gp_lat, gp_z,
|
395
|
-
u_mean, theta_mean,
|
396
|
-
uv_dash, vt_dash, uw_dash, dtheta_dz) = \
|
397
|
-
GPhys::EP_Flux::ep_full_sphere(gp_u,gp_v,gp_omega,gp_theta,false)
|
398
|
-
|
399
|
-
epflx_div = GPhys::EP_Flux::div_sphere(epflx_y, epflx_z)
|
400
|
-
|
401
|
-
# calculate Residual merdional mean circulation
|
402
|
-
strm_rmean = GPhys::EP_Flux::strm_rmean(v_rmean)
|
403
|
-
|
404
|
-
## analytical functions
|
405
|
-
f = 2*2*PI/rot*sin_phi
|
406
|
-
sig_cos3 = exp( -z/h )*cos_phi**3
|
407
|
-
avort = ( f + (10 + z)/radius*tan_phi )
|
408
|
-
epflx_y_ana = (sig_cos3 * ( h/(10.0*kappa) - 1 )).reshape(nlat,nz)
|
409
|
-
epflx_z_ana = (sig_cos3 * ( avort* h/(10.0*kappa) - 1.5 )).reshape(nlat,nz)
|
410
|
-
u_mean_ana = 10 + na_z.reshape(1,nz)
|
411
|
-
theta_mean_ana = 40 * exp(kappa*na_z.reshape(1,nz)/h)
|
412
|
-
uv_dash_ana = cos(na_phi.reshape(nlat, 1))**2
|
413
|
-
vt_dash_ana = 4* cos(na_phi.reshape(nlat, 1))**2 * exp(kappa*na_z.reshape(1,nz)/h)
|
414
|
-
uw_dash_ana = 1.5 * cos(na_phi.reshape(nlat, 1))**2
|
415
|
-
dtheta_dz_ana = 40 * kappa/h * exp(kappa*na_z.reshape(1,nz)/h)
|
416
|
-
epflx_div_ana = ( exp( -z/h )*-4*cos_phi**2*sin_phi/radius * ( h/(10.0*kappa) - 1 )).reshape(nlat,nz) \
|
417
|
-
- epflx_z_ana/h + \
|
418
|
-
(( exp( -z/h )*(cos_phi**2 * sin_phi) ) /radius * h/(10.0*kappa)).reshape(nlat,nz)
|
419
|
-
v_rmean_ana = 20 + cos(na_phi.reshape(nlat, 1))**2/10/kappa
|
420
|
-
w_rmean_ana = 30 + 3*h*cos(na_phi.reshape(nlat, 1))*sin(na_phi.reshape(nlat, 1))/10/radius/kappa
|
421
|
-
na_zp = p00_Pa*exp(-z/h).reshape(1, nz)
|
422
|
-
#strm_rmean_ana = v_rmean_ana * 2 * PI * radius * cos(na_phi.reshape(nlat, 1)) * na_zp/g.val
|
423
|
-
strm_rmean_ana = v_rmean_ana * 2 * PI * radius * cos(na_phi.reshape(nlat, 1)) * (na_zp - na_zp[-1])/g.val + v_rmean_ana[-1] * PI * radius * cos(na_phi.reshape(nlat, 1)) * na_zp[-1]/g.val
|
424
|
-
|
425
|
-
### check_precision_and_attribute
|
426
|
-
["epflx_y", "epflx_z", "v_rmean", "w_rmean", "u_mean", "theta_mean",
|
427
|
-
"uv_dash", "vt_dash", "uw_dash", "dtheta_dz", "epflx_div", "strm_rmean"].each { |gp_nm|
|
428
|
-
gp = eval(gp_nm) # ex. "epflx_y" => epflx_y
|
429
|
-
gp_ana = eval(gp_nm+"_ana") # ex. "epflx_y" => epflx_y_na
|
430
|
-
title = gp.data.get_att("long_name").to_s
|
431
|
-
p "***************** #{title} *****************"
|
432
|
-
show_attr(gp)
|
433
|
-
print_error_ratio_max_and_mean(gp.data.val, gp_ana)
|
434
|
-
}
|
435
|
-
|
436
|
-
p "--------------------------------------------------------------"
|
437
|
-
p "==== pattern 3: W, T in p-coordinate ===="
|
438
|
-
p "--------------------------------------------------------------"
|
439
|
-
|
440
|
-
gp_u, gp_v, gp_w, gp_t = \
|
441
|
-
gen_gphys__W_and_Temp_in_p_coordinate(na_u_p, na_v_p, na_w_p, na_t_p,
|
442
|
-
na_lon, na_lat, na_p)
|
443
|
-
( epflx_y, epflx_z, v_rmean, w_rmean, gp_lat, gp_z,
|
444
|
-
u_mean, theta_mean,
|
445
|
-
uv_dash, vt_dash, uw_dash, dtheta_dz) = \
|
446
|
-
GPhys::EP_Flux::ep_full_sphere(gp_u,gp_v,gp_w,gp_t,true)
|
447
|
-
|
448
|
-
epflx_div = GPhys::EP_Flux::div_sphere(epflx_y, epflx_z)
|
449
|
-
# calculate Residual merdional mean circulation
|
450
|
-
strm_rmean = GPhys::EP_Flux::strm_rmean(v_rmean)
|
451
|
-
|
452
|
-
## analytical functions
|
453
|
-
f = 2*2*PI/rot*sin_phi
|
454
|
-
avort = ( f + (10 + p)/radius*tan_phi )
|
455
|
-
epflx_y_ana = (( p/p00 * cos_phi**3 ) * ( -p/(10.0*kappa) - 1 )).reshape(nlat,nz)
|
456
|
-
epflx_z_ana = (( p/p00 * cos_phi**3 ) * ( avort * h/(10.0*kappa) - 1.5 )).reshape(nlat,nz)
|
457
|
-
u_mean_ana = 10 + na_p.reshape(1,nz)
|
458
|
-
theta_mean_ana = ( 40 * (p00/na_p.reshape(1,nz))**kappa )
|
459
|
-
uv_dash_ana = cos(na_phi.reshape(nlat, 1))**2
|
460
|
-
vt_dash_ana = ( 4* cos(na_phi.reshape(nlat, 1))**2 * (p00/na_p.reshape(1,nz))**kappa ).reshape(nlat,nz)
|
461
|
-
uw_dash_ana = 1.5 * cos(na_phi.reshape(nlat, 1))**2
|
462
|
-
dtheta_dz_ana = theta_mean_ana / h * kappa
|
463
|
-
epflx_div_ana = ( p/p00*-4*cos_phi**2*sin_phi/radius * ( -p/(10.0*kappa) - 1 )).reshape(nlat,nz) - epflx_z_ana/h + \
|
464
|
-
((-p**2/p00/h*cos_phi**2 ) * ( sin_phi/radius ) * h/(10.0*kappa)).reshape(nlat,nz)
|
465
|
-
v_rmean_ana = 20 + cos(na_phi.reshape(nlat, 1))**2/10/kappa
|
466
|
-
w_rmean_ana = 30 + 3*h*cos(na_phi.reshape(nlat, 1))*sin(na_phi.reshape(nlat, 1))/10/radius/kappa
|
467
|
-
strm_rmean_ana = v_rmean_ana * 2 * PI * radius * cos(na_phi.reshape(nlat, 1)) * (na_p.reshape(1, nz) - na_p[-1])*100/g.val + v_rmean_ana[-1] * PI * radius * cos(na_phi.reshape(nlat, 1)) * na_p[-1]*100/g.val
|
468
|
-
|
469
|
-
### check_precision_and_attribute
|
470
|
-
["epflx_y", "epflx_z", "v_rmean", "w_rmean", "u_mean", "theta_mean",
|
471
|
-
"uv_dash", "vt_dash", "uw_dash", "dtheta_dz", "epflx_div", "strm_rmean"].each { |gp_nm|
|
472
|
-
gp = eval(gp_nm) # ex. "epflx_y" => epflx_y
|
473
|
-
gp_ana = eval(gp_nm+"_ana") # ex. "epflx_y" => epflx_y_na
|
474
|
-
title = gp.data.get_att("long_name").to_s
|
475
|
-
p "***************** #{title} *****************"
|
476
|
-
show_attr(gp)
|
477
|
-
print_error_ratio_max_and_mean(gp.data.val, gp_ana)
|
478
|
-
}
|
479
|
-
|
480
|
-
|
481
|
-
p "--------------------------------------------------------------"
|
482
|
-
p "==== pattern 4: check div_sphere with easy data ===="
|
483
|
-
p "--------------------------------------------------------------"
|
484
|
-
|
485
|
-
## make axis
|
486
|
-
nlat = 50; nz = 10
|
487
|
-
na_lat = NArray.float(nlat).indgen! / (nlat - 1) * 180.0 - 90.0 # [-90, .., 90]
|
488
|
-
p ( na_z = 1000 * (NArray.float(nz).indgen!/(nz-1)) ) # [1000, .., 100]
|
489
|
-
va_lat = VArray.new( na_lat,
|
490
|
-
{"long_name"=>"latitude","units"=>"degrees"},
|
491
|
-
"lat" )
|
492
|
-
va_z = VArray.new( na_z,
|
493
|
-
{"long_name"=>"alt","units"=>"m"},
|
494
|
-
"z" )
|
495
|
-
lat = Axis.new.set_pos(va_lat)
|
496
|
-
z = Axis.new.set_pos(va_z)
|
497
|
-
grid = Grid.new(lat, z)
|
498
|
-
|
499
|
-
## make data
|
500
|
-
na_phi = PI/180.0*na_lat
|
501
|
-
na_z1 = na_z.dup.fill(1.0)
|
502
|
-
na_f_phi = 1.0 * cos(na_phi.reshape(nlat, 1)) * (na_z1).reshape(1, nz)
|
503
|
-
na_f_z = 3.0 * na_z.newdim(0) * cos(na_phi).reshape(nlat, 1)
|
504
|
-
|
505
|
-
va_f_phi = VArray.new( na_f_phi,
|
506
|
-
{"long_name"=>"epflx_y","units"=>"m2.s-2"},
|
507
|
-
"epy" )
|
508
|
-
va_f_z = VArray.new( na_f_z,
|
509
|
-
{"long_name"=>"epflx_z","units"=>"m2.s-2"},
|
510
|
-
"epz" )
|
511
|
-
|
512
|
-
gp_f_phi = GPhys.new(grid, va_f_phi)
|
513
|
-
gp_f_z = GPhys.new(grid, va_f_z)
|
514
|
-
|
515
|
-
kappa = (GPhys::EP_Flux::gas_const / GPhys::EP_Flux::cp).val
|
516
|
-
p00 = GPhys::EP_Flux::p00
|
517
|
-
scale_height = GPhys::EP_Flux::scale_height
|
518
|
-
rot_period = GPhys::EP_Flux::rot_period
|
519
|
-
radius = GPhys::EP_Flux::radius
|
520
|
-
|
521
|
-
|
522
|
-
na_z = na_z.reshape(1, nz)
|
523
|
-
na_phi = na_phi.reshape(nlat, 1)
|
524
|
-
p "*** epflx_div ***"
|
525
|
-
epflx_div = GPhys::EP_Flux::div_sphere(gp_f_phi, gp_f_z)
|
526
|
-
epflx_div_ana = -2*sin(na_phi) + 3 * cos(na_phi)
|
527
|
-
|
528
|
-
### check divergence
|
529
|
-
title = epflx_div.data.get_att("long_name").to_s
|
530
|
-
p "***************** #{title} *****************"
|
531
|
-
show_attr(epflx_div)
|
532
|
-
print_error_ratio_max_and_mean(epflx_div.data.val, epflx_div_ana)
|
533
|
-
|