2050年再エネ100%はどれくらい難しいか(2) - 発電所の規模について

昨日は2050年の年間消費電力量が1300~1500TWhになること、現在より増える理由は、人口減や省エネで減る電力消費よりも電化で増える消費電力が多いからだということを紹介しました。

methane.hatenablog.jp

今回はこれだけの電力量を発電するのに、太陽光、陸上風力、洋上風力それぞれどれくらいの発電所が必要なのかをざっくりと計算していきます。1つの電源で全ての電力を賄う訳ではないので、とりあえずどの発電方式も500TWh発電するのに必要な規模を計算します。3つ全てが500TWhを発電する必要はないし多分不可能でしょうが、最低1つの電源は500TWhを超える電力を発電してもらわなければなりません。

設備利用率について

発電所が年間を通して100%定格出力で発電できた場合、発電量は出力 (kW)×24×365になります。1GWの発電所の場合8760GWhを発電することになります。

実際にはそんなことはありえなくて、点検が必要だったり、地震で止まったり、発電量を需要に合わせるために定格以下の出力で発電することもあります。なので 平均的な年間発電量/(定格出力×24×365)のことを設備利用率と言います。

太陽光発電は夕方には発電量が落ち、夜はゼロになります。曇りの日もかなり出力が低下します。そのため太陽光発電の設備利用率は12%程度と言われています。風の強さで発電量が変わる風力も陸上で20%、洋上で30%と言われています。今回はこの数字を使って計算します。

よく新聞記事で発電所の規模を「原発○基分」という表現が使われますが、これは1GWを1基分としていることが多いです。発電量で考えた場合、(3.11前の設備利用率80%の)原発に比べると、4GWの陸上風力発電(設備利用率20%)は「原発4基分」ではなく「原発1基分」になります。

太陽光発電

設備利用率12%というのはすごく計算が楽で、24×365×0.12=1051.2なので、出力に1000をかければ年間発電量になります。1MWの発電所なら1GWhですね。今回は年間発電量500TWhを発電する場合に必要な規模を見積もるのですから500GWです。

だいたい1MWの太陽光発電所に必要な面積が1haと言われているので、500GWなら50万ha=5000平方kmです。琵琶湖が670平方kmなので、おおよそ琵琶湖7.5こ分の面積をソーラーで埋め尽くせば2050年の日本の電力需要の1/3 (500TWh) をまかなえることになります。

これだけの面積をどうやって日本から見つければいいのでしょうか?現在考えられているのが耕作放棄農地の転用と、農地での発電(ソーラーシェアリング)です。農地に関する統計によると、440万ha、荒廃農地が28万haあります。

農地に関する統計:農林水産省

ここからは私個人の予想(想像)になります。

日本は個人の財産、土地所有が憲法に守られているので、国が強制的に「この土地でソーラー発電しろ」とは言えません。ですが地方自治体、地主、農家、発電事業者が積極的に協力できれば、いいところ(100GW以上)までは行けそうです。

一方で、ソーラーの発電量が多い時間帯(晴れの日の10:00~14:00)は電力市場のスポット価格も低下しがちです。ソーラー発電の割合が増えれば増えるほどこの動きは顕著になり、発電量あたりの発電収入は下がってしまいます。指数関数的な導入量増大を実現できたとしても、500GWに到達する前に失速してしまうかもしれません。

JPEA(太陽光発電協会)の意見表明でも、2050年に300GWがビジョンとして示されています。

自由民主党再生可能エネルギー普及拡大議員連盟における意見表明について

陸上風力

設備利用率20%とすると、500000 × 5 ➗ (24×365) = 285 なので、年間発電量500TWhのためには約300GWが目標になります。

風車は大型にした方が効率がいいのですが、陸上だとあまりに巨大な風車は建設が大変なので、あまり大型化が進まず大型風車でも2MW程度が主流だと仮定すると、300,000MW / 2MW = 15万本の風車が必要になります。

300GWを30年間で実現するには毎年10GWの導入が必要です。とはいえいきなり来年から10GWをというのは無理です。今まで風力をほとんど育てていなかった日本はこれから産業を育成していかないといけません。2040年代のピークには年間30GW以上導入する年が必要になりそうです。

さて、ドイツでは2014年に4.7GWの風力を導入していたものの、2019年には1GWに減速しています。理由の一つに近隣住民とのトラブルが挙げられています。風車自体は太陽光よりも面積を使わないものの、低周波騒音を考えると住宅地の近くにはあまり建設できません。

https://eneken.ieej.or.jp/data/5945.pdf

www.fepc.or.jp

日本の場合を考えると、圧倒的に多くの導入ポテンシャルが北海道にあります。2050年まで減速せずに風力発電の導入量を指数関数的に伸ばしていくには、北海道の土地利用計画や送電線の整備が重要になってくると思います。

しかし、JWPA(日本風力発電協会)のビジョンでは、2050年の陸上風力導入量は40GW以下で、最近の報道を見ても洋上風力が過熱していて陸上風力のニュースは少ないです。

jwpa.cloud

北海道に大量に陸上風力を作っても結局関東まで電気を送るには長距離大容量送電線が必要になるから、洋上風力に比べて需要地の近くで発電できる陸上風力のメリットが活きないとか、陸上風力ではEUの方が進みすぎていて国内企業が競争しにくいとか、いろいろな理由があるのだと思いますが、今の流れでは2050年までに300GWはかなり難しそうです。

洋上風力

設備利用率30%とすると、500000 × 10 / 3 / (24×365) = 190 なので、年間発電量500TWhのためには約190GWが目標になります。まず設備利用率の段階で陸上風力よりも有利です。

洋上風力は大型化にも有利で、最近だと1基あたり12MWのものがあります。ここで大型化が止まったとしても、190000/12≒15800で、同じ電力量を発電するのに必要な数が陸上に比べて1割強で済みます。

ポテンシャルも日本の電力全てをまかなえるだけあり、全く問題ありません。唯一の問題は、日本には浅い海が少なく、低コストな着床式は沿岸にしか置けないことです。遠くにおける浮体式はまだコスト競争力がありません。

逆に見ると、陸上風力、着床式風力で圧倒的に先行しているEUに対して、日本が追いつき追い越すチャンスが残っているという事でもあります。これが最近洋上風力に関するニュースが過熱している理由だと思います。

JWPAのビジョンでは、2050年ではなく2040年で45GWになっており、政府もこの目標を採用する流れになっています。陸上風力や太陽光が発電量500TWhが難しい分、洋上風力は2050年に190GWどころか400GWくらい欲しいところですが、どこまで行けるかは未知数です。

まとめ

ポテンシャルは十分にあるので、業界が毎年成長し続けられるように環境を整えれば2050年に再エネ100%は不可能とは言えません。

一方で、JPEAとJPWAのビジョンを元に見積もると、JPWAは2050年の洋上風力を出していないので勝手に45GWの3倍の135GWとして355TWh、陸上風力は30GWとして53TWh、太陽光は300GWとして300TWh、合計で708TWhしかなく、1.3~1.5PWhの46%~54%しかありません。その他の再エネ(主に水力)は10%程度として、政府の2050年に再エネ50~60%とほぼ合致します。

ビジョンからの(特に風力の)上積みに期待しつつも、ビジョンを最低ラインとして必ず実現することに加え、その時に足りなくなる40~50%の電力をCO2フリーな輸入燃料(グリーン水素やアンモニア)で発電する準備も必要です。それにも国内外で10年以上かけた大規模なインフラ整備が必要になるので、2050年に再エネ50~60%という夢のない目安を安直に少なすぎると批判することもできません。

2050年再エネ100%はどれくらい難しいか(1) - 日本の消費電力量について

今年に入ってから環境問題、主に再エネについて少しずつ本を読んだりして調べています。

10月以降、菅政権が2050年カーボンニュートラルを打ち出してから、一気にこの分野の話題が過熱してきました。河野太郎大臣などが再エネの最大限導入のためにあらゆる障害を取り除く努力をされていて、リップサービスではなく本気で動き始めたことを喜んでいます。

一方で、経済産業省が2050年のエネルギー基本計画のたたき台になる目安として、2050年の電力のうち再生エネルギーが50~60%という数字が出てきて、若干失望もしました。今後菅政権の圧力で上方修正されることを期待しています。

www.jiji.com

とはいえ、「60%」「80%」「いーや、100%だっ」って、大きい数字を言った人がえらい訳ではありません。パーセントの数字だけを見ていても実感が湧かなくなってしまうので、2050年再エネ100%がどれくらい大変なことなのか、もうちょっと具体的にイメージできる形にしていきたいと思います。

今回は日本の電力需要を確認してみます。2019年度の電力調査統計を見てみると、総需要(電力会社以外が発電した分を含む)は約1222TWh、電力会社の発電量が約8600TWhあります。一方発電の内訳は、水力が84TWh、新エネ(風力、太陽光など)が42TWh (4.9%) しかありません。

この統計には太陽光の自家消費分などが入っていないので、実際にはもう少し多いと思われます。ISEPの試算では太陽光が7.6%となっています。

www.isep.or.jp

ざっくり年間で1200TWhくらいの電力を現在は使っている訳だけれども、2050年カーボンニュートラルを実現するためには、全ての化石燃料の需要(車のEV化はもちろん、産業では製鉄やセメントなど、家庭では暖房と給湯など)を可能な限り電気に、不可能な分は水素や水素から合成した燃料にしないといけません。その水素や合成燃料も化石燃料ではなくて再エネ由来にしなければなりません。(CCSは大きな部分は占めない。これはまた機会があれば。)

化石燃料の電化や再エネ由来燃料への置き換えに必要な電力量は、2050年までの省エネ努力や人口減で減る電力量よりも大幅に大きいと見込まれます。上の経済産業省の目安でも1300~1500TWhと計算されていました。この程度の増加で済んでいるのは、国内の水素や燃料需要のほとんどを輸入に頼る想定だからだと思います。

参考までに、1GWの原発や大型火力発電所の設備利用率が80%だった場合の年間発電量は、 24 * 365 * 0.8 ≒ 7008 なので約7TWhです。よく言う「原発n基分」で表現すると、1300 / 7 ≒ 186 なので「原発186基分」の電力をカーボンフリーで発電する必要があるのです。

次回はこの電力を100%国内の再エネで発電する場合の規模感を計算してみたいと思います。

go-sql-driver/mysql のバッファサイズが4KiBなのは小さすぎる??

qiita.com

go-sql-driver/mysql のバッファサイズは4KiBで、大きいクエリを送るなり大きいパケットを受信すれば自動的に増えますが、小さいrowを大量に受信する場合は4KiBのバッファを使って何度もReadをしてしまいます。これを大きくすればReadの回数が減って高速化できそうな気がします。

ということで、話題のリポジトリをforkして、DBからselectしてCSVを書き出す部分だけを100回ループしてみました。CSVの書き出しがネックにならないようにbufio.NewWriterSize()を使ってバッファリングしてあります。

profiling · methane/bench-docker@c333bd0 · GitHub

テスト環境は手元の MacBook Pro 13 (Retina, 13-inch, Mid 2014) で、あまり厳密なベンチではありません。

まずはバッファサイズ4KiBの場合のプロファイル結果。

f:id:methane:20201217170259p:plain
flamegraph (バッファサイズ 4KiB)

rows.Next が 3.01s で、呼び出し元の work は 3.33s です。

次にバッファサイズ16KiBの場合のプロファイル結果。

f:id:methane:20201217170529p:plain
flamegraph (バッファサイズ 16KiB)

rows.Next が 2.83s に減りましたが、期待したほどは減ってません。そして呼び出し元の work は 3.36s で、微妙に増えてしまいました。CSVを書き出すための fmt.Fprintf や Time.Format() が若干遅くなってしまってrows.Next の高速化分を打ち消してしまっています。

システムコールのオーバーヘッドの大きさにも依存しますが、むやみにバッファサイズを大きくしてもキャッシュに与える悪影響でシステムコールの回数を減らす効果が打ち消されるのかもしれません。

@kazuho さんさすがです。

Matebook 14 (2020)

amzn.to

税込み11万円弱で、AMD Ryzen 7 4800H、RAM 16GB、SSD 512GB、sRGB 100%の3:2液晶はすごいコスパ

Windowsはサブだけどある程度の開発生産性は欲しいという場面にいいと思って購入した。バタフライキーボードになる前のMBP 13 (2015)と比べて、

  • 日本語キー配列はいたって普通。キーボードのストローク、タイプ感も十分で、キートップを触ると若干の凹みも感じられて、十分にタイプしやすい。
  • 液晶解像度はMBPには劣るが、横解像度もFullHDよりも若干高めで、個人的には十分。
  • 低反射コーティングの質はMBPより悪い気がする。輝度を少し高めて使ってるけど、人によってはノングレアのフィルムを貼ったほうが良いかもしれない。
  • 重さは同じはず (1.49kg)
  • バッテリー持ちは(比較対象が古すぎるけど)圧倒的にいい。電源モードを「高パフォーマンス」(最高の1つ下)にして、一日リビングで充電なしで作業できる。
  • 液晶を開けただけではスタンバイから復帰せず、指紋センサー兼電源ボタンを押すことがある。でも復帰後にロック解除のために改めて指紋センサーを押す必要はないので使い勝手は十分にいい。
  • 液晶を開けるときに最初の1センチはいいんだけど、そこから開く力が重くなって下側が浮いてしまうので反対の手で下側を支えないといけないところに、細かいけれどもツメの甘さを感じる。
  • USB Type-C ポートが1つしかなくて、しかも充電がここからしかできないのがネック。

amzn.to

関数アノテーションを軽量化しました

この記事は KLab 2020 Advent Calendar の 12/2 分になります。 qiita.com

最近の Python に対する改善を紹介します。私が設計、コードレビューまでしましたが、実装は他のコントリビューターにしていただきました。 (プルリクエストはこちら)

背景として、Python 3.10 からは from __future__ import annotations がデフォルト化され、アノテーション部分は実行時に評価されずにただの文字列になります。( PEP 563 を参照してください。)

>>> def add(a: int, b: int) -> int:
...     return a+b
...
>>> add.__annotations__
{'a': 'int', 'b': 'int', 'return': 'int'}

アノテーションが実行時に評価されないということは、コンパイル時にアノテーションがすべて計算可能ということです。そこで Python 3.10 からさらなる最適化を導入しました。

まずは Python 3.9 で関数アノテーションがどう実装されていたかをおさらいします。

# a.py
from __future__ import annotations

def add(a: int, b: int) -> int:
    return a + b
$ python3 -m dis a.py
(snip)
  3          12 LOAD_CONST               2 ('int')
             14 LOAD_CONST               2 ('int')
             16 LOAD_CONST               2 ('int')
             18 LOAD_CONST               3 (('a', 'b', 'return'))
             20 BUILD_CONST_KEY_MAP      3
             22 LOAD_CONST               4 (<code object add at 0x7f7c9efac870, file "a.py", line 3>)
             24 LOAD_CONST               5 ('add')
             26 MAKE_FUNCTION            4 (annotations)
             28 STORE_NAME               2 (add)

4つのLOAD_CONST命令と1つのBUILD_CONST_KEY_MAP命令でdictを作って、それをMAKE_FUNCTIONに渡しています。この dict は function オブジェクトに格納されます。

これは関数の定義時に実行される命令なのでプログラムの実行速度への影響は軽微ですが、ループの中で inner function を定義している場合には毎回実行されますし、そうでなくても pyc ファイルを import する時間に多少影響を与える可能性があります。

これが Python 3.10 ではこうなります。

  3          12 LOAD_CONST               9 (('a', 'int', 'b', 'int', 'return', 'int'))
             14 LOAD_CONST               6 (<code object add at 0x7f9e932a7be0, file "a.py", line 3>)
             16 LOAD_CONST               7 ('add')
             18 MAKE_FUNCTION            4 (annotations)
             20 STORE_NAME               2 (add)

アノテーションが1つのタプルにまとめられ、このタプルが dict に変換されずそのまま MAKE_FUNCTION に渡され、関数オブジェクトに保存されるようになりました。これでアノテーション付きの関数を作る速度が数倍速くなります。 https://bugs.python.org/issue42202#msg381320 からマイクロベンチマーク結果を1つだけピックアップします。

def f(a: int, /, b: int, *, c: int, **d: int) -> None: pass

Python 3.9.0
5000000 loops, best of 5: 326 nsec per loop

Python 3.10.0a2+ (from __future__ import annotations がデフォルト化された状態)
5000000 loops, best of 5: 264 nsec per loop

Python 3.10.0a2+ with compact representation
5000000 loops, best of 5: 87.1 nsec per loop

さらにメモリ使用量にも影響があります。このタプルは func.__annotations__ が最初にアクセスされた時に dict に変換されるのですが、静的型チェックやコード補完機能、ドキュメントの目的で付けられた関数アノテーションは実行時には利用されないことが多いので、アクセスされないままならずっとタプルのままです。これでメモリ使用量は4割以下に減らせます。

>>> sys.getsizeof({"a":"int","b":"int","return":"int"})
232
>>> sys.getsizeof(("a","int","b","int","return","int"))
88

おまけに、同じソースファイルの中にある LOAD_CONST で読まれるタプルは、中身が同じであれば1つのインスタンスを使いまわします。 (Python 3.7までは1つのcodeオブジェクト(1つの関数など)内でしか使い回さなかったのですが、これも私が改良していました。 https://github.com/python/cpython/commit/c2e1607a51d7a17f143b5a34e8cff7c6fc58a091)

コードジェネレータに生成されたファイルなどで数千の同じシグネチャの関数がある場合は、今までは関数の数だけ dict オブジェクトを作っていたのが、 Python 3.10 ではたった1つのタプルで済むようになります。これでより気軽に関数アノテーションを使えるようになります。

将来の野望としては、関数アノテーションだけでなく docstring も、実際に利用されてからロードする遅延ロードが実装できたら良いなと思っています。しかしこれには pyc ファイルのフォーマットを完全に刷新する必要があり、しかもモジュールをロードしたあとに pyc ファイルが上書きされたらどうするのかという問題に対する解決策をまだ思いついていないので、 近い将来に実現するのは難しいです。いいアイデアを思いついたら教えて下さい。

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。