emerge 1.0.3__tar.gz → 1.0.5__tar.gz
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-1.0.3 → emerge-1.0.5}/.bumpversion.toml +1 -1
- emerge-1.0.5/.github/ISSUE_TEMPLATE/bug_report.md +25 -0
- {emerge-1.0.3 → emerge-1.0.5}/.github/ISSUE_TEMPLATE/feature_request.md +3 -0
- emerge-1.0.5/.nova/Configuration.json +3 -0
- {emerge-1.0.3 → emerge-1.0.5}/PKG-INFO +2 -3
- {emerge-1.0.3 → emerge-1.0.5}/README.md +1 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/__init__.py +7 -3
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/femdata.py +5 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/ned2_interp.py +73 -30
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/nedelec2.py +1 -0
- emerge-1.0.5/emerge/_emerge/emerge_update.py +63 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/operations.py +6 -3
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/polybased.py +37 -5
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geometry.py +5 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/logsettings.py +26 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/material.py +29 -8
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mesh3d.py +16 -13
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mesher.py +70 -3
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/assembler.py +5 -4
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/curlcurl.py +0 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/generalized_eigen.py +1 -2
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/generalized_eigen_hb.py +1 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/robin_abc_order2.py +0 -1
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/microwave_3d.py +37 -16
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/microwave_bc.py +6 -4
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/microwave_data.py +14 -11
- emerge-1.0.5/emerge/_emerge/plot/pyvista/cmap_maker.py +70 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/pyvista/display.py +93 -36
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/simmodel.py +77 -21
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/simulation_data.py +22 -4
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/solver.py +67 -32
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo10_sgh.py +3 -5
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo11_lumped_element_filter.py +3 -3
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo12_mode_alignment.py +2 -2
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo13_helix_antenna.py +2 -2
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo14_boundary_selection.py +2 -2
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo1_stepped_imp_filter.py +3 -3
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo2_combline_filter.py +2 -2
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo3_coupled_line_filter.py +3 -3
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo4_patch_antenna.py +5 -4
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo5_revolve.py +1 -2
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo6_striplines_with_vias.py +3 -3
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo7_periodic_cells.py +3 -3
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo8_waveguide_bpf_synthesis.py +4 -4
- {emerge-1.0.3 → emerge-1.0.5}/examples/demo9_dielectric_resonator.py +2 -2
- {emerge-1.0.3 → emerge-1.0.5}/pyproject.toml +1 -2
- {emerge-1.0.3 → emerge-1.0.5}/uv.lock +1 -12
- emerge-1.0.3/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- {emerge-1.0.3 → emerge-1.0.5}/.gitignore +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/.python-version +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/LICENSE +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/THIRD_PARTY_LICENSES.md +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/UMFPACK_Install_windows.md +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/UMFPACK_installer_windows.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/__main__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/bc.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/cacherun.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/const.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/coord.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/cs.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/dataset.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/index_interp.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/elements/nedleg2.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/horn.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/modeler.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/pcb.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/pcb_tools/calculator.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/pcb_tools/dxf.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/pcb_tools/macro.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/pmlbox.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/shapes.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo/step.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/geo2d.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/howto.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mth/_cache_check.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mth/common_functions.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mth/integrals.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mth/optimized.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/mth/pairing.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/periodic.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/adaptive_freq.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/periodicbc.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/assembly/robinbc.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/periodic.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/port_functions.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/sc.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/simjob.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/sparam.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/physics/microwave/touchstone.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/display.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/matplotlib/mpldisplay.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/pyvista/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/pyvista/display_settings.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot/simple_plots.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/plot.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/projects/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/projects/_gen_base.txt +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/projects/_load_base.txt +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/projects/generate_project.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/selection.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/settings.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/solve_interfaces/cudss_interface.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/solve_interfaces/pardiso_interface.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/_emerge/system.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/beta/dxf.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/cli.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/ext.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/lib.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/materials/__init__.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/materials/isola.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/materials/rogers.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/plot.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/emerge/pyvista.py +0 -0
- {emerge-1.0.3 → emerge-1.0.5}/src/__init__.py +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Create a report to help us improve
|
|
4
|
+
title: ''
|
|
5
|
+
labels: ''
|
|
6
|
+
assignees: FennisRobert
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
**Describe the bug**
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
**To Reproduce if applicable**
|
|
14
|
+
Provide the script you are running if possible or the lines of code that triggered it.
|
|
15
|
+
|
|
16
|
+
**Logfile**
|
|
17
|
+
By setting `emerge.SImulation('modelname', write_log=True)`, EMerge will dump a logging.log file in `modelname.EMResults/`. You can share this file. Make sure to vet it for potential confidential information and system information you might not want to share. The log file may contain
|
|
18
|
+
- Module version numbers
|
|
19
|
+
- Python version number
|
|
20
|
+
- OS
|
|
21
|
+
- Architecture
|
|
22
|
+
- CPU count
|
|
23
|
+
|
|
24
|
+
**Additional context**
|
|
25
|
+
Add any other context about the problem here.
|
|
@@ -18,3 +18,6 @@ A clear and concise description of any alternative solutions or features you've
|
|
|
18
18
|
|
|
19
19
|
**Additional context**
|
|
20
20
|
Add any other context or screenshots about the feature request here.
|
|
21
|
+
|
|
22
|
+
**IMPORTANT**
|
|
23
|
+
If you propose any support for file imports, please include an example file for me to use. Without file to be included, feature requests will not be worked on.
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: emerge
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: An open source EM FEM simulator in Python
|
|
5
5
|
Project-URL: Homepage, https://github.com/FennisRobert/EMerge
|
|
6
6
|
Project-URL: Issues, https://github.com/FennisRobert/EMerge/issues
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Python: <4.0,>=3.10
|
|
9
|
-
Requires-Dist: cloudpickle>=3.1.1
|
|
10
9
|
Requires-Dist: gmsh<4.14.0,>=4.13.0
|
|
11
10
|
Requires-Dist: joblib>=1.5.1
|
|
12
11
|
Requires-Dist: loguru>=0.7.3
|
|
@@ -33,7 +32,7 @@ Hello everybody. Thanks for showing interest in this repository.
|
|
|
33
32
|
Feel free to download your version of EMerge and start playing around with it!
|
|
34
33
|
If you have suggestions/changes/questions either use the Github issue system or join the Discord using the following link:
|
|
35
34
|
|
|
36
|
-
**https://discord.gg/
|
|
35
|
+
**[Discord Invitation](https://discord.gg/VMftDCZcNz)**
|
|
37
36
|
|
|
38
37
|
## How to install
|
|
39
38
|
|
|
@@ -5,7 +5,7 @@ Hello everybody. Thanks for showing interest in this repository.
|
|
|
5
5
|
Feel free to download your version of EMerge and start playing around with it!
|
|
6
6
|
If you have suggestions/changes/questions either use the Github issue system or join the Discord using the following link:
|
|
7
7
|
|
|
8
|
-
**https://discord.gg/
|
|
8
|
+
**[Discord Invitation](https://discord.gg/VMftDCZcNz)**
|
|
9
9
|
|
|
10
10
|
## How to install
|
|
11
11
|
|
|
@@ -18,7 +18,7 @@ along with this program; if not, see
|
|
|
18
18
|
"""
|
|
19
19
|
import os
|
|
20
20
|
|
|
21
|
-
__version__ = "1.0.
|
|
21
|
+
__version__ = "1.0.5"
|
|
22
22
|
|
|
23
23
|
############################################################
|
|
24
24
|
# HANDLE ENVIRONMENT VARIABLES #
|
|
@@ -30,8 +30,11 @@ os.environ["EMERGE_FILE_LOGLEVEL"] = os.getenv("EMERGE_FILE_LOGLEVEL", default="
|
|
|
30
30
|
os.environ["OMP_NUM_THREADS"] = os.getenv("OMP_NUM_THREADS", default="1")
|
|
31
31
|
os.environ["MKL_NUM_THREADS"] = os.getenv("MKL_NUM_THREADS", default="4")
|
|
32
32
|
os.environ["OPENBLAS_NUM_THREADS"] = NTHREADS
|
|
33
|
+
os.environ["VECLIB_NUM_THREADS"] = NTHREADS
|
|
33
34
|
os.environ["VECLIB_MAXIMUM_THREADS"] = NTHREADS
|
|
34
35
|
os.environ["NUMEXPR_NUM_THREADS"] = NTHREADS
|
|
36
|
+
os.environ["NUMBA_NUM_THREADS"] = "4"
|
|
37
|
+
os.environ.setdefault("NUMBA_THREADING_LAYER", "workqueue")
|
|
35
38
|
|
|
36
39
|
############################################################
|
|
37
40
|
# IMPORT MODULES #
|
|
@@ -44,6 +47,7 @@ LOG_CONTROLLER.set_default()
|
|
|
44
47
|
logger.debug('Importing modules')
|
|
45
48
|
LOG_CONTROLLER._set_log_buffer()
|
|
46
49
|
|
|
50
|
+
import gmsh
|
|
47
51
|
from ._emerge.simmodel import Simulation
|
|
48
52
|
from ._emerge.material import Material, FreqCoordDependent, FreqDependent, CoordDependent
|
|
49
53
|
from ._emerge import bc
|
|
@@ -53,12 +57,12 @@ from ._emerge.coord import Line
|
|
|
53
57
|
from ._emerge import geo
|
|
54
58
|
from ._emerge.selection import Selection, FaceSelection, DomainSelection, EdgeSelection
|
|
55
59
|
from ._emerge.geometry import select
|
|
56
|
-
|
|
60
|
+
from ._emerge.mth.common_functions import norm, coax_rout, coax_rin
|
|
57
61
|
from ._emerge.periodic import RectCell, HexCell
|
|
58
62
|
from ._emerge.mesher import Algorithm2D, Algorithm3D
|
|
59
63
|
from . import lib
|
|
60
64
|
from ._emerge.howto import _HowtoClass
|
|
61
|
-
|
|
65
|
+
from ._emerge.emerge_update import update_emerge
|
|
62
66
|
howto = _HowtoClass()
|
|
63
67
|
|
|
64
68
|
logger.debug('Importing complete!')
|
|
@@ -61,7 +61,7 @@ class FEMBasis:
|
|
|
61
61
|
return matmul(ibasis, np.array(self.interpolate(field, xyzg[0,:], xyzg[1,:], xyzg[2,:], tetids)))
|
|
62
62
|
return func
|
|
63
63
|
|
|
64
|
-
def interpolate(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, tetids: np.ndarray | None = None) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
64
|
+
def interpolate(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, tetids: np.ndarray | None = None, usenan: bool = True) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
65
65
|
raise NotImplementedError()
|
|
66
66
|
|
|
67
67
|
def interpolate_curl(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, constants: np.ndarray, tetids: np.ndarray | None = None, usenan: bool = True) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
@@ -70,6 +70,10 @@ class FEMBasis:
|
|
|
70
70
|
"""
|
|
71
71
|
raise NotImplementedError()
|
|
72
72
|
|
|
73
|
+
def interpolate_error(self, field: np.ndarray, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray, tetids: np.ndarray | None = None, cs: tuple[float, float] = (1.0, 1.0)) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
74
|
+
raise NotImplementedError()
|
|
75
|
+
|
|
76
|
+
|
|
73
77
|
def empty_tet_matrix(self) -> np.ndarray:
|
|
74
78
|
nnz = self.n_tets*self.n_tet_dofs**2
|
|
75
79
|
matrix = np.empty((nnz,), dtype=np.complex128)
|
|
@@ -192,6 +192,7 @@ def ned2_tet_interp(coords: np.ndarray,
|
|
|
192
192
|
Exl = np.zeros(x.shape, dtype=np.complex128)
|
|
193
193
|
Eyl = np.zeros(x.shape, dtype=np.complex128)
|
|
194
194
|
Ezl = np.zeros(x.shape, dtype=np.complex128)
|
|
195
|
+
V1 = (216*V**3)
|
|
195
196
|
for ie in range(6):
|
|
196
197
|
Em1, Em2 = Em1s[ie], Em2s[ie]
|
|
197
198
|
edgeids = l_edge_ids[:, ie]
|
|
@@ -202,11 +203,12 @@ def ned2_tet_interp(coords: np.ndarray,
|
|
|
202
203
|
x1, x2 = xvs[edgeids]
|
|
203
204
|
y1, y2 = yvs[edgeids]
|
|
204
205
|
z1, z2 = zvs[edgeids]
|
|
205
|
-
|
|
206
|
+
F1 = (a1 + b1*x + c1*y + d1*z)
|
|
207
|
+
F2 = (a2 + b2*x + c2*y + d2*z)
|
|
206
208
|
L = np.sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)
|
|
207
|
-
ex = L*(Em1*
|
|
208
|
-
ey = L*(Em1*
|
|
209
|
-
ez = L*(Em1*
|
|
209
|
+
ex = L*(Em1*F1 + Em2*F2)*(b1*F2 - b2*F1)/V1
|
|
210
|
+
ey = L*(Em1*F1 + Em2*F2)*(c1*F2 - c2*F1)/V1
|
|
211
|
+
ez = L*(Em1*F1 + Em2*F2)*(d1*F2 - d2*F1)/V1
|
|
210
212
|
|
|
211
213
|
Exl += ex
|
|
212
214
|
Eyl += ey
|
|
@@ -226,10 +228,16 @@ def ned2_tet_interp(coords: np.ndarray,
|
|
|
226
228
|
|
|
227
229
|
L1 = np.sqrt((x1-x3)**2 + (y1-y3)**2 + (z1-z3)**2)
|
|
228
230
|
L2 = np.sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
|
|
232
|
+
F1 = (a1 + b1*x + c1*y + d1*z)
|
|
233
|
+
F2 = (a2 + b2*x + c2*y + d2*z)
|
|
234
|
+
F3 = (a3 + b3*x + c3*y + d3*z)
|
|
235
|
+
|
|
236
|
+
Q1 = Em1*L1*F2
|
|
237
|
+
Q2 = Em2*L2*F3
|
|
238
|
+
ex = (-Q1*(b1*F3 - b3*F1) + Q2*(b1*F2 - b2*F1))/V1
|
|
239
|
+
ey = (-Q1*(c1*F3 - c3*F1) + Q2*(c1*F2 - c2*F1))/V1
|
|
240
|
+
ez = (-Q1*(d1*F3 - d3*F1) + Q2*(d1*F2 - d2*F1))/V1
|
|
233
241
|
|
|
234
242
|
Exl += ex
|
|
235
243
|
Eyl += ey
|
|
@@ -322,6 +330,10 @@ def ned2_tet_interp_curl(coords: np.ndarray,
|
|
|
322
330
|
Exl = np.zeros(x.shape, dtype=np.complex128)
|
|
323
331
|
Eyl = np.zeros(x.shape, dtype=np.complex128)
|
|
324
332
|
Ezl = np.zeros(x.shape, dtype=np.complex128)
|
|
333
|
+
|
|
334
|
+
V1 = (216*V**3)
|
|
335
|
+
V2 = (72*V**3)
|
|
336
|
+
|
|
325
337
|
for ie in range(6):
|
|
326
338
|
Em1, Em2 = Em1s[ie], Em2s[ie]
|
|
327
339
|
edgeids = l_edge_ids[:, ie]
|
|
@@ -334,9 +346,35 @@ def ned2_tet_interp_curl(coords: np.ndarray,
|
|
|
334
346
|
z1, z2 = zvs[edgeids]
|
|
335
347
|
|
|
336
348
|
L = np.sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
349
|
+
C1 = Em1*a1
|
|
350
|
+
C2 = Em1*b1
|
|
351
|
+
C3 = Em1*c1
|
|
352
|
+
C4 = Em1*c2
|
|
353
|
+
C5 = Em2*a2
|
|
354
|
+
C6 = Em2*b2
|
|
355
|
+
C7 = Em2*c1
|
|
356
|
+
C8 = Em2*c2
|
|
357
|
+
C9 = Em1*b2
|
|
358
|
+
C10 = Em2*b1
|
|
359
|
+
D1 = c1*d2
|
|
360
|
+
D2 = c2*d1
|
|
361
|
+
D3 = d1*d2
|
|
362
|
+
D4 = d1*d1
|
|
363
|
+
D5 = c2*d2
|
|
364
|
+
D6 = d2*d2
|
|
365
|
+
D7 = b1*d2
|
|
366
|
+
D8 = b2*d1
|
|
367
|
+
D9 = c1*d1
|
|
368
|
+
D10 = b2*d2
|
|
369
|
+
D11 = b1*c2
|
|
370
|
+
D12 = b2*c1
|
|
371
|
+
D13 = c1*c2
|
|
372
|
+
D14 = c1*c1
|
|
373
|
+
D15 = b2*c2
|
|
374
|
+
|
|
375
|
+
ex = L*(-C1*D1 + C1*D2 - C2*D1*x + C2*D2*x - C3*D1*y + C3*D2*y - C3*D3*z + C4*D4*z - C5*D1 + C5*D2 - C6*D1*x + C6*D2*x - C7*D5*y - C7*D6*z + C8*D2*y + C8*D3*z)/V2
|
|
376
|
+
ey = L*(C1*D7 - C1*D8 + C2*D7*x - C2*D8*x + C2*D1*y + C2*D3*z - C9*D9*y - C9*D4*z + C5*D7 - C5*D8 + C10*D10*x + C10*D5*y + C10*D6*z - C6*D8*x - C6*D2*y - C6*D3*z)/V2
|
|
377
|
+
ez = L*(-C1*D11 + C1*D12 - C2*D11*x + C2*D12*x - C2*D13*y - C2*D2*z + C9*D14*y + C9*D9*z - C5*D11 + C5*D12 - C10*D15*x - C10*c2*c2*y - C10*D5*z + C6*D12*x + C6*D13*y + C6*D1*z)/V2
|
|
340
378
|
Exl += ex
|
|
341
379
|
Eyl += ey
|
|
342
380
|
Ezl += ez
|
|
@@ -355,10 +393,28 @@ def ned2_tet_interp_curl(coords: np.ndarray,
|
|
|
355
393
|
|
|
356
394
|
L1 = np.sqrt((x1-x3)**2 + (y1-y3)**2 + (z1-z3)**2)
|
|
357
395
|
L2 = np.sqrt((x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2)
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
396
|
+
F1 = (a3 + b3*x + c3*y + d3*z)
|
|
397
|
+
F2 = (a1 + b1*x + c1*y + d1*z)
|
|
398
|
+
F3 = (a2 + b2*x + c2*y + d2*z)
|
|
399
|
+
N1 = (d1*F1 - d3*F2)
|
|
400
|
+
N2 = (c1*F1 - c3*F2)
|
|
401
|
+
N3 = (c1*d3 - c3*d1)
|
|
402
|
+
N4 = (d1*F3 - d2*F2)
|
|
403
|
+
N5 = (c1*F3 - c2*F2)
|
|
404
|
+
D1 = c1*d2
|
|
405
|
+
D2 = c2*d1
|
|
406
|
+
N6 = (D1 - D2)
|
|
407
|
+
N7 = (b1*F1 - b3*F2)
|
|
408
|
+
N8 = (b1*d3 - b3*d1)
|
|
409
|
+
N9 = (b1*F3 - b2*F2)
|
|
410
|
+
D7 = b1*d2
|
|
411
|
+
D8 = b2*d1
|
|
412
|
+
N10 = (D7 - D8)
|
|
413
|
+
D11 = b1*c2
|
|
414
|
+
D12 = b2*c1
|
|
415
|
+
ex = (Em1*L1*(-c2*N1 + d2*N2 + 2*N3*F3) - Em2*L2*(-c3*N4 + d3*N5 + 2*N6*F1))/V1
|
|
416
|
+
ey = (-Em1*L1*(-b2*N1 + d2*N7 + 2*N8*F3) + Em2*L2*(-b3*N4 + d3*N9 + 2*N10*F1))/V1
|
|
417
|
+
ez = (Em1*L1*(-b2*N2 + c2*N7 + 2*(b1*c3 - b3*c1)*F3) - Em2*L2*(-b3*N5 + c3*N9 + 2*(D11 - D12)*F1))/V1
|
|
362
418
|
|
|
363
419
|
Exl += ex
|
|
364
420
|
Eyl += ey
|
|
@@ -445,8 +501,7 @@ def ned2_tri_interp(coords: np.ndarray,
|
|
|
445
501
|
|
|
446
502
|
Exl = np.zeros(x.shape, dtype=np.complex128)
|
|
447
503
|
Eyl = np.zeros(x.shape, dtype=np.complex128)
|
|
448
|
-
|
|
449
|
-
|
|
504
|
+
|
|
450
505
|
for ie in range(3):
|
|
451
506
|
Em1, Em2 = Em1s[ie], Em2s[ie]
|
|
452
507
|
edgeids = l_edge_ids[:, ie]
|
|
@@ -534,17 +589,11 @@ def ned2_tri_interp_full(coords: np.ndarray,
|
|
|
534
589
|
yvs = nodes[1, tris[:,itri]]
|
|
535
590
|
|
|
536
591
|
a_s, b_s, c_s, A = tri_coefficients(xvs, yvs)
|
|
537
|
-
|
|
538
592
|
e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14 = Etri
|
|
539
593
|
|
|
540
594
|
a1, a2, a3 = a_s
|
|
541
595
|
b1, b2, b3 = b_s
|
|
542
596
|
c1, c2, c3 = c_s
|
|
543
|
-
|
|
544
|
-
# original Nedelec-1 order 2 formulation
|
|
545
|
-
# ex = (e1*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) + e2*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a2 + b2*x + c2*y) + e3*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) - e4*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e5*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e6*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a3 + b3*x + c3*y) + e7*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + e8*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y))/(8*A**3)
|
|
546
|
-
# ey = (e1*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) + e2*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a2 + b2*x + c2*y) + e3*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) - e4*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e5*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e6*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a3 + b3*x + c3*y) + e7*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + e8*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y))/(8*A**3)
|
|
547
|
-
# ez = (a1 + b1*x + c1*y)*(e10*(-A + a1 + b1*x + c1*y) + e11*(-A + a1 + b1*x + c1*y) + e12*(a2 + b2*x + c2*y) + e13*(a2 + b2*x + c2*y) + e14*(a2 + b2*x + c2*y) + e9*(-A + a1 + b1*x + c1*y))/(2*A**2)
|
|
548
597
|
|
|
549
598
|
# New Nedelec-1 order 2 formulation
|
|
550
599
|
ex = (-2*A*(e1*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y)) + e2*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y)) + e3*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))) - e4*((b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + (b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a1 + b1*x + c1*y)) - e5*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a1 - a2 + b1*x - b2*x + c1*y - c2*y) - e6*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a2 - a3 + b2*x - b3*x + c2*y - c3*y) - e7*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a1 - a3 + b1*x - b3*x + c1*y - c3*y) + e8*((b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + (b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y)))/(8*A**3)
|
|
@@ -617,18 +666,12 @@ def ned2_tri_interp_curl(coords: np.ndarray,
|
|
|
617
666
|
yvs = nodes[1, tris[:,itri]]
|
|
618
667
|
|
|
619
668
|
a_s, b_s, c_s, A = tri_coefficients(xvs, yvs)
|
|
620
|
-
|
|
621
669
|
e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14 = Etri
|
|
622
670
|
|
|
623
671
|
a1, a2, a3 = a_s
|
|
624
672
|
b1, b2, b3 = b_s
|
|
625
673
|
c1, c2, c3 = c_s
|
|
626
674
|
|
|
627
|
-
# original Nedelec-1 order 2 formulation
|
|
628
|
-
#hx = (4*A*(c1*(e10*(-A + a1 + b1*x + c1*y) + e11*(-A + a1 + b1*x + c1*y) + e12*(a2 + b2*x + c2*y) + e13*(a2 + b2*x + c2*y) + e14*(a2 + b2*x + c2*y) + e9*(-A + a1 + b1*x + c1*y)) + (a1 + b1*x + c1*y)*(c1*e10 + c1*e11 + c1*e9 + c2*e12 + c2*e13 + c2*e14)) + jB*(e1*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) + e2*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a2 + b2*x + c2*y) + e3*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) - e4*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e5*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e6*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a3 + b3*x + c3*y) + e7*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + e8*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y)))/(8*A**3)
|
|
629
|
-
# hy = (4*A*(b1*(e10*(-A + a1 + b1*x + c1*y) + e11*(-A + a1 + b1*x + c1*y) + e12*(a2 + b2*x + c2*y) + e13*(a2 + b2*x + c2*y) + e14*(a2 + b2*x + c2*y) + e9*(-A + a1 + b1*x + c1*y)) + (a1 + b1*x + c1*y)*(b1*e10 + b1*e11 + b1*e9 + b2*e12 + b2*e13 + b2*e14)) - jB*(e1*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) + e2*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a2 + b2*x + c2*y) + e3*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a1 + b1*x + c1*y) - e4*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e5*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + e6*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a3 + b3*x + c3*y) + e7*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + e8*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y)))/(8*A**3)
|
|
630
|
-
# hz = (-3*a1*b1*c2*e1 - 3*a1*b1*c3*e3 + 3*a1*b2*c1*e1 + a1*b2*c3*e4 + a1*b2*c3*e8 + 3*a1*b3*c1*e3 - a1*b3*c2*e4 - a1*b3*c2*e8 - 3*a2*b1*c2*e5 + 2*a2*b1*c3*e4 - a2*b1*c3*e8 + 3*a2*b2*c1*e5 - 3*a2*b2*c3*e2 - 2*a2*b3*c1*e4 + a2*b3*c1*e8 + 3*a2*b3*c2*e2 + a3*b1*c2*e4 - 2*a3*b1*c2*e8 - 3*a3*b1*c3*e7 - a3*b2*c1*e4 + 2*a3*b2*c1*e8 - 3*a3*b2*c3*e6 + 3*a3*b3*c1*e7 + 3*a3*b3*c2*e6 - 3*b1**2*c2*e1*x - 3*b1**2*c3*e3*x + 3*b1*b2*c1*e1*x - 3*b1*b2*c2*e5*x + 3*b1*b2*c3*e4*x + 3*b1*b3*c1*e3*x - 3*b1*b3*c2*e8*x - 3*b1*b3*c3*e7*x - 3*b1*c1*c2*e1*y - 3*b1*c1*c3*e3*y - 3*b1*c2**2*e5*y + 3*b1*c2*c3*e4*y - 3*b1*c2*c3*e8*y - 3*b1*c3**2*e7*y + 3*b2**2*c1*e5*x - 3*b2**2*c3*e2*x - 3*b2*b3*c1*e4*x + 3*b2*b3*c1*e8*x + 3*b2*b3*c2*e2*x - 3*b2*b3*c3*e6*x + 3*b2*c1**2*e1*y + 3*b2*c1*c2*e5*y + 3*b2*c1*c3*e8*y - 3*b2*c2*c3*e2*y - 3*b2*c3**2*e6*y + 3*b3**2*c1*e7*x + 3*b3**2*c2*e6*x + 3*b3*c1**2*e3*y - 3*b3*c1*c2*e4*y + 3*b3*c1*c3*e7*y + 3*b3*c2**2*e2*y + 3*b3*c2*c3*e6*y)/(8*A**3)
|
|
631
|
-
|
|
632
675
|
# New Nedelec-1 order 2 formulation
|
|
633
676
|
hx = (4*A*(2*c1*e12*(a2 + b2*x + c2*y) + 2*c1*e14*(a3 + b3*x + c3*y) + c1*e9*(a1 + b1*x + c1*y) - c1*e9*(A - a1 - b1*x - c1*y) + c2*e10*(a2 + b2*x + c2*y) - c2*e10*(A - a2 - b2*x - c2*y) + 2*c2*e12*(a1 + b1*x + c1*y) + 2*c2*e13*(a3 + b3*x + c3*y) + c3*e11*(a3 + b3*x + c3*y) - c3*e11*(A - a3 - b3*x - c3*y) + 2*c3*e13*(a2 + b2*x + c2*y) + 2*c3*e14*(a1 + b1*x + c1*y)) + jB*(2*A*(e1*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y)) + e2*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y)) + e3*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))) + e4*((c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + (c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a1 + b1*x + c1*y)) + e5*(c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a1 - a2 + b1*x - b2*x + c1*y - c2*y) + e6*(c2*(a3 + b3*x + c3*y) - c3*(a2 + b2*x + c2*y))*(a2 - a3 + b2*x - b3*x + c2*y - c3*y) + e7*(c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a1 - a3 + b1*x - b3*x + c1*y - c3*y) - e8*((c1*(a2 + b2*x + c2*y) - c2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + (c1*(a3 + b3*x + c3*y) - c3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y))))/(8*A**3)
|
|
634
677
|
hy = (4*A*(-2*b1*e12*(a2 + b2*x + c2*y) - 2*b1*e14*(a3 + b3*x + c3*y) - b1*e9*(a1 + b1*x + c1*y) + b1*e9*(A - a1 - b1*x - c1*y) - b2*e10*(a2 + b2*x + c2*y) + b2*e10*(A - a2 - b2*x - c2*y) - 2*b2*e12*(a1 + b1*x + c1*y) - 2*b2*e13*(a3 + b3*x + c3*y) - b3*e11*(a3 + b3*x + c3*y) + b3*e11*(A - a3 - b3*x - c3*y) - 2*b3*e13*(a2 + b2*x + c2*y) - 2*b3*e14*(a1 + b1*x + c1*y)) - jB*(2*A*(e1*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y)) + e2*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y)) + e3*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))) + e4*((b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y) + (b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a1 + b1*x + c1*y)) + e5*(b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a1 - a2 + b1*x - b2*x + c1*y - c2*y) + e6*(b2*(a3 + b3*x + c3*y) - b3*(a2 + b2*x + c2*y))*(a2 - a3 + b2*x - b3*x + c2*y - c3*y) + e7*(b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a1 - a3 + b1*x - b3*x + c1*y - c3*y) - e8*((b1*(a2 + b2*x + c2*y) - b2*(a1 + b1*x + c1*y))*(a3 + b3*x + c3*y) + (b1*(a3 + b3*x + c3*y) - b3*(a1 + b1*x + c1*y))*(a2 + b2*x + c2*y))))/(8*A**3)
|
|
@@ -637,4 +680,4 @@ def ned2_tri_interp_curl(coords: np.ndarray,
|
|
|
637
680
|
Ex[inside] = hx*dc[0,0]
|
|
638
681
|
Ey[inside] = hy*dc[1,1]
|
|
639
682
|
Ez[inside] = hz*dc[2,2]
|
|
640
|
-
return Ex, Ey, Ez
|
|
683
|
+
return Ex, Ey, Ez
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
from importlib import import_module
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from loguru import logger
|
|
7
|
+
except ImportError:
|
|
8
|
+
# Fallback if loguru isn't installed
|
|
9
|
+
class _Logger:
|
|
10
|
+
def info(self, msg): print(f"[INFO] {msg}")
|
|
11
|
+
def warning(self, msg): print(f"[WARN] {msg}")
|
|
12
|
+
def error(self, msg): print(f"[ERROR] {msg}")
|
|
13
|
+
logger = _Logger()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def update_emerge(branch: str = "main", confirm: bool = True, _dryrun: bool = False) -> str | None:
|
|
17
|
+
"""
|
|
18
|
+
Update the EMerge library directly from GitHub.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
branch : str, optional
|
|
23
|
+
The git branch or tag to install from. Default is "main".
|
|
24
|
+
confirm : bool, optional
|
|
25
|
+
If True, asks the user for confirmation before updating.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
str | None
|
|
30
|
+
The updated version string if successful, otherwise None.
|
|
31
|
+
"""
|
|
32
|
+
logger.warning(
|
|
33
|
+
"You are about to update EMerge from GitHub. "
|
|
34
|
+
"This is an experimental feature and may overwrite your installed version."
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
if confirm:
|
|
38
|
+
ans = input("Do you wish to proceed? [y/N] ").strip().lower()
|
|
39
|
+
if ans != "y":
|
|
40
|
+
logger.info("Update aborted by user.")
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
url = f"git+https://github.com/FennisRobert/EMerge.git@{branch}"
|
|
44
|
+
logger.info(f"Updating EMerge from branch/tag '{branch}'...")
|
|
45
|
+
|
|
46
|
+
if not _dryrun:
|
|
47
|
+
try:
|
|
48
|
+
subprocess.check_call(
|
|
49
|
+
[sys.executable, "-m", "pip", "install", "--upgrade", "--force-reinstall", url]
|
|
50
|
+
)
|
|
51
|
+
except subprocess.CalledProcessError as e:
|
|
52
|
+
logger.error(f"Update failed: {e}")
|
|
53
|
+
return None
|
|
54
|
+
else:
|
|
55
|
+
logger.info('Dry run... No update executed!')
|
|
56
|
+
try:
|
|
57
|
+
emerge = import_module("emerge")
|
|
58
|
+
version = getattr(emerge, "__version__", "unknown")
|
|
59
|
+
logger.info(f"Successfully updated to EMerge version {version}.")
|
|
60
|
+
return version
|
|
61
|
+
except Exception as e:
|
|
62
|
+
logger.error(f"Update installed but could not retrieve version: {e}")
|
|
63
|
+
return None
|
|
@@ -51,11 +51,13 @@ def add(main: T, tool: T,
|
|
|
51
51
|
GeoSurface | GeoVolume
|
|
52
52
|
A new object that is the union of the main and tool objects.
|
|
53
53
|
'''
|
|
54
|
+
|
|
54
55
|
out_dim_tags, out_dim_tags_map = gmsh.model.occ.fuse(main.dimtags, tool.dimtags, removeObject=remove_object, removeTool=remove_tool)
|
|
55
56
|
if out_dim_tags[0][0] == 3:
|
|
56
57
|
output = GeoVolume([dt[1] for dt in out_dim_tags])._take_tools(tool,main)
|
|
57
58
|
elif out_dim_tags[0][0] == 2:
|
|
58
59
|
output = GeoSurface([dt[1] for dt in out_dim_tags])._take_tools(tool,main)
|
|
60
|
+
|
|
59
61
|
if remove_object:
|
|
60
62
|
main._exists = False
|
|
61
63
|
if remove_tool:
|
|
@@ -300,15 +302,16 @@ def unite(*objects: GeoObject) -> GeoObject:
|
|
|
300
302
|
GeoObject: The resultant object
|
|
301
303
|
"""
|
|
302
304
|
main, *rest = objects
|
|
305
|
+
|
|
303
306
|
if not rest:
|
|
304
307
|
return main
|
|
308
|
+
|
|
305
309
|
main._exists = False
|
|
306
310
|
dts = []
|
|
307
|
-
for other in
|
|
311
|
+
for other in objects:
|
|
308
312
|
dts.extend(other.dimtags)
|
|
309
313
|
other._exists = False
|
|
310
|
-
|
|
311
|
-
new_dimtags, mapping = gmsh.model.occ.fuse(main.dimtags, dts)
|
|
314
|
+
new_dimtags, mapping = gmsh.model.occ.fuse(dts, main.dimtags)
|
|
312
315
|
|
|
313
316
|
new_obj = GeoObject.from_dimtags(new_dimtags)._take_tools(*objects)
|
|
314
317
|
new_obj.set_material(main.material)
|
|
@@ -24,6 +24,7 @@ from typing import Generator, Callable
|
|
|
24
24
|
from ..selection import FaceSelection
|
|
25
25
|
from typing import Literal
|
|
26
26
|
from functools import reduce
|
|
27
|
+
from loguru import logger
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
def _discretize_curve(xfunc: Callable, yfunc: Callable,
|
|
@@ -238,7 +239,8 @@ class XYPolygon:
|
|
|
238
239
|
def __init__(self,
|
|
239
240
|
xs: np.ndarray | list | tuple | None = None,
|
|
240
241
|
ys: np.ndarray | list | tuple | None = None,
|
|
241
|
-
cs: CoordinateSystem | None = None
|
|
242
|
+
cs: CoordinateSystem | None = None,
|
|
243
|
+
resolution: float = 1e-6):
|
|
242
244
|
"""Constructs an XY-plane placed polygon.
|
|
243
245
|
|
|
244
246
|
Args:
|
|
@@ -256,6 +258,7 @@ class XYPolygon:
|
|
|
256
258
|
self.fillets: list[tuple[float, int]] = []
|
|
257
259
|
|
|
258
260
|
self._cs: CoordinateSystem = cs
|
|
261
|
+
self.resolution: float = resolution
|
|
259
262
|
|
|
260
263
|
@property
|
|
261
264
|
def center(self) -> tuple[float, float]:
|
|
@@ -279,7 +282,7 @@ class XYPolygon:
|
|
|
279
282
|
The XYPolygon does not store redundant points p[0]==p[N] so if these are
|
|
280
283
|
the same, this function will remove the last point.
|
|
281
284
|
"""
|
|
282
|
-
if np.sqrt((self.x[-1]-self.x[0])**2 + (self.y[-1]-self.y[0])**2) < 1e-
|
|
285
|
+
if np.sqrt((self.x[-1]-self.x[0])**2 + (self.y[-1]-self.y[0])**2) < 1e-9:
|
|
283
286
|
self.x = self.x[:-1]
|
|
284
287
|
self.y = self.y[:-1]
|
|
285
288
|
|
|
@@ -329,6 +332,23 @@ class XYPolygon:
|
|
|
329
332
|
self.fillets.append((radius, i))
|
|
330
333
|
return self
|
|
331
334
|
|
|
335
|
+
def _cleanup(self, resolution: float | None = None) -> None:
|
|
336
|
+
# Compute differences between consecutive points
|
|
337
|
+
if resolution is None:
|
|
338
|
+
resolution = self.resolution
|
|
339
|
+
dx = np.diff(self.x)
|
|
340
|
+
dy = np.diff(self.y)
|
|
341
|
+
|
|
342
|
+
# Distances between consecutive points
|
|
343
|
+
dist = np.sqrt(dx**2 + dy**2)
|
|
344
|
+
|
|
345
|
+
# Keep the first point, then points where distance >= threshold
|
|
346
|
+
keep = np.insert(dist >= resolution, 1, True)
|
|
347
|
+
|
|
348
|
+
# Apply mask
|
|
349
|
+
self.x = self.x[keep]
|
|
350
|
+
self.y = self.y[keep]
|
|
351
|
+
|
|
332
352
|
def _make_wire(self, cs: CoordinateSystem) -> tuple[list[int], list[int], int]:
|
|
333
353
|
"""Turns the XYPolygon object into a GeoPolygon that is embedded in 3D space.
|
|
334
354
|
|
|
@@ -343,10 +363,23 @@ class XYPolygon:
|
|
|
343
363
|
self._check()
|
|
344
364
|
|
|
345
365
|
ptags = []
|
|
366
|
+
|
|
346
367
|
xg, yg, zg = cs.in_global_cs(self.x, self.y, 0*self.x)
|
|
347
368
|
|
|
369
|
+
points = dict()
|
|
348
370
|
for x,y,z in zip(xg, yg, zg):
|
|
349
|
-
|
|
371
|
+
reuse = False
|
|
372
|
+
for key, (px, py, pz) in points.items():
|
|
373
|
+
if ((x-px)**2 + (y-py)**2 + (z-pz)**2)**0.5 < 1e-12:
|
|
374
|
+
ptags.append(key)
|
|
375
|
+
reuse = True
|
|
376
|
+
break
|
|
377
|
+
if reuse:
|
|
378
|
+
logger.warning(f'Reusing {ptags[-1]}')
|
|
379
|
+
continue
|
|
380
|
+
ptag = gmsh.model.occ.add_point(x,y,z)
|
|
381
|
+
points[ptag] = (x,y,z)
|
|
382
|
+
ptags.append(ptag)
|
|
350
383
|
|
|
351
384
|
lines = []
|
|
352
385
|
for i1, p1 in enumerate(ptags):
|
|
@@ -375,6 +408,7 @@ class XYPolygon:
|
|
|
375
408
|
Returns:
|
|
376
409
|
GeoPolygon: The resultant 3D GeoPolygon object.
|
|
377
410
|
"""
|
|
411
|
+
self._cleanup()
|
|
378
412
|
ptags, lines, wiretag = self._make_wire(cs)
|
|
379
413
|
surftag = gmsh.model.occ.add_plane_surface([wiretag,])
|
|
380
414
|
poly = GeoPolygon([surftag,], name=name)
|
|
@@ -635,8 +669,6 @@ class Curve(GeoEdge):
|
|
|
635
669
|
self.dstart: tuple[float, float, float] = (p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2])
|
|
636
670
|
|
|
637
671
|
|
|
638
|
-
|
|
639
|
-
|
|
640
672
|
@property
|
|
641
673
|
def p0(self) -> tuple[float, float, float]:
|
|
642
674
|
"""The start coordinate
|
|
@@ -60,6 +60,11 @@ class _GeometryManager:
|
|
|
60
60
|
model = self.active
|
|
61
61
|
return [geo for geo in self.geometry_list[model].values() if geo._exists]
|
|
62
62
|
|
|
63
|
+
def set_geometries(self, geos: list[GeoObject], model: str | None = None):
|
|
64
|
+
if model is None:
|
|
65
|
+
model = self.active
|
|
66
|
+
self.geometry_list[model] = geos
|
|
67
|
+
|
|
63
68
|
def all_names(self, model: str | None = None) -> set[str]:
|
|
64
69
|
if model is None:
|
|
65
70
|
model = self.active
|
|
@@ -21,11 +21,25 @@ from typing import Literal
|
|
|
21
21
|
from pathlib import Path
|
|
22
22
|
import os
|
|
23
23
|
from collections import deque
|
|
24
|
-
|
|
24
|
+
import platform
|
|
25
|
+
import importlib
|
|
26
|
+
import multiprocessing
|
|
27
|
+
|
|
28
|
+
packages = ["numba", "numpy", "scipy", "gmsh", "joblib","matplotlib","pyvista","mkl","cloudpickle","scikit-umfpack","nvidia-cudss-cu12","nvmath-python[cu12]","cupy-cuda12x","ezdxf"]
|
|
29
|
+
|
|
30
|
+
def get_version(pkg_name):
|
|
31
|
+
try:
|
|
32
|
+
module = importlib.import_module(pkg_name)
|
|
33
|
+
return getattr(module, "__version__", "unknown")
|
|
34
|
+
except ImportError:
|
|
35
|
+
return "not installed"
|
|
36
|
+
|
|
25
37
|
_LOG_BUFFER = deque()
|
|
26
38
|
|
|
27
39
|
def _log_sink(message):
|
|
28
40
|
_LOG_BUFFER.append(message)
|
|
41
|
+
|
|
42
|
+
|
|
29
43
|
############################################################
|
|
30
44
|
# FORMATS #
|
|
31
45
|
############################################################
|
|
@@ -93,6 +107,17 @@ class LogController:
|
|
|
93
107
|
logger.opt(depth=6).log(msg.record["level"].name, msg.record["message"])
|
|
94
108
|
_LOG_BUFFER.clear()
|
|
95
109
|
|
|
110
|
+
def _sys_info(self) -> None:
|
|
111
|
+
for pkg in packages:
|
|
112
|
+
logger.trace(f" (!) {pkg} version: {get_version(pkg)}")
|
|
113
|
+
|
|
114
|
+
logger.trace(f" (!) OS: {platform.system()} {platform.release()} ({platform.version()})")
|
|
115
|
+
logger.trace(f" (!) Architecture: {platform.machine()} ({platform.architecture()[0]})")
|
|
116
|
+
logger.trace(f" (!) Processor: {platform.processor()}")
|
|
117
|
+
logger.trace(f" (!) Python build: {platform.python_build()}")
|
|
118
|
+
logger.trace(f" (!) Python version: {platform.python_version()} [{sys.version}]")
|
|
119
|
+
logger.trace(f" (!) CPU cores: {multiprocessing.cpu_count()}")
|
|
120
|
+
|
|
96
121
|
def set_std_loglevel(self, loglevel: str):
|
|
97
122
|
handler = {"sink": sys.stdout,
|
|
98
123
|
"level": loglevel,
|