• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Pablo1990 / pyVertexModel / 11368168500

16 Oct 2024 02:48PM UTC coverage: 0.794% (+0.001%) from 0.793%
11368168500

push

github

Pablo1990
refactor to obtain tris_areas

0 of 1003 branches covered (0.0%)

Branch coverage included in aggregate %.

0 of 2 new or added lines in 1 file covered. (0.0%)

113 existing lines in 3 files now uncovered.

51 of 5422 relevant lines covered (0.94%)

0.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/pyVertexModel/geometry/face.py
1
import numpy as np
×
2

3
from src.pyVertexModel.geometry import tris
×
4
from src.pyVertexModel.util.utils import copy_non_mutable_attributes
×
5

6

7
def get_key(dictionary, target_value):
×
8
    for key, value in dictionary.items():
×
9
        if value == target_value:
×
10
            return key
×
11
    return None
×
12

13

14
def get_interface(interface_type):
×
15
    """
16
    Standardize the InterfaceType attribute.
17
    :return:
18
    """
19
    valueset = [0, 1, 2]
×
20
    catnames = ['Top', 'CellCell', 'Bottom']
×
21
    interface_type_all_values = dict(zip(valueset, catnames))
×
22

23
    # Set InterfaceType to the string value
24
    interface_type_str = None
×
25
    if interface_type is not None:
×
26
        interface_type_str = next(key for key, value in interface_type_all_values.items()
×
27
                                  if
28
                                  value == interface_type or key == interface_type)
29

30
    return interface_type_str
×
31

32

33
class Face:
×
34
    """
35
    Class that contains the information of a face.
36
    """
37

38
    def __init__(self, mat_file=None):
×
39
        self.Aspect_Ratio = None
×
40
        self.Perimeter = None
×
41
        self.Tris = []
×
42
        if mat_file is None or mat_file[0].shape[0] == 0:
×
43
            self.InterfaceType = None
×
44
            self.ij = None
×
45
            self.globalIds = None
×
46
            self.Centre = None
×
47
            self.Area = None
×
48
            self.Area0 = None
×
49
        else:
50
            self.ij = mat_file[0][0] - 1
×
51
            self.Centre = mat_file[1][0]
×
52
            for c_tri in mat_file[2][0]:
×
53
                self.Tris.append(tris.Tris(c_tri))
×
54
            if mat_file[3][0][0] == -1:
×
55
                self.globalIds = None
×
56
            else:
57
                self.globalIds = mat_file[3][0][0] - 1
×
58
            self.InterfaceType = get_interface(mat_file[4][0][0] - 1)
×
59
            self.Area = mat_file[5][0][0]
×
60
            self.Area0 = mat_file[6][0][0]
×
61

62
        valueset = [0, 1, 2]
×
63
        catnames = ['Top', 'CellCell', 'Bottom']
×
64
        self.InterfaceType_allValues = dict(zip(valueset, catnames))
×
65
        get_interface(self.InterfaceType)
×
66

67
    def build_face(self, ci, cj, face_ids, nCells, Cell, XgID, Set, XgTop, XgBottom, oldFace=None):
×
68
        self.InterfaceType = None
×
69
        ij = [ci, cj]
×
70
        self.ij = ij
×
71
        self.globalIds = None
×
72
        self.build_interface_type(ij, XgID, XgTop, XgBottom)
×
73

74
        if oldFace is not None:
×
75
            self.Centre = oldFace.Centre
×
76
        else:
77
            self.build_face_centre(ij, nCells, Cell.X, Cell.Y[face_ids, :], Set.f,
×
78
                                   "Bubbles" in Set.InputGeo)
79

80
        self.build_edges(Cell.T, face_ids, self.Centre, self.InterfaceType, Cell.X, Cell.Y,
×
81
                         list(range(nCells)))
82

83
        # Move centre to the mean of the edge centres
84
        self.Centre = np.mean(np.concatenate(Cell.Y[[tri.Edge for tri in self.Tris], :]), axis=0)
×
85
        # self.Centre = np.mean(c_cell.Y[self.Tris.Edge], :], axis=0)
86

87
        self.Area, _ = self.compute_face_area(Cell.Y)
×
88
        self.Area0 = self.Area
×
89

90
    def build_interface_type(self, ij, XgID, XgTop, XgBottom):
×
91
        """
92
        Build the interface type of the face.
93
        :param ij:
94
        :param XgID:
95
        :param XgTop:
96
        :param XgBottom:
97
        :return:
98
        """
99

100
        if any(node in XgTop for node in ij):
×
101
            ftype = self.InterfaceType_allValues[0]  # Top
×
102
        elif any(node in XgBottom for node in ij):
×
103
            ftype = self.InterfaceType_allValues[2]  # Bottom/Substrate
×
104
        else:
105
            ftype = self.InterfaceType_allValues[1]  # Border face
×
106

107
        self.InterfaceType = get_interface(ftype)
×
108
        return self.InterfaceType
×
109

110
    def build_face_centre(self, ij, ncells, X, Ys, H, extrapolate_face_centre):
×
111
        """
112
        Compute the centre of the face.
113
        :param ij:
114
        :param ncells:
115
        :param X:
116
        :param Ys:
117
        :param H:
118
        :param extrapolate_face_centre:
119
        :return:
120
        """
121
        Centre = np.sum(Ys, axis=0) / len(Ys)
×
122
        if sum(node in range(ncells) for node in ij) == 1 and extrapolate_face_centre:
×
123
            runit = (Centre - X)
×
124
            runit = runit / np.linalg.norm(runit)
×
125
            Centre = X + H * runit
×
126

127
        self.Centre = Centre
×
128
        return Centre
×
129

130
    def build_edges(self, T, face_ids, face_centre, face_interface_type, X, Ys, non_dead_cells):
×
131
        """
132
        Build the edges of the face.
133
        :param T:
134
        :param face_ids:
135
        :param face_centre:
136
        :param face_interface_type:
137
        :param X:
138
        :param Ys:
139
        :param non_dead_cells:
140
        :return:
141
        """
142
        FaceTets = T[face_ids,]
×
143

144
        tet_order = np.zeros(len(FaceTets), dtype=int) - 1
×
145
        tet_order[0] = 0
×
146
        prev_tet = FaceTets[0, :]
×
147

148
        if len(FaceTets) > 3:
×
149
            for yi in range(1, len(FaceTets)):
×
150
                i = np.sum(np.isin(FaceTets, prev_tet), axis=1) == 3
×
151
                i = i & ~np.isin(np.arange(len(FaceTets)), tet_order)
×
152
                i = np.where(i)[0]
×
153
                if len(i) == 0:
×
154
                    raise Exception('BuildEdges:TetrahedraOrdering', 'Cannot create a face with these tetrahedra')
×
155
                tet_order[yi] = i[0]
×
156
                prev_tet = FaceTets[i[0], :]
×
157

158
            if np.sum(np.isin(FaceTets[0, :], prev_tet)) != 3:
×
159
                raise Exception('BuildEdges:TetrahedraOrdering', 'Cannot create a face with these tetrahedra')
×
160
        else:
161
            tet_order = np.array([0, 1, 2])
×
162

163
        tet_order = np.array(tet_order, dtype=int)
×
164

165
        surf_ids = np.arange(len(T))
×
166
        surf_ids = surf_ids[face_ids]
×
167
        if len(surf_ids) < 3:
×
168
            raise Exception('BuildEdges:TetrahedraMinSize', 'Length of the face is lower than 3')
×
169
        surf_ids = surf_ids[tet_order]
×
170

171
        Order = np.zeros(len(surf_ids))
×
172
        for iii in range(len(surf_ids)):
×
173
            if iii == len(surf_ids) - 1:
×
174
                v1 = Ys[surf_ids[iii], :] - face_centre
×
175
                v2 = Ys[surf_ids[0], :] - face_centre
×
176
            else:
177
                v1 = Ys[surf_ids[iii], :] - face_centre
×
178
                v2 = Ys[surf_ids[iii + 1], :] - face_centre
×
179

180
            Order[iii] = np.dot(np.cross(v1, v2), face_centre - X) / len(surf_ids)
×
181

182
        if np.all(Order < 0):
×
183
            surf_ids = np.flip(surf_ids)
×
184

185
        for currentTri in range(len(surf_ids) - 1):
×
186
            self.Tris.append(tris.Tris())
×
187
            self.Tris[currentTri].Edge = [surf_ids[currentTri], surf_ids[currentTri + 1]]
×
188
            currentTris_1 = T[self.Tris[currentTri].Edge[0], :]
×
189
            currentTris_2 = T[self.Tris[currentTri].Edge[1], :]
×
190
            self.Tris[currentTri].SharedByCells = np.intersect1d(currentTris_1[np.isin(currentTris_1, non_dead_cells)],
×
191
                                                                 currentTris_2[np.isin(currentTris_2, non_dead_cells)])
192

193
            self.Tris[currentTri].EdgeLength, self.Tris[currentTri].LengthsToCentre, self.Tris[currentTri].AspectRatio \
×
194
                = self.Tris[currentTri].compute_tri_length_measurements(Ys, face_centre)
195
            self.Tris[currentTri].EdgeLength_time = [0, self.Tris[currentTri].EdgeLength]
×
196

197
        self.Tris.append(tris.Tris())
×
198
        self.Tris[len(surf_ids) - 1].Edge = [surf_ids[len(surf_ids) - 1], surf_ids[0]]
×
199
        currentTris_1 = T[self.Tris[len(surf_ids) - 1].Edge[0], :]
×
200
        currentTris_2 = T[self.Tris[len(surf_ids) - 1].Edge[1], :]
×
201
        self.Tris[len(surf_ids) - 1].SharedByCells = np.intersect1d(
×
202
            currentTris_1[np.isin(currentTris_1, non_dead_cells)],
203
            currentTris_2[np.isin(currentTris_2, non_dead_cells)])
204

205
        self.Tris[len(surf_ids) - 1].EdgeLength, self.Tris[len(surf_ids) - 1].LengthsToCentre, self.Tris[
×
206
            len(surf_ids) - 1].AspectRatio = self.Tris[len(surf_ids) - 1].compute_tri_length_measurements(Ys,
207
                                                                                                          face_centre)
208
        self.Tris[len(surf_ids) - 1].EdgeLength_time = [0, self.Tris[len(surf_ids) - 1].EdgeLength]
×
209

210
        _, triAreas = self.compute_face_area(Ys)
×
211
        for i in range(len(self.Tris)):
×
212
            self.Tris[i].Area = triAreas[i]
×
213

214
        for tri in self.Tris:
×
215
            tri.Location = face_interface_type
×
216

217
    def compute_face_area(self, y):
×
218
        """
219
        Compute the area of the face.
220
        :param y:
221
        :return:
222
        """
223
        tris_area = np.zeros(len(self.Tris))
×
224

225
        for t, tri in enumerate(self.Tris):
×
226
            y3 = self.Centre
×
227
            y_tri = np.vstack([y[tri.Edge, :], y3])
×
228

229
            # Calculate the area of the triangle
230
            tri_area = 0.5 * np.linalg.norm(np.cross(y_tri[1, :] - y_tri[0, :], y_tri[0, :] - y_tri[2, :]))
×
UNCOV
231
            tris_area[t] = tri_area
×
232

UNCOV
233
        area = np.sum(tris_area)
×
234

235
        return area, tris_area
×
236

237
    def compute_perimeter(self):
×
238
        """
239
        Compute the perimeter of the face based on the edges that are shared by more than one cell.
240
        :return: float
241
        """
UNCOV
242
        perimeter = 0.0
×
UNCOV
243
        for tri in self.Tris:
×
UNCOV
244
            if len(tri.SharedByCells) > 1:
×
UNCOV
245
                perimeter += tri.EdgeLength
×
246
        return perimeter
×
247

248
    def copy(self):
×
249
        """
250
        Copy the face.
251
        :return:
252
        """
UNCOV
253
        new_face = Face()
×
254

UNCOV
255
        copy_non_mutable_attributes(self, ['Tris'], new_face)
×
UNCOV
256
        new_face.Tris = [tri.copy() for tri in self.Tris]
×
257

UNCOV
258
        return new_face
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc