emerge 0.6.6__py3-none-any.whl → 0.6.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 +2 -2
- emerge/_emerge/_cache_check.py +1 -1
- emerge/_emerge/elements/femdata.py +3 -2
- emerge/_emerge/elements/index_interp.py +1 -2
- emerge/_emerge/elements/ned2_interp.py +16 -16
- emerge/_emerge/elements/nedelec2.py +17 -6
- emerge/_emerge/elements/nedleg2.py +21 -9
- emerge/_emerge/geo/__init__.py +1 -1
- emerge/_emerge/geo/horn.py +0 -1
- emerge/_emerge/geo/modeler.py +1 -1
- emerge/_emerge/geo/operations.py +44 -4
- emerge/_emerge/geo/pcb.py +44 -9
- emerge/_emerge/geo/pcb_tools/calculator.py +2 -3
- emerge/_emerge/geo/pmlbox.py +35 -11
- emerge/_emerge/geo/shapes.py +61 -26
- emerge/_emerge/geometry.py +4 -4
- emerge/_emerge/material.py +326 -81
- emerge/_emerge/mesh3d.py +14 -8
- emerge/_emerge/physics/microwave/assembly/assembler.py +43 -20
- emerge/_emerge/physics/microwave/microwave_3d.py +57 -44
- emerge/_emerge/physics/microwave/microwave_bc.py +12 -8
- emerge/_emerge/physics/microwave/microwave_data.py +74 -5
- emerge/_emerge/plot/pyvista/display.py +132 -24
- emerge/_emerge/plot/simple_plots.py +1 -1
- emerge/_emerge/simmodel.py +22 -13
- emerge/_emerge/solver.py +49 -22
- {emerge-0.6.6.dist-info → emerge-0.6.8.dist-info}/METADATA +1 -1
- {emerge-0.6.6.dist-info → emerge-0.6.8.dist-info}/RECORD +31 -31
- {emerge-0.6.6.dist-info → emerge-0.6.8.dist-info}/licenses/LICENSE +2 -2
- {emerge-0.6.6.dist-info → emerge-0.6.8.dist-info}/WHEEL +0 -0
- {emerge-0.6.6.dist-info → emerge-0.6.8.dist-info}/entry_points.txt +0 -0
|
@@ -26,7 +26,7 @@ from typing import Iterable, Literal, Callable, Any
|
|
|
26
26
|
from ..display import BaseDisplay
|
|
27
27
|
from .display_settings import PVDisplaySettings
|
|
28
28
|
from matplotlib.colors import ListedColormap
|
|
29
|
-
|
|
29
|
+
from itertools import cycle
|
|
30
30
|
### Color scale
|
|
31
31
|
|
|
32
32
|
# Define the colors we want to use
|
|
@@ -40,6 +40,40 @@ cmap_names = Literal['bgy','bgyw','kbc','blues','bmw','bmy','kgy','gray','dimgra
|
|
|
40
40
|
'bkr','bky','coolwarm','gwv','bjy','bwy','cwr','colorwheel','isolum','rainbow','fire',
|
|
41
41
|
'cet_fire','gouldian','kbgyw','cwr','CET_CBL1','CET_CBL3','CET_D1A']
|
|
42
42
|
|
|
43
|
+
|
|
44
|
+
def _gen_c_cycle():
|
|
45
|
+
colors = [
|
|
46
|
+
"#0000aa",
|
|
47
|
+
"#aa0000",
|
|
48
|
+
"#009900",
|
|
49
|
+
"#990099",
|
|
50
|
+
"#994400",
|
|
51
|
+
"#005588"
|
|
52
|
+
]
|
|
53
|
+
return cycle(colors)
|
|
54
|
+
|
|
55
|
+
C_CYCLE = _gen_c_cycle()
|
|
56
|
+
|
|
57
|
+
class _RunState:
|
|
58
|
+
|
|
59
|
+
def __init__(self):
|
|
60
|
+
self.state: bool = False
|
|
61
|
+
self.ctr: int = 0
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def run(self):
|
|
65
|
+
self.state = True
|
|
66
|
+
self.ctr = 0
|
|
67
|
+
|
|
68
|
+
def stop(self):
|
|
69
|
+
self.state = False
|
|
70
|
+
self.ctr = 0
|
|
71
|
+
|
|
72
|
+
def step(self):
|
|
73
|
+
self.ctr += 1
|
|
74
|
+
|
|
75
|
+
ANIM_STATE = _RunState()
|
|
76
|
+
|
|
43
77
|
def gen_cmap(mesh, N: int = 256):
|
|
44
78
|
# build a linear grid of data‐values (not strictly needed for pure colormap)
|
|
45
79
|
vmin, vmax = mesh['values'].min(), mesh['values'].max()
|
|
@@ -201,6 +235,7 @@ class PVDisplay(BaseDisplay):
|
|
|
201
235
|
self._stop: bool = False
|
|
202
236
|
self._objs: list[_AnimObject] = []
|
|
203
237
|
self._do_animate: bool = False
|
|
238
|
+
self._closed_via_x: bool = False
|
|
204
239
|
self._Nsteps: int = 0
|
|
205
240
|
self._fps: int = 25
|
|
206
241
|
self._ruler: ScreenRuler = ScreenRuler(self, 0.001)
|
|
@@ -216,6 +251,15 @@ class PVDisplay(BaseDisplay):
|
|
|
216
251
|
self._ctr: int = 0
|
|
217
252
|
|
|
218
253
|
self.camera_position = (1, -1, 1) # +X, +Z, -Y
|
|
254
|
+
|
|
255
|
+
def _wire_close_events(self):
|
|
256
|
+
self._closed = False
|
|
257
|
+
|
|
258
|
+
def mark_closed(*_):
|
|
259
|
+
self._closed = True
|
|
260
|
+
self._stop = True
|
|
261
|
+
|
|
262
|
+
self._plot.add_key_event('q', lambda: mark_closed())
|
|
219
263
|
|
|
220
264
|
def _update_camera(self):
|
|
221
265
|
x,y,z = self._plot.camera.position
|
|
@@ -241,8 +285,12 @@ class PVDisplay(BaseDisplay):
|
|
|
241
285
|
self._update_camera()
|
|
242
286
|
self._add_aux_items()
|
|
243
287
|
if self._do_animate:
|
|
288
|
+
self._wire_close_events()
|
|
289
|
+
self.add_text('Press Q to close!',color='red', position='upper_left')
|
|
244
290
|
self._plot.show(auto_close=False, interactive_update=True, before_close_callback=self._close_callback)
|
|
245
291
|
self._animate()
|
|
292
|
+
|
|
293
|
+
|
|
246
294
|
else:
|
|
247
295
|
self._plot.show()
|
|
248
296
|
self._reset()
|
|
@@ -261,8 +309,9 @@ class PVDisplay(BaseDisplay):
|
|
|
261
309
|
self._plot = pv.Plotter()
|
|
262
310
|
self._stop = False
|
|
263
311
|
self._objs = []
|
|
312
|
+
C_CYCLE = _gen_c_cycle()
|
|
264
313
|
|
|
265
|
-
def _close_callback(self):
|
|
314
|
+
def _close_callback(self, arg):
|
|
266
315
|
"""The private callback function that stops the animation.
|
|
267
316
|
"""
|
|
268
317
|
self._stop = True
|
|
@@ -270,16 +319,44 @@ class PVDisplay(BaseDisplay):
|
|
|
270
319
|
def _animate(self) -> None:
|
|
271
320
|
"""Private function that starts the animation loop.
|
|
272
321
|
"""
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
322
|
+
|
|
323
|
+
self._stop = False
|
|
324
|
+
|
|
325
|
+
# guard values
|
|
326
|
+
steps = max(1, int(self._Nsteps))
|
|
327
|
+
fps = max(1, int(self._fps))
|
|
328
|
+
dt = 1.0 / fps
|
|
329
|
+
next_tick = time.perf_counter()
|
|
330
|
+
step = 0
|
|
331
|
+
|
|
332
|
+
while (not self._stop
|
|
333
|
+
and not self._closed_via_x
|
|
334
|
+
and self._plot.render_window is not None):
|
|
335
|
+
# process window/UI events so close button works
|
|
336
|
+
self._plot.update()
|
|
337
|
+
|
|
338
|
+
now = time.perf_counter()
|
|
339
|
+
if now >= next_tick:
|
|
340
|
+
step = (step + 1) % steps
|
|
341
|
+
phi = np.exp(1j * (step / steps) * 2*np.pi)
|
|
342
|
+
|
|
343
|
+
# update all animated objects
|
|
278
344
|
for aobj in self._objs:
|
|
279
|
-
phi = np.exp(1j*(step/self._Nsteps)*2*np.pi)
|
|
280
345
|
aobj.update(phi)
|
|
281
|
-
|
|
282
|
-
|
|
346
|
+
|
|
347
|
+
# draw one frame
|
|
348
|
+
self._plot.render()
|
|
349
|
+
|
|
350
|
+
# schedule next frame; catch up if we fell behind
|
|
351
|
+
next_tick += dt
|
|
352
|
+
if now > next_tick + dt:
|
|
353
|
+
next_tick = now + dt
|
|
354
|
+
|
|
355
|
+
# be kind to the CPU
|
|
356
|
+
time.sleep(0.001)
|
|
357
|
+
|
|
358
|
+
# ensure cleanup pathway runs once
|
|
359
|
+
self._close_callback(None)
|
|
283
360
|
|
|
284
361
|
def animate(self, Nsteps: int = 35, fps: int = 25) -> PVDisplay:
|
|
285
362
|
""" Turns on the animation mode with the specified number of steps and FPS.
|
|
@@ -357,11 +434,29 @@ class PVDisplay(BaseDisplay):
|
|
|
357
434
|
return None
|
|
358
435
|
|
|
359
436
|
## OBLIGATORY METHODS
|
|
360
|
-
def add_object(self, obj: GeoObject | Selection, *args, **kwargs):
|
|
361
|
-
|
|
437
|
+
def add_object(self, obj: GeoObject | Selection, mesh: bool = False, volume_mesh: bool = True, *args, **kwargs):
|
|
438
|
+
|
|
439
|
+
show_edges = False
|
|
440
|
+
opacity = obj.opacity
|
|
441
|
+
line_width = 0.5
|
|
442
|
+
color = obj.color_rgb
|
|
443
|
+
style='surface'
|
|
444
|
+
|
|
445
|
+
if mesh is True:
|
|
446
|
+
show_edges = True
|
|
447
|
+
opacity = 0.7
|
|
448
|
+
line_width= 1
|
|
449
|
+
style='wireframe'
|
|
450
|
+
color=next(C_CYCLE)
|
|
451
|
+
|
|
452
|
+
kwargs = setdefault(kwargs, color=color, opacity=opacity, line_width=line_width, show_edges=show_edges, pickable=True, style=style)
|
|
453
|
+
mesh_obj = self.mesh(obj)
|
|
362
454
|
|
|
363
|
-
|
|
364
|
-
|
|
455
|
+
if mesh is True and volume_mesh is True:
|
|
456
|
+
mesh_obj = mesh_obj.extract_all_edges()
|
|
457
|
+
|
|
458
|
+
actor = self._plot.add_mesh(mesh_obj, *args, **kwargs)
|
|
459
|
+
self._plot.add_mesh(self._volume_edges(_select(obj)), color='#000000', line_width=2, show_edges=True)
|
|
365
460
|
|
|
366
461
|
def add_scatter(self, xs: np.ndarray, ys: np.ndarray, zs: np.ndarray):
|
|
367
462
|
"""Adds a scatter point cloud
|
|
@@ -471,6 +566,7 @@ class PVDisplay(BaseDisplay):
|
|
|
471
566
|
grid = pv.StructuredGrid(x,y,z)
|
|
472
567
|
field_flat = field.flatten(order='F')
|
|
473
568
|
|
|
569
|
+
|
|
474
570
|
if scale=='log':
|
|
475
571
|
T = lambda x: np.log10(np.abs(x))
|
|
476
572
|
elif scale=='symlog':
|
|
@@ -486,25 +582,28 @@ class PVDisplay(BaseDisplay):
|
|
|
486
582
|
self._ctr += 1
|
|
487
583
|
grid[name] = static_field
|
|
488
584
|
|
|
585
|
+
grid_no_nan = grid.threshold(scalars=name)
|
|
586
|
+
|
|
587
|
+
# Determine color limits
|
|
489
588
|
if clim is None:
|
|
490
|
-
fmin = np.
|
|
491
|
-
fmax = np.
|
|
589
|
+
fmin = np.nanmin(static_field)
|
|
590
|
+
fmax = np.nanmax(static_field)
|
|
492
591
|
clim = (fmin, fmax)
|
|
493
|
-
|
|
494
592
|
if symmetrize:
|
|
495
|
-
lim = max(abs(clim[0]),abs(clim[1]))
|
|
593
|
+
lim = max(abs(clim[0]), abs(clim[1]))
|
|
496
594
|
clim = (-lim, lim)
|
|
497
595
|
|
|
498
596
|
kwargs = setdefault(kwargs, cmap=cmap, clim=clim, opacity=opacity, pickable=False, multi_colors=True)
|
|
499
|
-
actor = self._plot.add_mesh(
|
|
597
|
+
actor = self._plot.add_mesh(grid_no_nan, scalars=name, **kwargs)
|
|
598
|
+
|
|
500
599
|
|
|
501
600
|
if self._do_animate:
|
|
502
601
|
def on_update(obj: _AnimObject, phi: complex):
|
|
503
|
-
|
|
504
|
-
obj.grid[
|
|
505
|
-
self._objs.append(_AnimObject(field_flat, T,
|
|
506
|
-
|
|
507
|
-
|
|
602
|
+
field_anim = obj.T(np.real(obj.field * phi))
|
|
603
|
+
obj.grid[name] = field_anim
|
|
604
|
+
self._objs.append(_AnimObject(field_flat, T, grid_no_nan, actor, on_update))
|
|
605
|
+
|
|
606
|
+
|
|
508
607
|
def add_title(self, title: str) -> None:
|
|
509
608
|
"""Adds a title
|
|
510
609
|
|
|
@@ -524,6 +623,8 @@ class PVDisplay(BaseDisplay):
|
|
|
524
623
|
if abs_position is not None:
|
|
525
624
|
final_position = abs_position
|
|
526
625
|
viewport = True
|
|
626
|
+
else:
|
|
627
|
+
final_position = abs_position
|
|
527
628
|
self._plot.add_text(
|
|
528
629
|
text,
|
|
529
630
|
position=final_position,
|
|
@@ -554,6 +655,11 @@ class PVDisplay(BaseDisplay):
|
|
|
554
655
|
dx = dx.flatten().real
|
|
555
656
|
dy = dy.flatten().real
|
|
556
657
|
dz = dz.flatten().real
|
|
658
|
+
|
|
659
|
+
ids = np.invert(np.isnan(dx))
|
|
660
|
+
|
|
661
|
+
x, y, z, dx, dy, dz = x[ids], y[ids], z[ids], dx[ids], dy[ids], dz[ids]
|
|
662
|
+
|
|
557
663
|
dmin = _min_distance(x,y,z)
|
|
558
664
|
|
|
559
665
|
dmax = np.max(_norm(dx,dy,dz))
|
|
@@ -569,8 +675,10 @@ class PVDisplay(BaseDisplay):
|
|
|
569
675
|
kwargs = dict()
|
|
570
676
|
if color is not None:
|
|
571
677
|
kwargs['color'] = color
|
|
678
|
+
|
|
572
679
|
pl = self._plot.add_arrows(Coo, Vec, scalars=None, clim=None, cmap=None, **kwargs)
|
|
573
680
|
|
|
681
|
+
|
|
574
682
|
def add_contour(self,
|
|
575
683
|
X: np.ndarray,
|
|
576
684
|
Y: np.ndarray,
|
|
@@ -533,7 +533,7 @@ def plot_ff(
|
|
|
533
533
|
dB: bool = False,
|
|
534
534
|
labels: Optional[List[str]] = None,
|
|
535
535
|
xlabel: str = "Theta (rad)",
|
|
536
|
-
ylabel: str = "
|
|
536
|
+
ylabel: str = "",
|
|
537
537
|
linestyles: Union[str, List[str]] = "-",
|
|
538
538
|
linewidth: float = 2.0,
|
|
539
539
|
markers: Optional[Union[str, List[Optional[str]]]] = None,
|
emerge/_emerge/simmodel.py
CHANGED
|
@@ -245,13 +245,20 @@ class Simulation:
|
|
|
245
245
|
vM, vm, vp = [float(x) for x in version.split('.')]
|
|
246
246
|
cM, cm, cp = [float(x) for x in __version__.split('.')]
|
|
247
247
|
if vM != cM:
|
|
248
|
-
raise VersionError(f"You are running a script designed for version {version} with a possibly incompatible version of EMerge {__version__}")
|
|
248
|
+
raise VersionError(f"You are running a script designed for version {version} with a possibly incompatible version of EMerge {__version__}. \n You can upgrade your version of emerge with: pip --upgrade emerge")
|
|
249
249
|
if vm != cm:
|
|
250
|
-
raise VersionError(f"You are running a script designed for version {version} with a possibly incompatible version of EMerge {__version__}")
|
|
250
|
+
raise VersionError(f"You are running a script designed for version {version} with a possibly incompatible version of EMerge {__version__}. \n You can upgrade your version of emerge with: pip --upgrade emerge")
|
|
251
251
|
if vp != cp:
|
|
252
|
-
logger.warning(
|
|
252
|
+
logger.warning("You are running a script designed for a different version of EMerge.")
|
|
253
|
+
logger.warning(f"The script version: {version}")
|
|
254
|
+
logger.warning(f"EMerge version: {__version__}")
|
|
255
|
+
logger.warning("Usually EMerge works without a problem but Errors may occur.")
|
|
256
|
+
logger.warning("You can upgrade your version of emerge with: pip --upgrade emerge")
|
|
253
257
|
logger.warning("You may suppress this error by removing the call to .check_version().")
|
|
254
|
-
|
|
258
|
+
logger.warning("Press Ctrl+C to abort.")
|
|
259
|
+
ans = input('Press enter to proceed or [Q] to quit:')
|
|
260
|
+
if ans.lower().strip()=='q':
|
|
261
|
+
quit()
|
|
255
262
|
|
|
256
263
|
def save(self) -> None:
|
|
257
264
|
"""Saves the current model in the provided project directory."""
|
|
@@ -319,24 +326,26 @@ class Simulation:
|
|
|
319
326
|
def view(self,
|
|
320
327
|
selections: list[Selection] | None = None,
|
|
321
328
|
use_gmsh: bool = False,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
329
|
+
plot_mesh: bool = False,
|
|
330
|
+
volume_mesh: bool = True,
|
|
331
|
+
opacity: float | None = None) -> None:
|
|
325
332
|
"""View the current geometry in either the BaseDisplay object (PVDisplay only) or
|
|
326
333
|
the GMSH viewer.
|
|
327
334
|
|
|
328
335
|
Args:
|
|
329
|
-
selections (list[Selection], optional):
|
|
330
|
-
use_gmsh (bool, optional):
|
|
331
|
-
|
|
332
|
-
|
|
336
|
+
selections (list[Selection] | None, optional): Optional selections to highlight. Defaults to None.
|
|
337
|
+
use_gmsh (bool, optional): If GMSH's GUI should be used. Defaults to False.
|
|
338
|
+
plot_mesh (bool, optional): If the mesh should be plot instead of the object. Defaults to False.
|
|
339
|
+
volume_mesh (bool, optional): If the internal mesh should be plot instead of only the surface boundary mesh. Defaults to True
|
|
340
|
+
opacity (float | None, optional): The object/mesh opacity. Defaults to None.
|
|
341
|
+
|
|
333
342
|
"""
|
|
334
343
|
if not (self.display is not None and self.mesh.defined) or use_gmsh:
|
|
335
344
|
gmsh.model.occ.synchronize()
|
|
336
345
|
gmsh.fltk.run()
|
|
337
346
|
return
|
|
338
347
|
for geo in _GEOMANAGER.all_geometries():
|
|
339
|
-
self.display.add_object(geo)
|
|
348
|
+
self.display.add_object(geo, mesh=plot_mesh, opacity=opacity, volume_mesh=volume_mesh)
|
|
340
349
|
if selections:
|
|
341
350
|
[self.display.add_object(sel, color='red', opacity=0.3) for sel in selections]
|
|
342
351
|
self.display.show()
|
|
@@ -456,7 +465,7 @@ class Simulation:
|
|
|
456
465
|
|
|
457
466
|
logger.info(f'Iterating: {params}')
|
|
458
467
|
if len(dims_flat)==1:
|
|
459
|
-
yield
|
|
468
|
+
yield dims_flat[0][i_iter]
|
|
460
469
|
else:
|
|
461
470
|
yield (dim[i_iter] for dim in dims_flat) # type: ignore
|
|
462
471
|
self.mw.cache_matrices = True
|
emerge/_emerge/solver.py
CHANGED
|
@@ -289,10 +289,14 @@ class Solver:
|
|
|
289
289
|
|
|
290
290
|
def __init__(self):
|
|
291
291
|
self.own_preconditioner: bool = False
|
|
292
|
+
self.initialized: bool = False
|
|
292
293
|
|
|
293
294
|
def __str__(self) -> str:
|
|
294
295
|
return f'{self.__class__.__name__}'
|
|
295
296
|
|
|
297
|
+
def initialize(self) -> None:
|
|
298
|
+
return None
|
|
299
|
+
|
|
296
300
|
def duplicate(self) -> Solver:
|
|
297
301
|
return self.__class__()
|
|
298
302
|
|
|
@@ -324,6 +328,9 @@ class EigSolver:
|
|
|
324
328
|
def __init__(self):
|
|
325
329
|
self.own_preconditioner: bool = False
|
|
326
330
|
|
|
331
|
+
def initialize(self) -> None:
|
|
332
|
+
return None
|
|
333
|
+
|
|
327
334
|
def __str__(self) -> str:
|
|
328
335
|
return f'{self.__class__.__name__}'
|
|
329
336
|
|
|
@@ -513,7 +520,19 @@ class SolverUMFPACK(Solver):
|
|
|
513
520
|
super().__init__()
|
|
514
521
|
self.A: np.ndarray = None
|
|
515
522
|
self.b: np.ndarray = None
|
|
516
|
-
|
|
523
|
+
|
|
524
|
+
self.umfpack: um.UmfpackContext | None = None
|
|
525
|
+
|
|
526
|
+
# SETTINGS
|
|
527
|
+
self._pivoting_threshold: float = 0.001
|
|
528
|
+
|
|
529
|
+
self.fact_symb: bool = False
|
|
530
|
+
self.initalized: bool = False
|
|
531
|
+
|
|
532
|
+
def initialize(self):
|
|
533
|
+
if self.initalized:
|
|
534
|
+
return
|
|
535
|
+
self.umfpack = um.UmfpackContext('zl')
|
|
517
536
|
self.umfpack.control[um.UMFPACK_PRL] = 0 # ty: ignore
|
|
518
537
|
self.umfpack.control[um.UMFPACK_IRSTEP] = 2 # ty: ignore
|
|
519
538
|
self.umfpack.control[um.UMFPACK_STRATEGY] = um.UMFPACK_STRATEGY_SYMMETRIC # ty: ignore
|
|
@@ -522,21 +541,16 @@ class SolverUMFPACK(Solver):
|
|
|
522
541
|
self.umfpack.control[um.UMFPACK_SYM_PIVOT_TOLERANCE] = 0.001 # ty: ignore
|
|
523
542
|
self.umfpack.control[um.UMFPACK_BLOCK_SIZE] = 64 # ty: ignore
|
|
524
543
|
self.umfpack.control[um.UMFPACK_FIXQ] = -1 # ty: ignore
|
|
525
|
-
|
|
526
|
-
# SETTINGS
|
|
527
|
-
self._pivoting_threshold: float = 0.001
|
|
528
|
-
|
|
529
|
-
self.fact_symb: bool = False
|
|
530
|
-
|
|
544
|
+
self.initalized = True
|
|
531
545
|
def reset(self) -> None:
|
|
532
546
|
self.fact_symb = False
|
|
533
547
|
|
|
534
|
-
def set_options(self,
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
548
|
+
def set_options(self, pivoting_threshold: float | None = None) -> None:
|
|
549
|
+
self.initialize()
|
|
550
|
+
if pivoting_threshold is not None:
|
|
551
|
+
self.umfpack.control[um.UMFPACK_PIVOT_TOLERANCE] = pivoting_threshold # ty: ignore
|
|
552
|
+
self.umfpack.control[um.UMFPACK_SYM_PIVOT_TOLERANCE] = pivoting_threshold # ty: ignore
|
|
553
|
+
self._pivoting_threshold = pivoting_threshold
|
|
540
554
|
|
|
541
555
|
def duplicate(self) -> Solver:
|
|
542
556
|
new_solver = self.__class__()
|
|
@@ -568,11 +582,17 @@ class SolverPardiso(Solver):
|
|
|
568
582
|
|
|
569
583
|
def __init__(self):
|
|
570
584
|
super().__init__()
|
|
571
|
-
self.solver: PardisoInterface =
|
|
585
|
+
self.solver: PardisoInterface | None = None
|
|
572
586
|
self.fact_symb: bool = False
|
|
573
587
|
self.A: np.ndarray = None
|
|
574
588
|
self.b: np.ndarray = None
|
|
575
589
|
|
|
590
|
+
def initialize(self) -> None:
|
|
591
|
+
if self.initialized:
|
|
592
|
+
return
|
|
593
|
+
self.solver = PardisoInterface()
|
|
594
|
+
self.initialized = True
|
|
595
|
+
|
|
576
596
|
def solve(self, A, b, precon, reuse_factorization: bool = False, id: int = -1) -> tuple[np.ndarray, SolveReport]:
|
|
577
597
|
logger.info(f'[ID={id}] Calling Pardiso Solver')
|
|
578
598
|
if self.fact_symb is False:
|
|
@@ -594,11 +614,18 @@ class SolverPardiso(Solver):
|
|
|
594
614
|
class CuDSSSolver(Solver):
|
|
595
615
|
real_only = False
|
|
596
616
|
def __init__(self):
|
|
597
|
-
|
|
617
|
+
super().__init__()
|
|
618
|
+
self._cudss: CuDSSInterface | None = None
|
|
598
619
|
self.fact_symb: bool = False
|
|
599
620
|
self.fact_numb: bool = False
|
|
621
|
+
|
|
622
|
+
def initialize(self) -> None:
|
|
623
|
+
if self.initialized:
|
|
624
|
+
return
|
|
625
|
+
self._cudss = CuDSSInterface()
|
|
600
626
|
self._cudss._PRES = 2
|
|
601
|
-
|
|
627
|
+
self.initialized = True
|
|
628
|
+
|
|
602
629
|
def reset(self) -> None:
|
|
603
630
|
self.fact_symb = False
|
|
604
631
|
self.fact_numb = False
|
|
@@ -674,7 +701,7 @@ class SolverARPACK(EigSolver):
|
|
|
674
701
|
target_k0: float = 0,
|
|
675
702
|
which: str = 'LM',
|
|
676
703
|
sign: float = 1.0) -> tuple[np.ndarray, np.ndarray]:
|
|
677
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
704
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with ARPACK')
|
|
678
705
|
sigma = sign*(target_k0**2)
|
|
679
706
|
eigen_values, eigen_modes = eigs(A, k=nmodes, M=B, sigma=sigma, which=which)
|
|
680
707
|
return eigen_values, eigen_modes
|
|
@@ -698,7 +725,7 @@ class SmartARPACK_BMA(EigSolver):
|
|
|
698
725
|
which: str = 'LM',
|
|
699
726
|
sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
|
|
700
727
|
|
|
701
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
728
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK (BMA)')
|
|
702
729
|
qs = np.geomspace(1, self.search_range, self.symmetric_steps)
|
|
703
730
|
tot_eigen_values = []
|
|
704
731
|
tot_eigen_modes = []
|
|
@@ -747,7 +774,7 @@ class SmartARPACK(EigSolver):
|
|
|
747
774
|
target_k0: float = 0,
|
|
748
775
|
which: str = 'LM',
|
|
749
776
|
sign: float = 1.) -> tuple[np.ndarray, np.ndarray]:
|
|
750
|
-
logger.info(f'Searching around β = {target_k0:.2f} rad/m')
|
|
777
|
+
logger.info(f'Searching around β = {target_k0:.2f} rad/m with SmartARPACK')
|
|
751
778
|
qs = np.geomspace(1, self.search_range, self.symmetric_steps)
|
|
752
779
|
tot_eigen_values = []
|
|
753
780
|
tot_eigen_modes = []
|
|
@@ -1062,7 +1089,7 @@ class SolveRoutine:
|
|
|
1062
1089
|
if direct or A.shape[0] < 1000:
|
|
1063
1090
|
return self.solvers[EMSolver.LAPACK] # type: ignore
|
|
1064
1091
|
else:
|
|
1065
|
-
return self.solvers[EMSolver.
|
|
1092
|
+
return self.solvers[EMSolver.SMART_ARPACK_BMA] # type: ignore
|
|
1066
1093
|
|
|
1067
1094
|
def solve(self, A: csr_matrix | csr_matrix,
|
|
1068
1095
|
b: np.ndarray,
|
|
@@ -1085,7 +1112,7 @@ class SolveRoutine:
|
|
|
1085
1112
|
np.ndarray: The resultant solution.
|
|
1086
1113
|
"""
|
|
1087
1114
|
solver: Solver = self._get_solver(A, b)
|
|
1088
|
-
|
|
1115
|
+
solver.initialize()
|
|
1089
1116
|
NF = A.shape[0]
|
|
1090
1117
|
NS = solve_ids.shape[0]
|
|
1091
1118
|
|
|
@@ -1178,7 +1205,7 @@ class SolveRoutine:
|
|
|
1178
1205
|
SolveReport: The solution report
|
|
1179
1206
|
"""
|
|
1180
1207
|
solver = self._get_eig_solver_bma(A, B, direct=direct)
|
|
1181
|
-
|
|
1208
|
+
solver.initialize()
|
|
1182
1209
|
NF = A.shape[0]
|
|
1183
1210
|
NS = solve_ids.shape[0]
|
|
1184
1211
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
emerge/__init__.py,sha256=
|
|
1
|
+
emerge/__init__.py,sha256=d0irj6Zl58a3DO_ilpI77vqIe9_S1-UspMjSHbXCbr8,2693
|
|
2
2
|
emerge/__main__.py,sha256=WVf16sfrOI910QWohrQDaChZdRifMNoS6VKzCT6f3ZA,92
|
|
3
3
|
emerge/cli.py,sha256=NU1uhwuZ6i50680v3_I4kDZPTHqz74gOYK71UBhb8oE,666
|
|
4
4
|
emerge/ext.py,sha256=IBoHH5PQFj5pYMfp6r-uMpNNgbSe8c0g9x8qjBzzVmU,223
|
|
@@ -6,42 +6,42 @@ emerge/lib.py,sha256=kUb4n7VGK4ncR5IHdjvVVd8klSiqZ427ckmEFet16M0,23465
|
|
|
6
6
|
emerge/plot.py,sha256=AH2D9rKeWUXlSOlh-pUUfLt0oxVLcqF_piki-BmPEg0,83
|
|
7
7
|
emerge/pyvista.py,sha256=-Ht2YcZYsh8-dici5ZPNAWwsis6uz5wNj8n8mxv5fog,42
|
|
8
8
|
emerge/_emerge/__init__.py,sha256=aidfiILy33dt3VyiZ2mgtA87mq-WQ5pXItZUE5wR5ws,703
|
|
9
|
-
emerge/_emerge/_cache_check.py,sha256=
|
|
9
|
+
emerge/_emerge/_cache_check.py,sha256=_m9rV-VcaC4uNfETZ2Rp1tkA-gZ5FD3xL3KOHlgdvyA,1547
|
|
10
10
|
emerge/_emerge/bc.py,sha256=TeSVNkDgOGaoHw5raTzhUV0ngtyHa33sXAoL2hRn70M,8077
|
|
11
11
|
emerge/_emerge/const.py,sha256=PTZZTSDOP5NsZ8XnJrKTY2P0tPUhmutBJ1yrm-t7xsI,129
|
|
12
12
|
emerge/_emerge/coord.py,sha256=BKvyrcnHY-_bgHqysnByy5k9_DK4VVfr9KKkRaawG2E,4371
|
|
13
13
|
emerge/_emerge/cs.py,sha256=YNT2Nn6Dh8fYPUMlT6w0msHnQpZREbbl_ZXTGNppCVs,18392
|
|
14
14
|
emerge/_emerge/dataset.py,sha256=UcSAJ_siLrOjNBBWRWsS3GUZUpayp63EM6pP6ClwKDI,1534
|
|
15
15
|
emerge/_emerge/geo2d.py,sha256=e_HkX1GQ2iYrdO0zeEgzVOzfGyU1WGJyjeGBAobOttE,3323
|
|
16
|
-
emerge/_emerge/geometry.py,sha256=
|
|
16
|
+
emerge/_emerge/geometry.py,sha256=_hBZMRcYImO3rXRex0wcNWPDmdlrQoMJ6NZh4H_CUPo,19277
|
|
17
17
|
emerge/_emerge/howto.py,sha256=c4UxUNpA1tygr3OoR-LH-h0UZv-Tf9K8tpCiAU18BKE,8173
|
|
18
18
|
emerge/_emerge/logsettings.py,sha256=DcUWIUUhdLe9ev5XC1bd5ZUrJz00MjABkY8rnekFrPY,3373
|
|
19
|
-
emerge/_emerge/material.py,sha256=
|
|
20
|
-
emerge/_emerge/mesh3d.py,sha256=
|
|
19
|
+
emerge/_emerge/material.py,sha256=jMAe7W7qT1fcgbah_5DncaPDa7kVGF2GEdnNZ0aoh6k,14973
|
|
20
|
+
emerge/_emerge/mesh3d.py,sha256=2expfu7YR6KbtaEeR7JELxXkTul0cFECRwwO5bpdgqE,34697
|
|
21
21
|
emerge/_emerge/mesher.py,sha256=fKgPb6oZe_bqp0XYfZ6UNgBfRaAS3-tjUtZX8NalJe8,13199
|
|
22
22
|
emerge/_emerge/periodic.py,sha256=xfdKKq3qX7iBBestnRizOzJNfXlpr9lCPkiYhfrRIR8,12013
|
|
23
23
|
emerge/_emerge/plot.py,sha256=cf1I9mj7EIUJcq8vmANlUkqoV6QqVaJaP-zlC-T9E18,8041
|
|
24
24
|
emerge/_emerge/selection.py,sha256=x8cGN93BAmO80C0gn6feWcW126vorscsZVzhreTOLxs,21298
|
|
25
|
-
emerge/_emerge/simmodel.py,sha256=
|
|
25
|
+
emerge/_emerge/simmodel.py,sha256=OVAO1HdtLb7NdgPVWK3G1bRyINPjyC8jpawLDEK6rR8,20280
|
|
26
26
|
emerge/_emerge/simulation_data.py,sha256=r9-9lpLeA1Z5HU3jDVOXV1H80GVawnXL5K81_dvmlE4,14506
|
|
27
|
-
emerge/_emerge/solver.py,sha256=
|
|
27
|
+
emerge/_emerge/solver.py,sha256=kZr_lNnLbHe2LBO9ujyHdfh47jc_qqnFgrlPwhZZMHE,49348
|
|
28
28
|
emerge/_emerge/system.py,sha256=p4HNz7d_LMRNE9Gk75vVdFecDH2iN_groAM9u-yQTpk,1618
|
|
29
29
|
emerge/_emerge/elements/__init__.py,sha256=I3n9aic6lJW-oGeqTEZ-Fpxvyl2i-WqsHdnrM3v1oB8,799
|
|
30
|
-
emerge/_emerge/elements/femdata.py,sha256=
|
|
31
|
-
emerge/_emerge/elements/index_interp.py,sha256=
|
|
32
|
-
emerge/_emerge/elements/ned2_interp.py,sha256=
|
|
33
|
-
emerge/_emerge/elements/nedelec2.py,sha256=
|
|
34
|
-
emerge/_emerge/elements/nedleg2.py,sha256=
|
|
35
|
-
emerge/_emerge/geo/__init__.py,sha256=
|
|
36
|
-
emerge/_emerge/geo/horn.py,sha256=
|
|
37
|
-
emerge/_emerge/geo/modeler.py,sha256=
|
|
38
|
-
emerge/_emerge/geo/operations.py,sha256=
|
|
39
|
-
emerge/_emerge/geo/pcb.py,sha256=
|
|
40
|
-
emerge/_emerge/geo/pmlbox.py,sha256=
|
|
30
|
+
emerge/_emerge/elements/femdata.py,sha256=o5P-lRAW_xWEOQ_jrT5zRciFZwq1LqCIXfaWurWdjmw,8082
|
|
31
|
+
emerge/_emerge/elements/index_interp.py,sha256=02CTHaokaAepBRvt7cHVwh3EpOA3sVE3qvEAkDjmwro,2072
|
|
32
|
+
emerge/_emerge/elements/ned2_interp.py,sha256=TwZr6f7USERIHrSShhEWofq_mMwFV5xHqSIRLLiUz48,32650
|
|
33
|
+
emerge/_emerge/elements/nedelec2.py,sha256=9cPAkxUdEFIn2HrSVPuChm7fxEjW3QAqyM0o3z9wCCw,6467
|
|
34
|
+
emerge/_emerge/elements/nedleg2.py,sha256=6pPrBMEwQqhPwIa2LTHYfqyOrLQI19O4XAoAfmTvYAE,8884
|
|
35
|
+
emerge/_emerge/geo/__init__.py,sha256=ZLwXMj81H-5ti2CmWJHriECe8PRDKNwXKvTbawtsWQA,1151
|
|
36
|
+
emerge/_emerge/geo/horn.py,sha256=otrtPphO2zoRaSOb7NV-iRaydL1uWDAl2xJ6-8Sef24,4148
|
|
37
|
+
emerge/_emerge/geo/modeler.py,sha256=_PMz3lFSa7FmJHWdY-4U1Sqbed-Egy85S_AdjlCldC4,15572
|
|
38
|
+
emerge/_emerge/geo/operations.py,sha256=lqfCU99uiLc0vDGqILpMP1YgKs1e-gwEcSLbI_gE6TA,12441
|
|
39
|
+
emerge/_emerge/geo/pcb.py,sha256=MmY-A-Xnd85aQw6ouOnsZKcui_kH86fw4l0GoR4qQu0,53442
|
|
40
|
+
emerge/_emerge/geo/pmlbox.py,sha256=gaIG_AoZNQnIyJ8C7x64U-Hw5dsmllWMiZDAH4iRoM0,8784
|
|
41
41
|
emerge/_emerge/geo/polybased.py,sha256=loVJRBjYCTUlti5tHwfH8iU-Inb6n2sOS2Cw4gVKid4,31917
|
|
42
|
-
emerge/_emerge/geo/shapes.py,sha256
|
|
42
|
+
emerge/_emerge/geo/shapes.py,sha256=-ct-TJh69oj5fqJcQql4pNk3acJWTIQzYOQeAFXDfWk,23319
|
|
43
43
|
emerge/_emerge/geo/step.py,sha256=XcAiEN8W4umNmZdYmrGHX_aJUuiMgc6vgT-UIk8Gbqc,2689
|
|
44
|
-
emerge/_emerge/geo/pcb_tools/calculator.py,sha256=
|
|
44
|
+
emerge/_emerge/geo/pcb_tools/calculator.py,sha256=VbMP2xC9i7OFwtqnnwfYgyJSEcJIjr2VIy_Ez1hYqlU,859
|
|
45
45
|
emerge/_emerge/geo/pcb_tools/macro.py,sha256=0g-0anOFyxrEkFobiSu0cwWFRQ32xB8Az24mmwo0z6M,2992
|
|
46
46
|
emerge/_emerge/mth/common_functions.py,sha256=oURfF-8p_0s1dKbUATc15dnKHFwvqWa6GC-JMW9UwnI,2061
|
|
47
47
|
emerge/_emerge/mth/integrals.py,sha256=lL7KrHdyFGpboQyvf6W_4bZRZCrMbjd2e8GDHctL-B8,3572
|
|
@@ -50,16 +50,16 @@ emerge/_emerge/mth/pairing.py,sha256=i8bBvTeMmzgF0JdiDNJiTXxx913x4f10777pzD6FJo0
|
|
|
50
50
|
emerge/_emerge/physics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
51
|
emerge/_emerge/physics/microwave/__init__.py,sha256=QHeILGYWmvbfLl1o9wrTiWLm0evfXDgS0JiikUoMTts,28
|
|
52
52
|
emerge/_emerge/physics/microwave/adaptive_freq.py,sha256=aWhijhCVAbnuwkru-I1AaRdY20uyozf6OWRIh9r2ijg,9786
|
|
53
|
-
emerge/_emerge/physics/microwave/microwave_3d.py,sha256=
|
|
54
|
-
emerge/_emerge/physics/microwave/microwave_bc.py,sha256
|
|
55
|
-
emerge/_emerge/physics/microwave/microwave_data.py,sha256=
|
|
53
|
+
emerge/_emerge/physics/microwave/microwave_3d.py,sha256=lKHaMcL8kztwUF4V9zUycT7Ec7aTZS9SAiZh6auzCYc,42379
|
|
54
|
+
emerge/_emerge/physics/microwave/microwave_bc.py,sha256=5BJfxgQWmgUt_Kd0ofVW4YUgzZxXv2wb8gvcJmBfhCA,42443
|
|
55
|
+
emerge/_emerge/physics/microwave/microwave_data.py,sha256=0SQInYEVdp7rlDIUt51Hb6lQNg2GYnt3zqmTbMArVIk,49302
|
|
56
56
|
emerge/_emerge/physics/microwave/periodic.py,sha256=wYSUgLFVtCLqSG3EDKoCDRU93iPUzBdXzVRdHTRmbpI,3000
|
|
57
57
|
emerge/_emerge/physics/microwave/port_functions.py,sha256=aVU__AkVk8b1kH2J_oDLF5iNReCxC9nzCtesFSSSSQo,2112
|
|
58
58
|
emerge/_emerge/physics/microwave/sc.py,sha256=WZvoPhmHkfEv619RhmN09sXDBV0ryTqybwErA8Rc7lU,4735
|
|
59
59
|
emerge/_emerge/physics/microwave/simjob.py,sha256=aCWCs7IXBfVBWWYhwyHvXSRHY3FOd3CK5ABcaFEsNnM,4927
|
|
60
60
|
emerge/_emerge/physics/microwave/sparam.py,sha256=1SXGyr1UsrPnCIi4ffwobM4pzgkj50y4LrWCr_J5IRY,4946
|
|
61
61
|
emerge/_emerge/physics/microwave/touchstone.py,sha256=pMcCOLWVqIKctcShcJxyaV-0rhRWXMSS1Jz14dVQEyY,5799
|
|
62
|
-
emerge/_emerge/physics/microwave/assembly/assembler.py,sha256=
|
|
62
|
+
emerge/_emerge/physics/microwave/assembly/assembler.py,sha256=kOOHQErjcb-OEafYGKphs5P8v5vllJGRxr6mdyR1oCY,22826
|
|
63
63
|
emerge/_emerge/physics/microwave/assembly/curlcurl.py,sha256=iYHTNI48bmC6SjCiCMPoY4yqsf__e_h_vbW0fNKQpNQ,18686
|
|
64
64
|
emerge/_emerge/physics/microwave/assembly/generalized_eigen.py,sha256=LOybnxdy1x6R6d0lPnfnKckZSiYRfWOW9MUFlV_ygfs,16945
|
|
65
65
|
emerge/_emerge/physics/microwave/assembly/generalized_eigen_hb.py,sha256=XcWWoDVU7KlcjP8re3o-Kb63A3px4CJ-OPjCT57_J8E,17382
|
|
@@ -67,10 +67,10 @@ emerge/_emerge/physics/microwave/assembly/periodicbc.py,sha256=Zg1kgQMccDQA2oVEr
|
|
|
67
67
|
emerge/_emerge/physics/microwave/assembly/robinbc.py,sha256=syJ-NuHHA0WDQECuaPdeW-OfzIGHmxxqalKiokSyJFI,17742
|
|
68
68
|
emerge/_emerge/plot/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
69
69
|
emerge/_emerge/plot/display.py,sha256=TQLlKb-LkaG5ZOSLfxp9KXPlZPRFTxNj1LhVQ-Lp1-s,18476
|
|
70
|
-
emerge/_emerge/plot/simple_plots.py,sha256=
|
|
70
|
+
emerge/_emerge/plot/simple_plots.py,sha256=oFJXSNI--HwydgOUt88NdRsxqldxfy5mb38eZTx9qHs,24430
|
|
71
71
|
emerge/_emerge/plot/matplotlib/mpldisplay.py,sha256=szKafDrgdAW5Nyc5UOHuJC87n0WGkXYackOVv182TDQ,8671
|
|
72
72
|
emerge/_emerge/plot/pyvista/__init__.py,sha256=CPclatEu6mFnJZzCQk09g6T6Fh20WTbiLAJGSwAnPXU,30
|
|
73
|
-
emerge/_emerge/plot/pyvista/display.py,sha256=
|
|
73
|
+
emerge/_emerge/plot/pyvista/display.py,sha256=5pi1LSHHVCutspQT2lcwWaF-eWoR_VE1OmkKtpizQhI,37321
|
|
74
74
|
emerge/_emerge/plot/pyvista/display_settings.py,sha256=K2OhzKqeFzMXlEfZ5F4CQ9sN3l7nOgVjLplZBuMPjvE,899
|
|
75
75
|
emerge/_emerge/projects/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
76
76
|
emerge/_emerge/projects/_gen_base.txt,sha256=DqQz36PZg6v1ovQjHvPjd0t4AIbmikZdb9dmrNYsK3w,598
|
|
@@ -78,8 +78,8 @@ emerge/_emerge/projects/_load_base.txt,sha256=94o0eSWoDKlNR336EmhpG_S5syQHIUPHQx
|
|
|
78
78
|
emerge/_emerge/projects/generate_project.py,sha256=TNw-0SpLc82MBq0bd9hB_yqvBZCgmuPonCBsHTp91uk,1450
|
|
79
79
|
emerge/_emerge/solve_interfaces/cudss_interface.py,sha256=-SjiTNIyE7iJ8Bm14Cva5e2lpJDgfiS2Mvz1Bgy-UL4,9688
|
|
80
80
|
emerge/_emerge/solve_interfaces/pardiso_interface.py,sha256=iVFxToMmIzhj3hcAP-O_MDHKz82ePFIHY1us11kzUBU,15305
|
|
81
|
-
emerge-0.6.
|
|
82
|
-
emerge-0.6.
|
|
83
|
-
emerge-0.6.
|
|
84
|
-
emerge-0.6.
|
|
85
|
-
emerge-0.6.
|
|
81
|
+
emerge-0.6.8.dist-info/METADATA,sha256=Yi_WDwKLxyKakod3QDuaRgz7RvnxAAk0CJVuVnPii1M,3304
|
|
82
|
+
emerge-0.6.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
83
|
+
emerge-0.6.8.dist-info/entry_points.txt,sha256=8rFvAXticpKg4OTC8JEvAksnduW72KIEskCGG9XnFf8,43
|
|
84
|
+
emerge-0.6.8.dist-info/licenses/LICENSE,sha256=VOCXWddrjMN5j7TvnSAOh1Dx7jkugdwq9Lqhycf5inc,17852
|
|
85
|
+
emerge-0.6.8.dist-info/RECORD,,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
──────────────────────────────────────────────────────────────────────────────
|
|
2
|
-
PREAMBLE
|
|
2
|
+
PREAMBLE - Licence map and disclaimers (not part of the GNU GPL text)
|
|
3
3
|
──────────────────────────────────────────────────────────────────────────────
|
|
4
4
|
This repository is distributed under two distinct licences:
|
|
5
5
|
|
|
@@ -11,7 +11,7 @@ This repository is distributed under two distinct licences:
|
|
|
11
11
|
When you distribute binaries containing these components, the complete
|
|
12
12
|
corresponding source code must be offered under GPL-2.0+.
|
|
13
13
|
|
|
14
|
-
• **`lib.py`
|
|
14
|
+
• **`lib.py` - materials-property database**
|
|
15
15
|
This single file is dedicated to the public domain under **CC0 1.0**.
|
|
16
16
|
You may copy, modify, merge, publish, distribute, sublicense and/or sell
|
|
17
17
|
copies of `lib.py` without restriction. The data it contains are
|
|
File without changes
|
|
File without changes
|