Module: NumRu::GAnalysis::Planet

Defined in:
lib/numru/ganalysis/planet.rb

Constant Summary collapse

Earth =

< Pre-defined planets >

"Earth"
@@lonbc =

< Class variables regarding lon & lat >

GPhys::Derivative::CYCLIC_OR_LINEAR
@@lam =

@@latbc = GPhys::Derivative::LINEAR_EXT # this should be always fine

nil
@@phi =

lambda (lon in radian) obtaiend lately (see get_lambda_phi)

nil

Class Method Summary collapse

Class Method Details

.absvor_s(u, v) ⇒ Object



95
96
97
98
99
100
# File 'lib/numru/ganalysis/planet.rb', line 95

def absvor_s(u,v)
  avor = vor_s(u,v) + @@phi.sin * (2*@@Ome)
  avor.long_name = "Absolute Vorticity"
  avor.name = "avor"
  avor
end

.div_s(u, v) ⇒ Object



77
78
79
80
81
82
83
84
85
86
# File 'lib/numru/ganalysis/planet.rb', line 77

def div_s(u,v)
  lam, phi, lond, latd  = get_lambda_phi(u)
  cos_phi = phi.cos
  du_dlam = u.cderiv(lond,@@lonbc,lam)
  dvc_dphi  = (v*cos_phi).cderiv(latd,latbc(phi),phi)
  rot = (du_dlam + dvc_dphi) / (@@R*cos_phi)
  rot.long_name = "div(#{u.name},#{v.name})"
  rot.name = "div"
  rot
end

.find_lon_lat_dims(gp, err_raise = false) ⇒ Object

Find longitude and latitude coordinates.

ARGUMENTS

  • gp : GPhys to inspect

  • err_raise (OPTIONAL; default:false) : if true, exception is raised if longitude or latitude coordinate is not found.

SEARCH CRITERIA (1) Find coord having units “degrees_east” (lon) or

"degrees_north" (lat)

(2) Investigate coordinate name matches (to find a lonitude coord,

/longitude/i for long_name or standard_name, or /^lon/ for name)
and match units compatible with "degrees".

RETURN VALUE

  • lond,latd
    • lond: dimension number of longitude (0,1,..) if found / nil if not found

    • latd: dimension number of latitude (0,1,..) if found / nil if not found



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/numru/ganalysis/planet.rb', line 211

def find_lon_lat_dims(gp, err_raise=false)
  lond = nil
  latd = nil
  (0...gp.rank).each do |dim|
    crd = gp.coord(dim)
    if /^degrees?_east$/i =~ crd.get_att("units")
      lond = dim
      break
    elsif ( ( /longitude/i =~ crd.long_name || 
              /^lon/i =~ crd.name ||
              (nm=crd.get_att("standard_name") && /longitude/i =~ nm ) &&
              (crd.units =~ Units["degrees_east"]) ) )
      lond = dim
      break
    end
  end
  (0...gp.rank).each do |dim|
    next if dim == lond
    crd = gp.coord(dim)
    if /^degrees?_north$/i =~ crd.get_att("units")
      latd = dim
      break
    elsif ( ( /latitude/i =~ crd.long_name || 
              /^lat/i =~ crd.name ||
              (nm=crd.get_att("standard_name") && /latitude/i =~ nm ) &&
              (crd.units =~ Units["degrees_north"]) ) )
      latd = dim
      break
    end
  end
  if err_raise
    raise("Longitude dimension was not found") if !lond
    raise("Latitude dimension was not found") if !latd
  end
  [lond,latd]
end

.get_lambda_phi(gp, err_raise = true) ⇒ Object

Find longitude and latitude coordinates and convert into radian.

RETURN VALUE

  • lam, phi, lond, latd
    • lam (GPhys): longitude in radian (lambda). (nil if not found && !err_raise)

    • phi (GPhys): latitude in radian (lambda). (nil if not found && !err_raise)

    • lond : Interger to show that longitude is the lon-th dim if found; (nil if not found && !err_raise)

    • latd : Interger to show that latitude is the lat-th dim iffound; (nil if not found && !err_raise)



178
179
180
181
182
183
184
185
186
187
# File 'lib/numru/ganalysis/planet.rb', line 178

def get_lambda_phi(gp, err_raise=true)
  lond, latd = find_lon_lat_dims(gp, err_raise)
  lam = lond && gp.axis(lond).to_gphys.convert_units("rad") # lon in rad
  lam.units = "" if lond                            # treat as non-dim
  phi = latd && gp.axis(latd).to_gphys.convert_units("rad") # lat in rad
  phi.units = "" if latd                            # treat as non-dim
  @@lam = lam
  @@phi = phi
  [lam, phi, lond, latd]
end

.grad_s(s) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/numru/ganalysis/planet.rb', line 102

def grad_s(s)
  lam, phi, lond, latd  = get_lambda_phi(s)
  cos_phi = phi.cos
  xs = s.cderiv(lond,@@lonbc,lam) / (@@R*cos_phi)
  ys = s.cderiv(latd,latbc(phi),phi) / @@R
  xs.long_name = "xgrad(#{s.name})"
  xs.name = "xgrad"
  ys.long_name = "ygrad(#{s.name})"
  ys.name = "ygrad"
  [xs,ys]
end

.grad_sx(s) ⇒ Object



114
115
116
117
118
119
120
121
# File 'lib/numru/ganalysis/planet.rb', line 114

def grad_sx(s)
  lam, phi, lond, latd  = get_lambda_phi(s)
  cos_phi = phi.cos
  xs = s.cderiv(lond,@@lonbc,lam) / (@@R*cos_phi)
  xs.long_name = "xgrad(#{s.name})"
  xs.name = "xgrad"
  xs
end

.grad_sy(s) ⇒ Object



123
124
125
126
127
128
129
130
# File 'lib/numru/ganalysis/planet.rb', line 123

def grad_sy(s)
  lam, phi, lond, latd  = get_lambda_phi(s)
  cos_phi = phi.cos
  ys = s.cderiv(latd,latbc(phi),phi) / @@R
  ys.long_name = "ygrad(#{s.name})"
  ys.name = "ygrad"
  ys
end

.grad_sy_cosphifact(s, cosphi_exponent) ⇒ Object



132
133
134
135
136
137
138
139
140
# File 'lib/numru/ganalysis/planet.rb', line 132

def grad_sy_cosphifact(s,cosphi_exponent)
  lam, phi, lond, latd  = get_lambda_phi(s)
  cos_phi = phi.cos
  cos_phi_factor = cos_phi**cosphi_exponent
  ys = (s*cos_phi_factor).cderiv(latd,latbc(phi),phi)/cos_phi_factor / @@R
  ys.long_name = "ygrad(#{s.name})"
  ys.name = "ygrad"
  ys
end

.init(planet) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/numru/ganalysis/planet.rb', line 20

def init(planet)
  case planet
  when Earth
    @@R = UNumeric[6.37e6, "m"]
    @@Ome = UNumeric[2*Math::PI/8.64e4,"s-1"]
  else
    raise "Unsupported predefined planet: #{planet}."
  end
end

.latbc(phi) ⇒ Object

< Differentian at the planets’s near surface. With suffix “_s” >



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/numru/ganalysis/planet.rb', line 49

def latbc(phi)
=begin
  # not so good
  pi2 = Math::PI/2
  eps = 0.1
  xs = phi[0..1].val 
  xe = phi[-2..-1].val
  if (pi2-xs[0].abs) / (xs[0]-xs[1]).abs < eps and
     (pi2-xe[-1].abs) / (xe[-1]-xe[-2]).abs < eps 
    GPhys::Derivative::MIRROR_B
  else
    GPhys::Derivative::LINEAR_EXT
  end
=end
  GPhys::Derivative::LINEAR_EXT
end

.omegaObject



37
# File 'lib/numru/ganalysis/planet.rb', line 37

def omega; @@Ome; end

.omega=(o) ⇒ Object



35
# File 'lib/numru/ganalysis/planet.rb', line 35

def omega=(o);  @@Ome = o; end

.radiusObject



36
# File 'lib/numru/ganalysis/planet.rb', line 36

def radius; @@R; end

.radius=(r) ⇒ Object

< Adjustable planetary settings >



34
# File 'lib/numru/ganalysis/planet.rb', line 34

def radius=(r); @@R = r; end

.rot_s(u, v) ⇒ Object



66
67
68
69
70
71
72
73
74
75
# File 'lib/numru/ganalysis/planet.rb', line 66

def rot_s(u,v)
  lam, phi, lond, latd  = get_lambda_phi(u)
  cos_phi = phi.cos
  dv_dlam = v.cderiv(lond,@@lonbc,lam)
  duc_dphi  = (u*cos_phi).cderiv(latd,latbc(phi),phi)
  rot = (dv_dlam - duc_dphi) / (@@R*cos_phi)
  rot.long_name = "rot(#{u.name},#{v.name})"
  rot.name = "rot"
  rot
end

.vor_s(u, v) ⇒ Object



88
89
90
91
92
93
# File 'lib/numru/ganalysis/planet.rb', line 88

def vor_s(u,v)
  vor = rot_s(u,v)
  vor.long_name = "Relative Vorticity"
  vor.name = "vor"
  vor
end

.weight_cosphi(s, cos_exp, r_exp) ⇒ Object



149
150
151
152
153
154
# File 'lib/numru/ganalysis/planet.rb', line 149

def weight_cosphi(s, cos_exp, r_exp)
  lam, phi, lond, latd  = get_lambda_phi(s)
  cos_phi = phi.cos
  ys = s * (cos_phi**cos_exp * @@R**r_exp)
  ys
end

.weight_sinphi(s, sin_exp, r_exp) ⇒ Object



156
157
158
159
160
161
# File 'lib/numru/ganalysis/planet.rb', line 156

def weight_sinphi(s, sin_exp, r_exp)
  lam, phi, lond, latd  = get_lambda_phi(s)
  sin_phi = phi.sin
  ys = s * (sin_phi**sin_exp * @@R**r_exp)
  ys
end

.weight_tanphi(s, tan_exp, r_exp) ⇒ Object



142
143
144
145
146
147
# File 'lib/numru/ganalysis/planet.rb', line 142

def weight_tanphi(s, tan_exp, r_exp)
  lam, phi, lond, latd  = get_lambda_phi(s)
  tan_phi = phi.tan
  ys = s * (tan_phi**tan_exp * @@R**r_exp)
  ys
end