Python Numpy Array Verlauf loggen mit CSV

Tenferenzu

Banned
Registriert
Okt. 2017
Beiträge
6.473
Hi, ich benötige euer Schwarmwissen weil ich hier nicht wirklich weiterkomme.

Ich möchte den Verlauf einer Iteration in einem CSV loggen damit ich nachvollziehen kann bis wohin die Iteration stabil läuft und was der Parameter ist der dann zur Instabilität führt nur leider schaffe ich es nicht wirklich das numpy array 'richtig' in das CSV als Zeile anzuhängen(!).

Hat jemand vlt. eine Idee? Die ganzen Stackoverflowlösungen habe ich schon durch und irgendwie hat mein Problem noch keiner wirklich gehabt also vermute ich mal, dass es an meiner Methodik liegt und es eine viel leichtere Methode gibt um mein Problem zu lösen die ich gerade nicht finde..
P.s. Ich bin kein Programmierer ;) Die ganzen 'Fehlversuche' sind auskommentiert damit ihr einen Überblick darüber habt was ich schon versucht habe.

Ich hoffe es ist so halbwegs verständlich was mein Problem ist.

Python:
import numpy
from matplotlib import pyplot
import csv
import pandas

uncsv = open('un.csv', 'a', newline='')

def linearconv(nx):
    # nx = 41    # set plausible values. Too high - over/undershoot. Too low - asym
    dx = 2 / (nx-1)
    nt = 2000    # number of timesteps
    dt = .00025  # amount of time each timestep covers (delta t)
    c = 1      # assume wavespeed of c = 1 or one full 'unit' of convection
    c2 = 0.5
    # sigma = 0.5  # enforces the Courant Number and automatically sets the discretisation
    nu = 0.5
    # dt = sigma * dx

    u = numpy.ones(nx)    
    u[int(.5 / dx):int(1 / dx + 1)] = 2  # Initial condition
    print(u)
   
    un = numpy.ones(nx)  # initialize a temporary array
   
    for n in range(nt):  # loop for values of n from 0 to nt, so it will run nt times
        un = u.copy()  # copy the existing values of u into un
        print(un)
        # with open('un.csv', 'a', newline='') as uncsv:
        # writer = csv.writer (uncsv, delimiter=',')
        # for x in numpy.nditer(un.T, order='C'):
        #     row.append(str(u))
        #     writer.writerow(row)
        # DF = pandas.DataFrame(un)
        # DF.to_csv("unpandas.csv", mode='a')
        # uncsv.write(un)
        numpy.savetxt('savetext.csv', un, delimiter=',')
        # numpy.savetxt('un', un.reshape(1, -1), delimiter=',',newline='\n')  # überschreibt die Datei
        for i in range(1, nx):
        #for i in range(nx):
            # u[i] = un[i] - un[i] * dt / dx * (un[i] - un[i-1])  # non linear
            u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])  # linear
            # writer = csv.writer (uncsv, delimiter=',')
            # for x in numpy.nditer(u.T, order='C'):
            #     row.append(str(u))
            #     writer.writerow(row)
    # writer = csv.writer (uncsv, delimiter=',')
    # for x in numpy.nditer(u.T, order='C'):
    #     row.append(str(u))
    #     writer.writerow(row)
    pyplot.plot(numpy.linspace(0, 2, nx), u)

Der Code wäre angelehnt an dieses Projekt hier: https://github.com/barbagroup/CFDPython/blob/master/lessons/01_Step_1.ipynb

Bitte gebt mir etwas Zeit um zu Antworten da ich erstmal nach Hause und kochen muss :)
 
Hape etwas kopping und darum nicht mega ordentlich gelesen.

Wuerde das vermutlich mit Pandas machen, da deutlich einfacher zu handlen.

Python:
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd

def linearconv(nx):
    dx = 2 / (nx-1)
    nt = 2000    # number of timesteps
    dt = .00025  # amount of time each timestep covers (delta t)
    c = 1      # assume wavespeed of c = 1 or one full 'unit' of convection
    iterations = []  # To store the iterations

    u = np.ones(nx)    
    u[int(.5 / dx):int(1 / dx + 1)] = 2  # Initial condition

    for n in range(nt):  # loop for values of n from 0 to nt, so it will run nt times
        un = u.copy()  # copy the existing values of u into un
        iterations.append(un)
        for i in range(1, nx):
            u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])  # linear

    plt.plot(np.linspace(0, 2, nx), u)
    plt.show()

    return iterations

iterations = linearconv(41)

# Convert iterations to a DataFrame and save to CSV
df = pd.DataFrame(iterations)
df.to_csv('iterations.csv', index=False)


und mit der CSV Library:
Python:
import csv
import numpy as np
from matplotlib import pyplot as plt

def linearconv(nx):
    dx = 2 / (nx-1)
    nt = 2000    # number of timesteps
    dt = .00025  # amount of time each timestep covers (delta t)
    c = 1      # assume wavespeed of c = 1 or one full 'unit' of convection
    iterations = []  # To store the iterations

    u = np.ones(nx)    
    u[int(.5 / dx):int(1 / dx + 1)] = 2  # Initial condition

    for n in range(nt):  # loop for values of n from 0 to nt, so it will run nt times
        un = u.copy()  # copy the existing values of u into un
        iterations.append(un)
        for i in range(1, nx):
            u[i] = un[i] - c * dt / dx * (un[i] - un[i-1])  # linear

    plt.plot(np.linspace(0, 2, nx), u)
    plt.show()

    return iterations

iterations = linearconv(41)

with open('iterations.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerows(iterations)

gehts grob in die richtige richtung?
mit numpy.savetxt('savetext.csv', un, delimiter=',') apendest du halt nicht sondern ueberschreibst jedes mal

Edit: mal in die doku geschaut.
Probier mal:

Python:
with open('savetext.csv', 'ab') as f:
            np.savetxt(f, un.reshape(1, -1), delimiter=',')
 
Zuletzt bearbeitet:
Im Sinne von sobald eine Iteration durch ist wir direkt appended und nicht erst nachdem alle Iterationen fertig sind.

Warum? Damit ich das auch mal über Nach laufen lassen und am Morgen, vor erreichen von x Iterationen/Zeitschritten, schonmal einen Blick auf die Ergebnisse werfen kann :)

Edit: Das soll nämlich deutlich mehr als eine einzige Funktion werden. Ich habe hier einige Systemgleichungen die ich numerisch implementieren und anschließend nacheinander lösen und in unterschiedliche Files appenden will.. So zumindest der Plan. ;)
 
Zuletzt bearbeitet:
Du kannst den writer in die for-Schleife in linearconv setzen. Also Zeile 17 bei madmax. Und dann einfach beim Öffnen statt 'w' für write ein 'a' für append verwenden.
Am besten die Datei einmal öffnen, jede Iteration reinschreiben und erst danach schließen.
 
  • Gefällt mir
Reaktionen: madmax2010
Zurück
Oben