続・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 bmparams = dict(
 48     llcrnrlat=34.25,
 49     urcrnrlat=37.5,
 50     llcrnrlon=137.,
 51     urcrnrlon=140.825,
 52     resolution='i',
 53     projection='merc')
 54 
 55 fig, axes = plt.subplots(1, 2)
 56 fig.set_size_inches(16.53 * 2, 11.69 * 2)
 57 
 58 circles = np.arange(10, 90, 5)
 59 meridians = np.arange(-180, 180, 5)
 60 # -----------------------------------------------------
 61 # surface pressure as saturated vapour pressure
 62 latlons, e_s = data["Surface pressure"]
 63 
 64 # inverse of Murray's equation
 65 ln_es = np.log(e_s / 100. / 6.1078)
 66 T_B = 273.15 + (-ln_es * 237.3) / (ln_es - 17.2693882)
 67 
 68 
 69 lons = latlons[1]
 70 lats = latlons[0]
 71 #
 72 X = latlons[1][0,:]
 73 Y = latlons[0][:,0]
 74 bmparams["ax"] = axes[0]
 75 m = Basemap(**bmparams)
 76 x, y = m(lons, lats)
 77 m.drawcoastlines(color='white', linewidth=1)
 78 m.drawparallels(circles, labels=[1, 0, 0, 0])
 79 m.drawmeridians(meridians, labels=[0, 0, 0, 1])
 80 
 81 cs = m.contourf(
 82     x, y,
 83     T_B - 273.15,  # K to Celsius
 84     20,
 85     cmap=cm.coolwarm_r)
 86 m.colorbar(cs)
 87 axes[0].set_title("Boiling point of water\n[" + str(vd) + "]")
 88 # -----------------------------------------------------
 89 #
 90 # temperature
 91 latlons, T = data["Temperature"]
 92 
 93 bmparams["ax"] = axes[1]
 94 m = Basemap(**bmparams)
 95 x, y = m(lons, lats)
 96 m.drawcoastlines(color='black', linewidth=1)
 97 m.drawparallels(circles, labels=[1, 0, 0, 0])
 98 m.drawmeridians(meridians, labels=[0, 0, 0, 1])
 99 
100 #
101 cs = m.contourf(
102     x, y,
103     T_B - T,
104     20,
105     cmap=cm.coolwarm)
106 m.colorbar(
107     cs,
108     format=ticker.FuncFormatter(lambda x, pos: "%.1f" % x))
109 axes[1].set_title("required calories to boiler point (kcal/kg)\n[" + str(vd) + "]")
110 # -----------------------------------------------------
111 #plt.show()
112 plt.savefig("boiling_point_of_water2.png", bbox_inches="tight")

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

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

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

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