-
Notifications
You must be signed in to change notification settings - Fork 0
/
_rb_data_class.py
226 lines (195 loc) · 7.2 KB
/
_rb_data_class.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# -*- coding: utf-8 -*-
"""
@author: Olav M.S. Gran
"""
import numpy as np
from ._pod import compute_v
from .default_constants import eps_pod, e_young_range, nu_poisson_range, rb_grid, pod_sampling_mode, n_rom_cut
class ReducedOrderData:
def __init__(self):
"""
Setup
Returns
-------
None.
"""
# last n_rom used, set to something it never is
self.last_n_rom = -1
# maximum pod depet, set as a large number
self.n_rom_max = np.inf
# where to cut for n_rom_max
self.n_rom_cut = n_rom_cut
# Young's module range
self.e_young_range = e_young_range
# Poisson ratio range
self.nu_poisson_range = nu_poisson_range
# sampling grid
self.rb_grid = rb_grid
# number of snapshots
self.ns_rom = rb_grid[0] * rb_grid[1]
# pod tolerance
self.eps_pod = eps_pod
# pod sampling mode
self.pod_sampling_mode = pod_sampling_mode
# pod matrices and eigenvectors
self.v = None
self.z_mat = None
self.x05 = None
# snapshot matrix
self.s_mat = None
# singular values squared
self.sigma2_vec = None
# rb deegres of freedom
self.n_rom = None
# rb matrices and load vectors
self.a1_free_rom = None
self.a2_free_rom = None
self.f_load_lv_free_rom = None
self.f_load_neumann_free_rom = None
self.f1_dirichlet_rom = None
self.f2_dirichlet_rom = None
def set_rb_model_params(self, grid=None, e_young_range=None, nu_poisson_range=None, eps_pod=None,
mode=None, n_rom_cut=None):
"""
Set the reduced-order model parameters
Parameters
----------
grid : int, tuple, list optional
The grid size for the sampling, if int us it for both parameters.
If None set to rb_grid from default_constants
The default is None.
e_young_range : tuple, optional
range for the Young's module E.
If None set to e_young_range from default_constants
The default is None.
nu_poisson_range : tuple, optional
range for the poisson ratio nu.
If None set to nu_poisson_range from default_constants
The default is None.
eps_pod : float, optional
tolerance for the POD algorithm.
If None set to eps_POD from default_constants
The default is None.
mode : str, optional
sampling mode.
If None set to pod_sampling_mode from default_constants
The default is None.
n_rom_cut : int, str, optional
value to cut n_rom at, may be string "rank" fro the rank of the solution matrix.
If None set to n_rom_cut from default_constants
The default is None.
Raises
------
ValueError
if the parameter grid is not an int, tuple or list (of ints)..
Returns
-------
None.
"""
if grid is not None:
if isinstance(grid, int):
self.rb_grid = (grid, grid)
elif isinstance(grid, (tuple, list)):
self.rb_grid = grid
else:
raise ValueError("Parameter grid is not an int, tuple or list (of ints).")
self.ns_rom = self.rb_grid[0] * self.rb_grid[1]
if e_young_range is not None:
self.e_young_range = e_young_range
if nu_poisson_range is not None:
self.nu_poisson_range = nu_poisson_range
if eps_pod is not None:
self.eps_pod = eps_pod
if mode is not None:
self.pod_sampling_mode = mode
if n_rom_cut is not None:
self.n_rom_cut = n_rom_cut
def _compute_v(self, n_rom, n_free):
"""
Compute the matrix V
Parameters
----------
n_rom : int
our chosen "reduced-order degrees of freedom" ("n_rom"),
can be set to different from n_rom-true.
n_free : int
the high-fidelity degrees of freedom.
Raises
------
ValueError
if n_rom if larger than n_rom_max.
Returns
-------
None.
"""
if n_rom > self.n_rom_max:
raise ValueError(f"n_rom={n_rom} is larger than maximum reduced order dept: {self.n_rom_max}")
compute_v(n_rom, n_free, self)
def _compute_rom_matrices_and_vectors(self, hf_data, has_neumann, has_non_homo_dirichlet, has_non_homo_neumann):
"""
Compute the reduced-order matrices a1 and a2, and load vectors
Parameters
----------
hf_data :
High-fidelity data.
has_neumann : bool
Does the problem have Neumann boundary conditions.
has_non_homo_dirichlet : bool
Does the problem have non homogeneous Dirichlet boundary conditions.
has_non_homo_neumann : bool
Does the problem have non homogeneous Neumann boundary conditions.
Returns
-------
None.
"""
self.a1_free_rom = self.v.T @ hf_data.a1_free @ self.v
self.a2_free_rom = self.v.T @ hf_data.a2_free @ self.v
self.f_load_lv_free_rom = self.v.T @ hf_data.f_load_lv_free
if has_neumann and has_non_homo_neumann:
self.f_load_neumann_free_rom = self.v.T @ hf_data.f_load_neumann_free
if has_non_homo_dirichlet:
self.f1_dirichlet_rom = self.v.T @ hf_data.a1_dirichlet @ hf_data.rg
self.f2_dirichlet_rom = self.v.T @ hf_data.a2_dirichlet @ hf_data.rg
def compute_rb_matrices_and_vectors(self, n_rom, hf_data, has_neumann,
has_non_homo_dirichlet, has_non_homo_neumann):
"""
Compute the reduced-order matrices v, a1 and a2, and load vectors
Parameters
----------
n_rom : int
our chosen "reduced-order degrees of freedom" ("n_rom"),
can be set to different from n_rom-true.
hf_data :
High-fidelity data.
has_neumann : bool
Does the problem have Neumann boundary conditions.
has_non_homo_dirichlet : bool
Does the problem have non homogeneous Dirichlet boundary conditions.
has_non_homo_neumann : bool
Does the problem have non homogeneous Neumann boundary conditions.
Returns
-------
None.
"""
self._compute_v(n_rom, hf_data.n_free)
self._compute_rom_matrices_and_vectors(hf_data, has_neumann, has_non_homo_dirichlet, has_non_homo_neumann)
def set_n_rom_max(self):
"""
Set the maximum maximum reduced order dept
Returns
-------
None.
"""
if self.n_rom_cut == "rank":
self.n_rom_max = self.solution_matrix_rank()
else:
self.n_rom_max = np.max(np.argwhere(self.sigma2_vec > self.n_rom_cut)) + 1
def solution_matrix_rank(self):
"""
Get the rank of the solution matrix
Returns
-------
int
the rank of the solution matrix.
"""
return np.linalg.matrix_rank(self.s_mat)