Module: NumRu::GAnalysis::Planet
- Defined in:
- lib/numru/ganalysis/planet.rb
Overview
Library for spherical planets (thin spherical shell; default: Earth)
ASSUMPTIONS
-
longitude is assumed to increase in the eastward direction.
-
latitude is assumed to increase in the northward direction, and it is zero at the equator.
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
- .absvor_s(u, v) ⇒ Object
-
.ave_s(s) ⇒ Object
horizontal averaging considering the spherical geometry.
- .div_s(u, v) ⇒ Object
-
.find_lon_lat_dims(gp, err_raise = false) ⇒ Object
Find longitude and latitude coordinates.
-
.get_lambda_phi(gp, err_raise = true) ⇒ Object
Find longitude and latitude coordinates and convert into radian.
- .grad_s(s) ⇒ Object
- .grad_sx(s) ⇒ Object
- .grad_sy(s) ⇒ Object
- .grad_sy_cosphifact(s, cosphi_exponent) ⇒ Object
- .init(planet) ⇒ Object
-
.latbc(phi) ⇒ Object
< Differentian at the planets’s near surface.
- .omega ⇒ Object
- .omega=(o) ⇒ Object
- .radius ⇒ Object
-
.radius=(r) ⇒ Object
< Adjustable planetary settings >.
- .rot_s(u, v) ⇒ Object
- .vor_s(u, v) ⇒ Object
- .weight_cosphi(s, cos_exp, r_exp) ⇒ Object
- .weight_sinphi(s, sin_exp, r_exp) ⇒ Object
- .weight_tanphi(s, tan_exp, r_exp) ⇒ Object
Class Method Details
.absvor_s(u, v) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/numru/ganalysis/planet.rb', line 105 def absvor_s(u,v) avor = vor_s(u,v) + @@phi.sin * (2*@@Ome) avor.long_name = "Absolute Vorticity" avor.name = "avor" avor end |
.ave_s(s) ⇒ Object
horizontal averaging considering the spherical geometry
66 67 68 69 70 71 72 73 74 |
# File 'lib/numru/ganalysis/planet.rb', line 66 def ave_s(s) lam, phi, lond, latd = get_lambda_phi(s) xmean = s.mean(lond) cos_phi = phi.cos lond,latd = find_lon_lat_dims(xmean) # find latd again wgt = cos_phi / cos_phi.sum (xmean * wgt).sum(latd) end |
.div_s(u, v) ⇒ Object
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/numru/ganalysis/planet.rb', line 87 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
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 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/numru/ganalysis/planet.rb', line 221 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)
188 189 190 191 192 193 194 195 196 197 |
# File 'lib/numru/ganalysis/planet.rb', line 188 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
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/numru/ganalysis/planet.rb', line 112 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
124 125 126 127 128 129 130 131 |
# File 'lib/numru/ganalysis/planet.rb', line 124 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
133 134 135 136 137 138 139 140 |
# File 'lib/numru/ganalysis/planet.rb', line 133 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
142 143 144 145 146 147 148 149 150 |
# File 'lib/numru/ganalysis/planet.rb', line 142 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
19 20 21 22 23 24 25 26 27 |
# File 'lib/numru/ganalysis/planet.rb', line 19 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” >
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/numru/ganalysis/planet.rb', line 48 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 |
.omega ⇒ Object
36 |
# File 'lib/numru/ganalysis/planet.rb', line 36 def omega; @@Ome; end |
.omega=(o) ⇒ Object
34 |
# File 'lib/numru/ganalysis/planet.rb', line 34 def omega=(o); @@Ome = o; end |
.radius ⇒ Object
35 |
# File 'lib/numru/ganalysis/planet.rb', line 35 def radius; @@R; end |
.radius=(r) ⇒ Object
< Adjustable planetary settings >
33 |
# File 'lib/numru/ganalysis/planet.rb', line 33 def radius=(r); @@R = r; end |
.rot_s(u, v) ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/numru/ganalysis/planet.rb', line 76 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
98 99 100 101 102 103 |
# File 'lib/numru/ganalysis/planet.rb', line 98 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
159 160 161 162 163 164 |
# File 'lib/numru/ganalysis/planet.rb', line 159 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
166 167 168 169 170 171 |
# File 'lib/numru/ganalysis/planet.rb', line 166 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
152 153 154 155 156 157 |
# File 'lib/numru/ganalysis/planet.rb', line 152 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 |