Fix issues with limited numerical precision and artifacts with big N.
This commit is contained in:
@@ -43,11 +43,11 @@ int main(int argc, char* argv[]){
|
||||
// Output the solution
|
||||
string filename = "numerical_solution_" + to_string(N) + ".csv";
|
||||
ofstream ofs(filename);
|
||||
ofs << "x,u(x)" << endl;
|
||||
ofs << "x,v(x),u(x)" << endl;
|
||||
for (int i = 0; i <= N; i++) {
|
||||
ofs << fixed << setprecision(decimal_places) << scientific << x[i] << "," << solution[i] << endl;
|
||||
}
|
||||
ofs.close();
|
||||
ofs << fixed << setprecision(decimal_places) << scientific << x[i] << "," << solution[i] << "," << u[i] << endl;
|
||||
}
|
||||
ofs.close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,43 @@ args = parser.parse_args()
|
||||
FILENAME = args.filename
|
||||
REFERENCE = args.reference
|
||||
|
||||
def get_rc_params():
|
||||
colors = ["FF220C", "70D6FF", "8AAA79", "666370", "1C1F33"]
|
||||
rcParams = plt.rcParams
|
||||
# Use LaTeX for rendering
|
||||
# Setup fonts
|
||||
rcParams["text.usetex"] = True
|
||||
rcParams["font.family"] = "serif"
|
||||
rcParams["font.size"] = 12
|
||||
rcParams["axes.labelsize"] = 12
|
||||
rcParams["axes.titlesize"] = 12
|
||||
rcParams["legend.fontsize"] = 10
|
||||
rcParams["xtick.labelsize"] = 10
|
||||
rcParams["ytick.labelsize"] = 10
|
||||
# Figure size and resolution
|
||||
rcParams["figure.figsize"] = (6, 4)
|
||||
rcParams["figure.dpi"] = 300
|
||||
# Use colors from the palette
|
||||
rcParams["axes.prop_cycle"] = plt.cycler(color=[f"#{color}" for color in colors])
|
||||
# Grid
|
||||
rcParams["axes.grid"] = True
|
||||
rcParams["grid.alpha"] = 0.5
|
||||
rcParams["grid.linestyle"] = "--"
|
||||
# Point ticks to the inside of the axes
|
||||
rcParams["xtick.direction"] = "in"
|
||||
rcParams["ytick.direction"] = "in"
|
||||
rcParams["xtick.top"] = True
|
||||
rcParams["ytick.right"] = True
|
||||
return rcParams
|
||||
|
||||
|
||||
def singular_plot():
|
||||
plt.rcParams.update(get_rc_params())
|
||||
df = pd.read_csv(FILENAME)
|
||||
fig, ax = plt.subplots(figsize=(6,3))
|
||||
ax.plot(df["x"], df["u(x)"])
|
||||
ax.plot(df["x"], df[df.columns[1]])
|
||||
ax.set_xlabel(r"$x$")
|
||||
ax.set_ylabel(r"$u(x)$")
|
||||
ax.set_ylabel(rf"${df.columns[1]}$")
|
||||
|
||||
fig.tight_layout()
|
||||
|
||||
@@ -27,22 +58,21 @@ def singular_plot():
|
||||
fig.savefig(os.path.join(output_directory, output_file))
|
||||
|
||||
def reference_plot():
|
||||
plt.rcParams.update(get_rc_params())
|
||||
df = pd.read_csv(FILENAME).sort_values("x")
|
||||
df_ref = pd.read_csv(REFERENCE).sort_values("x")
|
||||
|
||||
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True, height_ratios=[3, 1], figsize=(4, 8))
|
||||
ax1.plot(df["x"], df["u(x)"], label="Numerical Solution")
|
||||
ax1.plot(df_ref["x"], df_ref["u(x)"], label="Reference Solution", linestyle="--")
|
||||
ax1.plot(df["x"], df["v(x)"], label="Numerical Solution")
|
||||
ax1.plot(df["x"], df["u(x)"], label="Reference Solution", linestyle="--")
|
||||
ax1.set_xlabel(r"$x$")
|
||||
ax1.set_ylabel(r"$u(x)$")
|
||||
ax1.legend()
|
||||
|
||||
combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
ratio = (combined_df["u(x)_num"] - combined_df["u(x)_ref"]) / combined_df["u(x)_ref"]
|
||||
ratio = (df["v(x)"] - df["u(x)"]) / df["u(x)"]
|
||||
|
||||
ax2.plot(combined_df["x"], ratio.abs())
|
||||
ax2.plot(df["x"], ratio.abs())
|
||||
ax2.set_xlabel(r"$x$")
|
||||
ax2.set_ylabel(r"$|\frac{u(x)_{num} - u(x)_{ref}}{u(x)_{ref}}|$")
|
||||
ax2.set_ylabel(r"$|\frac{v(x) - u(x)}{u(x)}|$")
|
||||
ax2.axhline(y=1, color="gray", linestyle="--")
|
||||
ax2.set_yscale("log")
|
||||
|
||||
@@ -53,30 +83,29 @@ def reference_plot():
|
||||
fig.savefig(os.path.join(output_directory, output_file))
|
||||
|
||||
def multiple_reference_plot():
|
||||
plt.rcParams.update(get_rc_params())
|
||||
# Filename is wildcard -> Find files
|
||||
import glob
|
||||
files = glob.glob(FILENAME)
|
||||
files.sort()
|
||||
fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True, height_ratios=[3, 1], figsize=(6,5))
|
||||
df_ref = pd.read_csv(REFERENCE).sort_values("x")
|
||||
|
||||
|
||||
for file in files:
|
||||
df = pd.read_csv(file).sort_values("x")
|
||||
label = f"Num. (N = {os.path.basename(file).replace(".csv", "").split("_")[-1]})"
|
||||
ax1.plot(df["x"], df["u(x)"], label=label)
|
||||
ax1.plot(df["x"], df["v(x)"], label=label)
|
||||
|
||||
combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
ratio = (combined_df["u(x)_num"] - combined_df["u(x)_ref"]) / combined_df["u(x)_ref"]
|
||||
ax2.plot(combined_df["x"], ratio.abs(), label=label)
|
||||
|
||||
ax1.plot(df_ref["x"], df_ref["u(x)"], label="Reference Solution", linestyle="--", color="gray")
|
||||
ratio = (df["v(x)"] - df["u(x)"]) / df["u(x)"]
|
||||
ax2.plot(df["x"], ratio.abs(), label=label)
|
||||
|
||||
ax1.plot(df["x"], df["u(x)"], label="Reference Solution", linestyle="--", color="gray")
|
||||
ax1.set_xlabel(r"$x$")
|
||||
ax1.set_ylabel(r"$u(x)$")
|
||||
ax1.legend()
|
||||
ax2.axhline(y=1, color="gray", linestyle="--")
|
||||
ax2.set_xlabel(r"$x$")
|
||||
ax2.set_ylabel(r"$|\frac{u(x)_{num} - u(x)_{ref}}{u(x)_{ref}}|$")
|
||||
ax2.set_ylabel(r"$|\frac{v(x) - u(x)}{u(x)}|$")
|
||||
ax2.set_yscale("log")
|
||||
|
||||
fig.tight_layout()
|
||||
@@ -92,6 +121,7 @@ def error_plots():
|
||||
|
||||
|
||||
def abs_error_plot():
|
||||
plt.rcParams.update(get_rc_params())
|
||||
import glob
|
||||
files = glob.glob(FILENAME)
|
||||
files.sort()
|
||||
@@ -101,12 +131,12 @@ def abs_error_plot():
|
||||
fig, ax = plt.subplots(figsize=(6,3))
|
||||
for file in files:
|
||||
df = pd.read_csv(file).sort_values("x")
|
||||
combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
log_abs_err = np.log10((combined_df["u(x)_num"] - combined_df["u(x)_ref"]).abs())
|
||||
ax.plot(combined_df["x"], log_abs_err, label=f"N={os.path.basename(file).replace('.csv','').split('_')[-1]}")
|
||||
# combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
log_abs_err = np.log10((df["u(x)"] - df["v(x)"]).abs())
|
||||
ax.plot(df["x"], log_abs_err, label=f"N={os.path.basename(file).replace('.csv','').split('_')[-1]}")
|
||||
|
||||
ax.set_xlabel(r"$x$")
|
||||
ax.set_ylabel(r"$\log_{10}(|u(x)_{num} - u(x)_{ref}|)$")
|
||||
ax.set_ylabel(r"$\log_{10}(|u(x) - v(x)|)$")
|
||||
ax.legend()
|
||||
|
||||
fig.tight_layout()
|
||||
@@ -117,6 +147,7 @@ def abs_error_plot():
|
||||
|
||||
|
||||
def rel_error_plot():
|
||||
plt.rcParams.update(get_rc_params())
|
||||
import glob
|
||||
files = glob.glob(FILENAME)
|
||||
files.sort()
|
||||
@@ -126,14 +157,14 @@ def rel_error_plot():
|
||||
fig, ax = plt.subplots(figsize=(6,3))
|
||||
for file in files:
|
||||
df = pd.read_csv(file).sort_values("x")
|
||||
combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
# combined_df = pd.merge_asof(df, df_ref, on="x", suffixes=("_num", "_ref"))
|
||||
# Drop rows where u(x)_ref is zero
|
||||
combined_df = combined_df[combined_df["u(x)_ref"].abs() > 1e-10]
|
||||
log_rel_err = np.log10((combined_df["u(x)_num"] - combined_df["u(x)_ref"]).abs() / combined_df["u(x)_ref"].abs())
|
||||
ax.plot(combined_df["x"], log_rel_err, label=f"N={os.path.basename(file).replace('.csv','').split('_')[-1]}")
|
||||
df = df[df["u(x)"] > 1e-10]
|
||||
log_rel_err = np.log10((df["u(x)"] - df["v(x)"]).abs() / df["u(x)"].abs())
|
||||
ax.plot(df["x"], log_rel_err, label=f"N={os.path.basename(file).replace('.csv','').split('_')[-1]}")
|
||||
|
||||
ax.set_xlabel(r"$x$")
|
||||
ax.set_ylabel(r"$\log_{10}(|\frac{u(x)_{num} - u(x)_{ref}}{u(x)_{ref}}|)$")
|
||||
ax.set_ylabel(r"$\log_{10}(|\frac{u(x) - v(x)}{u(x)}|)$")
|
||||
ax.legend()
|
||||
|
||||
fig.tight_layout()
|
||||
|
||||
@@ -4,10 +4,40 @@ import matplotlib.pyplot as plt
|
||||
import argparse
|
||||
import os
|
||||
|
||||
def get_rc_params():
|
||||
colors = ["FF220C", "70D6FF", "8AAA79", "666370", "1C1F33"]
|
||||
rcParams = plt.rcParams
|
||||
# Use LaTeX for rendering
|
||||
# Setup fonts
|
||||
rcParams["text.usetex"] = True
|
||||
rcParams["font.family"] = "serif"
|
||||
rcParams["font.size"] = 12
|
||||
rcParams["axes.labelsize"] = 12
|
||||
rcParams["axes.titlesize"] = 12
|
||||
rcParams["legend.fontsize"] = 10
|
||||
rcParams["xtick.labelsize"] = 10
|
||||
rcParams["ytick.labelsize"] = 10
|
||||
# Figure size and resolution
|
||||
rcParams["figure.figsize"] = (6, 4)
|
||||
rcParams["figure.dpi"] = 300
|
||||
# Use colors from the palette
|
||||
rcParams["axes.prop_cycle"] = plt.cycler(color=[f"#{color}" for color in colors])
|
||||
# Grid
|
||||
rcParams["axes.grid"] = True
|
||||
rcParams["grid.alpha"] = 0.5
|
||||
rcParams["grid.linestyle"] = "--"
|
||||
# Point ticks to the inside of the axes
|
||||
rcParams["xtick.direction"] = "in"
|
||||
rcParams["ytick.direction"] = "in"
|
||||
rcParams["xtick.top"] = True
|
||||
rcParams["ytick.right"] = True
|
||||
return rcParams
|
||||
|
||||
parser = argparse.ArgumentParser(description="Plot timing results from CSV file.")
|
||||
parser.add_argument("csv_file", help="Path to the CSV file containing timing results.")
|
||||
args = parser.parse_args()
|
||||
|
||||
plt.rcParams.update(get_rc_params())
|
||||
df = pd.read_csv(args.csv_file)
|
||||
for column in df.columns[1:]:
|
||||
df[column] = df[column] / df["N"] # Normalize by N
|
||||
|
||||
Reference in New Issue
Block a user