In [1]:
cd ~/projects/Okapi/tests/transfers/okapi-moose/pin_coupling/
In [2]:
import openmc
import matplotlib.pyplot as plt
%matplotlib inline
In [47]:
with openmc.StatePoint('statepoint.50.h5') as sp:
mesh_tally = sp.get_tally(id=2)
zernike_tally = sp.get_tally(id=1)
scores = ['kappa-fission', 'fission', 'flux']
mesh_tallies = [mesh_tally.get_slice(scores=[score]) for score in scores]
for tally in mesh_tallies:
tally.mean.shape = (100, 100)
for index, tally in enumerate(mesh_tallies):
fig = plt.subplot(131 + index)
fig.imshow(tally.mean)
In [48]:
import numpy as np
mesh_r = np.linspace(-60, 60, 100)
plt.plot(mesh_r, mesh_tallies[0].mean[50,:], label="kappa-fission")
plt.legend()
Out[48]:
In [49]:
plt.plot(mesh_r, mesh_tallies[1].mean[50,:], label="fission")
plt.legend()
Out[49]:
In [50]:
plt.plot(mesh_r, mesh_tallies[2].mean[50,:], label="flux")
plt.legend()
Out[50]:
In [43]:
with openmc.StatePoint('statepoint.20.h5') as sp:
mesh_tally = sp.get_tally(id=2)
zernike_tally = sp.get_tally(id=1)
scores = ['kappa-fission', 'fission', 'flux']
mesh_tallies = [mesh_tally.get_slice(scores=[score]) for score in scores]
for tally in mesh_tallies:
tally.mean.shape = (100, 100)
for index, tally in enumerate(mesh_tallies):
fig = plt.subplot(131 + index)
fig.imshow(tally.mean)
In [44]:
import numpy as np
mesh_r = np.linspace(-60, 60, 100)
plt.plot(mesh_r, mesh_tallies[0].mean[50,:], label="kappa-fission")
plt.legend()
Out[44]:
In [45]:
plt.plot(mesh_r, mesh_tallies[1].mean[50,:], label="fission")
plt.legend()
Out[45]:
In [46]:
plt.plot(mesh_r, mesh_tallies[2].mean[50,:], label="flux")
plt.legend()
Out[46]:
In [59]:
with openmc.StatePoint('statepoint.20.h5') as sp:
mesh_tally = sp.get_tally(id=2)
zernike_tally = sp.get_tally(id=1)
scores = ['kappa-fission', 'fission', 'flux', 'total']
mesh_tallies = [mesh_tally.get_slice(scores=[score]) for score in scores]
for tally in mesh_tallies:
tally.mean.shape = (100, 100)
for index, tally in enumerate(mesh_tallies):
fig = plt.subplot(101 + 10 * len(scores) + index)
fig.imshow(tally.mean)
In [60]:
import numpy as np
mesh_r = np.linspace(-60, 60, 100)
plt.plot(mesh_r, mesh_tallies[0].mean[50,:], label="kappa-fission")
plt.legend()
Out[60]:
In [61]:
plt.plot(mesh_r, mesh_tallies[1].mean[50,:], label="fission")
plt.legend()
Out[61]:
In [62]:
plt.plot(mesh_r, mesh_tallies[2].mean[50,:], label="flux")
plt.legend()
Out[62]:
In [63]:
plt.plot(mesh_r, mesh_tallies[3].mean[50,:], label="total")
plt.legend()
Out[63]:
The above calculations show that the tallies really are normalized to the number of source neutrons. This is done through the total_weight variable in tally_header.F90
In [56]:
mesh_tallies[0].num_realizations
Out[56]:
In [64]:
.01 * 10000
Out[64]:
In [65]:
zernike_fission = zernike_tally.get_slice(scores=['kappa-fission'])
zernike_flux = zernike_tally.get_slice(scores=['flux'])
In [66]:
from series.Zernike import Zernike
max_order = 10
zernike_list = [Zernike(order, 0, 0, 60) for order in range(max_order + 1)]
zernike_flux.mean.shape = (zernike_flux.mean.size)
for order in range(max_order + 1):
n = (order + 1) * (order + 2) // 2
zernike_list[order].coefficients = zernike_flux.mean[:n]
import numpy as np
r = np.linspace(0, 60, 100)
z_evals = [np.zeros((r.size)) for zernike in zernike_list]
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
for order, z in enumerate(z_evals):
if order % 2 == 0 and order <= 4:
plt.plot(r, z, label=str(order))
plt.legend()
Out[66]:
In [68]:
zernike_list[0].coefficients
Out[68]:
In [71]:
from math import pi
z_evals[0][0] * pi
Out[71]:
In [82]:
for z in z_evals:
print(np.trapz(z * r, r) / np.trapz(r, r) * pi)
Above we see the role of uncertainty beginning to set it
The first Zernike coefficient should match a tally with no filters.
In [78]:
np.trapz(z_evals[0] * r, r) / np.trapz(r, r) * pi
Out[78]:
In [79]:
np.trapz(z_evals[1] * r, r) / np.trapz(r, r) * pi
Out[79]:
In [80]:
np.trapz(z_evals[2] * r, r) / np.trapz(r, r) * pi
Out[80]:
In [81]:
np.trapz(z_evals[3] * r, r) / np.trapz(r, r) * pi
Out[81]:
In [54]:
from math import cos, pi
def sinusoid(r, phi, R=60):
return cos(pi * r / (2 * R))
for zernike in zernike_list:
zernike.generateCoefficients(sinusoid, num_rintervals=100, num_aintervals=10, normalization="standard")
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
for order, z in enumerate(z_evals):
if order == 10 or order == 9:
plt.plot(r, z, label=str(order))
true = np.zeros((r.size))
for index, radius in enumerate(r):
true[index] = sinusoid(radius, 0)
plt.plot(r, true, label='true')
plt.legend()
Out[54]:
In [55]:
from math import cos, pi
def sinusoid(r, phi, R=60):
return cos(pi * r / (2 * R))
for zernike in zernike_list:
zernike.generateCoefficients(sinusoid, num_rintervals=100, num_aintervals=20, normalization="standard")
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
for order, z in enumerate(z_evals):
if order == 10 or order == 9:
plt.plot(r, z, label=str(order))
true = np.zeros((r.size))
for index, radius in enumerate(r):
true[index] = sinusoid(radius, 0)
plt.plot(r, true, label='true')
plt.legend()
Out[55]:
In [14]:
def linear(r, phi):
return r
In [74]:
for index, zernike in enumerate(zernike_list):
if index >= 6:
zernike.generateCoefficients(linear, num_rintervals=10, num_aintervals=10,
normalization="standard")
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
if z_index >= 6:
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
for order, z in enumerate(z_evals):
if order % 2 == 0 and order > 6:
plt.plot(r, z, label=str(order))
plt.plot(r, r, label='true')
plt.legend()
Out[74]:
In [ ]:
for index, zernike in enumerate(zernike_list):
if index >= 6:
zernike.generateCoefficients(linear, num_rintervals=200, num_aintervals=200,
normalization="standard")
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
if z_index >= 6:
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
In [71]:
for order, z in enumerate(z_evals):
if order % 2 == 0 and order > 6:
plt.plot(r, z, label=str(order))
plt.plot(r, r, label='true')
plt.legend()
Out[71]:
In [36]:
import sympy as sp
def coeffs(m, n):
clist = []
clist.append(2 * (n - 1) * n * (n - 2))
clist.append((n - 1) * (-m**2 - n * (n - 2)))
clist.append(-n * (n + m - 2) * (n - m - 2) / 2)
return [item / ((n + m) * (n - m) * (n - 2)) * 2 for item in clist]
rho = sp.symbols('rho')
def R(m, n):
if m == n:
return rho**n
elif n == m + 2:
return ((m + 2) * rho**2 - (m + 1)) * rho**m
else:
coeff1, coeff2, coeff3 = coeffs(m, n)
return (coeff1 * rho**2 + coeff2) * R(m, n-2) + coeff3 * R(m, n-4)
In [ ]:
from series.Zernike import Zernike
max_order = 10
zernike_list = [Zernike(order, 0, 0, 60) for order in range(max_order + 1)]
zernike_tally.mean.shape = (zernike_tally.mean.size)
for order in range(max_order + 1):
n = (order + 1) * (order + 2) // 2
zernike_list[order].coefficients = zernike_tally.mean[:n]
import numpy as np
r = np.linspace(0, 60, 100)
z_evals = [np.zeros((r.size)) for zernike in zernike_list]
for r_index, radius in enumerate(r):
for z_index, zernike in enumerate(zernike_list):
z_evals[z_index][r_index] = zernike(radius, 0, normalization="orthonormal")
In [13]:
for order, z in enumerate(z_evals):
if order % 2 == 0 and order <= 4:
plt.plot(r, z, label=str(order))
plt.legend()
Out[13]:
Using the code above, we determined that the radial Zernike polynomials in the MOOSE FET module are accurate!