-
Notifications
You must be signed in to change notification settings - Fork 1
/
parameter.py
143 lines (131 loc) · 5.61 KB
/
parameter.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
"""Module providing functions needed handle parameters in FEM formulations."""
import numpy as np
import sys
import mesh as m
parameterList = []
# TODO: make parameter able to handle regions of different dimensions
class Parameter:
def __init__(self, rows=1):
self.settings = []
self.preparedValues = dict()
self.parameterDimension = 0
self.rows = rows
parameterList.append(self)
def checkDimensions(self):
for setting in self.settings:
if self.parameterDimension == 0:
self.parameterDimension = m.regionDimension(setting[0])
elif m.regionDimension(setting[0]) != self.parameterDimension:
print("Error: cannot mix regions with different dimensions in a parameter!")
sys.exit()
def set(self, regions, value):
if (not isinstance(value, list) and self.rows != 1) or (isinstance(value, list) and self.rows != len(value)):
print(f"Error: values for this parameter need to have {self.rows:d} rows!")
sys.exit()
if not isinstance(regions, list):
regions = [regions]
for region in regions:
if not [region, value] in self.settings:
self.settings.append([region, value])
self.settings.sort()
self.checkDimensions()
def prepareValues(self, ids):
self.preparedValues[str(ids)] = np.empty((0, self.rows))
preparedValues2 = dict()
preparedValues2[str(ids)] = []
for setting in self.settings:
if not setting[0] in ids:
continue
if self.rows == 1: # there is probably also a way to do it without this if-else
self.preparedValues[str(ids)] = np.append(
self.preparedValues[str(ids)],
np.repeat(
setting[1],
np.count_nonzero(m.getMesh()["physical"][0] == setting[0]),
),
)
self.preparedValues[str(ids)] = np.append(
self.preparedValues[str(ids)],
np.repeat(
setting[1],
np.count_nonzero(m.getMesh()["physical"][1] == setting[0]),
),
)
self.preparedValues[str(ids)] = np.append(
self.preparedValues[str(ids)],
np.repeat(
setting[1],
np.count_nonzero(m.getMesh()["physical"][2] == setting[0]),
),
)
else:
self.preparedValues[str(ids)] = np.row_stack(
(
self.preparedValues[str(ids)],
np.tile(
setting[1],
(
np.count_nonzero(m.getMesh()["physical"][0] == setting[0]),
1,
),
),
)
)
self.preparedValues[str(ids)] = np.row_stack(
(
self.preparedValues[str(ids)],
np.tile(
setting[1],
(
np.count_nonzero(m.getMesh()["physical"][1] == setting[0]),
1,
),
),
)
)
self.preparedValues[str(ids)] = np.row_stack(
(
self.preparedValues[str(ids)],
np.tile(
setting[1],
(
np.count_nonzero(m.getMesh()["physical"][2] == setting[0]),
1,
),
),
)
)
def getValues(self, region=[]):
ids = []
for x in self.settings:
ids.append(x[0])
if region == []: # use all regions if no region is specified
regionIds = ids
else:
# check if all ids exist in parameter
for regionId in region.ids:
if regionId not in ids:
print(f"Error: Region id {id:d} not present in parameter!")
sys.exit()
regionIds = region.ids
# use calculated values if possible
if not str(regionIds) in self.preparedValues:
self.prepareValues(regionIds)
return self.preparedValues[str(regionIds)]
# this function is quite inefficient, but its only for debug purpose anyway
# Problem: vertexValues at the border of a region get overwritten by neighbouring region
# but its only a problem for visualization, since this function is not used in calculation
def getVertexValues(self):
triangleValues = self.getValues()
if len(triangleValues) != m.numberOfTriangles():
print("getVertexValues() only works for parameters that are defined on all mesh regions!")
sys.exit()
if len(triangleValues.shape) > 1:
vertexValues = np.zeros((m.numberOfVertices(), triangleValues.shape[1]))
else:
vertexValues = np.zeros((m.numberOfVertices()))
for n in range(m.numberOfTriangles()):
vertexValues[m.getMesh()["pt"][n][0]] = triangleValues[n]
vertexValues[m.getMesh()["pt"][n][1]] = triangleValues[n]
vertexValues[m.getMesh()["pt"][n][2]] = triangleValues[n]
return vertexValues