emerge 0.4.6__py3-none-any.whl → 0.4.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of emerge might be problematic. Click here for more details.
- emerge/__init__.py +54 -0
- emerge/__main__.py +5 -0
- emerge/_emerge/__init__.py +42 -0
- emerge/_emerge/bc.py +197 -0
- emerge/_emerge/coord.py +119 -0
- emerge/_emerge/cs.py +523 -0
- emerge/_emerge/dataset.py +36 -0
- emerge/_emerge/elements/__init__.py +19 -0
- emerge/_emerge/elements/femdata.py +212 -0
- emerge/_emerge/elements/index_interp.py +64 -0
- emerge/_emerge/elements/legrange2.py +172 -0
- emerge/_emerge/elements/ned2_interp.py +645 -0
- emerge/_emerge/elements/nedelec2.py +140 -0
- emerge/_emerge/elements/nedleg2.py +217 -0
- emerge/_emerge/geo/__init__.py +24 -0
- emerge/_emerge/geo/horn.py +107 -0
- emerge/_emerge/geo/modeler.py +449 -0
- emerge/_emerge/geo/operations.py +254 -0
- emerge/_emerge/geo/pcb.py +1244 -0
- emerge/_emerge/geo/pcb_tools/calculator.py +28 -0
- emerge/_emerge/geo/pcb_tools/macro.py +79 -0
- emerge/_emerge/geo/pmlbox.py +204 -0
- emerge/_emerge/geo/polybased.py +529 -0
- emerge/_emerge/geo/shapes.py +427 -0
- emerge/_emerge/geo/step.py +77 -0
- emerge/_emerge/geo2d.py +86 -0
- emerge/_emerge/geometry.py +510 -0
- emerge/_emerge/howto.py +214 -0
- emerge/_emerge/logsettings.py +5 -0
- emerge/_emerge/material.py +118 -0
- emerge/_emerge/mesh3d.py +730 -0
- emerge/_emerge/mesher.py +339 -0
- emerge/_emerge/mth/common_functions.py +33 -0
- emerge/_emerge/mth/integrals.py +71 -0
- emerge/_emerge/mth/optimized.py +357 -0
- emerge/_emerge/periodic.py +263 -0
- emerge/_emerge/physics/__init__.py +0 -0
- emerge/_emerge/physics/microwave/__init__.py +1 -0
- emerge/_emerge/physics/microwave/adaptive_freq.py +279 -0
- emerge/_emerge/physics/microwave/assembly/assembler.py +569 -0
- emerge/_emerge/physics/microwave/assembly/curlcurl.py +448 -0
- emerge/_emerge/physics/microwave/assembly/generalized_eigen.py +426 -0
- emerge/_emerge/physics/microwave/assembly/robinbc.py +433 -0
- emerge/_emerge/physics/microwave/microwave_3d.py +1150 -0
- emerge/_emerge/physics/microwave/microwave_bc.py +915 -0
- emerge/_emerge/physics/microwave/microwave_data.py +1148 -0
- emerge/_emerge/physics/microwave/periodic.py +82 -0
- emerge/_emerge/physics/microwave/port_functions.py +53 -0
- emerge/_emerge/physics/microwave/sc.py +175 -0
- emerge/_emerge/physics/microwave/simjob.py +147 -0
- emerge/_emerge/physics/microwave/sparam.py +138 -0
- emerge/_emerge/physics/microwave/touchstone.py +140 -0
- emerge/_emerge/plot/__init__.py +0 -0
- emerge/_emerge/plot/display.py +394 -0
- emerge/_emerge/plot/grapher.py +93 -0
- emerge/_emerge/plot/matplotlib/mpldisplay.py +264 -0
- emerge/_emerge/plot/pyvista/__init__.py +1 -0
- emerge/_emerge/plot/pyvista/display.py +931 -0
- emerge/_emerge/plot/pyvista/display_settings.py +24 -0
- emerge/_emerge/plot/simple_plots.py +551 -0
- emerge/_emerge/plot.py +225 -0
- emerge/_emerge/projects/__init__.py +0 -0
- emerge/_emerge/projects/_gen_base.txt +32 -0
- emerge/_emerge/projects/_load_base.txt +24 -0
- emerge/_emerge/projects/generate_project.py +40 -0
- emerge/_emerge/selection.py +596 -0
- emerge/_emerge/simmodel.py +444 -0
- emerge/_emerge/simulation_data.py +411 -0
- emerge/_emerge/solver.py +993 -0
- emerge/_emerge/system.py +54 -0
- emerge/cli.py +19 -0
- emerge/lib.py +57 -0
- emerge/plot.py +1 -0
- emerge/pyvista.py +1 -0
- {emerge-0.4.6.dist-info → emerge-0.4.8.dist-info}/METADATA +1 -1
- emerge-0.4.8.dist-info/RECORD +78 -0
- emerge-0.4.8.dist-info/entry_points.txt +2 -0
- emerge-0.4.6.dist-info/RECORD +0 -4
- emerge-0.4.6.dist-info/entry_points.txt +0 -2
- {emerge-0.4.6.dist-info → emerge-0.4.8.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# EMerge is an open source Python based FEM EM simulation module.
|
|
2
|
+
# Copyright (C) 2025 Robert Fennis.
|
|
3
|
+
|
|
4
|
+
# This program is free software; you can redistribute it and/or
|
|
5
|
+
# modify it under the terms of the GNU General Public License
|
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
|
7
|
+
# of the License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, see
|
|
16
|
+
# <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
from ..mesh3d import Mesh3D
|
|
20
|
+
import numpy as np
|
|
21
|
+
from typing import Callable
|
|
22
|
+
from scipy.sparse import coo_matrix, csr_matrix
|
|
23
|
+
|
|
24
|
+
from ..mth.optimized import matmul
|
|
25
|
+
|
|
26
|
+
class FEMBasis:
|
|
27
|
+
|
|
28
|
+
def __init__(self, mesh: Mesh3D):
|
|
29
|
+
self.mesh: Mesh3D = mesh
|
|
30
|
+
self.n_edges: int = self.mesh.n_edges
|
|
31
|
+
self.n_tris: int = self.mesh.n_tris
|
|
32
|
+
self.n_tets: int = self.mesh.n_tets
|
|
33
|
+
|
|
34
|
+
self.n_tet_dofs: int = None
|
|
35
|
+
self.n_tri_dofs: int = None
|
|
36
|
+
|
|
37
|
+
self.n_field: int = 2*self.n_edges + 2*self.n_tris
|
|
38
|
+
|
|
39
|
+
self.tet_to_field: np.ndarray = None
|
|
40
|
+
|
|
41
|
+
self.edge_to_field: np.ndarray = None
|
|
42
|
+
|
|
43
|
+
self.tri_to_field: np.ndarray = None
|
|
44
|
+
|
|
45
|
+
self._rows: np.ndarray = None
|
|
46
|
+
self._cols: np.ndarray = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def interpolate_Ef(self, field: np.ndarray, basis: np.ndarray = None, origin: np.ndarray = None, tetids: np.ndarray = None) -> Callable:
|
|
50
|
+
'''Generates the Interpolation function as a function object for a given coordiante basis and origin.'''
|
|
51
|
+
if basis is None:
|
|
52
|
+
basis = np.eye(3)
|
|
53
|
+
|
|
54
|
+
if origin is None:
|
|
55
|
+
origin = np.zeros(3)
|
|
56
|
+
|
|
57
|
+
ibasis = np.linalg.pinv(basis)
|
|
58
|
+
def func(xs: np.ndarray, ys: np.ndarray, zs: np.ndarray) -> np.ndarray:
|
|
59
|
+
xyz = np.array([xs, ys, zs]) + origin[:, np.newaxis]
|
|
60
|
+
xyzg = matmul(basis, xyz)
|
|
61
|
+
return matmul(ibasis, np.array(self.interpolate(field, xyzg[0,:], xyzg[1,:], xyzg[2,:], tetids)))
|
|
62
|
+
return func
|
|
63
|
+
|
|
64
|
+
def interpolate(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, tetids: np.ndarray = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
def interpolate_curl(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, constants: np.ndarray, tetids: np.ndarray = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
68
|
+
"""
|
|
69
|
+
Interpolates the curl of the field at the given points.
|
|
70
|
+
"""
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
def empty_tet_matrix(self) -> np.ndarray:
|
|
74
|
+
nnz = self.n_tets*self.n_tet_dofs**2
|
|
75
|
+
matrix = np.empty((nnz,), dtype=np.complex128)
|
|
76
|
+
return matrix
|
|
77
|
+
|
|
78
|
+
def empty_tri_matrix(self) -> np.ndarray:
|
|
79
|
+
nnz = self.n_tris*self.n_tri_dofs**2
|
|
80
|
+
matrix = np.zeros((nnz,), dtype=np.complex128)
|
|
81
|
+
return matrix
|
|
82
|
+
|
|
83
|
+
def empty_tet_rowcol(self) -> tuple[np.ndarray, np.ndarray]:
|
|
84
|
+
N = self.n_tet_dofs
|
|
85
|
+
N2 = N**2
|
|
86
|
+
nnz = self.n_tets*N2
|
|
87
|
+
rows = np.empty(nnz, dtype=np.int64)
|
|
88
|
+
cols = np.empty(nnz, dtype=np.int64)
|
|
89
|
+
|
|
90
|
+
for itet in range(self.n_tets):
|
|
91
|
+
p = itet*N2
|
|
92
|
+
|
|
93
|
+
indices = self.tet_to_field[:, itet]
|
|
94
|
+
for ii in range(self.n_tet_dofs):
|
|
95
|
+
rows[p+N*ii:p+N*(ii+1)] = indices[ii]
|
|
96
|
+
cols[p+ii:p+N2:N] = indices[ii]
|
|
97
|
+
self._rows = rows
|
|
98
|
+
self._cols = cols
|
|
99
|
+
return rows, cols
|
|
100
|
+
|
|
101
|
+
def empty_tri_rowcol(self) -> tuple[np.ndarray, np.ndarray]:
|
|
102
|
+
N = self.n_tri_dofs
|
|
103
|
+
N2 = N**2
|
|
104
|
+
nnz = self.n_tris*N2
|
|
105
|
+
rows = np.empty(nnz, dtype=np.int64)
|
|
106
|
+
cols = np.empty(nnz, dtype=np.int64)
|
|
107
|
+
|
|
108
|
+
for itri in range(self.n_tris):
|
|
109
|
+
p = itri*N2
|
|
110
|
+
indices = self.tri_to_field[:, itri]
|
|
111
|
+
for ii in range(N):
|
|
112
|
+
rows[p+N*ii:p+N*(ii+1)] = indices[ii]
|
|
113
|
+
cols[p+ii:p+N2:N] = indices[ii]
|
|
114
|
+
|
|
115
|
+
self._rows = rows
|
|
116
|
+
self._cols = cols
|
|
117
|
+
return rows, cols
|
|
118
|
+
|
|
119
|
+
def tetslice(self, itet: int) -> slice:
|
|
120
|
+
N = self.n_tet_dofs**2
|
|
121
|
+
return slice(itet*N,(itet+1)*N)
|
|
122
|
+
|
|
123
|
+
def trislice(self, itri: int) -> slice:
|
|
124
|
+
N = self.n_tri_dofs**2
|
|
125
|
+
return slice(itri*N,(itri+1)*N)
|
|
126
|
+
|
|
127
|
+
def generate_csr(self, data: np.ndarray) -> csr_matrix:
|
|
128
|
+
ids = np.argwhere(data!=0)[:,0]
|
|
129
|
+
return csr_matrix((data[ids], (self._rows[ids], self._cols[ids])), shape=(self.n_field, self.n_field))
|
|
130
|
+
### QUANTITIES
|
|
131
|
+
|
|
132
|
+
def tet_to_edge_lengths(self, itet: int) -> np.ndarray:
|
|
133
|
+
"""
|
|
134
|
+
Returns the edge lengths of the tetrahedron itet.
|
|
135
|
+
"""
|
|
136
|
+
return self.mesh.edge_lengths[self.mesh.tet_to_edge[:,itet]]
|
|
137
|
+
|
|
138
|
+
def tri_to_edge_lengths(self, itri: int) -> np.ndarray:
|
|
139
|
+
"""
|
|
140
|
+
Returns the edge lengths of the triangle itri.
|
|
141
|
+
"""
|
|
142
|
+
return self.mesh.edge_lengths[self.mesh.tri_to_edge[:,itri]]
|
|
143
|
+
####### INDEX MAPPINGS
|
|
144
|
+
|
|
145
|
+
def local_tet_to_triid(self, itet: int) -> np.ndarray:
|
|
146
|
+
raise NotImplementedError("local_tet_to_triid not implemented")
|
|
147
|
+
|
|
148
|
+
def local_tet_to_edgeid(self, itet: int) -> np.ndarray:
|
|
149
|
+
raise NotImplementedError("local_tet_to_edgeid not implemented")
|
|
150
|
+
|
|
151
|
+
def interpolate_index(self, xs: np.ndarray,
|
|
152
|
+
ys: np.ndarray,
|
|
153
|
+
zs: np.ndarray,
|
|
154
|
+
tetids: np.ndarray = None) -> np.ndarray:
|
|
155
|
+
raise NotImplementedError()
|
|
156
|
+
|
|
157
|
+
def map_edge_to_field(self, edge_ids: np.ndarray) -> np.ndarray:
|
|
158
|
+
"""
|
|
159
|
+
Returns the field ids for the edges.
|
|
160
|
+
"""
|
|
161
|
+
return edge_ids
|
|
162
|
+
|
|
163
|
+
# ##### CUTS
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def bounds(self) -> tuple[tuple[float, float], tuple[float, float],tuple[float, float]]:
|
|
167
|
+
xmin = np.min(self.mesh.nodes[0,:])
|
|
168
|
+
xmax = np.max(self.mesh.nodes[0,:])
|
|
169
|
+
ymin = np.min(self.mesh.nodes[1,:])
|
|
170
|
+
ymax = np.max(self.mesh.nodes[1,:])
|
|
171
|
+
zmin = np.min(self.mesh.nodes[2,:])
|
|
172
|
+
zmax = np.max(self.mesh.nodes[2,:])
|
|
173
|
+
return (xmin, xmax), (ymin, ymax), (zmin, zmax)
|
|
174
|
+
|
|
175
|
+
# @staticmethod
|
|
176
|
+
# def tet_stiff_mass_submatrix(tet_vertices: np.ndarray,
|
|
177
|
+
# edge_lengths: np.ndarray,
|
|
178
|
+
# local_edge_map: np.ndarray,
|
|
179
|
+
# local_tri_map: np.ndarray,
|
|
180
|
+
# C_stiffness: float,
|
|
181
|
+
# C_mass: float) -> tuple[np.ndarray, np.ndarray]:
|
|
182
|
+
# pass
|
|
183
|
+
|
|
184
|
+
# @staticmethod
|
|
185
|
+
# def tri_stiff_mass_submatrix(tri_vertices: np.ndarray,
|
|
186
|
+
# edge_lengths: np.ndarray,
|
|
187
|
+
# local_edge_map: np.ndarray,
|
|
188
|
+
# C_stiffness: float,
|
|
189
|
+
# C_mass: float) -> tuple[np.ndarray, np.ndarray]:
|
|
190
|
+
# pass
|
|
191
|
+
|
|
192
|
+
# @staticmethod
|
|
193
|
+
# def tri_stiff_vec_matrix(lcs_vertices: np.ndarray,
|
|
194
|
+
# edge_lengths: np.ndarray,
|
|
195
|
+
# gamma: complex,
|
|
196
|
+
# lcs_Uinc: np.ndarray,
|
|
197
|
+
# DPTs: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
|
198
|
+
# pass
|
|
199
|
+
|
|
200
|
+
# @staticmethod
|
|
201
|
+
# def tri_stiff_matrix(lcs_vertices: np.ndarray,
|
|
202
|
+
# edge_lengths: np.ndarray,
|
|
203
|
+
# gamma: complex) -> tuple[np.ndarray, np.ndarray]:
|
|
204
|
+
# pass
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# @staticmethod
|
|
208
|
+
# def tri_surf_integral(lcs_vertices: np.ndarray,
|
|
209
|
+
# edge_lengths: np.ndarray,
|
|
210
|
+
# lcs_Uinc: np.ndarray,
|
|
211
|
+
# DPTs: np.ndarray) -> complex:
|
|
212
|
+
# pass
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# EMerge is an open source Python based FEM EM simulation module.
|
|
2
|
+
# Copyright (C) 2025 Robert Fennis.
|
|
3
|
+
|
|
4
|
+
# This program is free software; you can redistribute it and/or
|
|
5
|
+
# modify it under the terms of the GNU General Public License
|
|
6
|
+
# as published by the Free Software Foundation; either version 2
|
|
7
|
+
# of the License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, see
|
|
16
|
+
# <https://www.gnu.org/licenses/>.
|
|
17
|
+
from numba import njit, f8, c16, i8, types
|
|
18
|
+
import numpy as np
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@njit(i8[:](f8[:,:], i8[:,:], f8[:,:], i8[:]), cache=True, nogil=True)
|
|
22
|
+
def index_interp(coords: np.ndarray,
|
|
23
|
+
tets: np.ndarray,
|
|
24
|
+
nodes: np.ndarray,
|
|
25
|
+
tetids: np.ndarray):
|
|
26
|
+
''' Nedelec 2 tetrahedral interpolation of the analytic curl'''
|
|
27
|
+
# Solution has shape (nEdges, nsols)
|
|
28
|
+
nNodes = coords.shape[1]
|
|
29
|
+
|
|
30
|
+
prop = np.zeros((nNodes, ), dtype=np.int64)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
for i_iter in range(tetids.shape[0]):
|
|
34
|
+
itet = tetids[i_iter]
|
|
35
|
+
|
|
36
|
+
iv1, iv2, iv3, iv4 = tets[:, itet]
|
|
37
|
+
|
|
38
|
+
v1 = nodes[:,iv1]
|
|
39
|
+
v2 = nodes[:,iv2]
|
|
40
|
+
v3 = nodes[:,iv3]
|
|
41
|
+
v4 = nodes[:,iv4]
|
|
42
|
+
|
|
43
|
+
bv1 = v2 - v1
|
|
44
|
+
bv2 = v3 - v1
|
|
45
|
+
bv3 = v4 - v1
|
|
46
|
+
|
|
47
|
+
blocal = np.zeros((3,3))
|
|
48
|
+
blocal[:,0] = bv1
|
|
49
|
+
blocal[:,1] = bv2
|
|
50
|
+
blocal[:,2] = bv3
|
|
51
|
+
basis = np.linalg.pinv(blocal)
|
|
52
|
+
|
|
53
|
+
coords_offset = coords - v1[:,np.newaxis]
|
|
54
|
+
coords_local = (basis @ (coords_offset))
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
inside = ((coords_local[0,:] + coords_local[1,:] + coords_local[2,:]) <= 1.00000001) & (coords_local[0,:] >= -1e-6) & (coords_local[1,:] >= -1e-6) & (coords_local[2,:] >= -1e-6)
|
|
58
|
+
|
|
59
|
+
if inside.sum() == 0:
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
prop[inside] = itet
|
|
63
|
+
|
|
64
|
+
return prop
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# # EMerge is an open source Python based FEM EM simulation module.
|
|
2
|
+
# # Copyright (C) 2025 Robert Fennis.
|
|
3
|
+
|
|
4
|
+
# # This program is free software; you can redistribute it and/or
|
|
5
|
+
# # modify it under the terms of the GNU General Public License
|
|
6
|
+
# # as published by the Free Software Foundation; either version 2
|
|
7
|
+
# # of the License, or (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# # This program is distributed in the hope that it will be useful,
|
|
10
|
+
# # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# # GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
# # You should have received a copy of the GNU General Public License
|
|
15
|
+
# # along with this program; if not, see
|
|
16
|
+
# # <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
# from __future__ import annotations
|
|
19
|
+
# import numpy as np
|
|
20
|
+
# from ..mesh3d import Mesh3D
|
|
21
|
+
# from ..dataset_old import Dataset, Axis
|
|
22
|
+
# from .femdata import FEMBasis
|
|
23
|
+
# from ..mth.tet import leg2_tet_interp, leg2_tet_grad_interp, leg2_tet_stiff
|
|
24
|
+
# from ..mth.tri import leg2_tri_stiff
|
|
25
|
+
# from ..mth.optimized import local_mapping
|
|
26
|
+
# from typing import Callable
|
|
27
|
+
|
|
28
|
+
# ############### Nedelec2 Class
|
|
29
|
+
|
|
30
|
+
# class Legrange2(FEMBasis):
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# def __init__(self, mesh: Mesh3D):
|
|
34
|
+
# super().__init__(mesh)
|
|
35
|
+
|
|
36
|
+
# self.nedges: int = self.mesh.n_edges
|
|
37
|
+
# self.ntris: int = self.mesh.n_tris
|
|
38
|
+
# self.ntets: int = self.mesh.n_tets
|
|
39
|
+
|
|
40
|
+
# self.nfield: int = 2*self.nedges + 2*self.ntris
|
|
41
|
+
|
|
42
|
+
# self.axes: list[Axis] = []
|
|
43
|
+
# self.fieldata: Dataset = None
|
|
44
|
+
|
|
45
|
+
# ######## MESH Derived
|
|
46
|
+
|
|
47
|
+
# nedges = self.mesh.n_edges
|
|
48
|
+
# ntris = self.mesh.n_tris
|
|
49
|
+
|
|
50
|
+
# self.tet_to_field: np.ndarray = np.zeros((10, self.mesh.tets.shape[1]), dtype=int)
|
|
51
|
+
# self.tet_to_field[:4,:] = self.mesh.tets
|
|
52
|
+
# self.tet_to_field[4:10,:] = self.mesh.tet_to_edge + self.mesh.n_nodes
|
|
53
|
+
|
|
54
|
+
# self.edge_to_field: np.ndarray = np.arange(nedges) + self.mesh.n_nodes
|
|
55
|
+
|
|
56
|
+
# self.tri_to_field: np.ndarray = np.zeros((6,ntris), dtype=int)
|
|
57
|
+
|
|
58
|
+
# self.tri_to_field[:3,:] = self.mesh.tris
|
|
59
|
+
# self.tri_to_field[3:6,:] = self.mesh.tri_to_edge + self.mesh.n_nodes
|
|
60
|
+
|
|
61
|
+
# ##
|
|
62
|
+
# self._field: np.ndarray = None
|
|
63
|
+
|
|
64
|
+
# def __call__(self, **kwargs) -> Legrange2:
|
|
65
|
+
# self._field = self.fielddata(**kwargs)
|
|
66
|
+
# return self
|
|
67
|
+
|
|
68
|
+
# def interpolate(self, field, xs: np.ndarray, ys: np.ndarray, zs:np.ndarray, tet_ids: np.ndarray = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
69
|
+
# if tet_ids is None:
|
|
70
|
+
# tet_ids = np.arange(self.mesh.n_tets)
|
|
71
|
+
# return leg2_tet_interp(np.array([xs, ys,zs]), field, self.mesh.tets, self.mesh.tris, self.mesh.edges, self.mesh.nodes, self.tet_to_field, self.mesh.tet_to_edge, self.mesh.tet_to_tri, tet_ids)
|
|
72
|
+
|
|
73
|
+
# def interpolate_grad(self, field, xs: np.ndarray, ys: np.ndarray, zs:np.ndarray, tet_ids: np.ndarray = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
74
|
+
# if tet_ids is None:
|
|
75
|
+
# tet_ids = np.arange(self.mesh.tet_ids)
|
|
76
|
+
# return leg2_tet_grad_interp(np.array([xs, ys,zs]), field, self.mesh.tets, self.mesh.tris, self.mesh.edges, self.mesh.nodes, self.tet_to_field, self.mesh.tet_to_edge, self.mesh.tet_to_tri, tet_ids)
|
|
77
|
+
|
|
78
|
+
# def fieldf(self, field: np.ndarray, basis: np.ndarray = None, origin: np.ndarray = None) -> Callable:
|
|
79
|
+
# if basis is None:
|
|
80
|
+
# basis = np.eye(3)
|
|
81
|
+
|
|
82
|
+
# if origin is None:
|
|
83
|
+
# origin = np.zeros(3)
|
|
84
|
+
|
|
85
|
+
# ibasis = np.linalg.pinv(basis)
|
|
86
|
+
# def func(xs: np.ndarray, ys: np.ndarray, zs: np.ndarray) -> np.ndarray:
|
|
87
|
+
# xyz = np.array([xs, ys, zs]) + origin[:, np.newaxis]
|
|
88
|
+
# xyzg = basis @ xyz
|
|
89
|
+
# return ibasis @ np.array(self.interpolate(field, xyzg[0,:], xyzg[1,:], xyzg[2,:]))
|
|
90
|
+
# return func
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# ###### Vertex getter
|
|
94
|
+
|
|
95
|
+
# def field_to_vertices(self, ifield: np.ndarray):
|
|
96
|
+
# return_ids = ifield[ifield < self.mesh.n_nodes]
|
|
97
|
+
# return return_ids
|
|
98
|
+
|
|
99
|
+
# def field_to_edges(self, ifield: np.ndarray):
|
|
100
|
+
# return_ids = ifield[ifield >= self.mesh.n_nodes] - self.mesh.n_nodes
|
|
101
|
+
# return return_ids
|
|
102
|
+
# ###### INDEX MAPPINGS
|
|
103
|
+
|
|
104
|
+
# def local_tet_to_triid(self, itet: int) -> np.ndarray:
|
|
105
|
+
# tri_ids = self.tet_to_field[6:10, itet] - self.n_edges
|
|
106
|
+
# global_tri_map = self.mesh.tris[:, tri_ids]
|
|
107
|
+
# return local_mapping(self.mesh.tets[:, itet], global_tri_map)
|
|
108
|
+
|
|
109
|
+
# def local_tet_to_edgeid(self, itet: int) -> np.ndarray:
|
|
110
|
+
# global_edge_map = self.mesh.edges[:, self.tet_to_field[:6,itet]]
|
|
111
|
+
# return local_mapping(self.mesh.tets[:, itet], global_edge_map)
|
|
112
|
+
|
|
113
|
+
# def local_tri_to_edgeid(self, itri: int) -> np.ndarray:
|
|
114
|
+
# global_edge_map = self.mesh.edges[:, self.tri_to_field[:3,itri]]
|
|
115
|
+
# return local_mapping(self.mesh.tris[:, itri], global_edge_map)
|
|
116
|
+
|
|
117
|
+
# def map_edge_to_field(self, edge_ids: np.ndarray) -> np.ndarray:
|
|
118
|
+
# """
|
|
119
|
+
# Returns the field ids for the edges.
|
|
120
|
+
# """
|
|
121
|
+
# # Concatinate the edges with the edges + ntris + nedges
|
|
122
|
+
# edge_ids = np.array(edge_ids)
|
|
123
|
+
# return np.concatenate((edge_ids, edge_ids + self.ntris + self.nedges))
|
|
124
|
+
|
|
125
|
+
# ########
|
|
126
|
+
# @staticmethod
|
|
127
|
+
# def tet_stiff_mass_submatrix(tet_vertices: np.ndarray,
|
|
128
|
+
# edge_lengths: np.ndarray,
|
|
129
|
+
# local_edge_map: np.ndarray,
|
|
130
|
+
# local_tri_map: np.ndarray,
|
|
131
|
+
# C_stiffness: float,
|
|
132
|
+
# C_mass: float) -> tuple[np.ndarray, np.ndarray]:
|
|
133
|
+
# raise NotImplementedError("tet_stiff_mass_submatrix is not implemented for Legrange2")
|
|
134
|
+
|
|
135
|
+
# @staticmethod
|
|
136
|
+
# def tet_stiff_submatrix(tet_vertices: np.ndarray,
|
|
137
|
+
# edge_lengths: np.ndarray,
|
|
138
|
+
# local_edge_map: np.ndarray,
|
|
139
|
+
# local_tri_map: np.ndarray,
|
|
140
|
+
# C_stiffness: float) -> tuple[np.ndarray, np.ndarray]:
|
|
141
|
+
# raise leg2_tet_stiff(tet_vertices, edge_lengths, local_edge_map, local_tri_map, C_stiffness)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# @staticmethod
|
|
145
|
+
# def tri_stiff_mass_submatrix(tri_vertices: np.ndarray,
|
|
146
|
+
# edge_lengths: np.ndarray,
|
|
147
|
+
# local_edge_map: np.ndarray,
|
|
148
|
+
# C_stiffness: float,
|
|
149
|
+
# C_mass: float) -> tuple[np.ndarray, np.ndarray]:
|
|
150
|
+
# raise NotImplementedError("tri stiff mass is not implemented for Legrange2")
|
|
151
|
+
|
|
152
|
+
# @staticmethod
|
|
153
|
+
# def tri_stiff_submatrix(tri_vertices: np.ndarray,
|
|
154
|
+
# local_edge_map: np.ndarray,
|
|
155
|
+
# C_stiffness: float) -> np.ndarray:
|
|
156
|
+
# return leg2_tri_stiff(tri_vertices, local_edge_map, C_stiffness)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# @staticmethod
|
|
160
|
+
# def tri_stiff_vec_matrix(lcs_vertices: np.ndarray,
|
|
161
|
+
# edge_lengths: np.ndarray,
|
|
162
|
+
# gamma: complex,
|
|
163
|
+
# lcs_Uinc: np.ndarray,
|
|
164
|
+
# DPTs: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
|
165
|
+
# raise NotImplementedError("tri stiff mass is not implemented for Legrange2")
|
|
166
|
+
|
|
167
|
+
# @staticmethod
|
|
168
|
+
# def tri_surf_integral(lcs_vertices: np.ndarray,
|
|
169
|
+
# edge_lengths: np.ndarray,
|
|
170
|
+
# lcs_Uinc: np.ndarray,
|
|
171
|
+
# DPTs: np.ndarray) -> complex:
|
|
172
|
+
# raise NotImplementedError("tri stiff mass is not implemented for Legrange2")
|