Sisällysluettelo

Simulaatioita

Dynaamisten järjestelmien simulointia ja juttuja mallinnuksesta

2021-1-15


2020-12-14

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Elävä maalaus

 

Elävä maalaus

Taidenäyttelyn avajaisissa seinälle heijastettiin video vesiputouksesta, jossa vesi oli korvattu ykkösillä ja nollilla. Taiteilija kertoi pitävänsä tietokonetta monipuolisena 'siveltimenä'. Tulin kertoneeksi hänelle, että ole pitkään haaveillut simulaatiosta, jossa eriväriset maalit virtailevat muodostaen psykedeelisiä kuvioita. Soveltaisin fysiikan lakeja, mutta ottaisin taiteilijan vapauden muutella niitä.

—   Sehän on tekemistä vaille valmis, hän sanoi.

Tulkitsin taiteilijan ylistävän ideaani: Onpa jumalaisen omaperäinen idea ja toteutuskin valmiiksi mietitty.

Viikon aherruksen jälkeen aloin arvella taiteilijan vihjanneen, että epämääräisen haaveen ja valmiin teoksen väliin mahtuu paljon epätoivoista puurtamista ja silti lopputulos jää pahasti vajaaksi siitä, mitä on haavehoureissaan sielunsa silmillä nähnyt.


At the opening of an art exhibition, a video of a waterfall was projected on the wall, with water replaced by ones and zeros. The artist said he sees the computer as a versatile ‘brush’. I told him that I had long dreamed of a simulation in which paints of different colors flow, forming psychedelic patterns. I would apply the laws of physics, but with the artist’s freedom to modify them.

That's ready to do, he said.

I thought he praised my idea: Such a divine original idea with implementation already thought out.

After a week of strugling, I understood that the artist had hinted that there is a lot of desperate drilling between a vague fantasy and a finished work, and yet the end result will be far from the dream.

Tammikuussa 2021

Ikuisesti alavirtaan

video varalle, jos yo. ei toimi

Roiskeita

video varalle, jos yo. ei toimi

Videoni ei näytä alkuunkaan samalta kuin haaveissani. Vaan enpä minä tuota tehnytkään. Sen teki tietokoneeni, joka ei antanut unelmilleni armoa. Osansa on myös fysiikan laeilla, jotka eivät noudata kuvitelmiani.

Joku on saanut aikaiseksi tällaista . Okay, Mä hävisin.

Suurta taidetta en saanut aikaiseksi, mutta yksi monista pitkäaikaisista haaveistani toteutui: Olen opiskeluajoista lähtien halunnut tehdä ohjelman, joka ratkaisee osittaisdifferentiaaliyhtälöitä ja simuloi kaasujen ja nesteiden virtailua. Uskoin toki tietäväni ratkaisun periaatteen, mutta olen oppinut, että reaalimaailman ongelmat eivät kunnioita uskoani omaan kaikkitietävyyteeni. Uskominen omaan osaamiseen on paljon helpompaa kuin tekeminen.

Valistusvideon mukaan covid-19 -sodan todellisia sankareita ovat ne, jotka kykenevät ahdistumatta lojumaan kotisohvalla mitään tekemättä. Arvelin, että koodaminenkin on covid-19 -sodassa, ellei sankaruutta, niin ainakin sallittua. Minulle koodaaminen toimii meditaationa — Kunhan saan koodata mitä haluaa eivätkä dead-linet ahdista.

Jos aikoinaan töissä ollessani sain pomon vakuuttuneeksi, että joku homma on tärkeä, pomo kysyi, paljonko se vaatii työtä.

Pelkkä kysymys alkoi ahdistaa. Miten työmäärän voisi arvioida uudenlaisesta uppo-oudosta hankkeesta, josta ei mitään tiedä? Työmäärähän on jokseenkin viimeinen asia, mikä tällaisissa hankkeissa selviää. Työelämässä tärkeintä oli keksiä mahdollisimman iso niin pieni arvio työmäärälle, että pomo saattoi sen hyväksyä. Tällaisen pikkuhankkeen työmääräksi olisin ehkä arvioinut: 'parisen viikkoa' johon pomo olisi vastannut: 'saat viikon'.

Jos tämä olisi ollut työprojekti, muutama viikko dead-linen väärällä puolella minua olisi alkanut ahdistaa, vaikka sadas prototyyppi jo olisikin osoittanut alustavia toimimisen oireita. Kun alkaa ahdistaa, tulee hosuttua ja yritettyä quick-and-dirty temppuja. Homma tyssää siihen eikä auta kuin julistaa nolottavan keskeneräinen työ valmiiksi.

Syrjähyppynä linkki juttuun, jossa hämmästellään, miksi kaikki eivät tunne virtausdynamiikan lakeja

Loin tietokoneeseeni järven saarineen. Videolla vasemmassa ruudussa näkyy järven pinta ja veden virtaukset. Mitä punaisempaa, sitä korkeammalla vesi on. Nuolet osoittavat veden virtauksen suuntia. Mitä paksumpi nuoli, sitä enemmän vettä virtaa, mitä punaisempi nuoli, sitä nopeammin vesi virtaa. Saaria en jaksanut erikseen maalata. Ne alkavat erottua, kun niiden kohdalla "pinnankorkeus" ei muuta. Vesi virtaa tietysti alavirtaan, eli järveä sopivasti kiertäessään voi koko ajan lasketella alavirtaan. Ei siis ihan reaalimaailman järvi vaan fantasiamaailman järvi. Sen voi ajatella järveksi vaihtoehtoisen totuuden maailmassa. Nykyään vaihtoehtoiset totuudet ovat suosittuja politiikassa, miksei siis fysiikassakin.

Järveen ja saarille on roiskittu punaista ja vihreää väriä, joiden pitoisuudet näkyvät videon oikeanpuoleisessa ruudussa. Mistä tämä väri on tullut? Simulaation alkua edeltävistä tapahtumista tiedämme yhtä vähän kuin maailmankaikkeuden tapahtumista ennen alkuräjähdystä. Ehkä joku värikuulameteori on poksahtanut harmittavasti juuri järveni yläpuolella.

 

Yritykset ja erehdykset ja yritykset ja ...

../xml/Programming/Simulaatioita/Elava_maalaus/escherPutous.jpg
Escherin näkemys kanavasta 

Aluksi simuloin suorassa kanavassa virtaavaa paksuhkoa nestettä. Kun lopulta sain nesteen joten kuten virtaamaan, huomasin lopputuloksen sangen tylsäksi. Ei auttanut, vaikka väänsin kanavan mutkalle — ei auttanut toinenkaan mutka. Vaimokin käveli ohi pysähtymättä ihastelemaan. Algoritmin kehittely kuitenkin kiehtoi niin, etten luovuttanut.

Kun näin Escherin piirroksen vesiputouksesta, ymmärsin, ettei minunkaan tarvitse antaa reaalimaailman kahlehtia itseäni. Loin järven, jossa vesi valuu saarten välissä ikuisesti alavirtaan. Koska lukijan saattaa olla vaikea ymmärtää, millaisesta järvestä on kysymys, piirsiin järven pohjan kallistusten veteen aiheuttamat voimat järven eri kohdissa. Selvensi?

../xml/Programming/Simulaatioita/Elava_maalaus/kosket.png
Kallistusten aiheuttamat voimat 

lisäselvennykseksi itä-länsi ja pohjois-etelä -suuntaan vaikuttavien voimien suuruudet.

../xml/Programming/Simulaatioita/Elava_maalaus/kosket_u.png
Itä-länsi -suuntaisen voiman suuruus eri kohdissa järveä. Lämpimät sävyt positiivisia, kylmät negatiivisia 
../xml/Programming/Simulaatioita/Elava_maalaus/kosket_v.png
Etelä-pohjois -suuntaisen voiman suuruus. 

Videon alussa järvi on levossa ja vettä on kaikkialla tasainen kerros. Sitten vesi alkaa virrata alas koskista kiihtyvällä vauhdilla. Ken on niin kiinni reaalimaailmassa, ettei kykene moista koskien 'käynnistymistä' mielessään kuvittelemaan, voi korvata kosket järvessä kyljellään olevilla siipirattailla, joiden toinen puoli haukkaa vettä, toinen puoli haukkaa tyhjää.

Minun mielestäni vesi virtailee juuri niin kuin sen kuuluukin ja väriaineet liukenevat veteen ja kulkevat veden virtausten mukana juuri niin kuin kuuluukin. Kovin kaunista katseltavaa tuo ei ole, ellei osaa arvostaa 'luonnonilmiöiden' hienoutta.


Aluksi laitoin järveen suorakulmaisia saaria, mutta virtaukset aiheuttivat suoakulmioiden nurkkia kiertäessään niin suuria paine-eroja, että alkeellinen algoritmini ei tilanteesta selvinnyt.

Korvasin suorakulmiot ellipseillä. (Ehkä autot ja lentokoneetkin ovat pyöreäkulmaisia, koska insinöörien algoritmit eivät selviä virtausten jyrkistä käännöksistä :-)

Ei sentään. Insinöörit joutuvat kehittelemään algoritmejaan, kunnes saavat ongelmansa ratkaistua. Minun ei tarvinnut sellaiseen ryhtyä, koska minä ja järveni elämme vaihtoehtoisessa todellisuudessa. Helpompaa kuin algoritmini paranteleminen oli 'parannella' fantasiamaailmaani — muotoilla ja siirrellä saaria, muutella 'veden' viskositeettia (= 'paksuutta') — kunnes alkeellinen algoritmini onnistui liikuttelemaan 'virtauksia' suuremmin kompuroimatta.

 

Vesistön kartan piirtäminen

Saarien ja muoto ja sijainti pitää 'kertoa' simulaattorilleni sittaisdifferentiaaliyhtälöinä, mutta minä ymmärrän vain kaaviokuvia. Minulla ja simulaattorilla oli kommunikaatio-ongelma, joka tuotti ikäviä yllätyksiä. Jo kymmenennen yllätyksen jälkeen tein työkalun, joka piirtää minulle kartan siitä, millaisen saariston olen tullut keksineeksi ja joka osaa kirjoittaa sen yhtälöiksi, jotka simulointiohjelmani ymmärtää. Hauskaa matematiikan verryttelyä. Tai ei pelkkää verryttelyä — uuttakin piti opetella.

Tuntuu, että minun kouluaikoinani opetukseen liittyi sellainen harhakuvitelma, että opetettavaksi valituilla nippelitiedoilla pärjää loppuelämänsä. Matematiikan soveltamisessa tärkeintä kuitenkin on matemaattinen ajattelu, kyky opetella uusia nippelitaitoja ja ymmärrys siitä, mitä nippelitaitoja opetella. Matemaattinen ajattelu — mitä se on? Kiperä kysymys. Miten oppia opettelemaan uutta? Kiperä kysymys sekin.

Luonnontieteiden opetuksessakin tuntui riittävän, että osaa tietyt kaavat, joiden avulla ratkaista tietynlaiset tyyppitehtävät sen sijaan, että olisi ensin/samalla yritetty oikeasti ymmärtää luonnonilmiöitä. Tyttäreni kertoi, että nykyään yliopistolla on demotyyppejä, jotka ovat kunnolla miettineet, miten havainnollistaa luonnonilmiöitä.

Järvivesistön suunnittelun työkalu

Kun virtausilmiöitä simuloidaan, maailma jaetaan pieniksi kuutioiksi ja lasketaan, mitä kullekin kuutiolle tapahtuu ajan kuluessa. Järvessäni kuutio on joko maata tai nestettä. Tämän takia yllätyin ikävästi, kun testasin, miten simulointiohjelmani näkee ellipsin muotoiset saaret. Eivät olleet pehmeän pyöreitä vaan monikulmiota. Kulmia tuli paljon, mutta onneksi algoritmini ei niistä hermostunut yhtä pahasti kuin suorakulmioiden nurkista.

 

Yhtälöiden johtaminen

Virtausdynamiikan perusyhtälöt pitää vääntää simulointiin sopivaan muotoon. Opin jo koulussa, että yhtälöiden pyörittely ei ole ihmisen hommaa — ei sovi ainakaan minulle. Silloin harvoin kuin pääsin 'lopputulokseen' asti, se näytti aina jotenkin oudolta, minkä selitykseksi olin löytävinäni virheen yhtälöiden pyörittelyn alkuvaiheista tai jo lähtöyhtälöistä. Ei auttanut kuin tehdä kaikki uudestaan alusta lähtien. Ja huomata, että virhe olikin muualla. Taas alusta. Sitten huomata, että olihan se virhe siellä alussa, mutta eri kohdassa kuin ...

Onneksi yhtälöiden pyörittelyn voi teettää tietokoneella: Kirjoitetaan yhtälöt ja annetaan tietokoneen ratkaista ne. Jos lähtöyhtälöitä täytyy muuttaa, tehdään korjaukset ja klikataan 'ratkaise'. Jokohan koulussa nykyään kerrotaan tällaisesta mahdollisuudesta?

../xml/Programming/Simulaatioita/CFD/forces_eq.png
Voimia (http://www.eng.auburn.edu/~tplacek/courses/fluidsreview-1.pdf) 
../xml/Programming/Simulaatioita/CFD/mass_eq.png
Massan säilyminen (http://www.eng.auburn.edu/~tplacek/courses/fluidsreview-1.pdf) 
../xml/Programming/Simulaatioita/CFD/momentum_eq.png
Liikemäärän säilyminen (http://www.eng.auburn.edu/~tplacek/courses/fluidsreview-1.pdf) 

Jäljempänä olevan linkin takana kerrotaan, miten oheisista säilymislaeista tuotetaan automaattisesti seuraava, simuloinnissa tarvittava funktio.

    # -*- coding: utf-8 -*-

import params as par
import saaret as ly


def dfdt(kartta, rho_d, u_d, v_d, paint_d, Fe_u, Fe_v, D_rho, D_u, D_v, D_paint):
    for i in range(1, ly.DIM_i-1):
        for j in range(1, ly.DIM_j-1):
            if kartta[i, j] == 'jarvi':
                D_rho[i, j] = \
                 (0.5*rho_d[i, j]*u_d[i, j-1]-0.5*rho_d[i, j]*u_d[i,
                  j+1]+0.5*rho_d[i, j]*v_d[i-1, j]-0.5*rho_d[i,
                  j]*v_d[i+1, j]+0.5*rho_d[i, j-1]*u_d[i,
                  j]-0.5*rho_d[i, j+1]*u_d[i, j]+0.5*rho_d[i-1,
                  j]*v_d[i, j]-0.5*rho_d[i+1, j]*v_d[i, j])

                D_u[i, j] = \
                 ((-4.66666666666667*par.mu*u_d[i,
                  j]+1.33333333333333*par.mu*u_d[i,
                  j-1]+1.33333333333333*par.mu*u_d[i,
                  j+1]+1.0*par.mu*u_d[i-1, j]+1.0*par.mu*u_d[i+1,
                  j]+0.0833333333333333*par.mu*v_d[i-1,
                  j-1]-0.0833333333333333*par.mu*v_d[i-1,
                  j+1]-0.0833333333333333*par.mu*v_d[i+1,
                  j-1]+0.0833333333333333*par.mu*v_d[i+1,
                  j+1]-par.c_fr*u_d[i, j]+0.5*par.c_p*rho_d[i,
                  j-1]-0.5*par.c_p*rho_d[i, j+1]+(Fe_u[i,
                  j]+0.5*u_d[i, j]*u_d[i, j-1]-0.5*u_d[i, j]*u_d[i,
                  j+1]+0.5*u_d[i-1, j]*v_d[i, j]-0.5*u_d[i+1,
                  j]*v_d[i, j])*rho_d[i, j])/rho_d[i, j])

                D_v[i, j] = \
                 ((0.0833333333333333*par.mu*u_d[i-1,
                  j-1]-0.0833333333333333*par.mu*u_d[i-1,
                  j+1]-0.0833333333333333*par.mu*u_d[i+1,
                  j-1]+0.0833333333333333*par.mu*u_d[i+1,
                  j+1]-4.66666666666667*par.mu*v_d[i,
                  j]+1.0*par.mu*v_d[i, j-1]+1.0*par.mu*v_d[i,
                  j+1]+1.33333333333333*par.mu*v_d[i-1,
                  j]+1.33333333333333*par.mu*v_d[i+1,
                  j]-par.c_fr*v_d[i, j]+0.5*par.c_p*rho_d[i-1,
                  j]-0.5*par.c_p*rho_d[i+1, j]+(Fe_v[i, j]+0.5*u_d[i,
                  j]*v_d[i, j-1]-0.5*u_d[i, j]*v_d[i, j+1]+0.5*v_d[i,
                  j]*v_d[i-1, j]-0.5*v_d[i, j]*v_d[i+1, j])*rho_d[i,
                  j])/rho_d[i, j])

                D_paint[i, j] = \
                 (-4.0*par.D_pnt*paint_d[i,
                  j]+1.0*par.D_pnt*paint_d[i,
                  j-1]+1.0*par.D_pnt*paint_d[i,
                  j+1]+1.0*par.D_pnt*paint_d[i-1,
                  j]+1.0*par.D_pnt*paint_d[i+1, j]+0.5*paint_d[i,
                  j]*u_d[i, j-1]-0.5*paint_d[i, j]*u_d[i,
                  j+1]+0.5*paint_d[i, j]*v_d[i-1, j]-0.5*paint_d[i,
                  j]*v_d[i+1, j]+0.5*paint_d[i, j-1]*u_d[i,
                  j]-0.5*paint_d[i, j+1]*u_d[i, j]+0.5*paint_d[i-1,
                  j]*v_d[i, j]-0.5*paint_d[i+1, j]*v_d[i, j])


  

Yritin kirjoittaa seuraavan niin, että sitä lukiessa voi ohittaa yhtälöt ja python koodit pikaisella vilkaisulla. Virtausyhtälöiden johtaminen

Numeron murskaus

Simulointitehtävät eivät ratkea analyyttisesti yhtälöitä pyörittämällä vaan viimeisenä vaiheena joudutaan turvautumaan numeeriseen laskentaan. Laskemista on niin paljon, että kymmenen vuotta vanhalta tietokoneeltani kului useampi tunti alussa olleeseen videoon tarvittavien kuvien tuottamiseen. Pikkuisen mietityttää, miten nopeuttaa laskentaa. Mietityttää, muttei onneksi niin paljoa, että ryhtyisin koodia korjaamaan.

Eh harrasta videopelaamista, mutta aika ajoin haaviin on sattunut artikkeleita, joissa tarkastellaan videopelien tarpeisiin kehitettyjä nopeita luonnonilmiöiden simulointiin soveltuvia algoritmeja. Ilmeisesti suurinpiirtein fysiikan lakeja noudattavat tehosteet säväyttävät.


/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Elävä maalaus /virtaukset.py

 

virtaukset.py

@author: Heikki Välisuo

Thu Jan 14 18:33:14 2021

'''

Tämä ohjelma ei käy esimerkiksi tyylikkäästä ohjelmoinnista. Olen selvitellyt pahimpia sotkujani sitä mukaa, kun olen niihin kompastellut. Olen tehnyt sen verran siistiä koodia, että minun on itse tätä melko helppo muutella tarpeen mukaan, mutta tämän lukeminen lienee vaikeaa. Ehkä en vuoden kuluttua irsekään ymmärrä, mitä tässä tapahtuu. Yrittäessäni korjailla omia vanhoja ohjelmiani, olen huomannut, että ohjelmia on helpompi kirjoittaa lukea.

'''

import datetime as tim
import random
import numpy as np
import math
import matplotlib.pyplot as plt
import matplotlib.colors as colors

import dfdt_virtaukset as df
import params as par
import saaret as ly




'''

Ohjelmoinnissa on tapana kapseloida yhteen kuuluvia tietoja ja toimintoja olioiksi, joiden sisäisestä elämästä muun ohjelman ei tarvitse tietää mitään. Tyyppiä 'maalari' oleva olio maalaa simuloinnin jokaisella aika-askelella pinnankorkeuksista, virtauksista ja väriaineiden valumisesta kuvan.

Olion voin ajatella maalarin työpajaksi, jolle tarvittaessa lähetetään tiedot järven tilasta ja pyydetään sitä maalaamaan niistä havainnolliset kuvat.

Piirtelyyn käytin matplotlib.pyplot-modulia. Ei ollut helppo oppia sitäkään käyttämään.

'''


class Cl_Maalari:

    #  'figsize=[12.8, 7.2], dpi=100' tuottaa 1280x720 pixelin kuvia,
    #  joista saa helposti koottua vastaavan resoluution videon

    def __init__(self):
        self.fig, self.taulu = plt.subplots(1, 2, figsize=[12.8, 7.2],
                                            dpi=100, tight_layout=True)
        self.taulu[0].set_aspect('equal')
        self.taulu[1].set_aspect('equal')

        self.x = np.full(ly.DIM_j, 0.0)
        self.y = np.full(ly.DIM_i, 0.0)
        for j in range(0, ly.DIM_j):
            self.x[j] = par.ds*j
        for i in range(0, ly.DIM_i):
            self.y[i] = par.ds*i
        self.max_speed = 0.0

    def sys_plot(self, rho, u, v, paint, n):
        #  min_paint, max_paint = np.min(paint), np.max(paint)
        min_rho, max_rho = np.min(rho), np.max(rho)

        #  pinnankorkeus. Logaritminen asteikko tuo esiin sekä
        #  ison konsentraation roiskeet, että diffuusion aiheuttaman
        #  värien hitaan hiipumisen.
        self.taulu[0].pcolormesh(rho, cmap='RdYlGn_r',
                                 norm=colors.SymLogNorm(
                                     linthresh=0.01, base=10))  #  , clip=True

        #  virtausnuolet, väri hetkellisen nopeuden mukaan,
        #  paksuus veden virtauksen mukaan
        speed = np.sqrt(u**2 + v**2)
        self.max_speed = np.max(speed)
        if self.max_speed > 0.01:
            q = rho*speed  #  nesteen virtaus
            q_max = np.max(q)
            sp_lw = 4.0*q/q_max + 0.1
            #  clr = (131/255.0, 185/255.0, 0)  color=clr)

            self.taulu[0].streamplot(self.x, self.y, u, v,
                                     color=speed, cmap='coolwarm',
                                     linewidth=sp_lw)

        #  väriaineiden konsentraatio
        print('paint min max: ', np.min(paint), np.max(paint))

        self.taulu[1].pcolormesh(
            paint, cmap='RdYlGn',  #  'Spectral')
            norm=colors.SymLogNorm(
                linthresh=1.0, base=10))
        #  , clip=True, vmin=-par.pnt_cut, vmax=par.pnt_cut

        #  Näin voi zoomata
        #  taulu[1].pcolormesh(rho[80:105, 20:60], cmap='plasma_r')

        s1 = 'pinnankorkeus {:.4g} -- {:.4g}; '
        s2 = '  suurin nopeus: {:.4g};  aika: {:4.1f}'
        txt = self.fig.text(0.4, 0.98, (s1+s2).format(
            min_rho, max_rho, self.max_speed, n*par.dt,
            fontsize='x-large', backgroundcolor='white'))
        self.taulu[0].axis('off')
        self.taulu[1].axis('off')

        #  Kuva päivitetään joka simulointiaskelella.
        #  Ei onnistu ilman pikku pausea
        plt.pause(0.1)
        #  Tallennetaan kuva videon tekemistä varten
        figno = '{:05d}'.format(n)
        plt.savefig('/home/heikki/maalaus/taulu_'+figno+'.png', format='png')

        #  Tyhjennetään kuvien sisältö. Muuten uusi kuva tulee vanhan päälle
        self.taulu[0].cla()
        self.taulu[1].cla()
        txt.remove()




'''

Allaolevaan funktiota ei tarvita tässä ohjelmassa, mutta laitoin sen muistutukseksi siitä, että kannattaa olla perillä siitä, miten funktioiden parametrit välittyvät pythonissa.

(Eli siis tein aluksi muutaman vaikeasti jäljitettävän virheen.) Läheskään kaikista webissä olevista selityksistä ei selviä olennainen, mutta allaolevaa funktiota kokeilemalla selviää koko totuus.

'''


def test_swap():
    a = np.full((2, 2), 1.0)
    b = np.full((2, 2), 2.0)
    print(a, '\n', b, '\n\n')

    a, b = b, a
    print(a, '\n', b, '\n\n')

    a = b
    print(a, '\n', b, '\n\n')

    a[1, 1] = 100.0
    print(a, '\n', b, '\n\n')




'''

Sovelsin liiankin paljon paljon yritys-erehdys -menetelmää. Onneksi montaa toimintoa sai testattua piirtämällä kuvan sen tuloksesta.

Alla apufunktiota piirtelyyn. Ohjelmoitu quick-and-dirty copy-paste -menetelmällä

'''


def test_plt1(a, text):
    plt.matplotlib.use('qt5agg')
    plt.ion()

    fg, kuva = plt.subplots(1, 1, tight_layout=True)
    plt.axis('on')
    major_ticks = np.arange(0, ly.DIM_i+1, 10)
    minor_ticks = np.arange(0, ly.DIM_i+1, 5)
    kuva.set_aspect('equal')
    kuva.grid(which='both')
    kuva.set_xticks(major_ticks)
    kuva.set_xticks(minor_ticks, minor=True)
    kuva.set_yticks(major_ticks)
    kuva.set_yticks(minor_ticks, minor=True)

    kuva.pcolormesh(a, cmap='inferno')  #  , cmap='winter'
    fg.text(0.45, 0.97, text, fontsize='x-large', backgroundcolor='white')
    #  kuva[0].pcolormesh(a[0:20, 20:60])
    #  kuva[1].pcolormesh(b[30:90, 60:100])
    plt.savefig(text+'.png', format='png')


def test_plt(a, kartta, text):
    print(text, a.shape)
    print(text, kartta.shape)
    fg, kuva = plt.subplots(1, 1, tight_layout=True)
    plt.axis('on')

    major_ticks = np.arange(0, ly.DIM_i+1, 10)
    minor_ticks = np.arange(0, ly.DIM_i+1, 5)

    kuva.set_aspect('equal')
    kuva.grid(which='both')
    kuva.set_xticks(major_ticks)
    kuva.set_xticks(minor_ticks, minor=True)
    kuva.set_yticks(major_ticks)
    kuva.set_yticks(minor_ticks, minor=True)

    kuva.pcolormesh(a)  #  , cmap='Spectral_r'
    kuva.pcolormesh(kartta, alpha=0.1)
    fg.text(0.45, 0.97, text, fontsize='x-large', backgroundcolor='white')
    #  kuva[0].pcolormesh(a[0:20, 20:60])
    #  kuva[1].pcolormesh(b[30:90, 60:100])
    plt.savefig(text+'.png', format='png')


def test_plt2(a, b, kartta, text):
    fg, kuva = plt.subplots(1, 1, tight_layout=True)
    plt.axis('on')

    major_ticks = np.arange(0, ly.DIM_i+1, 10)
    minor_ticks = np.arange(0, ly.DIM_i+1, 5)

    kuva.set_aspect('equal')
    kuva.grid(which='both')
    kuva.set_xticks(major_ticks)
    kuva.set_xticks(minor_ticks, minor=True)
    kuva.set_yticks(major_ticks)
    kuva.set_yticks(minor_ticks, minor=True)

    x = np.full(ly.DIM_j, 0.0)
    y = np.full(ly.DIM_i, 0.0)
    for j in range(0, ly.DIM_j):
        x[j] = par.ds*j
    for i in range(0, ly.DIM_i):
        y[i] = par.ds*i

    speed = np.sqrt(a**2 + b**2)
    max_speed = np.max(speed)
    kuva.streamplot(x, y, a, b, linewidth=4.0*speed/max_speed,
                    color="green")  #  , cmap='Blues')

    kuva.pcolormesh(kartta, alpha=0.1)

    fg.text(0.45, 0.97, text, fontsize='x-large', backgroundcolor='white')
    plt.savefig(text+'.png', format='png')




'''

Geometrinen pähkinä:

Koski on ympyrän, jonka keskipiste on (i0, j0) sektorista [kulma0, kulma1] siivu, jonka säde on välillä [r0, r1]. (Mikä mahtaa olla tuollaisen siivun virallinen matemaattinen nimi?)

Koski aiheuttaa ympyrän kehän tangentin suuntaisen voiman F. Koskien aiheuttamat voimat esitetään kahtena NxN taulukkona, joista toisessa x-suuntaiset, toisessa y-suuntaiset voimien komponentit. Tee funktio tätä varten

Lisäksi olisi kiva kallistaa koskea sisäkarteeseen päin, eli lisätä pieni voima, joka osoittaa kohti ympyrän keskipistettä.

(Differentiaaliyhtälöiden numeerisen ratkaisu onnistuu helpommin, kun kaikki on pehmeän pyöreää. Matemaattisesti ilmaisten, kiva, jos funktiot olisivat jatkuvasti derivoituvia. Siksi olisi kiva, jos koski olisi joka suuntaan 'pyöreä'. Jos kosken niskalta voima kasvaa lineaarisesti, koski kääntyy laskuun pyöreästi. ???

Alla on typerä brute-force -ratkaisu. Koska tämä funktio suoritetaan vain kerran jokaisella koskella, koodin tehottomuus ei haittaa, mutta nolottaa kyllä.

'''


def koski(Fe_u, Fe_v, i0, j0, kulma0, kulma1, r0, r1, suunta, tilt, Fe):
    rsteps = 100
    ksteps = 100
    d_kulma = (kulma1 - kulma0)/ksteps
    dr = (r1-r0)/rsteps
    slope1 = 0.2*ksteps
    slope2 = 0.8*ksteps
    rslope1 = 0.3*rsteps
    rslope2 = 0.7*rsteps

    r = r0
    for mr in range(0, rsteps):
        if mr < rslope1:
            rscale = mr/rslope1
        elif mr > rslope2:
            rscale = (rsteps-mr)/(rsteps-rslope2)
        else:
            rscale = 1.0
        kulma = kulma0
        for k in range(0, ksteps):
            if k < slope1:
                scale = k/slope1
            elif k > slope2:
                scale = (ksteps-k)/(ksteps-slope2)
            else:
                scale = 1.0
            i = int(math.sin(kulma)*r)
            j = int(math.cos(kulma)*r)
            F = scale*rscale*Fe
            if suunta == 'pos':
                Fe_u[i0+i, j0+j], Fe_v[i0+i, j0+j] = \
                    rotate(F, kulma + np.pi/2.0 + tilt)
            else:
                Fe_u[i0+i, j0+j], Fe_v[i0+i, j0+j] = \
                    rotate(F, kulma - np.pi/2.0 - tilt)
            kulma += d_kulma
        r += dr




'''

Käännetään voimavektori 'kosken' kaarteen suuntaiseksi. Kokeilin satunnaisuuden lisäämistä 'koskiin', mutta tuntui turhalta, joten laitoin kommentiksi

'''


def rotate(R, alfa):
    Cu = 1.0  #  random.uniform(0.95, 1.05)
    Cv = 1.0  #  random.uniform(0.95, 1.05)
    return Cu*R*np.cos(alfa), Cv*R*np.sin(alfa)




'''

Alla koodissa on 'r1 = 38.0' -tyyppisiä lausekkeita. Yritys-ja-erehdys vaiheessa voi tilapäisesti käyttää tuollaisia häkkeröintejä, mutta jos niitä jää koodiin, koodia on tosi työläs muunnella. Ja muunneltavuus on välttämätöntä.

Ohjelmassani järven koko on NxN ruutua. Mitä suurempi N, sitä tarkempi ratkaisu ja sitä jyrkempiä virtausten mutkia se kykenee ratkaisemaan. Mutta, mitä suurempi N, sitä kauemmin laskenta kestää.

Tätä kirjoittaessani ohjelmani tuottaa taustalla videota varten kuvia noin kuvan sekunnissa. Olisi kiva pienentää N:ää ja kokeilla riittääkö tarkkuus. Vaan mitä kirjoittaa lausekkeen 'r1 = 38.0' tilalle? Miten edes löytäisin kaikki korjaamista tarvitsevat lausekkeet?

'Quick-and-dirty' on dirty, mutta ei quick

Ennen kuin kehitän ohjelmaani pidemmälle, nykyiset tilapäiset häkkäykset pitäisi korjata. Tuota miettiessä projekti alkaa tuntua riittävän valmiilta jo nyt.

'''


def kosket(**kwargs):

    Fe_u = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Fe_v = np.full((ly.DIM_i, ly.DIM_j), 0.0)

    #  ellipsit
    i_off = 10
    j_off = 10
    r0 = 20.0
    r1 = 38.0
    tilt = 0.2
    koski(Fe_u, Fe_v, ly.E_I - i_off, ly.E_J - j_off,
          3.0/4.0*math.pi, 7.0/4.0*math.pi,
          r0, r1, 'pos', tilt, par.Fe)
    koski(Fe_u, Fe_v, ly.E_I - i_off, ly.DIM_j - ly.E_J + j_off,
          -3.0/4.0*math.pi, 1.0/4.0*math.pi,
          r0, r1, 'pos', tilt, par.Fe)
    koski(Fe_u, Fe_v, ly.DIM_i - ly.E_I + i_off, ly.DIM_j - ly.E_J + j_off,
          -1.0/4.0*math.pi, 3.0/4.0*math.pi,
          r0, r1, 'pos', tilt, par.Fe)
    koski(Fe_u, Fe_v, ly.DIM_i - ly.E_I + i_off, ly.E_J - j_off,
          1.0/4.0*math.pi, 5.0/4.0*math.pi,
          r0, r1, 'pos', tilt, par.Fe)

    #  keskiympyrä
    # 
    #  parametrillä 'vastapyorre' voi valita, 'laskeeko' keskellä
    #  kiertävä koski myötä- vai vastapäivään
    r0 = 25.0
    r1 = 35.0
    if kwargs['vastapyorre']:
        Fey = -par.Fey
        tilt = -0.1
    else:
        Fey = par.Fey
        tilt = 0.1
    koski(Fe_u, Fe_v, ly.DI_2, ly.DJ_2,
          -1.0/8.0*math.pi, 1.0/8.0*math.pi,
          r0, r1, 'pos', tilt, Fey)
    koski(Fe_u, Fe_v, ly.DI_2, ly.DJ_2,
          7.0/8.0*math.pi, 9.0/8.0*math.pi,
          r0, r1, 'pos', tilt, Fey)
    koski(Fe_u, Fe_v, ly.DI_2, ly.DJ_2,
          3.0/8.0*math.pi, 5.0/8.0*math.pi,
          r0, r1, 'pos', tilt, Fey)
    koski(Fe_u, Fe_v, ly.DI_2, ly.DJ_2,
          11.0/8.0*math.pi, 13.0/8.0*math.pi,
          r0, r1, 'pos', tilt, Fey)
    return Fe_u, Fe_v


def test_kosket():
    a, b = kosket(vastapyorre=True)
    n_kartta = test_kartta()
    test_plt(a, n_kartta, 'kosket_u')
    test_plt(b, n_kartta, 'kosket_v')
    test_plt2(a, b, n_kartta, 'kosket')



'''

../xml/Programming/Simulaatioita/Elava_maalaus/kosket.png
Koskien voimakenttä 
../xml/Programming/Simulaatioita/Elava_maalaus/kosket_u.png
Koskien x-suuntaiset voimat 
../xml/Programming/Simulaatioita/Elava_maalaus/kosket_v.png
Koskien y-suuntaiset voimat 


Koskien voimien ohjelmointia vastaava, mutta helpompi tehtävä: Pyöristä järven kulmat, merkitsemällä R-säteisen ympyrän ulkopuolelle jäävä alue maaksi (= 'saari').

Käydään läpi järven nurkkaan piirretyn R-sivuisen neliön sisään jäävät pisteet ja merkitään maaksi ne, joiden etäisyys järvelle jäävästä neliön sivusta on > R. (Kyllä, jokaisesta geometrisesta ongelmasta kannattaa piirtää kuva)

Olisi tyylikästä ohjelmoida myös 'koski'-funktio tällä periaatteella, mutta en jaksa korjailla.

'''


def kulmatf(kartta, R):
    i0 = R
    j0 = R
    for i in range(0, i0+1):
        for j in range(0, j0+1):
            if (i0-i)**2 + (j0-j)**2 > R**2:
                kartta[i, j] = 'saari'
    i0 = R
    j0 = ly.DIM_j - R
    for i in range(0, i0+1):
        for j in range(j0-1, ly.DIM_j):
            if (i0-i)**2 + (j0-j)**2 > R**2:
                kartta[i, j] = 'saari'
    i0 = ly.DIM_i - R
    j0 = ly.DIM_j - R
    for i in range(i0-1, ly.DIM_i):
        for j in range(j0-1, ly.DIM_j):
            if (i0-i)**2 + (j0-j)**2 > R**2:
                kartta[i, j] = 'saari'
    i0 = ly.DIM_i - R
    j0 = R
    for i in range(i0-1, ly.DIM_i):
        for j in range(0, j0+1):
            if (i0-i)**2 + (j0-j)**2 > R**2:
                kartta[i, j] = 'saari'



'''

Kartta on taulukko, joka kertoo, onko ruutu maata, vettä vai rantaa.

ly.saaret on työkaluni tuottama lista saarien määrittelyistä: nimi, keskipiste, muoto ja asento

ly.saarella on työkaluni tuottama funktio, joka kertoo, onko ruutu saarta kuvaavan ellipsin sisällä.

'''


def init_kartta():
    kartta = np.full((ly.DIM_i, ly.DIM_j), 'jarvi', dtype='U5')
    for saari in ly.saaret:
        (name, (i0, j0), w, h, kulma) = saari
        #  skannataan varmuuden vuoksi koko järvi, vaikka riittäisi
        #  skannata suorakaide, jonka sisällä ellipsi on
        for i in range(1, ly.DIM_i-1):
            for j in range(1, ly.DIM_j-1):
                if ly.saarella(i, j, i0, j0, w, h, kulma) <= 0:
                    kartta[i, j] = 'saari'
    #  leikataan 'piikit'
    #  Pienen ympyrän kylkeen saattaa jäädä yksittäinen ruutu
    #  markkeeraamaan pyöreyttä.
    #  (Yo. kommentti on vain tulevaisuuden minulle tiedoksi :-)
    for i in range(1, ly.DIM_i-1):
        for j in range(1, ly.DIM_j-1):
            if kartta[i, j] == 'saari':
                if kartta[i-1, j] == 'jarvi' and kartta[i+1, j] == 'jarvi':
                    kartta[i, j] = 'jarvi'
                elif kartta[i, j-1] == 'jarvi' and kartta[i, j+1] == 'jarvi':
                    kartta[i, j] = 'jarvi'
    #  järven rannat merkataan maaksi, jotta saadaan
    #  reuna-ehdot toimimaan
    kartta[0:ly.DIM_i, 0] = 'saari'
    kartta[0:ly.DIM_i, 1] = 'saari'
    kartta[0:ly.DIM_i, ly.DIM_j-1] = 'saari'
    kartta[0:ly.DIM_i, ly.DIM_j-2] = 'saari'
    kartta[0, 0:ly.DIM_j] = 'saari'
    kartta[1, 0:ly.DIM_j] = 'saari'
    kartta[ly.DIM_i-1, 0:ly.DIM_j] = 'saari'
    kartta[ly.DIM_i-2, 0:ly.DIM_j] = 'saari'
    #  Ei tehdä suorakulmaista järveä.
    #  Pyöristetään nurkat.
    kulmatf(kartta, 35)
    #  Merkitään karttaan rannat
    reunapisteet(kartta)
    return kartta




''' Koska järven rannoilla pitää laskennassa ottaa huomioon reunaehdot, merkitään rannat karttaan. Jos ruutu on saarella, mutta jokin sen viereisistä ruuduista järvellä, merkitään ruutu rannaksi. '''


def reunapisteet(kartta):
    for i in range(1, ly.DIM_i-1):
        for j in range(1, ly.DIM_j-1):
            if kartta[i, j] == 'saari':
                rannallako(kartta, i, j)


def rannallako(kartta, i, j):
    if kartta[i, j+1] == 'jarvi':
        kartta[i, j] = 'ranta'
    elif kartta[i, j-1] == 'jarvi':
        kartta[i, j] = 'ranta'
    elif kartta[i-1, j] == 'jarvi':
        kartta[i, j] = 'ranta'
    elif kartta[i+1, j] == 'jarvi':
        kartta[i, j] = 'ranta'




'''

Tätä ei ole helppo selittää.

Virtausten ja pinnankorkeuden muutokset riippuvat viereisten kuutioiden tilasta. Entä jos viereiden kuutio onkin maalla?

Hakukoneilemalla 'fluid mechanics boundary layer' löysin toinen toistaan matemaattisempia selityksiä, miten ottaa rannat huomioon. En jaksanut perehtyä, mutta pari huomiota jäi mieleeni.

Rannan tuntumaan voi ajatella vyöhykkeen, jossa vesi ei virtaa rannan suuntaisesti eikä järvelle tai sieltä rantaan päin. Oikeassa järvessä aallot loiskuvat rantaan, mutta keskimäärin vesi ei nouse eikä laske, eli ei ole nettovirtausta.

Sattui niin kivasti, että tämän ohjelmani aluksi nollaan taulukot, joissa ylläpidetään tietoa virtauksista, eikä taulukoita sen jälkeen päivitetä siltä osin kuin ruudut ovat maalla.

Paine — tässä tapauksessa pinnan korkeus — on kiperämpi juttu. Kirjaviisauksien mukaan paine-eron kapean rantavyöhykkeen yli pitäisi olla nolla. Loogista. Yhtälöt eivät erota maata vedestä, mutta ymmärtävät, että kun paine rajan kahden puolen on sama, ei siitä mennä yli. Eli siis paine nollaksi, eli pinnankorkeudet samoiksi. Samoiksi missä? Välille 'ranta' — 'saari'

../xml/Programming/Simulaatioita/Elava_maalaus/boundary_layer.jpg
Rantavyöhyke. Lila on vettä, oranssi saaren rantaa, jonne kopion pinnankorkeuden arvot.  

Homma hoituu vaikkapa kopioimalla pinnankorkeuden arvot rantavyöhykkeeltä ruudun verran 'sisämaahan'. Paitsi kuvan ongelmaa: Samaan rutuun pitäisi saada kaksi eri pinnankorkeuden arvoa.

Minulla on ollut monta loistavaa ideaa, miten ratkaista yo. ongelma ja samalla sekunnilla, kun olen idean saanut, olen alkanut sitä myös ohjelmoida.

Mikään kuningasajatuksistani ei ole tuottanut kunnollista lopputulosta ja tuloksen nähtyäni minun oli helppo ymmärtää, miksei idea ollutkaan kovin hyvä. Hetken harkinta olisi pelastanut paljolta turhalta työltä.

Yksi ideoistani oli kirjoittaa alusta saakka erikseen yhtälöt rantavyöhykkeelle. Sekin tuotti 'seisovia aaltoja' laajalle alueelle. Ehkä rosoreunainen ranta tuottaa oikeasti tuollaisen ilmiön. Onneksi näin taidetta tehdessä tuo ei haittaa.

../xml/Programming/Simulaatioita/Elava_maalaus/aaltoilu.jpg
Kuvan aallot eivät johtune fysiikan laeista vaan siitä, etten viitsinyt miettiä loppuun saakka, millainen reuna-ehto rannoille pitäisi koodata.  

Seuraavat kolme funktiota kopioivat kuvan lilalta vyöhykkeeltä pinnankorkeuden arvoja oranssille vyöhykkeelle.

'''


def rantavedet(kartta):
    rannat = []
    for i in range(1, ly.DIM_i-1):
        for j in range(1, ly.DIM_j-1):
            if kartta[i, j] == 'ranta':
                viereiset = []
                #  for (m, n) in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:
                for m in range(i-1, i+2):
                    for n in range(j-1, j+2):
                        if kartta[m, n] == 'jarvi':
                            viereiset.append((m, n))
                if len(viereiset) > 0:
                    rannat.append(((i, j), viereiset))
    return rannat


def tasaa_paineita(rho, rannat):
    for (p0, viereiset) in rannat:
        rho[p0] = keskiarvo(p0, rho, viereiset)


def keskiarvo(p0, rho, viereiset):
    N = float(len(viereiset))
    if N > 0:
        x = 0
        for viereinen in viereiset:
            x += rho[viereinen]
        return x/N
    else:
        return rho[p0]


def test_kartta():
    tmp = np.full((ly.DIM_i, ly.DIM_j), -1.0)
    kartta = init_kartta()
    rannat = rantavedet(kartta)
    for i in range(0, ly.DIM_i):
        for j in range(0, ly.DIM_j):
            if kartta[i, j] == 'jarvi':
                tmp[i, j] = -2.0
            elif kartta[i, j] == 'ranta':
                tmp[i, j] = 1.0
            elif kartta[i, j] == 'saari':
                tmp[i, j] = 2.0
    for (po, viereiset) in rannat:
        for p1 in viereiset:
            tmp[p1] = -1.0
    test_plt1(tmp, 'rannat')
    return tmp




'''

Luodaan taulukko väriaineille

Jos parametri maasto=True, maat ja vedet peitetään alussa satunnaisesti levitetyillä väriaineilla.

Toinen vaihtoehto on roiskia simuloinnin alussa maisemaan pieniä yksittäisiä väriläiskiä alempana olevalla funktiolla.

'''


def init_paint(kartta, **kwargs):
    paint = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    if kwargs['maasto']:
        tau = 0.97
        pnt0 = par.pnt_0
        paint[0, 0] = 0.0  #  random.uniform(-pnt0, pnt0)
        for i in range(1, ly.DIM_i):
            paint[i, 0] = tau*paint[i-1, 0] + \
                (1.0-tau)*random.uniform(-pnt0, pnt0)
        for j in range(1, ly.DIM_j):
            paint[0, j] = tau*paint[0, j-1] + \
                (1.0-tau)*random.uniform(-pnt0, pnt0)
        for i in range(1, ly.DIM_i):
            for j in range(1, ly.DIM_j):
                x = tau*paint[i-1, j] + (1.0-tau)*random.uniform(-pnt0, pnt0)
                y = tau*paint[i, j-1] + (1.0-tau)*random.uniform(-pnt0, pnt0)
                #  paint[i, j] = min(par.pnt_cut, max(-par.pnt_cut, (x+y)/2.0))
                paint[i, j] = (x+y)/2.0
    print('paint min max: ', np.min(paint), np.max(paint))
    return paint  #  np.where(abs(paint) < 0.02*par.pnt_0, 0, paint)




'''

Roiskaistaan maisemaan muutama väritäplä. Väritäplän muotoilun pitäisi onnistua parilla sisäkkäisellä for-silmukalla, mutta sitä oli yllättävän vaikea suunnitella, joten hätäpäissäni turvauduin copy-pasteamiseen.

Tämän ohjelman alussa esitellyn maalari-olion toivomuksesta tehdään jokaista punaista roisketta vastaava sininen. Näin värien keskiarvo pysyy nollana, mikä helpottaa maalarin työtä.

Maalari-olio maalaa positiiviset arvot punaisen sävyillä ja negatiiviset sinisen sävyillä, joten ohjelmassa riittää tarkastella vain yhden väriaineen liikkeitä. Sekoittuessaan väriaineet neutraloivat toisensa, koska maalari maalaa nollaruudut valkoisella.

'''


def roiskeita(paint):
    for k in range(0, 20):
        clr = random.uniform(0, par.pnt_0)

        ip = random.randrange(2, ly.DIM_i-3)
        jp = random.randrange(2, ly.DIM_j-3)
        paint[ip, jp] = clr
        paint[ip-1, jp] = 2.0/3.0*clr
        paint[ip+1, jp] = 2.0/3.0*clr
        paint[ip-2, jp] = 1.0/3.0*clr
        paint[ip+2, jp] = 1.0/3.0*clr
        paint[ip, jp-1] = 2.0/3.0*clr
        paint[ip, jp+1] = 2.0/3.0*clr
        paint[ip, jp-2] = 1.0/3.0*clr
        paint[ip, jp+2] = 1.0/3.0*clr
        paint[ip-1, jp-1] = 0.5*clr
        paint[ip-1, jp+1] = 0.5*clr
        paint[ip+1, jp-1] = 0.5*clr
        paint[ip+1, jp+1] = 0.5*clr

        clr = -clr
        ip = random.randrange(2, ly.DIM_i-3)
        jp = random.randrange(2, ly.DIM_j-3)
        paint[ip, jp] = clr
        paint[ip-1, jp] = 2.0/3.0*clr
        paint[ip+1, jp] = 2.0/3.0*clr
        paint[ip-2, jp] = 1.0/3.0*clr
        paint[ip+2, jp] = 1.0/3.0*clr
        paint[ip, jp-1] = 2.0/3.0*clr
        paint[ip, jp+1] = 2.0/3.0*clr
        paint[ip, jp-2] = 1.0/3.0*clr
        paint[ip, jp+2] = 1.0/3.0*clr
        paint[ip-1, jp-1] = 0.5*clr
        paint[ip-1, jp+1] = 0.5*clr
        paint[ip+1, jp-1] = 0.5*clr
        paint[ip+1, jp+1] = 0.5*clr
    return(paint)


 #  Ihan vaan muistutus siitä, mitä kaikkea numpy:llä voi tehdä
 #  kätevän tehokkaasti

 #  def nollaa_vari_huiput(a):
 #      return np.where(abs(a) < 0.99*par.pnt_0, a, 0)

def test_plots():
    x = np.full(ly.DIM_j, 0.0)
    y = np.full(ly.DIM_i, 0.0)
    for j in range(0, ly.DIM_j):
        x[j] = par.ds*j
    for i in range(0, ly.DIM_i):
        y[i] = par.ds*i

    test_kartta()
    #  test_reunat()
    test_kosket()
    #  test_valuma(x, y)


 # #############################################################
 #  Pääohjelman alku
 # #############################################################
def main():
    print(tim.datetime.now())
    random.seed()
    #  Turha jatkaa simulointia numpy-rutiinien ylivuodon jälkeen
    #  Asetetaan ylivuoto virhetilanteeksi
    np.seterr(over='raise')
    plt.matplotlib.use('qt5agg')
    plt.ion()

    #  Luodaan maalarin työpaja
    Maalari = Cl_Maalari()
    #  Tein toisenkin maalailemaan zoomauksia, mutta kaksi maalaria
    #  vilkuttelivat kilvan tuotoksiaan niin ikävästi, että
    #  jouduin kommentoimaan toisen sivuun.
    #  zoom = Cl_Maalari()

    rho = np.full((ly.DIM_i, ly.DIM_j), par.rho_0)
    Dt0_rho = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt1_rho = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    rho_nxt = np.full((ly.DIM_i, ly.DIM_j), par.rho_0)
    u = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt0_u = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt1_u = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    u_nxt = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    v = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt0_v = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt1_v = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    v_nxt = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt0_paint = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    Dt1_paint = np.full((ly.DIM_i, ly.DIM_j), 0.0)
    paint_nxt = np.full((ly.DIM_i, ly.DIM_j), 0.0)

    kartta = init_kartta()
    rannat = rantavedet(kartta)
    paint = init_paint(kartta, maasto=True)  #  !!!
    Fe_u, Fe_v = kosket(vastapyorre=True)
    n = 0
    t = 0.0
    dt = par.dt
    overflow = False

    #  +++++++++++++++ simulointi ++++++++++++++++++++++++++


'''

Muuntaessani x- ja y- suunnan osittaisdifferentiaaliyhtälöitä differenssiyhtälöiksi, olisin voinut muuntaa myös aikaderivaatat differenssiyhtälöiksi ja sen jälkeen ratkaista nopeuksien, pinnankorkeuden ja väriaineiden konsentraatiot kussakin ruudussa hetkellä t + dt niiden arvojen hetkellä t perusteella. Menettelyä kutsutaan eulerin algoritmiksi.

Sitä aluksia kokeilinkin. Tiesin, että Eulerin algoritmi ei ole kovin tarkka, mutta ajattelin, ettei se haittaa näin taiteen teossa. Eri juttu, jos suunnittelisin lentokoneita. (Tosin Boeing 737 MAX onnettomuuksien syistä päätellen, eivät lentokoneiden suunnittelijatkaan ole turhan tarkkoja).

Pieni virhe ei olisi minua haitannut, mutta virhettä kertyi niin, että tietokoneestani 'loppuivat numerot' — Järven pintaan pullahti niin korkea kupru, ettei tietokoneestani löytynyt riittävän suurta numeroa siitä kertomaan. Tapahtui 'floating point overflow', kuten tietokonekielellä on tapana sanoa.

Onneksi wikipedia tiesi kertoa Heunin menetelmästä

'''

    while t < 1000 and not overflow:
        #  simuloinnin alkuaskelilla roiskitaan väritäpliä maisemaan
        #  if n < 100:
        #      paint = roiskeita(paint)
        #  try — except rakentaan avulla pysäytän simuloinnin, jos
        #  tulee 'floating point overflow'
        try:
            #  Lasketaan kussakin ruudussa aikaderivaatat nopeudella
            #  ja pinnankorkeudelle: Heun vaihe 1
            df.dfdt(kartta, rho, u, v, paint, Fe_u, Fe_v,
                    Dt0_rho, Dt0_u, Dt0_v, Dt0_paint)
            rho_nxt = rho + Dt0_rho*dt
            paint_nxt = paint + Dt0_paint*dt
            u_nxt = u + Dt0_u*dt
            v_nxt = v + Dt0_v*dt
            #  Heunin menetelmän vaihe 2.
            df.dfdt(kartta, rho_nxt, u_nxt, v_nxt, paint_nxt, Fe_u, Fe_v,
                    Dt1_rho, Dt1_u, Dt1_v, Dt1_paint)
            rho_nxt = rho + (Dt0_rho + Dt1_rho)/2.0*dt
            paint_nxt = paint + (Dt0_paint + Dt1_paint)/2.0*dt
            u_nxt = u + (Dt0_u + Dt1_u)/2.0*dt
            v_nxt = v + (Dt0_v + Dt1_v)/2.0*dt
        except FloatingPointError as err:
            print('Overflow ', err)
            print('n, t ', n, t)
            overflow = True
        #  Tämä näyttänee hämärältä?
        #  Vaihdetaan 'vanhoihin' ja 'uusiin' taulukoihin osoittavat
        #  pointterit.
        #  Useimmat muuttujat tässä simuloinnissa ovat isoja numpy —
        #  'numeric python' — taulukoita, joita pitää käsitellä harkiten
        rho, rho_nxt = rho_nxt, rho
        paint, paint_nxt = paint_nxt, paint
        u, u_nxt = u_nxt, u
        v, v_nxt = v_nxt, v
        Maalari.sys_plot(rho, u, v, paint, n)
        tasaa_paineita(rho, rannat)
        #  i0 = 145
        #  i1 = 185
        #  j0 = 90
        #  j1 = 135
        #  zoom.sys_plot(rho[i0:i1, j0:j1], u[i0:i1, j0:j1], v[i0:i1, j0:j1],
        #                paint[i0:i1, j0:j1], n)
        t += dt
        n += 1
    plt.close('all')

    print(tim.datetime.now())


if __name__ == "__main__":
    main()


Kuvat videoksi

Simulaatio-ohjelma tuotti kymmenentuhatta kuvaa. Jos ottaisi joka sadannen ja näyttäisi ne slide-showna? Ei käy: Ilmiön dynamiikasta hukkuisi olennainen. Video? Vaikkapa 48 kuvaa sekunnissa. Syntyy noin parin minuutin video. Vilistääkö olennainen liian nopeasti? Pitää kokeilla.

Miten kuvista saa videon? Kirjoitetaan webin hakukoneelle 'photos pictures to video' tai jotain tuon suuntaista. Hakukone vastaa 'ffmpeg'. Kas, minulla on koneella valmiina ffmpeg. Linuxin vakiovaruste? Vaan miten sitä käytetään?

Sitähän voidaan käyttää vaikka mihin. Ohjeita on kymmeniä sivuja. Parametrejä niin ikään kymmeniä ja jokaisen merkitystä selitetty ainakin sivun verran. Mitäs nyt tehdään?

Haetaan hakukoneella 'ffmpeg example demo tutorial' tai jotain tuon suuntaista, copy-pastetaan yksinkertaisimman näköinen löytö komentotiedostoksi ja täydennellään pikkuisen:

#!/usr/bin/env bash

cd $HOME

if [[ $1 = '' ]]
then
        echo "Laita argumentiksi hakemisto, jossa kuvat!"
else
    nice -17 ffmpeg -r 48 -i $1'/taulu_%05d.png' $1.webm
fi




2015-06-11

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Siltanosturi — virtuaalinen mekaaninen lelu

 

Siltanosturi — virtuaalinen mekaaninen lelu

Siltanosturi ei ehkä ole pelinä erityisen jännittävä, mutta sopinee esimerkiksi tutkivasta oppimisesta.

Kesäkuu 2015

Innostus tähän verryttelyyn heräsi lukion fysiikan tuntia seuratessa. Ajattelin tehdä vaikutuksen ja näyttää, miten parilla pienellä ohjelmanpätkällä voisi havainnollistaa dynaamisten järjestelmien toimintaa. Seuraavalla hyppytunnilla opettajanhuoneessa kävi ilmi, etten osaa kirjoittaa yksinkertaisen nosturin tilayhtälöitä. Tein mielestäni kaiken oikein, mutta kirjoittamilleni yhtälöille ei löytynyt ratkaisua. Ongelma kääntyi pakkomielteeksi, joka vaivasi pari kuukautta, eli siihen asti, että lopulta sain ongelman ratkaistua. Tulipa tutkittua ja opittua.

demovideo

video varalle, jos yo. ei toimi

Siltanosturin simulointi ja liikeradan optimointi


2018-10-02

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Outomerellä hyppelehtivä väkkärä

 

Outomerellä hyppelehtivä väkkärä

Pieni matemaattinen sormiharjoitus. Symbolista ja numeerista laskentaa tietokoneella.

2 lokakuuta 2018

Väkkärän loikka

video varalle, jos yo. ei toimi

Väkkärän liikeyhtälöidem yms.johtaminen

Esimerkkejä differentiaaliyhtälöiden numeerisesta ratkaisemisesta pythonilla.


2018-2-19

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Peikkometsän hiilitase

 

Peikkometsän hiilitase

Me - peikkokoulun Python-kerho - teimme pelin, joka auttaa ymmärtämään kraatterimme metsien hakkuun vaikutusta kraatterimme ilmastoon.

Helmikuu 2018

Peikkojen metsä kasvaa lasikupolilla katetussa tulivuoren kraaterissa. Kraaterin ilmastoon vaikuttava hiili on varastoituneena metsän puihin, kraaterin ilmaan ja polttopuihin peikkojen puuliitereissä. Koska kraaterissa on oma pienoisilmastonsa, meidän täytyy pitää tarkasti huolta ilman hiilidioksidipitoisuudesta, että kraatteri pysyy sopivan lämpimänä.

(Jonkun mielestä kraatterin ilman lämpötilaa voisi säädellä tuulettamalla ja kaihtimilla, mutta eihän satu ole enää satu, jos kaikki tosiasiat otetaan huomioon. Ehkä ulkopuolinen ilma on saastunutta tai peikot pelkäävät noitien lennoillaan levittämää taikapölyä. Ehkä peikot ja kraatterin kasvit tarvitsevat kaiken saatavilla olevan auringonvalon.)

Satumetsän puut kasvavat sangen oikukkaasti, joten meidän satumetsän peikkojen on hoidettava metsää erityisellä huolella. Tätä varten päätimme tehdä simulaattorin, jolla harjoitella metsän hoitoa. Tai no, oikeastaan halusimme kokeilla, millaista ohjelmointi on. Olimme kulleet väitettävän ohjelmointia hauskaksi.

Puiden kasvusta on tehty tutkimuksia, mutta meillä oli niin kiire päästä ohjelmoinnin alkuun, ettemme varsinaisesti ehtineet tutustua niihin. Arvelimme, ettei metsän kasvua ole kovin monimutkaista mallintaa: Puu muuttaa ravinteet auringon valon avulla selluloosaksi yms. Mitä suurempi lehvästö ja juuristo, sitä vauhdikkaammin puu kasvaa. Jos puut kasvavat liian lähekkäin, ne varjostavat toisiaan ja kilpailevat vedestä ja ravinteista. Haitta on tietysti verrannollinen siihe, kuinka pahasti lomittain puut kasvavat. Satumetsän puut eivät kasva rajattomasti. Tietyn rajan jälkeen niiden kasvu hidastuu ja lopulta pysähtyy. Puuvanhukset kasvavat hitaammin kuin nuoret puut. Lopulta puu kuolee vanhuuteen ja alkaa lahota.

Oli yllättävän iso työ kirjoittaa työ python-kielelle. Se on ihan erilaista kuin meidän peikkojen kieli ja kaikki pitää kertoa yksityiskohtaisesti ja täsmällisesti. Python-kielessä ei esimerkiksi ole "vauhdikkaammin" -sanaa. Toisaalta oli sangen opettavasti miettiä perusteellisesti, mitä puhekieli tarkkaan ottaen tarkoittaa. Kävi ilmi, että meistä jokainen oli ymmärtänyt eri tavalla, mitä puhekielinen kuvaus metsän kasvusta tarkoittaa.

Simulointien tuloksista voi oppia monen laista. Opimme, että satumetsän puiden kasvu ei noudata kuvittelemiamme lainalaisuuksia. Karvas oppi, mutta onneksi simulaattorista tuli hauska peli, jonka suunnittelu opetti meidät miettimään, mikä on olennaista metsän kasvun ja kraatterin hiilidioksitaseen kannalta. Monet puhuvat ihan puuta-heinää, koska eivät ymmärrä ongelman ydintä.

 

Miten piirtää metsä tietokone-ohjelmalla

Tarkoituksemme oli, että simulaattori piirtää kuvaruudulle kasvamaan oikean näköisen metsän, jota voisi käännellä ja katsella miltä puolen haluaa. Voisi nähdä, miten ison puun varjo siirtyy auringon nousemisen myötä pois pienen puun yltä. Puiden lomassa lennähtelevät ja niiden oksilla sirkuttavat linnut olisivat olleet mukava yksityiskohta.

Loppujen lopuksi puista tuli pyörylöillä kuvattuja palloja ja metsää voi katsoa joko tasan ylhäältä tai tasan alhaalta. Aurinko paistaa suoraan ylhäältä. Puiden varjon korvasimme puuta ympäröivällä kehällä, mutta se teki näytöstä niin psykedeelisen, että tarjoamme vaihtoehtona sekä puun, että sen varjon kattavaa kiekkoa. Puun varjo ei liiku auringon mukana, koska aurinkokaan ei liiku. Varjo on eräänlainen keskimääräinen varjo. Kiekon väri kertoo, kuinka pahasti puu on muiden katveessa. Puun kuollessa se muuttuu ruskeaksi ja lahoaa hitaasti olemattomiin.

Ohjelmoimme erilaisia hakkuustrategioita polttopuun korjuuseen: Avohakkuu, vanhojen puiden hakkaaminen, varjoon jäävien karsiminen yms. Yhtä vähän kuin simulaattorin puut kasvoivat niin kuin kuvittelimme, hakkuut vaikuttivat niin kuin kuvittelimme. Toistuva avohakkuu tosin näyttää huonolta strategialta aivan kuten peikkojen perimätietokin kertoo.

Yksinkertaistamisen vastapainoksi päätimme laskea tarkkaan , paljonko pyörylät varjostavat toisiaan. Oikeasti puut eivät ole pyörylöitä, mutta näin tulee laskettua tarkkaan edes se, mitä tapahtuisi, jos ne olisivat. "Pii kertaa peukalo" mutisi opettaja nähtyään laskelmamme. "Miksi laskea jotain tarkkaan, jos muu on pelkkää arvailua" Vastasimme laskevamme kaiken parhaalla mahdollisella tarkkuudella. Muuten joutuu kaltevalle pinnalle ja päätyy piirtämään simulointitulokset vapaalla kädellä.

Puut ovat mallissamme palloja, joista auringonvalon suuntaa näkyy kiekko. Pieni puu on isoa matalampi, joten oikeastaan vain se on varjossa, mutta oikeassa metsässä pienikin puu liian lähellä häiritsee isomman kasvua. Imee vettä ja ravinteita, haittaa oksiston kasvua, varjostaa alaoksia, ... Päädyimme arvioon, että valo lankeaa toisiaan varjostaville puiden osille puiden säteiden suhteessa. Varjostus pinta-alojen suhteessa olisi looginen sekin.

Puuta voi varjostaa kahdeksan viereistä puuta. Aluksi laskimme kunkin puun aiheuttaman katveen yhteen, mutta silloin puun saama valo meni pahimmillaan miinukselle ei hyvä. Entä jos yhden puun aiheuttaman varjon alueella valo vähenee vain 1/8? Varjostus vaikutti "normaalitapauksissa" kovin vähän. Annoimme varjojen vaikuttaa reilusti, mutta leikkaamme vaikutukset niin, että valo ei mene miinukselle. Pikkupeikko koodasi tämän kohdan. En ole varma, onko koodi oikein. Selvää on, että oikeassa peikkometsässä homma ei mene ihan näin.

Tässä vaiheessa pitkällä kiipesimme kraatterin reunaa ylös tähyilemään metsää ylhäältä päin: metsä näytti vähän kuin tiuhassa kasvavilta palloilta. Siltä osin mallimme ei liene aivan pielessä, mutta kävelyllä satumetsän siimeksessä aloimme aavistella, että simulaattorimme puut eivät välttämättä kasva kuin satumetsän puut. Pitäisi olla ainakin sadan vuoden ajalta kuvia eri-ikäisten ja erilaisissa oloissa elävien puiden kasvusta ja lahoamisesta, että osaisi edes arvioida, onko mallissa mitään tolkkua. Päätimme vakaasti, että luemme tutkimuksia puiden kasvusta. Kunhan ensin kokeilemme ohjelmointia.

 

Hakkuustrategiat

Mielellään olisimme tehneet ohjelman, joka laskee optimaalisen tavan karsia satumetsää, mutta jo simulointimallin tekeminen otti hermoon sen verran, että jätimme optimoinnin myöhemmäksi ja ohjelmoimamme kokeiltavaksi muutaman erilaisen hakkuustrategian.

Avohakkuu
Kaadetaan kaikki puut kerralla. Arvauksemme on, että hakkuun jälkeen metsä kasvaa tosi hitaasti kiihtyen puiden lehvästön kasvaessa ja pyydystäessä entistä enemmän aurinkoa. Kasvu hidastuu metsän tullessa "täyteen" ja puiden täysikasvuiseksi. Metsän hiilivaraston osalta ollaan silloin samassa tilanteessa kuin ennen avohakkuuta. Jos hakattua puuta poltetaan säästeliäästi, avohakkuu ei ole ilmaston kannalta katastrofi, vaikkakin todennäköisesti huonoin ratkaisu.
Karsitaan vanhat puut
Korjataan talteen vanhat huonokuntoiset ja jo kuolleet puut.
Karsitaan isot puut
Korjataan talteen täysikasvuiset ja lähes täysikasvuiset puut. Nämä varjostavat nuoria hyväkasvuisia puita, mutta aivan vanhimpia lukuunottamatta nämä olisivat vielä pitkään hyviä hiilivarastoja.
Karsitaan puut muiden varjoista
Muiden varjossa kasvavat puut haittaavat niitä varjostavien kasvua ainakin pikkuisen eivätkä itse juurikaan kasva.
Kaadetaan joka toinen puu
Harvennetaan metsää niin, että jäljelläoleville tulee tilaa kasvaa.

Puiden polttaminen

Jos kaikki kaadetut puut varastoitaisiin pysyvästi, ei hirveästi haittaisi, miten satumetsän puita hakattaisiin. Satumetsä kasvaa sen verran hyvin, että hiiltä varastoituisi joka tapauksessa riittävästi. Jos taas polttaisimme heti kaiken hakatun puun, metsään olisi paras olla koskematta lainkaan. Simulaattorissa voi muuttaa vauhtia, jolla poltamme puita ja siten tehdä hakkuutehtävästä helpomman tai vaikeamman.

 

Alku aina hankala

Kopioimme itsellemme yksinkertaisen Python-kielisen pelin, josta arvelimme pienellä muokkauksella saavamme oivallisen metsäsimulaattorin. Installoimme ohjelmointiympäristön, latasimme koodin ja ...

Pelin ohjelmakoodi näytti englannin ja matematiikan sotkulta, eikä siitä ymmärtänyt mitään. Aina kun muutimme pelin koodia, ruutu tuli täyteen käsittämättömiä virheilmoituksia eikä näytölle piirtynyt puun puuta.

Melkoinen yllätys. Me peikot olemme tottuneet siihen, että osaamme mitä vaan ja saamme yhdessä hujauksessa valmiiksi kaiken mihin ryhdymme. Peikkovanhukset naureskelivat, että noin käy, kun ei noudata perinteitä vaan ryhtyy johonkin, mitä esi-isät eivät ole opettaneet. Totta, tämä oli ensimmäinen kerta, kun poikkesimme perinteistä. Siitä vanhukset eivät pitäneet. Kun eivät mitään ymmärtäneet.

Yksi meistä jatkoi sinnikkäästi kokeilemista, minä aloin googlailemalla selvittää, mitä ohjelman koodi tarkoittaa ja yksi meistä alkoi suorittaa ohjelmoinnin peruskurssia verkossa. Kolme kertaa päivässä kokoonnuimme kiistelemään siitä, mitä kannattaisi tehdä.

Kolmantena päivänä onnistuimme muuttamaan alkuperäisen pelin koodia niin, että yksi pelin hahmoista kääntyi ylösalaisin ja taivas värjäytyi keltaiseksi. Ilon päivä. Olimme koukussa ohjelmointiin.

Viikon kuluttua malliksi ottamamme peli oli muuttunut metsäsimulaattoriksi, joka kasvatti ensimmäisen puunsa. Puu kasvoi ja kasvoi, täytti koko ruudun ja lopetti vasta kun ruudulle tuli joku overflow -ilmoitus.

Vasta kuukauden kuluttua simulaattori oli valmis. Kuukauden! Peikkojen keskittymiskyvyllä jo päivä yhtä hommaa on huippusuoritus. Ohjelmointi koukuttaa.

Vilkaisimme opasta, jossa kuvailtiin laadukasta ja tyylikästä koodia. Ehkä joskus myöhemmin teemme simulaattorista tyylikkään version.

Tässä demovideo simulaattorista

video varalle, jos yo. ei toimi

 

Algoritmin yksityiskohtia

Yritimme parhaamme mukaan kommentoida ohjelman koodia , mutta muutaman yksityiskohdan selitämme tässä. Koodi kannattaa kuitenkin lukea. Roiskaisimme sinne paljon kaikenlaisia havaintoja ohjelmoinnista ja sen opiskelusta yleensä sekä simuloinnista erityisesti.

Käytämme puiden kasvun simulointiin Eulerin algoritmia: x(t+dt) = x(t) + dx(t)/dt. Se on yksinkertaisin mahdollinen. Ei kovin tarkka, mutta riittää näin yksinkertaisessa tehtävässä.

Integrointiaskeleen pituus? Kiperä kysymys! "Ehkä puu kasvaa s-käyrän muotoisesti". Ehkä. Piirsimme makaavan S:n ja sitä seurailemaan murtoviivan. 1/4 vuoden välein piirretty murtoviiva seurasi kuvittelemaamme metsän kasvun käyrää melko hyvin. Ehkä 1/4 vuosi olisi sopiva integrointiaskel. Tai sitten ei. Onneksi löysimme vihjeen: ""Kokeile, paljonko tulos muuttuu, jos lyhennät integrointiaskeleen puoleen." Ohjelmoimme algoritmin kokeilemaan joka askelta myös kahdella puoliaskeleella.

Virhe oli iso, vaikka kuinka pienensimme integrointiaskelta. Lisäsimme välitulostuksia, kunnes älysimme, että virhe oli suuri vain, kun puu oli lähes olemattoman pieni. Kun puu on lahonnut lähes olemattomiin, seuraava integrointiaskel vie sen massan miinukselle. Lyhyemmällä askelella algoritmi huomaa nopeammin, milloin puu on lahonnut olemattomiin, pitkällä askeleella se lahoaa enemmän miinukselle. Mitätön juttu, mutta suhteellinen virhe oli iso.

Tuollainen salapoliisityö tekee ohjelmoinnista mielenkiintoista. En tiedä, loppuuko tuollainen salapoliisityö sitten, kun oppii tämän homman.

 

Mitä opimme

Romaanien kirjoittajat väittävät, että lukijat tulkitsevat heidän tarinoitaan yllättävillä tavoilla. Se on kuitenkin pientä siihen verrattuna, miten yllättävästi tietokone tulkitsee ohjelmakoodia. Silloin kuin yleensä suostuu sitä tulkitsemaan.

Emme yllättyneet siitä, että metsä simulaattorissamme ei kasva ihan samalla tavalla kuin kuvittelimme peikkometsän kasvavan. Olemme seuranneet metsän kasvua, leikkineet siellä, vain reilut kymmenen vuotta, joten käsityksemme siitä, miten se kasvaa seuraavat muutaman sata vuotta, on sangen hatara. Kiusallista on, ettemme kaikilta osin ymmärrä, miksi simuloitu metsä kasvaa niin oudosti kuin kasvaa.

Koska mallimme perustuu kuvitelmiimme satumetsän kasvusta, simulaattorikin kertoo kuvitelmistamme. Oli opettavaista nähdä, että kuvitelmamme johti erilaiseen lopputulokseen kuin mitä — kuvittelimme. Jouduimme korjaamaan kuvitelmiemme metsän kasvun lainalaisuuksista. Toki joskus olimme niin varmoja kuvitelmistamme, että korjailiamme simulaattoria toimimaan niiden mukaisesti. Opettaja huomautti, että tiedettä ei tehdä noin, vaikka lopputulos toki käy järkeen.

 

Lisäkoodausta

Nykyisellä ohjelmaversiolla voi tehdä kaikenlaista hauskaa, jos osaa ohjelmoida ja tuntee koodin sen verran, että osaa varoa muutamaa siihen vielä jäänyttä sudenkuoppaa. Olisi kuitenkin hienoa tehdä ohjelmasta oikea peli, jossa olisi kunnon käyttöliittymä. Ensin tietysti pitäisi miettiä pelin idea.


2018-12-5

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Ajatusmallini metsien hakkuiden vaikutuksesta ilmastomuutokseen

 

Ajatusmallini metsien hakkuiden vaikutuksesta ilmastomuutokseen

Olen seurannut webissä käytävää keskustelua metsien hakkuista. Ajoittain on tuntunut, että kaikilla ei ole aivan samaa käsitystä metsien kasvusta ja sen vaikutuksesta maapallon ilmastoon. Päätin koodata ajatusmallini/käyttöteoriani Python-koodiksi, että minä ja muut näkisimme, millainen minun ajatusmallini on ja toimiiko se järkevästi.

5 joulukuuta 2018

Olen myös seurannut keskustelua tietotekniikan hyödyistä ja haitoista opetuksessa. Törmäsin myös ryhmään innokkaita, jotka soveltavat tietotekniikkaa matematiikan ja fysiikan opetuksessa. Niinpä dokumentoin tähän samaan tekstiin tekemäni python-koodin.

Satuinpa myös seuraamaan keskustelua oppiainerajat ylittävästä opetuksesta. Tässäpä tarkastelen ilmiötä, joka pikkuisen ylittää oppiainerajat. Olen lisäksi soveltanut OPSin rajat ylittäviä menetelmiä. En ole dokumentoinut tekemisiäni ja tuloksia oppiainerajojen mukaisessa järjestyksessä vaan sen mukaan, miten asiat tulivat vastaan työtä tehdessä. Eli sen mukaan, missä järjestyksessä oppijatkin ehkä sattuisivat apua pyytämään.

"Ennen vanhaan" koulutehtävät rajattiin valmiiksi niin, että ratkaisuun oli yksi, opettajan antama suora valmis polku, josta ei ollut syytä poiketa. Elävän ilmiöiden tarkastelu rönsyilee väkisinkin, eikä ole niinkään selvää, mitkä polut vievät kelvolliseen ratkaisuun tai mikä yleensä on kelvollinen ratkaisu. Elävään elämään kuuluu myös pähkäily, onko tässä mitään järkeä, koulussa riittää tarkistaa, että vastaus on oikea. Tämäkin juttu rönsyilee muistutukseksi siitä, miten elävän elävän ilmiöiöiden tutkiminen ja yksittäisen asian harjoittelemiseen räätälöidyt tehtävät poikkeavat toisistaan.

Metsien hakkuut ja puu polttoaineena


2020-8-24

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Ilmastomallinnus ja ilmastodenialismi

 

Ilmastomallinnus ja ilmastodenialismi

Muutama sana varsinaisesta ilmastomallinnuksesta ja pari esimerkkiä ilmastodenialistien jutuista selittämään, millä perusteilla leimaan tietynlaiset väitteet huuhaaksi. Tämä juttu jäi vaille viimeistelyä. Lienee raskas lukea, mutta vielä raskaampaa oli yrittää kommentoida selkeästi isoa määrää epäjohdonmukaisia väitteitä.

Elokuu 2020

Tämä juttu on siinä mielessä vanhentunut, että pääosa niistä, jotka vastustavat toimia hillitä ilmastonmuutosta, ovat jo luopuneet yrityksistä horjuttaa ihmisten luottamusta ilmastonmallinnukseen ja sen tuloksiin. Sensijaan he ovat alkaneet väittää, että seuraukset eivät ole niin pahoja kuin väitetään; ilmastoimet tulevat niin kalliiksi, että niiden aiheuttama talouskatastrofi aiheuttaa enemmän vahinkoa kuin ilmastomuutos; Meitä on niin vähän, ettei tekomme vaikuta eivätkä todelliset syylliset kuitenkaan tee mitään; nyt on jo liian myöhäistä; ...

Ilmastomallinnuksen perusteista on asiantuntijoiden kirjoittamia hyviä kirjoja ja IPCC on raportoinut simulointien tuloksista. Paljon hyödyllisempää, kuin perata denialisteiksi tiedettyjen väitteitä, on perehtyä ilmastomallinnukseen ja muodostaa oma käsityksensä.

Tämä ei ole mikään huolella koostettu setti oppimateriaalia:

The Discovery of Global Warming ; NASA, carboncycle . Tieteellisemmmin em. prosesseja on kuvattu esimerkiksi seuraavassa: IPCC, The Carbon Cycle and Atmospheric Carbon Dioxide . Raskas lukea, mutta jo silmäilemällä saa käsityksen, mitä ilmastomallinnus on. Ilmastomallinnuksen periaatteista ja tavoitteista kertoo mm. kirja Demystifying Climate Models . Muilla on varmaankin muita suosituksia.

Pääsääntöisesti en kommentoi denialistien väitteitä. Vaikka heidän väitteensä kyseenalaistaisi miten hyvänsä vakuuttavin perustein, he jatkavat väitteiden levittämistä antautumatta vuoropuheluun. Sosiaalisessa mediassa denialistien väitteitä levittävät ihmiset, jotka eivät itse tunnu niihin perehtyneen: "Ilmastonmuutos todistettu vääräksi. Lue oheinen suomalaisen tiedemiehen artikkeli tai katso video ja todista sen väitteet vääräksi." Ei pienintäkään vihjettä, mihin väite perustuu. En tiedä, mikä motiivi heillä on, mutta ei ainakaan halu selvittää totuus, joten rationaalisin perustein heihin ei voi vaikuttaa. Ainakin minulle pitää esittää selkeä, hyvin perusteltu kysymys ennen kuin viitsin alkaa epämääräisiä juttuja lukea.

Pistokokeen omaisesti olen kuitenkin satunnaisesti perehtynyt ja verryttelyn vuoksi muutamaa denialistien väitettä kommentoinut. Jäljempänä on pari esimerkkiä.

Nämä esimerkit eivät tietenkään todista, että kaikki ilmastomallinnukseen kohdistuva kritiikki olisi huuhaata. Lähden siitä, että jos pistokokeeni osoittaa jonkin tahon julkaisseen huuhaata, heille ei ole halua tai kykyä tieteelliseen työhön, eikä maksa vaivaa tutustua sen enempää heidän väitteisiinsä. Trollaus perustuu siihen, että huuhaata on sata tai tuhat kertaa nopeampi tuottaa kuin todistaa se virheelliseksi niin perusteellisesti, ettei laajalle yleisöllekään jäisi epäselväksi trollaajien väitteiden virheellisyys.

Ilmastomallinnuksessa sovelletaan jo pitkään tunnettuja ja muillakin aloilla hyödynnettyjä luonnon lainalaisuuksia ja matemaattisia menetelmiä. Mallit eivät tietenkään voi kuvat jokaisen ekosfäärin atomia liikkeitä, joten eksofäärin ilmiöitä kuvaavat luonnonlait ja niihin perustuvat mallit ovat yksinkertaistuksia. Yksinkertaistusten vaikutusta tulosten tarkkuuteen arvioidaan huolella, mutta vaikka arvioitu virhe olisi promillen luokkaa, denialistit julistavat mallit täysin virheelliseksi ja julistavat jääkauden uhkaavan meitä.

Demokratiassa kansalaiset päättävät, joten on tärkeää, että kansalaiset mahdollisimman hyvin ymmärtävät, mistä päättävät. Ilmastotutkijoiden pitää kansantajuistaa ilmastomallinnusta ja sen tuottamia tuloksia, jotta kansalaisilla on edellytykset ymmärtää ehdotettujen toimenpiteiden perusteita.

Valitettavasti ilmastomallinuksen syvällinen ymmärtäminen edellyttää perehtymistä, joka vaatii mielenkiintoa tai alan koulutusta. Äänestäjä joutuu arvioimaan eri tahojen luotettavuutta. Tämä antaa tilaa populismille: Äänestäjä valitsee puolensa sen mukaan, millaisessa porukassa haluaa olla ja mihin haluaa uskoa. Valinnalla ei ole mitään tekemistä itse asian ja faktojen kanssa.

Ensimmäisenä kommenttejani facebookissa kuukausia sitten hehkutettuun Suomalaisprofessoreiden (teknillisen termodynamiikan professori Pertti Sarkomaa ja lämpö- ja virtaustekniikan ja polttotekniikan professori Seppo Ruottu) tutkimukseen.

Toinen esimerkki on vastaukseni facebookissa esitettyihin väitteisiin ipcc:n mallien virheistä. Facebookista en enää löytänyt alkuperäistä viestiketjua, mutta siinä toisteltiin monen kertaan muuallakin esitettyjä virheellisiä väittämiä, joten tuleepa vastattua niihin.

Kumpaakin juttua levitettiin facebookissa täystyrmäyksenä ilmastonmuutoksella pelottelulle. Tällaisissa tutkimuksissa on virheellisiä väitteitä, jotka ovat joko tahallisia valheita tai johtuvat vähäisen asiantuntemuksen ja valtavan itseluottamuksen aiheuttamista väärintulkinnoista. Tällaisten 'tutkimusten' kommentointi tuntuu turhauttavalta ajanhukalta, joten huitaisin kommentit vain selvemmistä virheistä tai selvennystä vaativista kohdista. Kommentit ovat siis luonnoksia facebookiin aikoinaan laittamiini kommenteihin.


18.8.2020

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Ilmastomallinnus ja ilmastodenialismi / Vaihtohtoista tiedettä

 

Vaihtohtoista tiedettä

"Suomalaisprofessoreiden tutkimusraportti toteaa IPCC:n raportin täysin virheelliseksi" toteaa maaseutumedia.

Peittoaako maaseutumedia maailman tiedejulkaisut?

Elokuu 2020

lehtijuttu ja itse 'tutkimusartikkeli' climate_change_and_use_of_fossil_fuels

Tutkimusta ei näy julkaistun millään tyypillisellä tieteellisen tiedon julkaisufoorumilla, joten ensimmäiseksi pitäisi tarkistaa maaseutumedian taustat. En kuitenkaan nyt ryhdy siihen.

Proffien artikkelia ei ole kirjoitettu normaalin tieteellisen artikkelin tapaan eikä se etene järin johdonmukaisesti, joten sitä on pikkuisen hankala arvioida. Koska tässä otetaan kantaa yhteiskunnallisesti erittäin tärkeään asiaan, voi olettaa artikkelin tänne jakaneen tarkistaneen sen huolellisesti, joten hän kyennee auttamaan artikkelin lukemisessa.

Ilmastotutkijat ovat esittäneet ihmisen aiheuttaman ilmastomuutoksen pääsyyksi fossiilisten polttoaineiden käyttämisen. Toinen merkittävä tekijä on maankäytön muutokset niin, että kasvustoon ja maaperään sitoutunutta hiiiltä vapautuu hiilidioksidina ilmakehään.

Jos haluaa tyrmätä ihmisen aiheuttaman ilmastonmuutoksen, pitää kunnolla perustella ainakin jokin seuraavista virheelliseksi. Joko periaatteessa tai ainakin osoittaa, että laskelmat vaikutusten suuruuksista ovat ihan pielessä.

Artikkelin alussa on monenmoisia väitteitä:

The basic claim of IPCC (hence forward the Basic Claim) is that increase of carbon dioxide in the atmosphere causes disastrous global warming.

"The Basic Claim is based on calculations by climate models which apply hypothetical and heuristic quantities “climate sensitivity, clear sky radiative forcing and cloud feedback” These quantities prove univocally that the more than 6000 authors of IPCC’s assessment reports don’t understand mathematical theory of compound, momentum, energy and radiative transfer. The mathematical theory of compound, momentum, energy and radiative transfer doesn’t know, need or allow hypothetical or heuristic quantities hence their use in the climate models of IPCC’s assessment reports is as such a fatal error. "

Ilmastomallien perustana ovat fysiikan peruslait proffien toivomalla tavalla. Ymmärtääkseni Cloud feedback ovat ilmiöitä, joita on selvitetty ilmastomallien perusteella, eivät laskelmien perusteita. Saattaa olla, että johonkin tiettyyn tarkoitukseen laaditussa yksinkertaistetussa mallissa käytetään heuristisia suureita, mutta niiden arvo on selvitetty perusteellisilla laskelmilla. Toivoisin proffien osoittavan tarkemmin, missä kohdin IPCC:n malleissa on tällainen virhe.

Vesihöyryn ja pilvien vaikutus ilmakehään on toki monimutkainen ja hankala mallintaa eksaktisti. Proffat eivät vaikuta perehtyneen siihen, miten IPCC:n malleissa pilviä on kuvattu. (Puhun IPCC:n malleista lyhyyden vuoksi. Tarkoitan malleja, joita on käytetty tutkimuksissa, joihin IPCC perustaa johtopäätöksensä.)

Oletan jutun tänne jakaneen tarkistaneen, miten nuo 6000 tutkijaa ovat ottaneet pilvien vaikutuksen huomioon, ovatko nämä kaksi suomalaista tutkijaa ymmärtäneet oikein IPCC:n mallit ja missä mielessä he teksteissään käyttävät ym. termejä. Heidän väitteensä siitä, miten pilvet vaikuttavat, vaatisi sekin lisäperusteluja.

Aiemmin tässä ketjussa on jo esitetty perusteluja sille, että nämä proffat ovat ymmärtäneet väärin IPCC:n raportit. Yhä uskon enemmän IPCC:n laadukkaaseen työhön, kuin kahden sekavasti kirjoittavan suomalaisproffan väitteisiin. Vielä en tunne tarvetta lähteä tätä tonkimaan. Todistaminen taakka on jutun tänne jakaneella. Allaolevissa satunnaisesti googlatuissa jutuissa mikään ei viittaa, että proffien väite olisi totta. Päinvastoin, niissä korostetaan fysiikan peruslakeja:

climate model, wikipedia ; how do climate models work ; climate models primer ;

"From the carbon dioxide balance of the atmosphere it follows that carbon dioxide concentration in the atmosphere starts to decrease immediately when the outgoing carbon dioxide flow is greater than the incoming flow. In the global energy balances of the atmosphere, accumulation of energy is negligible in comparison with other energy flows hence global mean temperatures are independent of time. Accordingly, the insignificant warming influence of carbon dioxide would start to decrease immediately when the outgoing carbon dioxide flow became greater than the incoming flow"

Käytännössä hiilidioksidia yhä virtaa ilmakehään enemmän kuin poistuu sieltä, joten pohdinta ei koske nykytilannetta.

Varsinainen väite lämpiämisen pysähtymisestä heti kun hiilidioksidipitoisuus lakkaa kasvamasta, on väärä. Maapallo, varsinkin meret, lämpiävät hitaasti. Lämmönsiirto riippuu ilmakehän, merien pintakerroksen ja merien syvien kerrosten lämpötilaeroista. Vasta kun nämä ovat tasaantuneet, ilmakehän lämpiäminen pysähtyy, vaikka co2 tasaantuisi tänään. Siitä seuraa 'nykyisellä lämmitysteholla', että ilmakehä lämpiää vielä nykyisestä ennen kuin tasapaino saavutetaan, vaikka kasvihuonekaasujen tupruttelu lopetettaisiin nyt. Proffat katsoo ilmiötä liian kapeasti.

Myös jäätköiden sulaminen sitoo lämpöä.

"Claim 1.3: NO2 and CH4 are hundreds of times “stronger greenhouse gases” than CO2. The claim 1.3 proves unfathomable ignorance on radiative heat transfer of the thousands of authors of IPCC’s assessment reports."

"IPCC determines the “greenhouse gas strength” of compounds according to their indefinite “residence times” in the atmosphere. In this classification NO2 is a more than 300 times stronger greenhouse gas than CO2. “Residence time” has nothing to do with radiation. Only thermostatic state of the compounds matters. Concentration must be calculated by the compound balance, not by “residence times”."

Metaanista kun puhutaan, aina muistetaan mainita, että se ei pysy ilmakehässä koviin pitkään. Tämän poistuman dynamiikka on mukana malleissa. Miksi ihmeessä ei olisi? Kun malleissa lasketaan säteilyn vaikutusta tietyllä hetkellä, silloin tietysti käytetään sen hetkisiä konsentraatioita. Karkeammissa laskelmissa, kun arvioidaan päästöjen kokonaisvaikutusta pitkällä aikavälillä, voidaan käyttää tuollaista “greenhouse gas strength”. Eli kun puhutaan päästön kokonaisvaikutuksesta esim. seuraavan sadan vuoden aikana, pitää tietysti ottaa residence time huomioon. Kun lasketaan tarkoilla malleilla päästöjen vaikutuksia, malleissa on mukana kunkin aineen pitoisuuden muutosta kuvaavat yhtälöt, eli malleissa lasketaan kunkinhetkistä pitoisuutta. Proffat ovat sotkeneet eri asioita keskenään.

"The influence of a “greenhouse gas compound” on the thermodynamic mean temperature of the ground does not depend only on its radiation properties, but also on the radiation properties of all other compounds of all entities and the beam length. Therefore, it is entirely wrong to classify compounds according their “greenhouse gas strengths”. The only physically reasonable “greenhouse gas strength” is the linear emission coefficient of a compound of an entity. In the atmosphere the linear emission coefficients of NO2 and CH4 are insignificant and much less than the linear emission coefficient of carbon dioxide. "

En ymmärrä. Tarkoitetaanko tällä, että eri kasvihuonekaasujen määrät pitäisi ottaa huomioon? Eikö IPCC ole ottanut näitä huomioon. Mitä sanoo artikkelin jakaja?

Webistä löytyy paljon juttuja ilmastomallinnuksesta. Esimerkki (tuskin sopivin tähän tarkoitukseen) ilmakehän monikerrosmalli En jaksa perehtyä yksityiskohtaisesti näihin, mutta jo pikavilkaisulla syntyy vaikutelma, että proffat kritisoivat oman mielikuvituksensa tuotetta, eivät todellisia IPCC:n hyödyntämiä malleja.

Minun mielestäni proffat sotkevat IPCC:n raporteista poimimiaan kohtia. Samaan viittaa seuraava lainaus. Ymmärtääkseni näiden parametrien arvot on laskettu ilmastomallien avulla, mutta sitä proffat eivät halua ymmärtää, vaan päättelevat että maailmassa on tuhansia ilmastomallintajia, jotka eivät tunne perusfysiikkaa eivätkä muutenkaan ymmärrä mistään mitään. (Artikkelin jakaja voinee selittää oman näkemyksensä?)

"In late September 2013, the Intergovernmental Panel on Climate Change (IPCC) reported that methane is a far more potent greenhouse gas than had been previously assumed. The IPCC calculated that methane is 34 times stronger as a heat-trapping gas than CO2 over a 100-year time scale. That means the heat-trapping strength (i.e. global-warming potential, or GWP) of methane is nearly 40 percent greater than the previously estimated 25 percent. The IPCC report also stated that over a 20-year period, methane has a global warming potential of 84 compared to carbon dioxide, up from the previous estimate of 72."

Greenhouse Gases Absorb Infrared Radiation

"Claim 1.4: Water vapor is not a greenhouse gas The claim 1.4 proves unfathomable ignorance on radiative heat transfer of the thousands of authors of IPCC’s assessment reports. Even though water vapor differs from all other gases of the atmosphere by its thermostatic properties it is by far the “strongest greenhouse gas” of the atmosphere. In the lower atmosphere, mean linear emission coefficient of water vapor is about 27 times the linear emission coefficient of carbon dioxide. "

Tämä on jo tahallista väärinymmärtämistä. Näytäpä sellainen ilmastotutkijoiden malli, jossa vesihöyryn vaikutusta ei olisi huomioitu. Kukaan asiantunteva tutkija ei esittäisi, ei kehtaisi esittää, näin täysin vastoin totuutta olevaa väitettä.

Dynaamisia malleja tarkastellessa usein erotellaan input suureet ja tilasuuret, eli järjestelmän sisäiset, inputeista riippuvat suureet. Koska veden kierto riippuu monimutkaisella tavalla lämpötiloista, se on otettava tilasuureeksi. Inputteja, forcing factors, ovat auringon säteily, co2-tupruttelu yms.

Veden haihtuminen, tiivistyminen, pilvet ja vesihöyryn absorboima lämpösäteily ovat olennainen osa kaikkia malleja. Joka muuta väittää, ei ole tutustunut tutkimuksiin joita kritisoi.

"Claim 1.6: If the carbon dioxide flow to the atmosphere cannot be reduced, mankind will become extinct. This claim is univocally wrong, because carbon dioxide concentration in the atmosphere does not depend only on carbon dioxide flow to the atmosphere but on carbon dioxide flow to and from the atmosphere. This wrong claim is due to that nobody from the thousands of researchers of IPCC’s assessment reports hasn’t understood the mathematical theory of carbon dioxide concentration of the atmosphere. Physical and mathematical foundations of this theory and on the corresponding mathematical model (hence forward the SRcompound model) has been presented in Appendix 3. "

Kaikkialla kuvataan hiilikierto niin, että siinä on sekä virtaukset ilmakehään että siitä pois. Kaikki ymmärtävät tämän. Mallintajat laskevat enemmän tai vähemmän yksityiskohtaisesti näiden virtauksien suuruuksia kasvipeitteestä, merien lämpötilasta, ilman lämpötilasta yms. riippuen. Jopa se otetaan joissain malleissa huomioon, että hiilidioksidin lisääntyminen ilmakehässä lisää kasvien kasvua, jotka siten sitovat lisää hiilidioksidia. Väite tarkoittaa sitä, että jos hiilidioksidin tupruttelu jatkuu nykyvauhtia, hiilidioksidipitoisuus kasvaa vaarallisen korkeaksi. CO2-pitoisuuden kasvaessa ilmakehässä, myös sen poistuma kasvaa, mutta ei yhtä paljoa, eikä ole tiedossa käyttökelpoista keinoa lisätä nieluja riittävästi. Siksi tuo johtopäätös, että co2 tupruttelua pitää vähentää.

carbon cycle

Ihan päätön väite siis tämäkin. Proffat eivät joko ole lainkaan perehtyneet IPCC:n käyttämiin malleihin tai valehtelevat. Eiköhän tämä riittänyt näiden väitteiden käsittelystä. Vai mitä mieltä on tämän artikkelin jakaja? Ihan oikeastiko uskot ennemmin näitä kahta kuin 6000 ilmastotutkijaa?

"Calculations with the SRcompound model prove that this can be achieved even with the current carbon dioxide flow to the atmosphere by reducing use of forests (logging, etc.)."

Okei, tämä liittyy ylläolevaan. Proffat väittävät, että metsät voisivat toimia riittävänä nieluna. Hyvässä kasvuvahdissa olevien metsien hakkuiden lykkääminen vaikuttaisi muutaman vuosikymmentä oikeaan suuntaan, muttei riittävästi. Jos aina järeimmät puut hakattaisiin ja käytettäisiin vaikka puurakennuksiin, saataisiin pysyvä hiilinielu. Suuruutta en tässä osaa arvioida. Nykyisen, yhä kasvavan co2-tupruttelun vaikutusta ei ymmärtääkseni voi korvata metsien hakkuuta vähentämällä, vaikka hakkuita toki kannattaisi vähentää.

"Chapter 2: Wrong claim on biomass and fossil fuels Claim 2.1: Photosynthetic biomass is a carbon-neutral fuel Amount of carbon in the atmosphere depends only on incoming and outgoing carbon flows of the atmosphere. As shown in Appendix 2, use of photosynthetic biomass instead of any fossil fuel will increase carbon flow per produced energy to the atmosphere. Anybody with elementary knowledge on chemistry can confirm this. At the same time, use of photosynthetic biomass decreases carbon flow from the atmosphere. Anybody with common sense understands this. Therefore, regarding carbon dioxide concentration of the atmosphere, photosynthetic biomass is not carbon neutral but by far the most “carbon intensive” of all fuels. "

Tämä lienee oikeansuuntainen väite proffilta. Joskus tulevaisuudessa, kun kaikki on kauniisti tasapainossa voi ajatella, että puun polton ja puiden kasvun vaikutus voisi olla tasapainossa ja kaikki hyvin. Lähivuosikymmeninä pitäisi sitoa hiilidioksidia, siihen +-0 tasapaino ei riitä.

MUTTA, onko IPCC:n raporteissa väitetty jotain päinvastaista? Missä? Missä on viite IPCC:n virheelliseen raporttiin? Onko ipcc ottanut kantaa biopolttoaineisiin vai ottavatko proffat tässä kohtaa kantaa Suomessa käytävään keskusteluun.

"Claim 3.1: Increase of carbon dioxide in the atmosphere increases storms. Cyclones (hurricanes and typhoons) are born when vertical air flow approaches tangentially ascending air flow. Small changes of the mean temperature of the ground have practically no influence on the velocities of cyclones. Heavy rains, which are related to cyclones, are due to fast condensing of water vapor due to conversion of sensible energy into kinetic and potential energy. Even though carbon dioxide concentration in the atmosphere is the same, each cyclone has different velocities and precipitation. Influence of carbon dioxide concentration in the atmosphere has nothing to do with cyclones. "

On väitetty, että CO2-tupruttelusta aiheutuva ilmaston lämpeneminen lisää myrskyjen määrää ja voimaa, koska lämpimämmässä meristä haihtuu enemmän ja lämpimämpää kosteutta, joten siinä on enemmän energiaa. Kuka on väittänyt, että hiilidioksidipitoisuus suoraan vaikuttaisi myrskyihin? Taas proffat tyrmäävät väitteen, jota kukaan ei ole esittänyt. co2 vaikuttaa myrskyihin epäsuorasta aiheuttamalla merien lämpenemistä.

Proffat perustelevat väitettään Navier-Stokes yhtälöillä. Heiltä kuitenkin näyttää puuttuvan laskelmistaan myrskyjen perussyy, meren lämpötilan vaikutus haihtuvaan vesimäärään ja sen mukana ylös nousevaan energiaan. Olkiukko tämäkin väite ???

Mankind

During the past 150 years the mankind has influenced in the ecosystem by many harmful ways.

Noillakin on vaikutusta, mutta fossiilisten polttoaineiden vaikutus puuttuu tästä listasta.

"Introduction

In this appendix it is proved by thermostatic considerations that replacing of energy of fossil fuels by energy of photosynthetic biomass increases CO2 concentration in the atmosphere. It is also shown that production of energy by from the photosynthetic biomass processed biofuel increases CO2 concentration in the atmosphere more than if the equal amount of energy had been produced by direct combustion of the photosynthetic biomass which is needed to produce the biofuel. "

Tästä lienee jonkinmoinen yhteisymmärrys tutkijoiden kesken. Eli puun polttaminen ei ole varsinainen ilmastoteko ja vielä vähemmän polttonesteen valmistaminen siitä. Ei ainakaan tässä tilanteessa, kun co2-pitoisuuden nousu pitäisi saada laskuun. Joskus hamassa tulevaisuudessa, kun ilmasto on tasapainossa, puuta voisi polttaa samaa vauhtia kuin uutta kasvaa.

"Summary

Proffien väite: The atmosphere is a mixture of gas, droplets and solid particles (hence forward the Entities). Compound, momentum, energy and number balances of the Entities form the only physically and mathematically relevant foundation of climate models. However, in IPCC’s 3D time-dependent models, compound, momentum, energy and number balances of the Entities are replaced by total mass, momentum and energy balances of the Entities and number balances are totally missing. In addition, radiative energy transfer of the 3D time-dependent models has been modelled incorrectly whereupon the models are physically and mathematically wrong.

The heat and fluid dynamical and mathematical foundations of 1D global climate model is presented in this paper. Because IPCC’s claim neglects temperature differences between the Entities the developed climate model (hence forward the SRclimate model) is simplified accordingly and applied to investigate the influence of carbon dioxide on the global mean temperatures. The investigation proves that the influence of carbon dioxide on the global mean temperatures is insignificant. "

Tässä kohtaa kirjoittajien pitäisi täsmentää väitettään — Osoittaa IPCC:n malliyhtälöistä tuo virheellinen oletus niin, että minäkin ymmärtäisin. Koska proffat eivät paljasta, missä kohdin ipcc:n malleja tuo virhe on, minun pitäisi syventyä ipcc:n 3D mallien yhtälöihin. Tässä kohdin luottamukseni näihin proffiin ei kuitenkaan enää ole niin korkealla, että viitsisin moiseen ryhtyä. Nyt voin vain todeta, että perustelemattoman väitteen perusteella he korvaavat IPCC:n mallit yksinkertaisemmalla, jota ovat vielä yksinkertaistaneet perustelemattoman väitteensä perusteella. Näiden laskelmien perusteella he sitten todistavat muun maailman olevan väärässä.

"Therefore, influence of increase of carbon dioxide in the atmosphere on radiation to the ground must be calculated by accounting simultaneously the influences of carbon dioxide and clouds. In climate models of IPCC’s assessment reports these influences are separated into clear sky “radiative forcing” and “cloud feedback” which is a fatal error."

Ilmaston ilmiöitä tutkitaan yleensä 3D-malleilla. Sen lisäksi saatetaan käyttää yksinkertaisempia malleja, joiden 'heuristiset' parametrit on määritetty 3D-mallien avulla. Tällaisia yksinkertaisempia malleja tarvitaan, jos halutaan tehdä tuhansia entä-jos-laskelmia tai muuta vastaavaa. Tarkoilla, fysiikan lakeihin perustuvilla, malleilla selvitetään, mitä oikeasti tapahtuu ja yksinkertaisemmat mallit 'viritetään' tämän perusteella. Proffilla on tällainen yksinkertainen malli, jota he vertaavat ipcc:n yksinkertaisiin malleihin. Ehkä.

Saattaa olla, että proffat eivät ole ymmärtäneet, mitä IPCC tarkoittaa cloud feedbackilla, mihin sitä käytetään ja miten se on laskettu. Hehän Käyttävät yksinkertaista 1D mallia. Ehkä se hämää heitä? IPPCC:n raporteissa cloud feedback näyttää tarkoittavan tutkittavaa ilmiötä. Mikään ei viittaa proffien kuvaamaan erotteluun itse malleissa.

Pilvien vaikutus on oikeasti monimutkainen juttu ja jotkut denialistit mitätöivät tämän perusteella kaiken IPCC:n tutkimuksen. Jonkun ilmiön toteaminen vaikeaksi mallintaa ei ole "fatal error". Ennenminkin proffat tekevät fatal errorin väittäessään, että heidän mallinsa kuvaa ilmiön oikein.

Ken haluaa perehtyä tarkemmin siihen, mitä ipcc tarkoittaa näillä termeillä ja miten pilviä mallinnetaan, voi lukaista oheiset jutut. Pikavillkaisulla syntyi vaikutelma, että proffien väite ei liity ipcc:n malleihin. Sen varmistamiseen, onko ipcc:n malleissa virheitä, tai kuvaavatko poimimani artikkelit oikein ipcc:n mallinnuksia, en jaksa ryhtyä. En tunne tarvetta.

"Cloud feedback studies point to five aspects of the cloud response to climate change which are distinguished here: changes in high-level cloud altitude, effects of hydrological cycle and storm track changes on cloud systems, changes in low-level cloud amount, microphysically induced opacity (optical depth) changes and changes in high-latitude clouds." sceptical science, cloud feedback ; IPCC, Clouds and Aerosols

"3D time-dependent climate models of IPCC assessment reports

For a big surprise of professor Sarkomaa and professor Ruottu (hence forward the Authors) their discussions with the Finnish Meteorological Institute and meteorologists of Helsinki University revealed that meteorologists don’t understand theoretical foundations of radiative energy transfer and cloud formation. References 11 and 13 of IPCC’s assessment reports prove that their authors, authors of their references and reviewers of IPCC’s assessment reports don’t understand heat and fluid dynamics. "

Ihmehän tuo olisi. Ihmeisiin en usko, ennen kuin näen. Eli yksilöidymmät perustelut haluaisin.

In the following, the Authors show that FMI’s temperature measurements are in inevitable contradiction with IPCC’s claim about 2.2 ºC warming of northern areas.

Artikkelissa vertaillaan Kaisaniemen ja Tähtelän lämpötiloja ja co2-pitoisuuksia

Kukaan ei ole väittänyt, että ilmakehän co2-pitoisuus ja paikalliset muutaman valikoidun päivän lämpötilat korreloisivat suoraan. En ymmärrä, mitä tolkkua on esittää nuo regressiot.

Noiden mittausten perusteella proffat väittävät, että IPCC on väärässä esittäessään, että ilmastonmuutoksen myötä napa-alueet lämpiävät enemmän kuin päiväntasaajan seutu. Saman tasoa kuin todistaa ilmastomuutos kiinalaisten juoneksi tuomalla lumipallo kongressisaliin.

En löytänyt mistään tietoja, miten SRclimate model:ia on validoitu. Tähän mennessä lukemani perusteella en tunne motivaatiota lähteä sen yhtälöitä tutkimaan. Olisi kiva, jos joku, joka väittää sillä saatuja todemmiksi kuin varsinaisten ilmastotutkijoiden malleilla, selittäisi selkeämmin, mikä SRclimate mallissa on parempaa.


/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Ilmastomallinnus ja ilmastodenialismi /

 

Löysin arkistoistani luonnoksen vastauksestani erääseen ilmastodenialistien facebookissa esittämään väitteeseen. Harmi kyllä, en löytänyt po. viestiketjua, joten tämä kommenttini jää pikkuisen irralliseksi. Toisaalta nuo samat virheellisiksi osoitetut väitteet pomppaavat esiin yhä uudelleen, joten ehkei tämä juttu ihan hukkaan mene.

Elokuu 2020

Tuntuu, kuin olisin jäänyt koukkuun some-ajan teekkarijäynään, kun palaan tähän keskusteluun.

Keskustelun aloittaja väittää, että laskelmat, joiden mukaan ihmisen toiminta on syynä ilmastonmuutoksen, ovat virheellisiä. Väitteensä hän perustaa ilmastodenialisti Ed Berryn artikkeliin , jonka mukaan maapallon ekosfääri toimii kuin vuotava ämpäri ja kaikki sitä monimutkaisempi mallintaminen on turhaa. Linearisoitua vuotavan ämpärin mallia Berry kutsuu physics modeliksi.

Ilmastomallinnukseen vaikka vain pinnallisestikin perehtyneelle on selvää, että ämpärimalli ei riitä ilmaston ilmiöiden hyödylliseen tarkasteluun. Varsinkaan se ei ansaitse nimeä 'physics model'

Ipcc:n malleilla on kokeiltu (monen muun asian lisäksi) mitä tapahtuu, jos ekosysteemin tasapainoa häiritsee alkamalla puhaltaa ilmakehään pikkuisen lisää co2:ta (Ihmisen aiheuttama lisä luonnon hiilikiertoon on noin 5%). Mallien mukaan luonnon prosessit — co2 lähteet ja nielut — sopeutuvat ilmakehän co2-pitoisuuden nousuun niin, että ilmakehästä poistuu aiempaa enemmän co2:ta, mutta ei kuitenkaan koko lisäys — vajaa puolet ilmakehään puhkutusta co2-lisästä jää ilmakehään. Tätänykyä. Pidemmän päälle merien kyky liuottaa itseensä co2:ta heikkenee, mikä vähentää nieluja.

Tässä keskusteluketjussa viitataan artikkeliin: co2 levels airborne fraction increasing? Artikkelin pointti on, että ihmisen tuottamien hiilipäästöjen ja ilmakehän co2-pitoisuuden välillä on vahva riippuvuus. Koska muuta selitystä co2-pitoisuuden nousulle ei ole löytynyt, tuntuu loogiselta, että ihminen on ilmastomuutoksen aiheuttaja. Matemaattisen eksakti tieteellinen todistus tällainen päättely ei tietenkään ole, mutta niin kauan kuin muuta selitystä ei löydy, ihminen on aika hyvä selitys.

Seuraavat lainaukset ovat tästä fb-keskusteluketjusta: "jos kyseinen artikkeli kohtelisi ihmis- ja luontoperäistä hiilidioksidia samanarvoisina, hiilidioksidipitoisuus nousisi 0,43*804/3,76/2,14 ppm vuodessa." ja "Tuossa artikkelissa on ihan hurja virhe, se väittää että 43% CO2-tuotannosta jää ilmakehään. Jos kaikista tuotantolähteistä jäisi noin paljon ilmakehään, pitoisuus nousisi noin 43 ppm vuosittain. Esim. Mauna Loalla se on kuitenkin noussut 1,4 - 2,2 ppm vuosittain. Virhe on kertaluokkaa 24!"

Virhe on iso vaan onko se ipcc:n?

"...jos kyseinen artikkeli kohtelisi ihmis- ja luontoperäistä hiilidioksidia samanarvoisina..." Artikkelista ei voi päätellä, että ihmis- ja luontoperäistä hiilidioksidia ei kohdeltaisi samanarvoisina. Sellainen olisi ihan älytöntäkin. Kaikissa malleissa niitä käsitellään samanarvoisina. Tietysti. Artikkeli tarkoittaa, että kun ilmakehään tuprutetaan lisää hiilidioksidia, luonnon hiilinielut eivät kykene nielemään lisäystä kokonaan, vaan lisäyksestä 43% jää ilmakehään. Näin kummallista väärinkäsitystä ei olisi syntynyt, jos olisi perehdytty ilmastomallinnukseen. Tai sitten 'väärinkäsitys' on tahallinen.

Laskelmissa yllä co2-lähteet on oletettu todenmukaisiksi, mutta entä nielut? Jotta ilmaan jäisi noin paljon enemmän co2:ta, nielujen pitäisi vastaavasti olla paljon nykyistä pienempiä, eikö totta. Eikö se olisi outoa? Jos yo. väitteen/laskelman esittäjä olisi tarkastellut koko hiilikiertoa, hän olisi ymmärtänyt virheensä.

Lisäksi 'ämpärimallissa' on oletettu ekosysteemi lineaariseksi. Jos ämpärimallia korjaisi fysikaalisemmaksi niin, että virtaus pohjan reiästä olisi verrannollinen paine-eroon eli pinnankorkeuden neliöjuureen, ämpärimallin avullakin voisi ehkä ymmärtää virheelliseksi väitetyn artikkelin pointin.

Oletetaan, että meillä on vuotava ämpäri, johon lorotamme vettä niin, että ämpäri pysyy puolillaan. Jos alamme lorottaa ämpäriin lisää vettä, pinta nousee, kunnes vuoto lisääntyy vastaavasti. Tässäkään emme kohdelleet eri tavoin alkuperäistä veden virtausta ja siihen tehtyä lisäystä.

Vielä voi miettiä, miten yo. laskelmassa on otettu huomioon se, että järjestelmä ei ole tasapainotilassa vaan päästöt ja co2-pitoisuus kasvavat koko ajan. Pitäisi osoittaa, että kaikki luonnon prosessit reagoivat muutoksiin niin nopeasti, että tätä ei tarvitse ottaa huomioon. Muuten Berryn analyysi ei ole pätevä.

Tässä fb-ketjussakin viitataan Ed Berryn katteettomaan väitteeseen, että ipcc:n mallit kohtelisivat eri tavoin ihmis- ja luontoperäistä hiilidioksidia. Ei Berry eikä kukaan muukaan ole kyennyt perustelemaan tätä (usein toistettua) väitettä.

Aivan kuten laskelmasta yllä myös Berryn artikkelin kuvasta 16 ja siihen liittyvästä selittelystä puuttuu kokonaan nielut, eli Berryn termein reikä ämpärin pohjasta. Berry ei näytä ymmärtävän edes ämpärinsä toimintaa. Jos alkaa lisätä ämpäriin juoksevaa vettä, pinta alkaa nousta ja sen seurauksena pohjassa olevasta reiästä alkaa virrata enemmän vettä. Lopputuloksena ämpärin pinta alkaa nousta ja virtaus pohjasta kasvaa. Pinta nousee niin kauan kuin virtausta lisätään. Osa virtauksen lisäyksestä siis jää ämpäriin, osa virtaa ulos.

Berry ja tämän keskustelun aloittaja kritisoivat ipcc:n käyttämään Bernin mallia. Kuvaus yhdestä sen versioista: yksinkertaistettu ilmastomalli

Koska varsinaiset fysikaaliset ilmastomallit vaativat paljon laskentakapasiteettia, tutkijat ovat varsinaisten mallien tulosten avulla kehittäneet tällaisia 'kevytversioita'. Varsinaisilla malleilla selvitellään 'perusasioita' ja kevytversiota käytetään esimerkiksi erilaisissa satoja ja tuhansia iteraatioita vaativissa entä-jos skenaarioissa. Näitä yksinkertaisia malleja ei siis käytetä todistamaan mitään ekosfäärin perusilmiöistä.

On tarkistettu, että 'normaalilla' toiminta-alueella mallin kevytversio toimii riittävän hyvin samalla tavalla kuin varsinaiset fysikaaliset mallit. Berry ei arvioi tätä vertailua millään lailla. Liioin hän ei millään lailla arvioi varsinaisia fysikaalisia malleja vaan toteaa:

"Agreement among models does not prove they are accurate." Ei tietenkään. Missä tämmöistä on väitetty? Mutta agreement among models tietyllä toiminta-alueella tarkoittaa, että ne tuolla alueella antavat samat tulokset. Erikseen on tarkistettu, kuinka hyvin varsinaiset mallit kuvaavat reaalimaailman ilmiöitä.

Berry mm. väittää, että Bernin malli toimii väärin, koska se jättää ilmakehään pitkäksi aikaa co2:ta, mutta ei perustele, miksi tämä on mahdotonta. Ei ehkä ole perehtynyt fysiikkaan ipcc:n mallien takana.

Artikkelinsa kuvalla 9 Berry 'todistaa', että ipcc:n malli toimii väärin.

Ilmakehässä tehtyjen ydinkokeiden takia ilmakehässä on radioaktiivista 14co2 isotooppia suhteessa enemmän kuin metsän puissa, merissä yms. Normaalin hiilikierron myötä tämä ero tasaantuu. Tätä tasaantumista kuvaamaan Berryn ämpärimalli sopii hyvin. (Noin joka triljoonas hiiliatomi on isotooppia 14co2)

Tämä tasaantuminen on dynamiikaltaan aivan eri ilmiö kuin luonnon normaali hiilikierto, jota Bernin malli kuvaa. Kuvan 9 kaltainen vertailu on siis merkityksetön. Jos ilmastomallin haluaisi ottavan tasaantumisen huomioon, siihen pitäisi lisätä omiksi muuttujikseen 14co2 pitoisuudet ekosysteemin eri osissa. Vaan miksi?

Mitähän yksikköjä kuvan 9 y-akseli edustaa? Onko Bernin malli edes toiminta-alueellaan? Yksinkertaistetut malleja on tarkoitus käyttää vain rajatulla toiminta-alueella.

Berry kirjoittaa: "The IPCC Bern model cannot continue its same prediction line if it is restarted at any point. The Bern model cannot properly restart because it depends upon its history, which makes it an invalid model."

En ymmärrä. Simuloinnin tulos riippuu aina mallin alkutilasta, joka kertoo järjestelmän historiasta sen, mikä tarvitaan tulevaisuuden ennustamiseen. Erilaisissa malleissa mallin tila näky eri tavoin. Jos Berry tekisi ämpäristään differenssiyhtälömuotoisen mallin, mallin tilan kertoisi pinnankorkeus nykyisenä ja edellisenä ajanhetkenä. Ehkä Berry ei ole osannut käyttää Bernin mallia.

Paljon muutakin Berry väittää Bernin mallista, mutta sen arviointi ei mahdu fb:n sallimaan 8000 merkkiin, joten totean vain, että hänen kritiikkinsä ei ole perusteltua, eikä edusta normaalia systeemianalyyttista käytäntöä.

Webistä löytyy paljon Berryn artikkelia vastaavia. Tiedeperustaista työtä ei ole levittää kritiikittä yksittäisen tutkijan väitteitä. Vertaisarvioituja tutkimuksiakaan ei kannata automaattisesti pitää totena. Vertainen kun ei välttämättä tarkoita asiantuntijaa.

Tällainen vähän huitaistenkin tehty juttu opettavainen, mutta varsin raskas. Väitteet näyttävät soopalta, mutta niiden varmistaminen soopaksi ja todistaminen mahdollisimman kansantajuisesti soopaksi on haastavaa. Ymmärrän, jos joku menee halpaan.

Hyödyllisempää taitaisi olla perehtyä lisää varsinaiseen ilmastomallinnukseen ja yrittää kertoa siitä.


2020-5-15

/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / COVID-19 mallinnusta

 

COVID-19 mallinnusta

Lukaisin läpi artikkelin epidemiologisesta mallinnuksesta

toukokuu 2020, (v1: 2020-5-15, v2: 2020-5-17)

Mielenkiintoinen agenttipohjainen malli koronaviruksen leviämisestä

Tutkimusta ei ole vertaisarvioitu (ei kai THL:n) laskelmiakaan. Muutenkaan en tekisi päätöksiä yksinomaan tällaisten simulaatioiden perusteella. Tällaisten simulaatioiden tarkoitus on avartaa näkemystä ilmiöstä. Pitää tietysti osata arvioida, avartavatko tosimaailman suuntaan ;-)

Pikavilkaisulla (mutkat suoriksi vetäen, kannattaa lukea koko juttu) kirjoittajien johtopäätös näyttää olevan, että liikkumisen rajoituksia ja sosiaalisen etäisyyden pitämistä (1) kannattaa tukea testaamisella ja jäljittämisellä (2). Sitten kun epidemia on saatu tiukoilla rajoituksilla sopivasti kuriin, rajoituksia voi ehkä löysätä, jos testataan ja jäljitetään huolella.

Strategiaa (1) he kutsuvat mitigation (rajoittaminen, hallitseminen?) ja strategiaa (2) suppression (kuristaminen/nitistäminen?) (1) strategiaa seuraavat kuulemma saattavat tyytyä siihen, että tautiluvut tasaantuvat kun taas (2) strategiassa pyritään saamaan tautiluvut laskuun.

Toteavat yhdeksi merkittäväksi epävarmuustekijäksi sen, että taudin tappavuutta on vaikea arvioida, koska ei tiedetä, moniko sairastaa oireettomasti. Heidän mielestään tiedon lisäännyttyä alkaa näyttää siltä, että oireettomasti sairastaneita on alunperin oletettua vähemmän, mistä seuraisi, että tappavuus (kuolleisuus) voi olla aiemmin arvioitua korkeampi. Ymmärtääkseni, jos oireettomasti sairastaneita on vähän, kuuluisa R0 on pienempi kuin alunperin oletettiin.

Epidemiologisissa malleissa ihmiset näytään jaettavan ryhmiin taudin vaiheen mukaan: Susceptible, Exposed, Infectious and Recovered, (altis?, altistunut?, sairastunut?, toipunut?) Lisäksi väestö voidaan jakaa ryhmiin iän mukaan ja käyttää hyväksi sosiaalitieteilijöiden hankkimaa tietoa ikäryhmien välisistä kontakteista (jotain tuollaista. Mallissa on kontakteja kuvaaja neliömatriisi)

Taudin leviämistä kuvaavien muutaman parametrin perusteella lasketaan esimerkiksi vuorokauden välein, paljonko porukkaa siirtyy taudin tilasta toiseen. Taudin leviämiseen vaikuttavat tietysti ihmisten välisiin kontakteihin vaikuttavat toimenpiteet.

Tärkeä on ymmärtää millä perusteilla parametreille löydetään arvot. Planeettojen liikkeitä laskiessa tiedämme gravitaatiovakion monen desimaalin tarkkuudella. Koronaviruksesta tiedämme vähemmän.

Keskeinen parametri on R0. Se kertoo, montako ihmistä tautinen tartuttaa 'neitseellisessä' väestössä, siis epidemian alkaessa. R0 kuvaa viruksen ominaisuuksia. Mainitsevat myös Rt:n, joka riippuu (lisäksi?) väestön kulttuurisista tavoista.

Eniten tässä jutussa innostuin artikkelissa kuvatusta agenttipohjaisesta mallinnusmenetelmästä. Sensijaan, että laskisivat, montako ihmistä on missäkin taudin vaiheessa, heidän ohjelmassaan jokainen ihminen on oma olionsa, joka käy taudin vaiheita läpi. (Jos jokainen tyyppi ei mahdu tietokoneen muistiin, niin sitten kai voi laittaa kunkin agentin edustamaan vaikka sataa tai tuhatta ihmistä ???)

(Ensimmäisiä simulaatioharjoituksiani -70 luvulla oli agentti/olio -pohjainen parkkipaikan simulointi, johon laitoimme satoja autoja huristelemaan, jonottamaan parkkipaikalle yms. Siksi kai tämä sykähdytti. Toki kaikenlaiset väitteet koronastrategioista herättivät ajatuksen, että pitää kai epidemioiden mallinnukseen perehtyä)

Jokaisella agentilla – oliolla – on ikä, taudin vaihe (ja montako päivää on kyseisessä taudin tilassa ollut), yms. Senkin laittavat muistiin, keitä muita on tartuttanut. Agenteille on helppo laittaa erilaisia ominaisuuksia. Malliin on helpo laittaa satunnaisuutta.

Agentit voivat vaikka 'kuleksia kaupungilla' ja arpa (satunnaisluku) kertoo, saavatko tartunnan, jos kohtaavat tautisen (aivan näin eivät simulaatioitaan artikkelissa kuvaa ;-) kehuvat kuitenkin, että agenttipohjaisella mallilla on helpompi kokeilla mikrotason juttuja, mukaanlukien erilaiset rajoitukset. Kontaktoinnissa voisi ottaa huomioon jotain ihmisten arkea kuvaavia parametreja, kuten työ, asuinpaikka, työmatkasta jotain, yms. Näitä ei ole tässä eikä muissakaan malleissa.

"The possible states of a person are the following: susceptible, incubation (infected but actual illness not yet started; may spread virus), illness, hospitalized, in intensive care, recovered (i.e., immune), and dead (Figure 1). The symptom severity of a patient can be asymptomatic, mild, severe, or critical. The model follows every individual through the whole disease path from susceptible to recovery or death. "

"The agents represent individual people, who have the following properties: age (years), infected (yes/no), infection detected (yes/no), immunity (yes/no), days of incubation period left (d), days of illness since the onset of symptoms (d), other people infected (identifiers of agents that this agent infected; used for tracing), state, and symptom severity."

"The healthcare system has the following properties: number of hospital beds, number of hospital beds available, number of intensive care beds, number of intensive care beds available, testing mode (lazy: test only people with severe symptoms; active: test also people with mild symptoms; aggressive: test also people with mild symptoms and contacts of coronavirus positive people), number of coronavirus tests run per day, length of testing queue"

R0:n tilalla agenttimallissa on todennäköisyydet, millä ihmiset kohtaavat toisensa ja millä todennäköisyydellä tautinen tartuttaa terveen missäkin taudin vaiheessa:

"The model uses explicit estimates for the three quantifiable processes that are usually embedded in R​0​, namely contacts, exposure, and infectivity. " Kontaktit riippuvat kulttuurista, joten globaalista datasta estimoitu R0 ei ole yhtä hyvä kuin ilmiöiden erottelu.

"A Finnish ​contact matrix​ giving empirical contact frequencies for individuals by age is available with age-specific numbers of physical contacts per day."

Toteavat, että on epävarmaa, moniko sairastaa oireettomasti ja millä todennäköisyydellä virus tarttuu kohtaamisessa, ovat tehneet herkkyysanalyysejä ajamalla mallia eri parametreilla. Herkkyyttä satunnaisuudelle ovat tarkastelleet ajamalla 100 ajoa kullakin parametrilla (tietokoneen satunnaisluvut ovat näennäissatunnaisia, mutta se on oma juttunsa. 'pseudo random' tai jotain sellaista googlaamalla selviää)

Simuloinneissa on tarkasteltu HUSin alueen väestöä. Vertailtu lazy and aggressive testing strategioita eri asteisilla liikkumisrajoituksilla. Uudenmaan rajat lienevät mallissa kiinni, koska artikkelissa ei ole mainintaa ulkopuolelta tulevista sairastuneista. Tiukka karanteeni ja testaaminen estäisi ulkoa tulevat pöpöt, mutta muuten ulkoa tulisi jatkuva virta tautisia.

Tarkastelevat simuloimalla myös oireettomien määrän (joka siis toistaiseksi tunnetaan huonosti) vaikutusta. Jos suurin osa on oireettomia, tai juuri kukaan ei ole oireeton, silloin testaamisesta ja jäljittämisestä ei saada suurta lisähyötyä.

Miten hyvin malli kuvaa HUSin alueen väestön käyttäytymistä? Miten hyvin kuvaa viruksen käyttäytymistä? Tuntuu, että mallin tekijät ymmärtävät, mitä on mallintaminen ja erityisesti epidemiologinen mallintaminen. Miten lähellä totuutta pääsevät? Saattaapa hyvinkin antaa oikeansuuntaisia tuloksia. Paljon paremmin kuin päässälaskuna arveleminen tai fiilispohjalta luuleminen/toivominen.

Sen jälkeen, kun mallilla on saatu jotain tuloksia, pitää miettiä, tuntuvatko ne järkeviltä? Jos ei, onko vika järjessä vai mallissa. Joskus simulaatiot antavat ahaa-elämyksiä, intuition vastaisia tuloksia, jotka osoittavat intuition vääräksi. Mutta voi järkikin osoittaa mallista virheitä. Äkkiseltään ei minulle tullut suuria yllätyksiä. En ihan tarkkaan katsonut, milloin asteikko ulottui miljoonaan, milloin sataantuhanteen.

Vielä pitää kysyä, miksi malli antoi sellaisia tuloksia kuin antoi?

Merkittävin tulos oli, että testaaminen, jäljittäminen ja tautisten eristäminen kannattaa. Muita rajoituksia voidaan löysätä, jos tämä onnistuu hyvin. Käy järkeen. Ehkä jopa ilman mallinnusta voisi päätyä tällaiseen johtopäätökseen.

Riippuu tietysti siitä, moniko sairastaa oireettomasti. Jos kaikki saavat oireita nopeasti tartunnan jälkeen, tautiset löytää testaamattakin. Jos taas melkein kaikki sairastavat oireettomasti niin, äääh, mitä siitä seuraa? Testauksen tarkkuus, jäljittämisen onnistuminen: Näitä ei tarkasteltu. Mitä vaikuttaa, jos tautisista jää havaitsematta 10%, 20%? Miten hyvin jäjittäminen toimii? Kuinka monta prosenttia altistuneista löydetään?

Simulointien perusteellakin toteavat, että alussa tautiin kannattaa joka tapauksessa iskeä moukarilla, eli tiukoin rajoitustoimin.

Simulointitulosten mukaan, jos ei testata vaan pidetään tauti hoitokapasiteetin rajoissa pelkästään rajoitustoimilla, tarvitaan tiukempia rajoituksia ja tauti on pitkään keskuudessamme. Pahimmillaan se talttuu vasta laumasuojaan? Mikäli sille yleensä tulee immuuniksi, kuten useimmille virustaudeille. Loogista tuokin. Ellei satuta löytämään tehokkaita rajoitustoimia, joilla tauti tukehtuu.

Jossain määrin tulee fiilis, että epidemiologisissa malleissa on paras käytettävissä oleva tieto, joten niitä ei pidä ylenkatsoa. Toisaalta tuntuu, ettei paras käytettävissä oleva tieto ole toistaiseksi järin eksaktia. Virus ja ihmiset ei kulje yhtä täsmällisesti kuin planeetat radoillaan.

Selkein tulos lienee, että kannattaa sekä rajoittaa että testata ja jäljittää. Miten ja kuinka paljon riippuu monesta sellaisesta seikasta, joista malli ei tiedä mitään. Eikä mikään eikä kukaan muukaan. Myöhemmin ollaan viisaampia. Jälkeenpäin muistamme vain ne väitteemme, jotka sattuivat tuurilla osumaan oikeaan.

Toimittajilta toivoisi klikkiotsikoiden revittelyn sijaan yritystä ymmärtää ongelmaa – holistisesti – ja yritystä auttaa ihmisiä ymmärtämään. Useimmilla toimittajista tuntuu olevan syyttäjän ja rikostutkijan vaisto. Rasittavimmat ovat 'nippelikyyliä' ja epäonnistuneiden sanavalintojen metsästäjiä. Tarpeellista sekin joskus, mutta välillä olisi hyvä kokeilla jotain rakentavampaa toimintamoodia. Osa toimittajista senkin osaa.

Muutenkin, kaikki jotka vaativat saada kuulla täsmällisen strategian hallitukselta, voisivat ehdotella kunnolla mietittyjä toimenpiteitä ja strategioita.

(Muistutus todellisuuden monimutkaisuudesta: Seuraava juttu tuossa artikkelipankissa on: The socio-economic determinants of the coronavirus disease (COVID-19) pandemic) (en ehtinyt lukea)

EDIT (vartti jutun julkaisemisen jälkeen ;-) Jutun kirjoitettuani luin hesarin tiedejutun taudin leviämisestä Siinä oli pikkuin erisuuntaisia, mutta järkevän kuuloisia näkemyksiä ja tulkintoja. Onnellisia kaiken varmaksi tietävät. En kuitenkaan toivo ketään sellaista tekemään tärkeitä päätöksiä.


/ Heikin pohteita/ Ohjelmointia, matematiikkaa, fysiikkaa … Simulaatioita / Muiden tekemiä esimerkkejä

 

Muiden tekemiä esimerkkejä

En ole ainoa, jonka mielestä olisi syytä lähentää matematiikan, fysiikan ja ohjelmoinnin opetusta. Oma harrastukseni lähtee puhtaasti siitä, mikä minua kiinnostaa ja se on toisinaan kaukana ainakin kouluopetuksen realiteeteista. Laitan tähän linkkejä sitä mukaa, kun tulee vastaan muiden harrastajien sivuja.

Tammikuu 2021

Kari Peisa, simulaatioita vpythonilla