続・GPVで沸点予報(間違い探し)

お遊びの上塗り。

沸点がわかるとすれば、水が外気温と同じ水温と仮定して、この水温から沸点まで上げるのに必要なカロリーがわかる:

  1 # -*- coding: utf-8 -*-
  2 import sys
  3 import pygrib
  4 import numpy as np
  5 
  6 
  7 def _read(srcfn):
  8     # keys in Surfece:
  9     #    Pressure reduced to MSL
 10     #    Surface pressure
 11     #    10 metre U wind component
 12     #    10 metre V wind component
 13     #    Temperature
 14     #    Relative humidity
 15     #    Low cloud cover
 16     #    Medium cloud cover
 17     #    High cloud cover
 18     #    Total cloud cover
 19     #    Total precipitation
 20     #
 21     src = pygrib.open(srcfn)
 22     for s in src:
 23         yield (s.name, s.parameterName), s.validDate, s.latlons(), s.values
 24     src.close()
 25 
 26 
 27 data = {}
 28 for yk, vd, latlons, values in _read(sys.argv[1]):
 29     if "Pressure reduced to MSL" in yk and "Pressure reduced to MSL" not in data:
 30         data["Pressure reduced to MSL"] = latlons, values
 31     elif "Surface pressure" in yk and "Surface pressure" not in data:
 32         data["Surface pressure"] = latlons, values
 33     elif "Temperature" in yk and "Temperature" not in data:
 34         data["Temperature"] = latlons, values
 35     if len(data) == 3:
 36         break
 37 
 38 
 39 # -----------------------------------------------------
 40 #
 41 from mpl_toolkits.basemap import Basemap
 42 import matplotlib.pyplot as plt
 43 import matplotlib.cm as cm
 44 import matplotlib.ticker as ticker
 45 
 46 
 47 with plt.xkcd():  # I JUST TYPED import antigravity!
 48 
 49     bmparams = dict(
 50         llcrnrlat=34.25,
 51         urcrnrlat=37.5,
 52         llcrnrlon=137.,
 53         urcrnrlon=140.825,
 54         resolution='i',
 55         projection='merc')
 56 
 57     fig, axes = plt.subplots(1, 2)
 58     fig.set_size_inches(16.53 * 2, 11.69 * 2)
 59 
 60     circles = np.arange(10, 90, 5)
 61     meridians = np.arange(-180, 180, 5)
 62     # -----------------------------------------------------
 63     # surface pressure as saturated vapour pressure
 64     latlons, e_s = data["Surface pressure"]
 65 
 66     # inverse of Murray's equation
 67     ln_es = np.log(e_s / 100. / 6.1078)
 68     T_B = 273.15 + (-ln_es * 237.3) / (ln_es - 17.2693882)
 69 
 70 
 71     lons = latlons[1]
 72     lats = latlons[0]
 73     #
 74     X = latlons[1][0,:]
 75     Y = latlons[0][:,0]
 76     bmparams["ax"] = axes[0]
 77     m = Basemap(**bmparams)
 78     x, y = m(lons, lats)
 79     m.drawcoastlines(color='white', linewidth=1)
 80     m.drawparallels(circles, labels=[1, 0, 0, 0])
 81     m.drawmeridians(meridians, labels=[0, 0, 0, 1])
 82 
 83     cs = m.contourf(
 84         x, y,
 85         T_B - 273.15,  # K to Celsius
 86         20,
 87         cmap=cm.coolwarm_r)
 88     m.colorbar(cs)
 89     axes[0].set_title("Boiling point of water\n[" + str(vd) + "]")
 90     # -----------------------------------------------------
 91     #
 92     # temperature
 93     latlons, T = data["Temperature"]
 94 
 95     bmparams["ax"] = axes[1]
 96     m = Basemap(**bmparams)
 97     x, y = m(lons, lats)
 98     m.drawcoastlines(color='black', linewidth=1)
 99     m.drawparallels(circles, labels=[1, 0, 0, 0])
100     m.drawmeridians(meridians, labels=[0, 0, 0, 1])
101 
102     #
103     cs = m.contourf(
104         x, y,
105         T_B - T,
106         20,
107         cmap=cm.coolwarm)
108     m.colorbar(
109         cs,
110         format=ticker.FuncFormatter(lambda x, pos: "%.1f" % x))
111     axes[1].set_title("required calories to boiler point (kcal/kg)\n[" + str(vd) + "]")
112     # -----------------------------------------------------
113     #plt.show()
114     plt.savefig("boiling_point_of_water3.png", bbox_inches="tight")

ちなみに水の比熱を調べたのは、水1度上げるのに必要なエネルギーが何かに依存して変化するんだったっけか、てのを知りたくて調べようとしたの。変わらない、でいいんだっけか。不変なら、ここでやった通り、「水1gを1℃上げるのに必要なカロリーは1cal (1kgを1℃、で1kcal)」。(1kg ≒ 1リットル、ね。)

標高が高い場所では、「100℃にはならないわ、余計にカロリー必要だわ」で踏んだり蹴ったり、の巻。

以前水の煮沸の話で国際山岳連合医療部会(UIAA MedCom)公認基準の話をちょっと紹介した。滅菌・殺菌のために必要なのは沸騰ではなく温度だけれども、沸騰でほぼ死滅させることは出来る。UIAA MedCom の「煮沸のデメリット」として「水を沸騰させるために燃料と時間を消費する」と言っているが、平地より余計にエネルギーが必要だ、ってわけ。

あ、「水温が外気温と同じ」はかなり無理がある仮定よ。例えば登山ならそんな水の運搬したら命に関わるし、平地の水道水は、おそらく浄水場の水温が保たれてるはず。水の比熱が高いから、ね。外気温の影響受けにくい。


2021-05-07追記:
紹介した basemap だが、作者である Jeff Whitaker が「basemap プロジェクト」としての保守を完全にやめ、pip でのインストールも不可能になった。自身による説明:

Deprecation Notice
Basemap is deprecated in favor of the Cartopy project. See notes in Cartopy, New Management, and EoL Announcement for more details.

リンク先をちょっと読むに、「より大きなプロジェクトに取り込まれた」ということに見える。cartopy はワタシ自身にとって完全に未知なのでまだ何も言わないけれど、余力があったらそのうち何か書くかも。

2021-05-14追記:cartopy について書いた