-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevaluate_gradient.py
More file actions
130 lines (100 loc) · 5.11 KB
/
Copy pathevaluate_gradient.py
File metadata and controls
130 lines (100 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import os
import sys
import numpy as np
import rayvis
from matplotlib import pyplot as plt
from matplotlib.gridspec import GridSpec
from mpl_toolkits.axes_grid1 import make_axes_locatable
import yaml
import scipy.optimize as optimize
def calc_max_norm(field, analytic, h):
error = field - analytic
return max(error.norm()) / max(analytic.norm())
def calc_l2_norm(field, analytic, h):
error = field - analytic
return np.sqrt(np.sum(error.norm() ** 2)) / np.sqrt(np.sum(analytic.norm() ** 2))
def load_vector_fields(file_names):
for file_name in file_names:
with open(file_name, "rb") as f:
yield rayvis.read_vector_field(f)
def calc_norms(vector_fields, analytic_vector_fields, norm_func):
for (vector_field, analytic_vector_field) in zip(vector_fields, analytic_vector_fields):
yield norm_func(vector_field, analytic_vector_field, 1.0 / (len(vector_field.coord_x) - 1))
def plot_grad_summary(fig, dual_mesh, grid_function, gradient, analytic):
gs = GridSpec(nrows=2, ncols=2, width_ratios=[1, 1], height_ratios=[1, 1])
fun_axes = fig.add_subplot(gs[0, 0])
grad_axes = fig.add_subplot(gs[1, 0])
analytic_axes = fig.add_subplot(gs[0, 1])
diff_axes = fig.add_subplot(gs[1, 1])
contour = rayvis.plot_vector_field(grad_axes, gradient, dual_mesh)
fig.colorbar(contour, cax=make_axes_locatable(grad_axes).append_axes("right", size="5%", pad=0.05))
contour = rayvis.plot_grid_function(fun_axes, grid_function)
fig.colorbar(contour, cax=make_axes_locatable(fun_axes).append_axes("right", size="5%", pad=0.05))
error = gradient - analytic
grad_norm = np.asarray(2 * [gradient.norm()])
contour = rayvis.plot_vector_field(diff_axes, error, dual_mesh)
fig.colorbar(contour, cax=make_axes_locatable(diff_axes).append_axes("right", size="5%", pad=0.05))
contour = rayvis.plot_vector_field(analytic_axes, analytic, dual_mesh)
analytic_axes.set_xlabel("analytic")
fig.colorbar(contour, cax=make_axes_locatable(analytic_axes).append_axes("right", size="5%", pad=0.05))
def load_config(filename):
with open(filename, 'r') as stream:
try:
return yaml.safe_load(stream)
except yaml.YAMLError as exc:
print(exc)
def main(folder, config_name="config.yaml"):
path = os.path.join(folder, "output/grad{}_{}.msgpack")
analytic_path = os.path.join(folder, "output/analytic_grad{}_{}.msgpack")
config = load_config(os.path.join(folder, "input", config_name))
segments_count = [int(count) for count in config["meshes"]["segments"]]
factors = config["meshes"]["random_factors"]
conv_fig, conv_axes = plt.subplots()
displacement_from0 = []
for factor in factors:
file_names = [path.format(count, factor) for count in segments_count]
analytic_file_names = [analytic_path.format(count, factor) for count in segments_count]
vector_fields = list(load_vector_fields(file_names))
analytic_vector_fields = list(load_vector_fields(analytic_file_names))
norms = list(calc_norms(vector_fields, analytic_vector_fields, calc_l2_norm))
try:
def fit_func(h, a):
return a * h ** -2
popt, pcov = optimize.curve_fit(fit_func, segments_count, norms, p0=[14.])
except RuntimeError as e:
def fit_func(h, a):
return a * np.ones(len(h))
popt, pcov = optimize.curve_fit(fit_func, segments_count, norms, p0=[1.])
line, = conv_axes.loglog(segments_count, norms, "o", label="$f$ = {}".format(factor))
x = np.linspace(min(segments_count), max(segments_count), 100)
conv_axes.loglog(x, fit_func(x, *popt), color=line.get_color())
for segments, vector_field, analytic_vector_field in zip(segments_count, vector_fields, analytic_vector_fields):
if segments > 30:
continue
fig = plt.figure(figsize=(10, 5), dpi=150)
with open(os.path.join(folder, "output/mesh{}_{}.mfem".format(segments, factor))) as f:
mesh = rayvis.read_mfem_mesh(f)
with open(os.path.join(folder, "output/dual_mesh{}_{}.mfem".format(segments, factor))) as f:
dual_mesh = rayvis.read_mfem_mesh(f)
with open(os.path.join(folder, "output/func{}_{}.gf".format(segments, factor))) as f:
gf = rayvis.read_grid_function(f, mesh)
plot_grad_summary(fig, dual_mesh, gf, vector_field, analytic_vector_field)
plt.savefig(os.path.join(folder, "output/summary{}_{}.png".format(segments, factor)))
conv_axes.legend()
conv_fig.savefig(os.path.join(folder, "output/conv.png"))
"""
conv_error_fig, conv_error_axes = plt.subplots()
conv_error_axes.plot(factors, displacement_from0, "o")
conv_error_axes.grid()
conv_error_axes.set_xlabel("factor")
conv_error_axes.set_ylabel("$b$")
conv_error_fig.savefig(os.path.join(folder, "output/conv_error.png"))
"""
if __name__ == '__main__':
args = list(sys.argv)
if len(args) == 2:
main(sys.argv[1])
elif len(sys.argv) == 3:
main(sys.argv[1], sys.argv[2])
else:
print("Invalid args")