Pythonskole

Newtons avkjølingslov

I dette forsøket skal vi undersøke Newtons avkjølingslov, ved å gjennomføre en måleserie som viser hvordan temperaturen endres i et objekt som kjøles ned i forhold til omgivelsene. Forsøket kan enten gjøres ved at man varmer opp en temperatursensor, og lar denne avkjøle, eller ved at man setter sensoren i noe varmt (f.eks. en kaffekopp). Etterpå skal vi lese innsamlede data inn i Python, og sammenligne data med teorien på to måter.  

Innholdsfortegnelse

Målingene

Forsøket kan enten gjøres ved at man varmer opp en temperatursensor, og lar denne avkjøle, eller ved at man setter sensoren i noe varmt (f.eks. en kaffekopp).

Temperaturdata hentes inn ved hjelp av tilgjengelig måleutstyr og lagres som funksjon av tid. Vi har brukt PASCO sin trådløse temperatursensor og eksportert data fra CapStone. Dette kan også gjøres manuelt om dataene skrives inn i et regneark og eksporteres som .csv-filer. 

Etter å ha gjennomført målingene og lagret dataene (i SPARKvue eller Capstone hvis du bruker PASCO sin temperatursensor), trekker vi fra rom-temperaturen i alle dataene, slik at temperaturen går mot 0 𝐶. Vi laster deretter inn dataene i Python, hvor vi analyserer dataene videre og sammenligner med teorien for dette forsøket.

Teorien

Når vi skal sammenligne målingene som er gjort med teori, bruker vi Newtons avkjølingslov. Denne forteller oss at nedkjølingen er proporsjonal med differensen  i temperaturen i koppen T og i rommet T0 («T-null»). Konstanten k kalles varmekoeffisienten og beskriver hvor raskt en gass eller væske kan endre sin temperatur. Vi ønsker å sammenligne begge disse likningene, eksponentiallikningen og differensiallikningen, med de målingene vi har gjort av temperaturen av den varme væsken.

Forbered koden

Det meste av programmering i Python baserer seg på bruk av eksisterende biblioteker (kode andre har skrevet for deg). Her importerer vi alle funksjonene (*) fra biblioteket pylab

				
					from pylab import *
				
			

Les data

Dataene, som er lagret i en tekstfil (.csv- eller .txt-format) lastes inn i Python som lister / eller arrays. Slike lister er nyttige, siden de inngå i enkle regneoppgaver, hvor du gjør regneoperasjonen på alle elementene i listen, fremfor ett og ett element av gangen. 

Her leses hver enkelt linje av datafilen og verdiene i 2. og 3.kolonne lagres som hhv. tid og temperatur. Når dataene lagres, lagres to kopier av temperaturen. Én slik temperatursensoren målte den, og én hvor romtemperaturen er trukket fra. 

				
					# Lister for lagring av data
tid_data = []
temp_data = []
temp_reg_data = []

# Innlesing av data
with open('avkjoling.csv') as file: # Åpner datafilen
    next(file) # Hopper over overskrift-linjen

    # Løkke som leser hver linje i datafilen.
    for line in file:
        # Klargjør data for lagring i lister
        line = line.replace(",",".") # Bytter desimaltegn
        line = line.replace("\n","") # Fjerner linjeskift
        line = line.split(";") #Del linjen i elementer

        # Konverterer fra tekst til tall og lagrer
        tid_data.append(float(line[1]))    #Tid
        temp_data.append(float(line[2]))   #Temperatur

        #Lagrer en kopi av temperatur minus romtemp.
        temp_reg_data.append(float(line[2]) - temp_rom)
				
			

Data-filen som er brukt i dette eksempelet kan lastes ned fra denne siden (se lenger ned). Dersom du ønsker å lage din egne data-filer, kan det gjøres i excel, f.eks. som vist til høyre. Du står fritt til å velge hva tittel/overskrift til kolonnene skal være helt selv. 

Regresjon

Biblioteket Pylab har en innebygget funksjon for regresjon av  polynomer, men dessverre ikke for eksponensial-funksjoner. Fremfor å laste inn flere biblioteker, beregner vi heller logaritmen av temperaturen og bruker en lineær regresjon av de logaritmiske dataene med polyfit

Etter å ha beregnet koeffisientene a og b i uttrykket y=ax+b, regner vi ut en beste tilpasning av en eksponensial-funksjon exp(y). Dette gir oss verdier som skal være direkte sammenlignbare med målte data, men hvor vi på grunn av omveien via logaritmen, forventer avvik i begynnelsen av datasettet hvor temperatur-kurven er brattest. 

				
					#Finn logaritmen av temperaturdataene
logaritmisk_temp = log(temp_reg_data)

# Gjennomfør en lineær regresjon med
# den innebygde funksjonen 'polyfit'
a,b = polyfit(tid_data,logaritmisk_temp,1)
temp_reg = [] # Her skal vi lagre regresjonen

# Løp gjennom alle verdiene i tid
for t_verdi in tid_data:

    #Beregn temperaturen fra regresjonen
    temp = exp(a*t_verdi + b)

    #Lagre verdien i listen
    temp_reg.append(temp + temp_rom)
				
			

Simulering

Newtons avkjølingslov kan også simuleres direkte fra sin differensialform. Dette gjøres ved å skrive inn likningen for den deriverte i en diskret form, med endelige størrelser for endring i temperatur (delta T) for en gitt endring i tid (delta t).

Som med alle andre simuleringer, må vi selv velge/sette initialbetingelsene. Siden vi skriver denne simuleringen i samme kode som der vi leser de målte dataene, setter vi intialverdiene for tid og temperatur lik de vi har i forsøket. Vi velger oss en størrelse på steglengden i tid, og sier at når den har simulert like lenge som målingene ble tatt, så kan vi stanse simuleringen. 

Resultatet av dette blir lagret i en liste som vi kan direkte sammenligne med målte data, hvor vi ikke forventer store avvik fra eksperimentet. Prøv allikevel å lek deg med ulike verdier for tids-steglengden, siden den kan ha store utslag for resultatet. 

				
					# Startverdier i simuleringen i tid og temperatur settes lik målte verdier
tid = tid_data[0] 
temp = temp_data[0]

# Simuleringsteknisk
dt = 0.001 # Lengde på tidssteg (sekunder)
tid_slutt = tid_data[-1] # Sluttid settes lik siste tid i målte data 
tid_sim = [tid] # Liste for lagring av tid
temp_sim = [temp] # Liste for lagring av temperatur

# Løkke som beregner ny temperatur og tid
while tid < tid_slutt:
    temp = temp - k*(temp-temp_rom)*dt
    tid = tid + dt

    temp_sim.append(temp)
    tid_sim.append(tid)
				
			

Plotting

Helt til sist plotter vi de målte temperaturdataene (temp_data, som punkter), kurvetilpasningen (temp_reg) og resultatet av simuleringer over (temp_sim) sammen i ett vindu. Vi setter merkelapper på aksene, og lager en legende (en tekstboks i graf-området med forklaring på hva som er vist). 

				
					plot(tid_data,temp_data,".")    # Plotter data som punkter
plot(tid_data,temp_reg)         # Plotter regresjonsgraf
plot(tid_sim,temp_sim)          # Plotter simulerte data
title("Newtons avkjølingslov, data, regresjon og simulering")
xlabel("Tid / s")               # x-akse tittel
ylabel("Temperatur / Celcius")  # y-akse tittel
legend(["Data","Regresjon","Simulering"]) # navngivning av punkter og grafer
grid()   # Tegner rutenett
show()   # Vis plottet
				
			

Vi ser at etter ca. 100 sekunder, er det god overenstemmelse mellom de tre tilnærmingene. Det største avviket ser vi er mellom regresjonen og målte data før t=50 sekunder, som vi forventet siden vi gjorde regresjonen etter å ha beregnet logaritmen av temperaturen. 

Last ned

Hele koden kan også leses/lastes ned her:

				
					# PYTHON & PASCO: Newtons avkjølingsmetode
# Versjon: 6.10.2021
# Kontakt: post@pythonskole.no
from pylab import *

# -------------------- Verdier for simulering og regresjon ---------------------
# k har mye å si for simuleringen
# temp_rom hvor fort temperaturendringen skjer.
k = 0.01              # Avkjølingskonstant i s^(-1)
temp_rom = 23.0       # Temperatur i rommet i grader C.

# Modell for temperaturendring.
def temp_endring(temp):          # Funksjon som regner temperaturendringen
    endring = -k*(temp-temp_rom) # Endring proporsjonal med temp-forskjell
    return endring               # Returnerer endringen.

# --------------------------- Importering av data ------------------------------
# Lister for lagring av data
tid_data = []
temp_data = []
temp_reg_data = []
# Innlesing av data
with open('avkjoling.csv') as file:       # Åpner datafilen fra PASCO
    next(file)      # Hopper over overskrift-linjen
    # Løkke over hver linje i datafilen. Linjer leses som tekst/streng.
    for line in file:
        # Klargjør data for lagring i lister
        line = line.replace(",",".")      # Bytter desimaltegn
        line = line.replace("\n","")      # Fjerner uønskede linjeskift
        line = line.split(";")            # Splitter streng til liste
        # Tallene i lista står som tekst, konverterer til tall og lagrer
        tid_data.append(float(line[1]))   # Tidsdata lagres i egen liste
        temp_data.append(float(line[2]))  # Temperaturdata lagres i liste
        temp_reg_data.append(float(line[2]) - temp_rom)

# --------------------------- Regresjon på data --------------------------------
# Kurvetilpasning med polyfit(x,y,polynomgrad)
# Vi bruker at en eksponensiell modell er lineær med logaritmisk skala.
# Vi korrigerer for romtemperaturen slik at regresjonen fungerer
logaritmisk_temp = log(temp_reg_data)       # Andreaksen gjøres logaritmisk
a,b = polyfit(tid_data,logaritmisk_temp,1)  # Lineær regresjon på log-data
temp_reg = []                             # Liste for y-verdiene fra regresjon
for t_verdi in tid_data:                  # Løkke over tidspunkter i data
    temp = exp(a*t_verdi + b)             # Kalkulerer temperatur i et tidspunkt
    temp_reg.append(temp + temp_rom)      # Lagrer temperatur med romtemperatur

# -------------------------- Simulering av data --------------------------------
# Startverdier
tid = tid_data[0]       # Starttid settes til første tidsverdi i data
temp = temp_data[0]     # Starttemperatur settes til første temperatur i data

# Simuleringsteknisk
dt = 0.001            # Lengde på tidssteg, s
tid_slutt = tid_data[-1]    # Sluttid for simulering er siste tidsdata
tid_sim = [tid]       # Liste for lagring av tid
temp_sim = [temp]     # Liste for lagring av temperatur

# Løkke som beregner ny temperatur og tid
while tid < tid_slutt:
    temp = temp + temp_endring(temp)*dt
    tid = tid + dt

    temp_sim.append(temp)
    tid_sim.append(tid)
# ------------------------ Plotting av resultater ------------------------------
# Data fra PASCO plottes som punkter, regresjon og modell som grafer
plot(tid_data,temp_data,".")    # Plotter data som punkter
plot(tid_data,temp_reg)         # Plotter regresjonsgraf
plot(tid_sim,temp_sim)          # Plotter simulerte data
title("Newtons avkjølingslov, data, regresjon og simulering")
xlabel("Tid / s")               # x-akse tittel
ylabel("Temperatur / Celcius")  # y-akse tittel
legend(["Data","Regresjon","Simulering"]) # navngivning av punkter og grafer
grid()   # Tegner rutenett
show()   # Vis plot
				
			

Takk for din bestilling!

Vi kontakter deg så snart vi har lest din bestilling. Om du er på jakt etter inspirasjon til hva det kurset du ønsker skal handle om, kan du se vår YouTube-kanal.

Om du blir utålmodig eller har travelt med å få bekreftet din bestilling, kontakt oss på 93024034 eller kontakt@pythonskole.no.

Vennlig hilsen Vegard & Co