emerge 0.4.11__py3-none-any.whl → 0.5.0__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 +15 -8
- emerge/_emerge/bc.py +41 -2
- emerge/_emerge/geo/__init__.py +1 -1
- emerge/_emerge/geo/pcb.py +49 -11
- emerge/_emerge/howto.py +2 -2
- emerge/_emerge/logsettings.py +83 -5
- emerge/_emerge/mesh3d.py +30 -12
- emerge/_emerge/mth/common_functions.py +28 -1
- emerge/_emerge/mth/integrals.py +25 -3
- emerge/_emerge/mth/optimized.py +126 -33
- emerge/_emerge/mth/pairing.py +97 -0
- emerge/_emerge/periodic.py +22 -0
- emerge/_emerge/physics/microwave/assembly/assembler.py +129 -155
- emerge/_emerge/physics/microwave/assembly/curlcurl.py +35 -3
- emerge/_emerge/physics/microwave/assembly/periodicbc.py +130 -0
- emerge/_emerge/physics/microwave/microwave_3d.py +3 -3
- emerge/_emerge/physics/microwave/microwave_bc.py +5 -4
- emerge/_emerge/physics/microwave/microwave_data.py +2 -2
- emerge/_emerge/projects/_gen_base.txt +1 -1
- emerge/_emerge/simmodel.py +137 -126
- emerge/_emerge/solve_interfaces/pardiso_interface.py +468 -0
- emerge/_emerge/solver.py +102 -31
- emerge/lib.py +276 -41
- {emerge-0.4.11.dist-info → emerge-0.5.0.dist-info}/METADATA +1 -1
- {emerge-0.4.11.dist-info → emerge-0.5.0.dist-info}/RECORD +28 -26
- emerge/_emerge/pardiso/pardiso_solver.py +0 -455
- {emerge-0.4.11.dist-info → emerge-0.5.0.dist-info}/WHEEL +0 -0
- {emerge-0.4.11.dist-info → emerge-0.5.0.dist-info}/entry_points.txt +0 -0
- {emerge-0.4.11.dist-info → emerge-0.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -22,12 +22,11 @@ from typing import Callable, Literal
|
|
|
22
22
|
from ...selection import Selection, FaceSelection
|
|
23
23
|
from ...cs import CoordinateSystem, Axis, GCS
|
|
24
24
|
from ...coord import Line
|
|
25
|
-
from ...geometry import GeoSurface, GeoObject
|
|
25
|
+
from ...geometry import GeoSurface, GeoObject
|
|
26
26
|
from dataclasses import dataclass
|
|
27
27
|
from collections import defaultdict
|
|
28
28
|
from ...bc import BoundaryCondition, BoundaryConditionSet, Periodic
|
|
29
|
-
from ...
|
|
30
|
-
from ...periodic import PeriodicCell, HexCell, RectCell, Alignment
|
|
29
|
+
from ...periodic import PeriodicCell, HexCell, RectCell
|
|
31
30
|
|
|
32
31
|
class MWBoundaryConditionSet(BoundaryConditionSet):
|
|
33
32
|
|
|
@@ -309,7 +308,7 @@ class FloquetPort(PortBC):
|
|
|
309
308
|
self.port_number: int= port_number
|
|
310
309
|
self.active: bool = True
|
|
311
310
|
self.power: float = power
|
|
312
|
-
self.type: str = '
|
|
311
|
+
self.type: str = 'TEM'
|
|
313
312
|
self._field_amplitude: np.ndarray = None
|
|
314
313
|
self.mode: tuple[int,int] = (1,0)
|
|
315
314
|
self.cs: CoordinateSystem = cs
|
|
@@ -920,3 +919,5 @@ class LumpedElement(RobinBC):
|
|
|
920
919
|
complex: The γ-constant
|
|
921
920
|
"""
|
|
922
921
|
return 1j*k0*376.730313412/self.surfZ(k0)
|
|
922
|
+
|
|
923
|
+
|
|
@@ -888,11 +888,11 @@ class MWField:
|
|
|
888
888
|
else:
|
|
889
889
|
tags = faces.tags
|
|
890
890
|
|
|
891
|
-
|
|
891
|
+
center = np.mean(self.mesh.nodes, axis=1).squeeze()
|
|
892
|
+
surface = self.basis.mesh.boundary_surface(tags, center)
|
|
892
893
|
field = self.interpolate(*surface.exyz)
|
|
893
894
|
vertices = surface.nodes
|
|
894
895
|
triangles = surface.tris
|
|
895
|
-
print(surface._origin, surface._alignment_origin)
|
|
896
896
|
origin = surface._origin
|
|
897
897
|
E = field.E
|
|
898
898
|
H = field.H
|
emerge/_emerge/simmodel.py
CHANGED
|
@@ -22,8 +22,7 @@ from .geo.modeler import Modeler
|
|
|
22
22
|
from .physics.microwave.microwave_3d import Microwave3D
|
|
23
23
|
from .mesh3d import Mesh3D
|
|
24
24
|
from .selection import Selector, FaceSelection, Selection
|
|
25
|
-
from .logsettings import
|
|
26
|
-
from .plot.display import BaseDisplay
|
|
25
|
+
from .logsettings import LOG_CONTROLLER
|
|
27
26
|
from .plot.pyvista import PVDisplay
|
|
28
27
|
from .dataset import SimulationDataset
|
|
29
28
|
from .periodic import PeriodicCell
|
|
@@ -40,6 +39,11 @@ from pathlib import Path
|
|
|
40
39
|
from atexit import register
|
|
41
40
|
import signal
|
|
42
41
|
|
|
42
|
+
|
|
43
|
+
############################################################
|
|
44
|
+
# EXCEPTION DEFINITIONS #
|
|
45
|
+
############################################################
|
|
46
|
+
|
|
43
47
|
_GMSH_ERROR_TEXT = """
|
|
44
48
|
--------------------------
|
|
45
49
|
Known problems/solutions:
|
|
@@ -48,10 +52,15 @@ Known problems/solutions:
|
|
|
48
52
|
--------------------------
|
|
49
53
|
"""
|
|
50
54
|
|
|
55
|
+
|
|
51
56
|
class SimulationError(Exception):
|
|
52
57
|
pass
|
|
53
58
|
|
|
54
59
|
|
|
60
|
+
############################################################
|
|
61
|
+
# BASE 3D SIMULATION MODEL #
|
|
62
|
+
############################################################
|
|
63
|
+
|
|
55
64
|
class Simulation3D:
|
|
56
65
|
|
|
57
66
|
def __init__(self,
|
|
@@ -74,6 +83,7 @@ class Simulation3D:
|
|
|
74
83
|
logfile (bool, optional): If a file should be created that contains the entire log of the simulation. Defaults to False.
|
|
75
84
|
path_suffix (str, optional): The suffix that will be added to the results directory. Defaults to ".EMResults".
|
|
76
85
|
"""
|
|
86
|
+
|
|
77
87
|
caller_file = Path(inspect.stack()[1].filename).resolve()
|
|
78
88
|
base_path = caller_file.parent
|
|
79
89
|
|
|
@@ -93,8 +103,9 @@ class Simulation3D:
|
|
|
93
103
|
self._cell: PeriodicCell = None
|
|
94
104
|
|
|
95
105
|
self.display = PVDisplay(self.mesh)
|
|
106
|
+
|
|
96
107
|
if logfile:
|
|
97
|
-
self.set_logfile(
|
|
108
|
+
self.set_logfile()
|
|
98
109
|
|
|
99
110
|
self.save_file: bool = save_file
|
|
100
111
|
self.load_file: bool = load_file
|
|
@@ -107,6 +118,11 @@ class Simulation3D:
|
|
|
107
118
|
self._initialize_simulation()
|
|
108
119
|
|
|
109
120
|
self._update_data()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
############################################################
|
|
124
|
+
# PRIVATE FUNCTIONS #
|
|
125
|
+
############################################################
|
|
110
126
|
|
|
111
127
|
def __setitem__(self, name: str, value: Any) -> None:
|
|
112
128
|
"""Store data in the current data container"""
|
|
@@ -116,6 +132,82 @@ class Simulation3D:
|
|
|
116
132
|
"""Get the data from the current data container"""
|
|
117
133
|
return self.data.sim[name]
|
|
118
134
|
|
|
135
|
+
def __enter__(self) -> Simulation3D:
|
|
136
|
+
"""This method is depricated with the new atexit system. It still exists for backwards compatibility.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Simulation3D: the Simulation3D object
|
|
140
|
+
"""
|
|
141
|
+
return self
|
|
142
|
+
|
|
143
|
+
def __exit__(self, type, value, tb):
|
|
144
|
+
"""This method no longer does something. It only serves as backwards compatibility."""
|
|
145
|
+
self._exit_gmsh()
|
|
146
|
+
return False
|
|
147
|
+
|
|
148
|
+
def _install_signal_handlers(self):
|
|
149
|
+
# on SIGINT (Ctrl-C) or SIGTERM, call our exit routine
|
|
150
|
+
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
151
|
+
signal.signal(sig, self._handle_signal)
|
|
152
|
+
|
|
153
|
+
def _handle_signal(self, signum, frame):
|
|
154
|
+
"""
|
|
155
|
+
Signal handler: do our cleanup, then re-raise
|
|
156
|
+
the default handler so that exit code / traceback
|
|
157
|
+
is as expected.
|
|
158
|
+
"""
|
|
159
|
+
try:
|
|
160
|
+
# run your atexit-style cleanup
|
|
161
|
+
self._exit_gmsh()
|
|
162
|
+
except Exception:
|
|
163
|
+
# log but don’t block shutdown
|
|
164
|
+
logger.exception("Error during signal cleanup")
|
|
165
|
+
finally:
|
|
166
|
+
# restore default handler and re‐send the signal
|
|
167
|
+
signal.signal(signum, signal.SIG_DFL)
|
|
168
|
+
os.kill(os.getpid(), signum)
|
|
169
|
+
|
|
170
|
+
def _initialize_simulation(self):
|
|
171
|
+
"""Initializes the Simulation data and GMSH API with proper shutdown routines.
|
|
172
|
+
"""
|
|
173
|
+
_GEOMANAGER.sign_in(self.modelname)
|
|
174
|
+
|
|
175
|
+
# If GMSH is not yet initialized (Two simulation in a file)
|
|
176
|
+
if gmsh.isInitialized() == 0:
|
|
177
|
+
logger.debug('Initializing GMSH')
|
|
178
|
+
gmsh.initialize()
|
|
179
|
+
|
|
180
|
+
# Set an exit handler for Ctrl+C cases
|
|
181
|
+
self._install_signal_handlers()
|
|
182
|
+
|
|
183
|
+
# Restier the Exit GMSH function on proper program abortion
|
|
184
|
+
register(self._exit_gmsh)
|
|
185
|
+
|
|
186
|
+
# Create a new GMSH model or load it
|
|
187
|
+
if not self.load_file:
|
|
188
|
+
gmsh.model.add(self.modelname)
|
|
189
|
+
self.data: SimulationDataset = SimulationDataset()
|
|
190
|
+
else:
|
|
191
|
+
self.load()
|
|
192
|
+
|
|
193
|
+
# Set the Simulation state to active
|
|
194
|
+
self.__active = True
|
|
195
|
+
return self
|
|
196
|
+
|
|
197
|
+
def _exit_gmsh(self):
|
|
198
|
+
# If the simulation object state is still active (GMSH is running)
|
|
199
|
+
if not self.__active:
|
|
200
|
+
return
|
|
201
|
+
logger.debug('Exiting program')
|
|
202
|
+
# Save the file first
|
|
203
|
+
if self.save_file:
|
|
204
|
+
self.save()
|
|
205
|
+
# Finalize GMSH
|
|
206
|
+
gmsh.finalize()
|
|
207
|
+
logger.debug('GMSH Shut down successful')
|
|
208
|
+
# set the state to active
|
|
209
|
+
self.__active = False
|
|
210
|
+
|
|
119
211
|
def _update_data(self) -> None:
|
|
120
212
|
"""Writes the stored physics data to each phyics class insatnce"""
|
|
121
213
|
self.mw.data = self.data.mw
|
|
@@ -128,18 +220,22 @@ class Simulation3D:
|
|
|
128
220
|
"""Returns all boundary condition objects stored in the simulation file"""
|
|
129
221
|
return [obj for obj in self.sim.default.values() if isinstance(obj, BoundaryCondition)]
|
|
130
222
|
|
|
131
|
-
|
|
132
|
-
def passed_geometries(self) -> list[GeoObject]:
|
|
133
|
-
""""""
|
|
134
|
-
return self.data.sim['geometries']
|
|
135
|
-
|
|
136
|
-
def set_mesh(self, mesh: Mesh3D) -> None:
|
|
223
|
+
def _set_mesh(self, mesh: Mesh3D) -> None:
|
|
137
224
|
"""Set the current model mesh to a given mesh."""
|
|
138
225
|
self.mesh = mesh
|
|
139
226
|
self.mw.mesh = mesh
|
|
140
227
|
self.mesher.mesh = mesh
|
|
141
228
|
self.display._mesh = mesh
|
|
142
229
|
|
|
230
|
+
############################################################
|
|
231
|
+
# PUBLIC FUNCTIONS #
|
|
232
|
+
############################################################
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def passed_geometries(self) -> list[GeoObject]:
|
|
236
|
+
""""""
|
|
237
|
+
return self.data.sim['geometries']
|
|
238
|
+
|
|
143
239
|
def save(self) -> None:
|
|
144
240
|
"""Saves the current model in the provided project directory."""
|
|
145
241
|
# Ensure directory exists
|
|
@@ -186,11 +282,8 @@ class Simulation3D:
|
|
|
186
282
|
# Load data
|
|
187
283
|
datapack = joblib.load(str(data_path))
|
|
188
284
|
self.data = datapack['simdata']
|
|
189
|
-
self.
|
|
285
|
+
self._set_mesh(datapack['mesh'])
|
|
190
286
|
logger.info(f"Loaded simulation data from: {data_path}")
|
|
191
|
-
|
|
192
|
-
def load_data(self, key: str) -> Any:
|
|
193
|
-
return self.save_data[key]
|
|
194
287
|
|
|
195
288
|
def set_loglevel(self, loglevel: Literal['DEBUG','INFO','WARNING','ERROR']) -> None:
|
|
196
289
|
"""Set the loglevel for loguru.
|
|
@@ -198,12 +291,11 @@ class Simulation3D:
|
|
|
198
291
|
Args:
|
|
199
292
|
loglevel ('DEBUG','INFO','WARNING','ERROR'): The loglevel
|
|
200
293
|
"""
|
|
201
|
-
|
|
202
|
-
logger.configure(handlers=[handler])
|
|
294
|
+
LOG_CONTROLLER.set_std_loglevel(loglevel)
|
|
203
295
|
|
|
204
296
|
def set_logfile(self) -> None:
|
|
205
297
|
"""Adds a file output for the logger."""
|
|
206
|
-
|
|
298
|
+
LOG_CONTROLLER.set_write_file(self.modelpath)
|
|
207
299
|
|
|
208
300
|
def view(self,
|
|
209
301
|
selections: list[Selection] = None,
|
|
@@ -240,15 +332,20 @@ class Simulation3D:
|
|
|
240
332
|
'sure that this method is properly implemented.')
|
|
241
333
|
|
|
242
334
|
def set_periodic_cell(self, cell: PeriodicCell, excluded_faces: list[FaceSelection] = None):
|
|
243
|
-
"""
|
|
335
|
+
"""Set the given periodic cell object as the simulations peridicity.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
cell (PeriodicCell): The PeriodicCell class
|
|
339
|
+
excluded_faces (list[FaceSelection], optional): Faces to exclude from the periodic boundary condition. Defaults to None.
|
|
340
|
+
"""
|
|
244
341
|
self.mw.bc._cell = cell
|
|
245
342
|
self._cell = cell
|
|
246
343
|
|
|
247
|
-
def
|
|
248
|
-
"""
|
|
249
|
-
in the simulation. Please make sure to include all geometries. Its currently unclear how the
|
|
250
|
-
system behaves if only a part of all geometries are included.
|
|
344
|
+
def commit_geometry(self, *geometries: list[GeoObject]) -> None:
|
|
345
|
+
"""Finalizes and locks the current geometry state of the simulation.
|
|
251
346
|
|
|
347
|
+
The geometries may be provided (legacy behavior) but are automatically managed underwater.
|
|
348
|
+
|
|
252
349
|
"""
|
|
253
350
|
if not geometries:
|
|
254
351
|
geometries = _GEOMANAGER.all_geometries()
|
|
@@ -258,15 +355,10 @@ class Simulation3D:
|
|
|
258
355
|
self.mesher.submit_objects(geometries)
|
|
259
356
|
self._defined_geometries = True
|
|
260
357
|
self.display._facetags = [dt[1] for dt in gmsh.model.get_entities(2)]
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
self.mesher.set_periodic_cell(self._cell)
|
|
264
|
-
|
|
265
|
-
self.mw._initialize_bcs()
|
|
266
|
-
|
|
267
|
-
def generate_mesh(self):
|
|
358
|
+
|
|
359
|
+
def generate_mesh(self) -> None:
|
|
268
360
|
"""Generate the mesh.
|
|
269
|
-
This can only be done after
|
|
361
|
+
This can only be done after commit_geometry(...) is called and if frequencies are defined.
|
|
270
362
|
|
|
271
363
|
Args:
|
|
272
364
|
name (str, optional): The mesh file name. Defaults to "meshname.msh".
|
|
@@ -275,8 +367,14 @@ class Simulation3D:
|
|
|
275
367
|
ValueError: ValueError if no frequencies are defined.
|
|
276
368
|
"""
|
|
277
369
|
if not self._defined_geometries:
|
|
278
|
-
self.
|
|
370
|
+
self.commit_geometry()
|
|
279
371
|
|
|
372
|
+
# Set the cell periodicity in GMSH
|
|
373
|
+
if self._cell is not None:
|
|
374
|
+
self.mesher.set_periodic_cell(self._cell)
|
|
375
|
+
|
|
376
|
+
self.mw._initialize_bcs()
|
|
377
|
+
|
|
280
378
|
# Check if frequencies are defined: TODO: Replace with a more generic check
|
|
281
379
|
if self.mw.frequencies is None:
|
|
282
380
|
raise ValueError('No frequencies defined for the simulation. Please set frequencies before generating the mesh.')
|
|
@@ -296,25 +394,7 @@ class Simulation3D:
|
|
|
296
394
|
self.mesh.update(self.mesher._get_periodic_bcs())
|
|
297
395
|
self.mesh.exterior_face_tags = self.mesher.domain_boundary_face_tags
|
|
298
396
|
gmsh.model.occ.synchronize()
|
|
299
|
-
self.
|
|
300
|
-
|
|
301
|
-
def get_boundary(self, face: FaceSelection = None, tags: list[int] = None) -> tuple[np.ndarray, np.ndarray]:
|
|
302
|
-
''' Return boundary data.
|
|
303
|
-
|
|
304
|
-
Parameters
|
|
305
|
-
----------
|
|
306
|
-
obj: GeoObject
|
|
307
|
-
tags: list[int]
|
|
308
|
-
|
|
309
|
-
Returns:
|
|
310
|
-
----------
|
|
311
|
-
nodes: np.ndarray
|
|
312
|
-
triangles: np.ndarray
|
|
313
|
-
'''
|
|
314
|
-
if tags is None:
|
|
315
|
-
tags = face.tags
|
|
316
|
-
tri_ids = self.mesh.get_triangles(tags)
|
|
317
|
-
return self.mesh.nodes, self.mesh.tris[:,tri_ids]
|
|
397
|
+
self._set_mesh(self.mesh)
|
|
318
398
|
|
|
319
399
|
def parameter_sweep(self, clear_mesh: bool = True, **parameters: np.ndarray) -> Generator[tuple[float,...], None, None]:
|
|
320
400
|
"""Executes a parameteric sweep iteration.
|
|
@@ -349,7 +429,7 @@ class Simulation3D:
|
|
|
349
429
|
gmsh.clear()
|
|
350
430
|
mesh = Mesh3D(self.mesher)
|
|
351
431
|
_GEOMANAGER.reset(self.modelname)
|
|
352
|
-
self.
|
|
432
|
+
self._set_mesh(mesh)
|
|
353
433
|
self.mw.reset()
|
|
354
434
|
|
|
355
435
|
params = {key: dim[i_iter] for key,dim in zip(paramlist, dims_flat)}
|
|
@@ -363,81 +443,12 @@ class Simulation3D:
|
|
|
363
443
|
yield (dim[i_iter] for dim in dims_flat)
|
|
364
444
|
self.mw.cache_matrices = True
|
|
365
445
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
Returns:
|
|
370
|
-
Simulation3D: the Simulation3D object
|
|
371
|
-
"""
|
|
372
|
-
return self
|
|
446
|
+
############################################################
|
|
447
|
+
# DEPRICATED FUNCTIONS #
|
|
448
|
+
############################################################
|
|
373
449
|
|
|
374
|
-
def
|
|
375
|
-
"""
|
|
376
|
-
self._exit_gmsh()
|
|
377
|
-
return False
|
|
378
|
-
|
|
379
|
-
def _install_signal_handlers(self):
|
|
380
|
-
# on SIGINT (Ctrl-C) or SIGTERM, call our exit routine
|
|
381
|
-
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
382
|
-
signal.signal(sig, self._handle_signal)
|
|
383
|
-
|
|
384
|
-
def _handle_signal(self, signum, frame):
|
|
385
|
-
"""
|
|
386
|
-
Signal handler: do our cleanup, then re-raise
|
|
387
|
-
the default handler so that exit code / traceback
|
|
388
|
-
is as expected.
|
|
450
|
+
def define_geometry(self, *args):
|
|
451
|
+
"""DEPRICATED VERSION: Use .commit_geometry()
|
|
389
452
|
"""
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
self._exit_gmsh()
|
|
393
|
-
except Exception:
|
|
394
|
-
# log but don’t block shutdown
|
|
395
|
-
logger.exception("Error during signal cleanup")
|
|
396
|
-
finally:
|
|
397
|
-
# restore default handler and re‐send the signal
|
|
398
|
-
signal.signal(signum, signal.SIG_DFL)
|
|
399
|
-
os.kill(os.getpid(), signum)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
def _initialize_simulation(self):
|
|
403
|
-
"""Initializes the Simulation data and GMSH API with proper shutdown routines.
|
|
404
|
-
"""
|
|
405
|
-
_GEOMANAGER.sign_in(self.modelname)
|
|
406
|
-
|
|
407
|
-
# If GMSH is not yet initialized (Two simulation in a file)
|
|
408
|
-
if gmsh.isInitialized() == 0:
|
|
409
|
-
logger.debug('Initializing GMSH')
|
|
410
|
-
gmsh.initialize()
|
|
411
|
-
|
|
412
|
-
# Set an exit handler for Ctrl+C cases
|
|
413
|
-
self._install_signal_handlers()
|
|
414
|
-
|
|
415
|
-
# Restier the Exit GMSH function on proper program abortion
|
|
416
|
-
register(self._exit_gmsh)
|
|
417
|
-
|
|
418
|
-
# Create a new GMSH model or load it
|
|
419
|
-
if not self.load_file:
|
|
420
|
-
gmsh.model.add(self.modelname)
|
|
421
|
-
self.data: SimulationDataset = SimulationDataset()
|
|
422
|
-
else:
|
|
423
|
-
self.load()
|
|
424
|
-
|
|
425
|
-
# Set the Simulation state to active
|
|
426
|
-
self.__active = True
|
|
427
|
-
return self
|
|
428
|
-
|
|
429
|
-
def _exit_gmsh(self):
|
|
430
|
-
# If the simulation object state is still active (GMSH is running)
|
|
431
|
-
if not self.__active:
|
|
432
|
-
return
|
|
433
|
-
logger.debug('Exiting program')
|
|
434
|
-
# Save the file first
|
|
435
|
-
if self.save_file:
|
|
436
|
-
self.save()
|
|
437
|
-
# Finalize GMSH
|
|
438
|
-
gmsh.finalize()
|
|
439
|
-
logger.debug('GMSH Shut down successful')
|
|
440
|
-
# set the state to active
|
|
441
|
-
self.__active = False
|
|
442
|
-
|
|
443
|
-
|
|
453
|
+
logger.warning('define_geometry() will be derpicated. Use commit_geometry() instead.')
|
|
454
|
+
self.commit_geometry(*args)
|