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

Pablo1990 / pyVertexModel / 11776819502

11 Nov 2024 10:34AM UTC coverage: 0.797% (+0.005%) from 0.792%
11776819502

push

github

Pablo1990
intercalations seem to work?????

0 of 995 branches covered (0.0%)

Branch coverage included in aggregate %.

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

355 existing lines in 6 files now uncovered.

51 of 5408 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
        if oldFace is not None:
×
88
            self.Area = oldFace.Area
×
89
            self.Area0 = oldFace.Area0
×
90
        else:
91
            self.Area, _ = self.compute_face_area(Cell.Y)
×
NEW
92
            self.Area0 = self.Area * Set.ref_A0
×
93

94

95
    def build_interface_type(self, ij, XgID, XgTop, XgBottom):
×
96
        """
97
        Build the interface type of the face.
98
        :param ij:
99
        :param XgID:
100
        :param XgTop:
101
        :param XgBottom:
102
        :return:
103
        """
104

105
        if any(node in XgTop for node in ij):
×
106
            ftype = self.InterfaceType_allValues[0]  # Top
×
107
        elif any(node in XgBottom for node in ij):
×
108
            ftype = self.InterfaceType_allValues[2]  # Bottom/Substrate
×
109
        else:
110
            ftype = self.InterfaceType_allValues[1]  # Border face
×
111

112
        self.InterfaceType = get_interface(ftype)
×
113
        return self.InterfaceType
×
114

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

132
        self.Centre = Centre
×
133
        return Centre
×
134

135
    def build_edges(self, T, face_ids, face_centre, face_interface_type, X, Ys, non_dead_cells):
×
136
        """
137
        Build the edges of the face.
138
        :param T:
139
        :param face_ids:
140
        :param face_centre:
141
        :param face_interface_type:
142
        :param X:
143
        :param Ys:
144
        :param non_dead_cells:
145
        :return:
146
        """
147
        FaceTets = T[face_ids,]
×
148

149
        tet_order = np.zeros(len(FaceTets), dtype=int) - 1
×
150
        tet_order[0] = 0
×
151
        prev_tet = FaceTets[0, :]
×
152

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

163
            if np.sum(np.isin(FaceTets[0, :], prev_tet)) != 3:
×
164
                raise Exception('BuildEdges:TetrahedraOrdering', 'Cannot create a face with these tetrahedra')
×
165
        else:
166
            tet_order = np.array([0, 1, 2])
×
167

168
        tet_order = np.array(tet_order, dtype=int)
×
169

170
        surf_ids = np.arange(len(T))
×
171
        surf_ids = surf_ids[face_ids]
×
172
        if len(surf_ids) < 3:
×
173
            raise Exception('BuildEdges:TetrahedraMinSize', 'Length of the face is lower than 3')
×
174
        surf_ids = surf_ids[tet_order]
×
175

176
        Order = np.zeros(len(surf_ids))
×
177
        for iii in range(len(surf_ids)):
×
178
            if iii == len(surf_ids) - 1:
×
179
                v1 = Ys[surf_ids[iii], :] - face_centre
×
180
                v2 = Ys[surf_ids[0], :] - face_centre
×
181
            else:
182
                v1 = Ys[surf_ids[iii], :] - face_centre
×
183
                v2 = Ys[surf_ids[iii + 1], :] - face_centre
×
184

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

187
        if np.all(Order < 0):
×
188
            surf_ids = np.flip(surf_ids)
×
189

190
        for currentTri in range(len(surf_ids) - 1):
×
191
            self.Tris.append(tris.Tris())
×
192
            self.Tris[currentTri].Edge = [surf_ids[currentTri], surf_ids[currentTri + 1]]
×
193
            currentTris_1 = T[self.Tris[currentTri].Edge[0], :]
×
194
            currentTris_2 = T[self.Tris[currentTri].Edge[1], :]
×
195
            self.Tris[currentTri].SharedByCells = np.intersect1d(currentTris_1[np.isin(currentTris_1, non_dead_cells)],
×
196
                                                                 currentTris_2[np.isin(currentTris_2, non_dead_cells)])
197

198
            self.Tris[currentTri].EdgeLength, self.Tris[currentTri].LengthsToCentre, self.Tris[currentTri].AspectRatio \
×
199
                = self.Tris[currentTri].compute_tri_length_measurements(Ys, face_centre)
200
            self.Tris[currentTri].EdgeLength_time = [0, self.Tris[currentTri].EdgeLength]
×
201

202
        self.Tris.append(tris.Tris())
×
203
        self.Tris[len(surf_ids) - 1].Edge = [surf_ids[len(surf_ids) - 1], surf_ids[0]]
×
204
        currentTris_1 = T[self.Tris[len(surf_ids) - 1].Edge[0], :]
×
205
        currentTris_2 = T[self.Tris[len(surf_ids) - 1].Edge[1], :]
×
206
        self.Tris[len(surf_ids) - 1].SharedByCells = np.intersect1d(
×
207
            currentTris_1[np.isin(currentTris_1, non_dead_cells)],
208
            currentTris_2[np.isin(currentTris_2, non_dead_cells)])
209

210
        self.Tris[len(surf_ids) - 1].EdgeLength, self.Tris[len(surf_ids) - 1].LengthsToCentre, self.Tris[
×
211
            len(surf_ids) - 1].AspectRatio = self.Tris[len(surf_ids) - 1].compute_tri_length_measurements(Ys,
212
                                                                                                          face_centre)
213
        self.Tris[len(surf_ids) - 1].EdgeLength_time = [0, self.Tris[len(surf_ids) - 1].EdgeLength]
×
214

215
        _, triAreas = self.compute_face_area(Ys)
×
216
        for i in range(len(self.Tris)):
×
217
            self.Tris[i].Area = triAreas[i]
×
218

219
        for tri in self.Tris:
×
220
            tri.Location = face_interface_type
×
221

222
    def compute_face_area(self, y):
×
223
        """
224
        Compute the area of the face.
225
        :param y:
226
        :return:
227
        """
228
        tris_area = np.zeros(len(self.Tris))
×
229

230
        for t, tri in enumerate(self.Tris):
×
231
            y3 = self.Centre
×
232
            y_tri = np.vstack([y[tri.Edge, :], y3])
×
233

234
            # Calculate the area of the triangle
235
            tri_area = 0.5 * np.linalg.norm(np.cross(y_tri[1, :] - y_tri[0, :], y_tri[0, :] - y_tri[2, :]))
×
236
            tris_area[t] = tri_area
×
237

238
        area = np.sum(tris_area)
×
239

240
        return area, tris_area
×
241

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

253
    def copy(self):
×
254
        """
255
        Copy the face.
256
        :return:
257
        """
258
        new_face = Face()
×
259

260
        copy_non_mutable_attributes(self, ['Tris'], new_face)
×
261
        new_face.Tris = [tri.copy() for tri in self.Tris]
×
262

263
        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