forked from loganharbour/radpydro
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgeometry.py
118 lines (102 loc) · 3.64 KB
/
geometry.py
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
import numpy as np
class Geometry:
def __init__(self, rp):
self.rp = rp
self.input = rp.input
# Radius at cell edges (user defined)
self.r_half = np.copy(self.input.r_half)
self.r_half_p = np.copy(self.r_half)
self.r_half_old = np.copy(self.r_half)
# Number of cells
self.N = self.r_half.size - 1
# Areas (defined at edges)
self.A = np.zeros(self.N + 1)
self.A_p = np.zeros(self.N + 1)
self.A_old = np.zeros(self.N + 1)
# Volumes (defined on spatial cells)
self.V = np.zeros(self.N)
self.V_p = np.zeros(self.N)
self.V_old = np.zeros(self.N)
# Radius at cell centers
self.r = np.zeros(self.N)
self.r_p = np.zeros(self.N)
self.r_old = np.zeros(self.N)
# Cells widths
self.dr = np.zeros(self.N)
self.dr_p = np.zeros(self.N)
self.dr_old = np.zeros(self.N)
# Initialize A, V, r and copy to old
self.recomputeGeometry(False)
self.stepGeometry()
def moveMesh(self, dt, predictor):
r_half_old = self.r_half_old
u_old = self.rp.fields.u_old
m = self.rp.mat.m
if predictor:
u_new = self.rp.fields.u_p
V_new = self.V_p
r_half_new = self.r_half_p
rho_new = self.rp.fields.rho_p
else:
u_new = self.rp.fields.u
V_new = self.V
r_half_new = self.r_half
rho_new = self.rp.fields.rho
# Update radii at edges
for i in range(self.N + 1):
r_half_new[i] = r_half_old[i] + (u_new[i] + u_old[i]) / 2 * dt
# Recompute A, V, and r using newly obtained r_half
self.recomputeGeometry(predictor)
# Recompute densities
for i in range(self.N):
rho_new[i] = m[i] / V_new[i]
# Recompute A, V, dr, and r using r_half_p (predictor = true) or
# r_half (predictor = false)
def recomputeGeometry(self, predictor):
if predictor:
A = self.A_p
V = self.V_p
r_half = self.r_half_p
r = self.r_p
dr = self.dr_p
else:
A = self.A
V = self.V
r_half = self.r_half
r = self.r
dr = self.dr
# Update areas
self.recomputeAreas(A, r_half)
# Update volumes
self.recomputeVolumes(V, r_half)
# Update cell centered radii and cell widths
for i in range(self.N):
r[i] = (r_half[i] + r_half[i + 1]) / 2
dr[i] = (r_half[i + 1] - r_half[i])
# Copy over all new values to old positions
def stepGeometry(self):
np.copyto(self.r_half_old, self.r_half)
np.copyto(self.A_old, self.A)
np.copyto(self.V_old, self.V)
np.copyto(self.r_old, self.r)
np.copyto(self.dr_old, self.dr)
class SlabGeometry(Geometry):
def recomputeAreas(self, A, r_half):
A.fill(1.0)
def recomputeVolumes(self, V, r_half):
for i in range(self.N):
V[i] = r_half[i + 1] - r_half[i]
class CylindricalGeometry(Geometry):
def recomputeAreas(self, A, r_half):
for i in range(self.N + 1):
A[i] = 2 * np.pi * r_half[i]
def recomputeVolumes(self, V, r_half):
for i in range(self.N):
V[i] = np.pi * (r_half[i + 1]**2 - r_half[i]**2)
class SphericalGeometry(Geometry):
def recomputeAreas(self, A, r_half):
for i in range(self.N + 1):
A[i] = 4 * np.pi * r_half[i]**2
def recomputeVolumes(self, V, r_half):
for i in range(self.N):
V[i] = 4 * np.pi * (r_half[i + 1]**3 - r_half[i]**3) / 3