-
Hörl, Maximilian authoredHörl, Maximilian authored
mmdgAnalysis.py 5.36 KiB
import numpy as np
from os import mkdir, remove, system
from os.path import join, exists
from subprocess import call
from math import log
# changes the parameter file such that gridfile is used
def writeINI(gridfile):
# storage for file content
lines = None
# new line to write
newline = "gridfile = " + gridfile
# indicates whether the parameter gridfile already exists
hasGridlineParameter = False
# read file content and replace gridfile parameter if existent
with open("parameterMMDG.ini", "r") as file:
lines = file.read().splitlines()
for i in range(len(lines)):
if (lines[i].startswith("gridfile")):
lines[i] = newline
hasGridlineParameter = True
break
# add parameter gridfile if not already existent
if (not hasGridlineParameter):
lines.append(newline)
# write parameters to file
with open("parameterMMDG.ini", "w") as file:
file.write("\n".join(lines))
# reads error, run time and maximum edge length, i.e. the output from the
# excuted discontinuous Galerkin scheme
def readData():
file = open("convergenceData", "r")
# read data
errorBulk = float(file.readline())
errorInterface = float(file.readline())
errorTotal = float(file.readline())
hMax = float(file.readline())
hMaxInterface = float(file.readline())
timeTotal = float(file.readline())
file.close()
# return data
return np.array([errorBulk, errorInterface, errorTotal, hMax, \
hMaxInterface, timeTotal])
# determines the problem type and the parameter "fastEOC" from the ini file
def getProblemType ():
# storage for problem type (1 to 6)
problemType = None
# boolean that determines whether to exclude computationally expensive grids
fastEOC = False
# read file content and get problem type
with open("parameterMMDG.ini", "r") as file:
lines = file.read().splitlines()
for i in range(len(lines)):
if (lines[i].startswith("problem")):
problemType = int(lines[i].rstrip()[-1])
elif (lines[i].startswith("fastEOC") and \
lines[i].rstrip().lower().endswith("true")):
fastEOC = True
return problemType, fastEOC
# determines experimental order of convergence (EOC),
# data is assumed to be a numpy array with
# first column: error,
# second column: maximum edge length
def EOCloop (data):
EOC = np.empty(data.shape[0] - 1)
for i in range(len(EOC)):
if data[i, 0] != 0:
EOC[i] = log(data[i, 0] / data[i+1, 0]) / \
log(data[i, 1] / data[i+1, 1])
else:
EOC[i] = -1.0 * float('inf')
# end for i
return EOC
# === main ===
# create directory for the plots if necessary
if not exists("plots"):
mkdir("plots")
# number of runs from which the run times are taken as mean value
numberOfMeans = 1
# names of the grid files sorted by refinement
# 2d characteristic lengths: np.reciprocal(np.logspace(0,2.7,12))
# 3d characteristic lengths: np.reciprocal(np.logspace(0,1.55,7))
gridfiles_2d = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"]
gridfiles_3d = ["A", "B", "C", "D", "E", "F", "G"]
# get problem type (integer from 1 to 6) from ini file
problemType, fastEOC = getProblemType()
if problemType in [1, 4, 6, 7]: # these problems use the same grids
problemType = 2
if fastEOC: # exclude computationally expensive grids
gridfiles_2d = gridfiles_2d[:-3]
gridfiles_3d = gridfiles_3d[:-2]
else:
print("fastEOC = false. This may take some minutes.\n")
gridfiles_2d = ["mmdg" + str(problemType) + "_" + s for s in gridfiles_2d]
gridfiles_3d = ["mmdg" + str(problemType) + "_" + s for s in gridfiles_3d]
for dim in [2, 3]:
gridfiles = gridfiles_2d if (dim == 2) else gridfiles_3d
# storage for errors, run times and largestEdgeLength
# column 0: bulk error
# column 1: interface error
# column 2: total error
# column 3: maximum edge length (bulk)
# column 4: maximum edge length (interface)
# column 5: total run time
# different rows correspond to different numbers of grid elements
data = np.zeros((len(gridfiles), 6))
for i in range(len(gridfiles)):
# write dgf file
writeINI(gridfiles[i])
# take mean value over numberOfMeans runs
for j in range(numberOfMeans):
# run executable
call(join(".", "mmdg-" + str(dim) + "d"))
# store data
data[i, :] += readData()
# end for j
# end for i
# divide by numberOfMeans
data /= numberOfMeans
# determine experimental order of convergence (EOC)
EOCbulk = EOCloop(data[:, [0,3]])
EOCinterface = EOCloop(data[:, [1,4]])
EOCtotal = \
EOCloop(np.column_stack([data[:,2], np.maximum(data[:,3], data[:,4])]))
# print EOCs
print("\n-------------------------------------------------------------\n")
print("EOCs (" + str(dim) + "d):")
print("\nbulk:")
print(EOCbulk)
print("\ninterface:")
print(EOCinterface)
print("\ntotal:")
print(EOCtotal)
print("\n=============================================================\n\n")
# write data to file
np.savetxt(join("plots", "mmdgAnalysis_" + str(dim) + "d"), data)
np.savetxt(join("plots", "mmdgEOC_" + str(dim) + "d"), EOCtotal)
# end for dim
# remove output files
remove("convergenceData")