-
Notifications
You must be signed in to change notification settings - Fork 0
/
PROM.py
135 lines (90 loc) · 3.12 KB
/
PROM.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import numpy as np
import matplotlib.pyplot as plt
def PROM(sample, V, M = 50):
#same as diffusion code
print("starting...\n")
h = 1/M
num_timesteps = 100 #timesteps
dt = 2 #timestep size
#create the del matrix with upwinding
du = 1/h
d = -1/h
dl = 0
#create the matrix in one dimension
exu = np.arange(M - 1)
exl = np.arange(M - 1) + 1
eyu = np.arange(M - 1)
eyl = np.arange(M - 1) + 1
I = np.identity(M)
Ax = I*d
Ax[exu, exu] /= exu + 1
Ax[exu, exu+1] += du/(exu + 1)
Ax[exl, exl-1] += dl/(exl + 1)
Ax[-1, -1] = -1/(h*M)
Ax[-1, -2] = 1/(h*M)
del1 = np.kron(I, Ax)
#create the del^2 matrix with central differences
du= 1/h**2 #upper diagonal value
d = (-2/h**2) #middle diagonal value
dl = du #lower diagonal value
#create the matrix in one dimension
exu = np.arange(M - 1)
exl = np.arange(M - 1) + 1
eyu = np.arange(M - 1)
eyl = np.arange(M - 1) + 1
#set the diagonals for the base matrices
Ax = I*d
Ax[exu, exu + 1] += du
Ax[exl, exl- 1] += dl
Ax[-1,-1] = 0
Ax[-1,-2] = 0
Ax[0,0] = 0
Ax[0,1] = 0
Ay = I*d
Ay[eyu, eyu + 1] += du
Ay[eyl, eyl - 1] += dl
#set the neumann boundary conditions
Ay[-1,-1] = 0
Ay[-1, -2] = 0
Ay[0,0] = 0
Ay[0,1] = 0
del2_y = np.kron(I, Ax)
del2_x = np.kron(Ay, I)
del2 = (del2_y + del2_x)
#set the time stepping matrix with upwinding
d = -1/dt
At = I*d
delt_x = np.kron(I, At)
delt_y = np.kron(At, I)
delt = delt_x + delt_y
#set the time stepping matrix with upwinding
d = -1/dt
At = I*d
delt_x = np.kron(I, At)
delt_y = np.kron(At, I)
delt = delt_x + delt_y
Fs = np.zeros((1, num_timesteps, M, M))
F = np.zeros((M, M))
F_prev = np.zeros((M, M))
scaling_factors = []
#create the right hand side matrix and implement dirichlet boundary conditions
#dirichlet boundary conditions
scaling_factor = sample[0]/((h**2)) + sample[1]/(2*h)
scaling_factors.append(scaling_factor)
LHS = np.matmul(np.matmul(V.T, (sample[0]*del2 + sample[1]*del1 + delt)), V) #LHS reduced order array
t = 0
F_prev = np.zeros((M, M))
F_prev[:,:] = scaling_factor
F_prev[int(np.floor(M/2 -5)):int(np.floor(M/2 + 5)), -1] = 2*scaling_factor
while t < num_timesteps:
print("timestep :", t)
F_eval = F_prev.reshape(M*M,1)
RHS = np.matmul(V.T, F_eval)
F = np.matmul(V, np.linalg.solve(-LHS,RHS))
F = F.reshape(M, M)
Fs[0, t, :, :] = F
F[0,:] = scaling_factor
F[int(np.floor(M/2 -5)):int(np.floor(M/2 + 5)),-1] = 2*scaling_factor
F_prev = F
t += 1
return Fs