radia 1.3.2__py3-none-any.whl → 1.3.4__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.
- python/nastran_mesh_import.py +441 -0
- python/netgen_mesh_import.py +572 -0
- python/rad_ngsolve.pyd +0 -0
- python/radia_field_cached.py +274 -274
- python/radia_ngsolve.pyd +0 -0
- python/radia_ngsolve_utils.py +293 -0
- python/radia_vtk_export.py +106 -19
- {radia-1.3.2.dist-info → radia-1.3.4.dist-info}/METADATA +16 -19
- radia-1.3.4.dist-info/RECORD +17 -0
- {radia-1.3.2.dist-info → radia-1.3.4.dist-info}/licenses/LICENSE +93 -93
- python/nastran_reader.py +0 -295
- python/radia.pyd +0 -0
- radia-1.3.2.dist-info/RECORD +0 -15
- {radia-1.3.2.dist-info → radia-1.3.4.dist-info}/WHEEL +0 -0
- {radia-1.3.2.dist-info → radia-1.3.4.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
radia_ngsolve_utils.py - Utilities for Radia-NGSolve integration
|
|
4
|
+
|
|
5
|
+
This module provides high-level utilities for working with Radia and NGSolve together,
|
|
6
|
+
including mesh import and VTK export functionality.
|
|
7
|
+
|
|
8
|
+
Author: Radia Development Team
|
|
9
|
+
Created: 2025-11-22
|
|
10
|
+
Version: 1.0.0
|
|
11
|
+
|
|
12
|
+
Key Features
|
|
13
|
+
------------
|
|
14
|
+
- Import Netgen/OCC tetrahedral meshes to Radia
|
|
15
|
+
- Export Radia geometry to VTK for visualization
|
|
16
|
+
- Export NGSolve solutions to VTK
|
|
17
|
+
- Unified interface for both solvers
|
|
18
|
+
|
|
19
|
+
Functions
|
|
20
|
+
---------
|
|
21
|
+
create_radia_from_mesh : Import Netgen mesh to Radia with VTK export
|
|
22
|
+
export_ngsolve_vtk : Export NGSolve solution to VTK
|
|
23
|
+
export_radia_vtk : Export Radia geometry to VTK
|
|
24
|
+
|
|
25
|
+
Example
|
|
26
|
+
-------
|
|
27
|
+
>>> import radia as rad
|
|
28
|
+
>>> from ngsolve import Mesh
|
|
29
|
+
>>> from netgen.occ import Box, OCCGeometry
|
|
30
|
+
>>> from radia_ngsolve_utils import create_radia_from_mesh, export_radia_vtk
|
|
31
|
+
>>>
|
|
32
|
+
>>> # Setup
|
|
33
|
+
>>> rad.FldUnits('m')
|
|
34
|
+
>>>
|
|
35
|
+
>>> # Create mesh
|
|
36
|
+
>>> geo = OCCGeometry(Box((-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)))
|
|
37
|
+
>>> mesh = Mesh(geo.GenerateMesh(maxh=0.2))
|
|
38
|
+
>>>
|
|
39
|
+
>>> # Import to Radia and export VTK
|
|
40
|
+
>>> mag = create_radia_from_mesh(
|
|
41
|
+
... mesh,
|
|
42
|
+
... material={'magnetization': [0, 0, 1.2]},
|
|
43
|
+
... vtk_filename='magnet'
|
|
44
|
+
... )
|
|
45
|
+
>>>
|
|
46
|
+
>>> # Apply material and solve
|
|
47
|
+
>>> rad.MatApl(mag, rad.MatStd('NdFeB', 1.2))
|
|
48
|
+
>>> rad.Solve(mag, 0.0001, 10000)
|
|
49
|
+
>>>
|
|
50
|
+
>>> # Export final geometry
|
|
51
|
+
>>> export_radia_vtk(mag, 'magnet_solved')
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
import os
|
|
55
|
+
import radia as rad
|
|
56
|
+
from netgen_mesh_import import netgen_mesh_to_radia
|
|
57
|
+
from radia_vtk_export import exportGeometryToVTK
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def create_radia_from_mesh(mesh, material=None, units='m', combine=True,
|
|
61
|
+
verbose=False, material_filter=None, vtk_filename=None):
|
|
62
|
+
"""
|
|
63
|
+
Import Netgen mesh to Radia and optionally export to VTK.
|
|
64
|
+
|
|
65
|
+
This is a convenience wrapper around netgen_mesh_to_radia that adds
|
|
66
|
+
automatic VTK export functionality.
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
mesh : ngsolve.Mesh
|
|
71
|
+
NGSolve mesh object to import
|
|
72
|
+
material : dict, optional
|
|
73
|
+
Material properties. Should contain 'magnetization' key with [Mx, My, Mz] in Tesla.
|
|
74
|
+
Default: {'magnetization': [0, 0, 0]}
|
|
75
|
+
units : str, optional
|
|
76
|
+
Length units: 'm' (meters) or 'mm' (millimeters)
|
|
77
|
+
Default: 'm' (recommended for NGSolve integration)
|
|
78
|
+
combine : bool, optional
|
|
79
|
+
If True, combine all tetrahedra into single container
|
|
80
|
+
If False, return list of individual tetrahedra
|
|
81
|
+
Default: True
|
|
82
|
+
verbose : bool, optional
|
|
83
|
+
Print detailed import information
|
|
84
|
+
Default: False
|
|
85
|
+
material_filter : str, optional
|
|
86
|
+
Filter mesh by material name (e.g., 'magnetic', 'air')
|
|
87
|
+
If None, import all materials
|
|
88
|
+
Default: None
|
|
89
|
+
vtk_filename : str, optional
|
|
90
|
+
If provided, export geometry to VTK file with this name (without .vtk extension)
|
|
91
|
+
Default: None (no VTK export)
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
int or list
|
|
96
|
+
Radia object ID (if combine=True) or list of object IDs (if combine=False)
|
|
97
|
+
|
|
98
|
+
Example
|
|
99
|
+
-------
|
|
100
|
+
>>> from netgen.occ import Box, OCCGeometry
|
|
101
|
+
>>> from ngsolve import Mesh
|
|
102
|
+
>>> import radia as rad
|
|
103
|
+
>>> from radia_ngsolve_utils import create_radia_from_mesh
|
|
104
|
+
>>>
|
|
105
|
+
>>> rad.FldUnits('m')
|
|
106
|
+
>>> geo = OCCGeometry(Box((0, 0, 0), (0.1, 0.1, 0.1)))
|
|
107
|
+
>>> mesh = Mesh(geo.GenerateMesh(maxh=0.03))
|
|
108
|
+
>>>
|
|
109
|
+
>>> magnet = create_radia_from_mesh(
|
|
110
|
+
... mesh,
|
|
111
|
+
... material={'magnetization': [0, 0, 1.2]},
|
|
112
|
+
... vtk_filename='my_magnet'
|
|
113
|
+
... )
|
|
114
|
+
>>> # Creates my_magnet.vtk in current directory
|
|
115
|
+
"""
|
|
116
|
+
# Import mesh to Radia
|
|
117
|
+
radia_obj = netgen_mesh_to_radia(
|
|
118
|
+
mesh=mesh,
|
|
119
|
+
material=material,
|
|
120
|
+
units=units,
|
|
121
|
+
combine=combine,
|
|
122
|
+
verbose=verbose,
|
|
123
|
+
material_filter=material_filter
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Export to VTK if requested
|
|
127
|
+
if vtk_filename is not None:
|
|
128
|
+
export_radia_vtk(radia_obj, vtk_filename)
|
|
129
|
+
|
|
130
|
+
return radia_obj
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def export_radia_vtk(radia_obj, filename):
|
|
134
|
+
"""
|
|
135
|
+
Export Radia geometry to VTK file.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
radia_obj : int
|
|
140
|
+
Radia object ID
|
|
141
|
+
filename : str
|
|
142
|
+
Output filename without .vtk extension
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
str
|
|
147
|
+
Full path to created VTK file
|
|
148
|
+
|
|
149
|
+
Example
|
|
150
|
+
-------
|
|
151
|
+
>>> import radia as rad
|
|
152
|
+
>>> from radia_ngsolve_utils import export_radia_vtk
|
|
153
|
+
>>>
|
|
154
|
+
>>> magnet = rad.ObjRecMag([0, 0, 0], [10, 10, 10], [0, 0, 1])
|
|
155
|
+
>>> vtk_path = export_radia_vtk(magnet, 'my_magnet')
|
|
156
|
+
>>> print(f"VTK exported to: {vtk_path}")
|
|
157
|
+
"""
|
|
158
|
+
# Ensure .vtk extension
|
|
159
|
+
if not filename.endswith('.vtk'):
|
|
160
|
+
base_filename = filename
|
|
161
|
+
filename = filename + '.vtk'
|
|
162
|
+
else:
|
|
163
|
+
base_filename = filename[:-4]
|
|
164
|
+
|
|
165
|
+
# Export using radia_vtk_export
|
|
166
|
+
exportGeometryToVTK(radia_obj, base_filename)
|
|
167
|
+
|
|
168
|
+
# Get absolute path
|
|
169
|
+
vtk_path = os.path.abspath(filename)
|
|
170
|
+
|
|
171
|
+
return vtk_path
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def export_ngsolve_vtk(mesh, gridfunction, filename, field_name='solution'):
|
|
175
|
+
"""
|
|
176
|
+
Export NGSolve solution to VTK file.
|
|
177
|
+
|
|
178
|
+
Uses NGSolve's built-in VTK export functionality.
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
mesh : ngsolve.Mesh
|
|
183
|
+
NGSolve mesh
|
|
184
|
+
gridfunction : ngsolve.GridFunction
|
|
185
|
+
Solution to export (e.g., H-field, B-field, potential)
|
|
186
|
+
filename : str
|
|
187
|
+
Output filename without .vtk extension
|
|
188
|
+
field_name : str, optional
|
|
189
|
+
Name for the field in VTK file
|
|
190
|
+
Default: 'solution'
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
str
|
|
195
|
+
Full path to created VTK file
|
|
196
|
+
|
|
197
|
+
Example
|
|
198
|
+
-------
|
|
199
|
+
>>> from ngsolve import *
|
|
200
|
+
>>> from netgen.occ import Box, OCCGeometry
|
|
201
|
+
>>> from radia_ngsolve_utils import export_ngsolve_vtk
|
|
202
|
+
>>>
|
|
203
|
+
>>> geo = OCCGeometry(Box((0, 0, 0), (1, 1, 1)))
|
|
204
|
+
>>> mesh = Mesh(geo.GenerateMesh(maxh=0.2))
|
|
205
|
+
>>> fes = H1(mesh, order=2)
|
|
206
|
+
>>> gfu = GridFunction(fes)
|
|
207
|
+
>>> # ... solve for gfu ...
|
|
208
|
+
>>>
|
|
209
|
+
>>> vtk_path = export_ngsolve_vtk(mesh, gfu, 'solution', 'phi')
|
|
210
|
+
>>> print(f"NGSolve VTK exported to: {vtk_path}")
|
|
211
|
+
"""
|
|
212
|
+
from ngsolve import VTKOutput
|
|
213
|
+
|
|
214
|
+
# Ensure .vtk extension
|
|
215
|
+
if filename.endswith('.vtk'):
|
|
216
|
+
filename = filename[:-4]
|
|
217
|
+
|
|
218
|
+
# Create VTK output
|
|
219
|
+
vtk = VTKOutput(
|
|
220
|
+
ma=mesh,
|
|
221
|
+
coefs=[gridfunction],
|
|
222
|
+
names=[field_name],
|
|
223
|
+
filename=filename,
|
|
224
|
+
subdivision=2
|
|
225
|
+
)
|
|
226
|
+
vtk.Do()
|
|
227
|
+
|
|
228
|
+
# Get absolute path
|
|
229
|
+
vtk_path = os.path.abspath(filename + '.vtk')
|
|
230
|
+
|
|
231
|
+
return vtk_path
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def export_comparison_vtk(mesh_ngsolve, gfu_ngsolve, radia_obj,
|
|
235
|
+
prefix='comparison', ngsolve_field_name='H_ngsolve'):
|
|
236
|
+
"""
|
|
237
|
+
Export both NGSolve and Radia results to VTK for comparison.
|
|
238
|
+
|
|
239
|
+
Creates two VTK files:
|
|
240
|
+
- {prefix}_ngsolve.vtk : NGSolve solution
|
|
241
|
+
- {prefix}_radia.vtk : Radia geometry
|
|
242
|
+
|
|
243
|
+
Parameters
|
|
244
|
+
----------
|
|
245
|
+
mesh_ngsolve : ngsolve.Mesh
|
|
246
|
+
NGSolve mesh
|
|
247
|
+
gfu_ngsolve : ngsolve.GridFunction
|
|
248
|
+
NGSolve solution
|
|
249
|
+
radia_obj : int
|
|
250
|
+
Radia object ID
|
|
251
|
+
prefix : str, optional
|
|
252
|
+
Prefix for output filenames
|
|
253
|
+
Default: 'comparison'
|
|
254
|
+
ngsolve_field_name : str, optional
|
|
255
|
+
Name for NGSolve field in VTK
|
|
256
|
+
Default: 'H_ngsolve'
|
|
257
|
+
|
|
258
|
+
Returns
|
|
259
|
+
-------
|
|
260
|
+
tuple of str
|
|
261
|
+
(ngsolve_vtk_path, radia_vtk_path)
|
|
262
|
+
|
|
263
|
+
Example
|
|
264
|
+
-------
|
|
265
|
+
>>> from radia_ngsolve_utils import export_comparison_vtk
|
|
266
|
+
>>>
|
|
267
|
+
>>> # After solving both NGSolve and Radia...
|
|
268
|
+
>>> ngsolve_vtk, radia_vtk = export_comparison_vtk(
|
|
269
|
+
... mesh, gfu, radia_system,
|
|
270
|
+
... prefix='cube_benchmark',
|
|
271
|
+
... ngsolve_field_name='H_field'
|
|
272
|
+
... )
|
|
273
|
+
>>> print(f"NGSolve: {ngsolve_vtk}")
|
|
274
|
+
>>> print(f"Radia: {radia_vtk}")
|
|
275
|
+
"""
|
|
276
|
+
ngsolve_filename = f"{prefix}_ngsolve"
|
|
277
|
+
radia_filename = f"{prefix}_radia"
|
|
278
|
+
|
|
279
|
+
ngsolve_vtk = export_ngsolve_vtk(mesh_ngsolve, gfu_ngsolve,
|
|
280
|
+
ngsolve_filename, ngsolve_field_name)
|
|
281
|
+
radia_vtk = export_radia_vtk(radia_obj, radia_filename)
|
|
282
|
+
|
|
283
|
+
return ngsolve_vtk, radia_vtk
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
# Module-level constants
|
|
287
|
+
__version__ = '1.0.0'
|
|
288
|
+
__all__ = [
|
|
289
|
+
'create_radia_from_mesh',
|
|
290
|
+
'export_radia_vtk',
|
|
291
|
+
'export_ngsolve_vtk',
|
|
292
|
+
'export_comparison_vtk'
|
|
293
|
+
]
|
python/radia_vtk_export.py
CHANGED
|
@@ -7,10 +7,32 @@ Functions for exporting Radia geometry to VTK format for visualization
|
|
|
7
7
|
in ParaView and other VTK-compatible tools.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
import radia as rad
|
|
11
10
|
import csv
|
|
12
11
|
from itertools import accumulate
|
|
13
12
|
|
|
13
|
+
def _get_radia_length_unit():
|
|
14
|
+
"""
|
|
15
|
+
Get current Radia length unit by querying rad.FldUnits().
|
|
16
|
+
|
|
17
|
+
Returns:
|
|
18
|
+
tuple: (unit_name, scale_to_meters)
|
|
19
|
+
('mm', 0.001) if Radia is using millimeters
|
|
20
|
+
('m', 1.0) if Radia is using meters
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ValueError: If length unit cannot be determined
|
|
24
|
+
"""
|
|
25
|
+
import radia as rad
|
|
26
|
+
|
|
27
|
+
units_str = rad.FldUnits()
|
|
28
|
+
|
|
29
|
+
if 'Length: mm' in units_str:
|
|
30
|
+
return ('mm', 0.001)
|
|
31
|
+
elif 'Length: m' in units_str:
|
|
32
|
+
return ('m', 1.0)
|
|
33
|
+
else:
|
|
34
|
+
raise ValueError(f"Cannot determine Radia length unit from: {units_str}")
|
|
35
|
+
|
|
14
36
|
def chunks(lst, n):
|
|
15
37
|
"""
|
|
16
38
|
Yield successive n-sized chunks from a list.
|
|
@@ -45,7 +67,8 @@ def exportGeometryToVTK(obj, fileName='radia_Geometry'):
|
|
|
45
67
|
>>> mag = rad.ObjRecMag([0,0,0], [10,10,10], [0,0,1])
|
|
46
68
|
>>> exportGeometryToVTK(mag, 'my_magnet')
|
|
47
69
|
"""
|
|
48
|
-
|
|
70
|
+
import radia as rad
|
|
71
|
+
|
|
49
72
|
vtkData = rad.ObjDrwVTK(obj, 'Axes->False')
|
|
50
73
|
|
|
51
74
|
lengths = vtkData['polygons']['lengths']
|
|
@@ -55,34 +78,41 @@ def exportGeometryToVTK(obj, fileName='radia_Geometry'):
|
|
|
55
78
|
points = vtkData['polygons']['vertices']
|
|
56
79
|
nPnts = int(len(points)/3)
|
|
57
80
|
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
conn = list(range(nPnts))
|
|
81
|
+
# Get Radia's current length unit and convert to meters for VTK standard
|
|
82
|
+
unit_name, scale_to_meters = _get_radia_length_unit()
|
|
83
|
+
points = [round(num * scale_to_meters, 8) for num in points]
|
|
84
|
+
|
|
63
85
|
# define colours array
|
|
64
86
|
colors = vtkData['polygons']['colors']
|
|
65
87
|
|
|
66
88
|
# pre-process the output lists to have chunkLength items per line
|
|
67
|
-
chunkLength = 9 # this writes 9 numbers per line
|
|
68
|
-
offsets = list(chunks(offsets, chunkLength))
|
|
89
|
+
chunkLength = 9 # this writes 9 numbers per line
|
|
69
90
|
points = list(chunks(points, chunkLength))
|
|
70
|
-
conn = list(chunks(conn, chunkLength))
|
|
71
91
|
colors = list(chunks(colors, chunkLength))
|
|
72
92
|
|
|
73
|
-
# write the data to file
|
|
93
|
+
# write the data to file (VTK Legacy format - most compatible)
|
|
74
94
|
with open(fileName + ".vtk", "w", newline="") as f:
|
|
75
|
-
f.write('# vtk DataFile Version
|
|
95
|
+
f.write('# vtk DataFile Version 3.0\n')
|
|
76
96
|
f.write('vtk output\nASCII\nDATASET POLYDATA\n')
|
|
77
97
|
f.write('POINTS ' + str(nPnts) + ' float\n')
|
|
78
98
|
writer = csv.writer(f, delimiter=" ")
|
|
79
99
|
writer.writerows(points)
|
|
80
100
|
f.write('\n')
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
|
|
102
|
+
# POLYGONS in classic format (most compatible with all ParaView versions)
|
|
103
|
+
# Format: nPoly totalSize
|
|
104
|
+
# Each line: nVertices v1 v2 v3 ...
|
|
105
|
+
total_size = sum(lengths) + nPoly # sum of (nVertices + nVertices) for each polygon
|
|
106
|
+
f.write('POLYGONS ' + str(nPoly) + ' ' + str(total_size) + '\n')
|
|
107
|
+
for i in range(nPoly):
|
|
108
|
+
n_vertices = lengths[i]
|
|
109
|
+
start = offsets[i]
|
|
110
|
+
end = offsets[i+1]
|
|
111
|
+
f.write(str(n_vertices))
|
|
112
|
+
for j in range(start, end):
|
|
113
|
+
f.write(' ' + str(j))
|
|
114
|
+
f.write('\n')
|
|
115
|
+
|
|
86
116
|
f.write('\n')
|
|
87
117
|
f.write('CELL_DATA ' + str(nPoly) + '\n')
|
|
88
118
|
f.write('COLOR_SCALARS Radia_colours 3\n')
|
|
@@ -93,6 +123,62 @@ def exportGeometryToVTK(obj, fileName='radia_Geometry'):
|
|
|
93
123
|
print(f" Points: {nPnts}")
|
|
94
124
|
|
|
95
125
|
|
|
126
|
+
def exportFieldToVTK(points, field_data, fileName='field_distribution', field_name='B_field'):
|
|
127
|
+
"""
|
|
128
|
+
Export magnetic field distribution to VTK Legacy format file.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
points: List of observation points [[x, y, z], ...] in Radia's current units
|
|
132
|
+
field_data: List of field vectors [[Bx, By, Bz], ...] in Tesla
|
|
133
|
+
fileName: Output file name (without .vtk extension)
|
|
134
|
+
field_name: Name for the vector field in VTK file
|
|
135
|
+
|
|
136
|
+
Note:
|
|
137
|
+
Points are automatically converted to meters (VTK standard) based on
|
|
138
|
+
Radia's current unit setting (queried via rad.FldUnits()).
|
|
139
|
+
"""
|
|
140
|
+
import numpy as np
|
|
141
|
+
|
|
142
|
+
points = np.array(points)
|
|
143
|
+
field_data = np.array(field_data)
|
|
144
|
+
|
|
145
|
+
if points.shape[0] != field_data.shape[0]:
|
|
146
|
+
raise ValueError(f"Points ({points.shape[0]}) and field data ({field_data.shape[0]}) must have same length")
|
|
147
|
+
|
|
148
|
+
if points.shape[1] != 3 or field_data.shape[1] != 3:
|
|
149
|
+
raise ValueError("Points and field data must be Nx3 arrays")
|
|
150
|
+
|
|
151
|
+
# Get Radia's current length unit
|
|
152
|
+
unit_name, scale_to_meters = _get_radia_length_unit()
|
|
153
|
+
|
|
154
|
+
# Ensure .vtk extension
|
|
155
|
+
if not fileName.endswith('.vtk'):
|
|
156
|
+
fileName += '.vtk'
|
|
157
|
+
|
|
158
|
+
with open(fileName, 'w') as f:
|
|
159
|
+
# Header
|
|
160
|
+
f.write('# vtk DataFile Version 3.0\n')
|
|
161
|
+
f.write('Magnetic Field Distribution\n')
|
|
162
|
+
f.write('ASCII\n')
|
|
163
|
+
f.write('DATASET POLYDATA\n')
|
|
164
|
+
|
|
165
|
+
# Points (convert to meters for VTK standard)
|
|
166
|
+
f.write(f'POINTS {len(points)} float\n')
|
|
167
|
+
for pt in points:
|
|
168
|
+
# Convert to meters using detected unit scale
|
|
169
|
+
f.write(f'{pt[0]*scale_to_meters} {pt[1]*scale_to_meters} {pt[2]*scale_to_meters}\n')
|
|
170
|
+
|
|
171
|
+
# Point data (vector field)
|
|
172
|
+
f.write(f'\nPOINT_DATA {len(points)}\n')
|
|
173
|
+
f.write(f'VECTORS {field_name} float\n')
|
|
174
|
+
for B in field_data:
|
|
175
|
+
f.write(f'{B[0]} {B[1]} {B[2]}\n')
|
|
176
|
+
|
|
177
|
+
print(f"VTK field file exported: {fileName}")
|
|
178
|
+
print(f" Points: {len(points)}")
|
|
179
|
+
print(f" Field: {field_name}")
|
|
180
|
+
|
|
181
|
+
|
|
96
182
|
if __name__ == '__main__':
|
|
97
183
|
"""
|
|
98
184
|
Demo: Export a simple Radia geometry to VTK format
|
|
@@ -101,8 +187,9 @@ if __name__ == '__main__':
|
|
|
101
187
|
import os
|
|
102
188
|
|
|
103
189
|
# Add build directory to path
|
|
104
|
-
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'build', '
|
|
105
|
-
|
|
190
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'build', 'Release'))
|
|
191
|
+
|
|
192
|
+
import radia as rad
|
|
106
193
|
|
|
107
194
|
print("=" * 60)
|
|
108
195
|
print("Radia VTK Export Demo")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: radia
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Radia 3D Magnetostatics with NGSolve Integration and OpenMP Parallelization
|
|
5
5
|
Home-page: https://github.com/ksugahar/Radia_NGSolve
|
|
6
6
|
Author: Pascal Elleaume
|
|
@@ -88,12 +88,12 @@ pip install radia-ngsolve
|
|
|
88
88
|
# 1. Build radia.pyd (core module)
|
|
89
89
|
.\Build.ps1
|
|
90
90
|
|
|
91
|
-
# 2. Build
|
|
91
|
+
# 2. Build radia_ngsolve.pyd (optional, for NGSolve integration)
|
|
92
92
|
.\Build_NGSolve.ps1
|
|
93
93
|
|
|
94
94
|
# Outputs:
|
|
95
95
|
# - dist/radia.pyd
|
|
96
|
-
# - build/Release/
|
|
96
|
+
# - build/Release/radia_ngsolve.pyd
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
See [README_BUILD.md](README_BUILD.md) for detailed build instructions.
|
|
@@ -117,12 +117,12 @@ print(f"Field: {field} T")
|
|
|
117
117
|
|
|
118
118
|
### NGSolve Integration
|
|
119
119
|
|
|
120
|
-
The `
|
|
120
|
+
The `radia_ngsolve` module provides a C++ CoefficientFunction interface for using Radia magnetic fields in NGSolve FEM analysis.
|
|
121
121
|
|
|
122
122
|
**Function Specification:**
|
|
123
123
|
|
|
124
124
|
```python
|
|
125
|
-
|
|
125
|
+
radia_ngsolve.RadiaField(radia_obj, field_type='b')
|
|
126
126
|
```
|
|
127
127
|
|
|
128
128
|
**Parameters:**
|
|
@@ -149,7 +149,7 @@ import ngsolve
|
|
|
149
149
|
from ngsolve import Mesh, H1, GridFunction
|
|
150
150
|
|
|
151
151
|
import radia as rad
|
|
152
|
-
import
|
|
152
|
+
import radia_ngsolve
|
|
153
153
|
|
|
154
154
|
# Create Radia magnet
|
|
155
155
|
magnet = rad.ObjRecMag([0,0,0], [20,20,20], [0,0,1.2]) # mm units
|
|
@@ -157,10 +157,10 @@ rad.MatApl(magnet, rad.MatPM(1.2, 900000, [0,0,1])) # NdFeB permanent magnet
|
|
|
157
157
|
rad.Solve(magnet, 0.0001, 10000)
|
|
158
158
|
|
|
159
159
|
# Create NGSolve CoefficientFunction for different field types
|
|
160
|
-
B_field =
|
|
161
|
-
H_field =
|
|
162
|
-
A_field =
|
|
163
|
-
M_field =
|
|
160
|
+
B_field = radia_ngsolve.RadiaField(magnet, 'b') # Flux density [T]
|
|
161
|
+
H_field = radia_ngsolve.RadiaField(magnet, 'h') # Magnetic field [A/m]
|
|
162
|
+
A_field = radia_ngsolve.RadiaField(magnet, 'a') # Vector potential [T·m]
|
|
163
|
+
M_field = radia_ngsolve.RadiaField(magnet, 'm') # Magnetization [A/m]
|
|
164
164
|
|
|
165
165
|
# Use in FEM analysis (NGSolve mesh in meters)
|
|
166
166
|
gf = GridFunction(fes)
|
|
@@ -177,13 +177,10 @@ See [examples/Radia_to_NGSolve_CoefficientFunction/](examples/Radia_to_NGSolve_C
|
|
|
177
177
|
- [docs/DIRECTORY_STRUCTURE.md](docs/DIRECTORY_STRUCTURE.md) - Project structure
|
|
178
178
|
|
|
179
179
|
### NGSolve Integration
|
|
180
|
-
- [RAD_NGSOLVE_BUILD_SUCCESS.md](RAD_NGSOLVE_BUILD_SUCCESS.md) - Complete
|
|
180
|
+
- [RAD_NGSOLVE_BUILD_SUCCESS.md](RAD_NGSOLVE_BUILD_SUCCESS.md) - Complete radia_ngsolve documentation
|
|
181
181
|
- [examples/Radia_to_NGSolve_CoefficientFunction/README.md](examples/Radia_to_NGSolve_CoefficientFunction/README.md) - NGSolve examples overview
|
|
182
182
|
- [examples/Radia_to_NGSolve_CoefficientFunction/EXAMPLES_GUIDE.md](examples/Radia_to_NGSolve_CoefficientFunction/EXAMPLES_GUIDE.md) - Detailed usage guide
|
|
183
|
-
- [tests/
|
|
184
|
-
|
|
185
|
-
### Visualization
|
|
186
|
-
- [docs/PYVISTA_VIEWER.md](examples/2024_02_03_振分電磁石/PYVISTA_VIEWER.md) - PyVista viewer guide
|
|
183
|
+
- [tests/test_radia_ngsolve.py](tests/test_radia_ngsolve.py) - Integration tests
|
|
187
184
|
|
|
188
185
|
### Development
|
|
189
186
|
- [docs/TAB_CONVERSION_REPORT.md](docs/TAB_CONVERSION_REPORT.md) - Code style conversion
|
|
@@ -239,7 +236,7 @@ python tests/test_radia.py
|
|
|
239
236
|
python tests/test_advanced.py
|
|
240
237
|
|
|
241
238
|
# NGSolve integration test
|
|
242
|
-
python tests/
|
|
239
|
+
python tests/test_radia_ngsolve.py
|
|
243
240
|
|
|
244
241
|
# OpenMP performance test
|
|
245
242
|
python tests/test_parallel_performance.py
|
|
@@ -248,7 +245,7 @@ python tests/test_parallel_performance.py
|
|
|
248
245
|
pytest tests/
|
|
249
246
|
|
|
250
247
|
# Run specific test suite
|
|
251
|
-
pytest tests/
|
|
248
|
+
pytest tests/test_radia_ngsolve.py -v
|
|
252
249
|
```
|
|
253
250
|
|
|
254
251
|
See [tests/README.md](tests/README.md) for detailed testing documentation.
|
|
@@ -296,7 +293,7 @@ export_geometry_to_vtk(mag, 'geometry.vtk')
|
|
|
296
293
|
### Runtime Requirements
|
|
297
294
|
- Python 3.12
|
|
298
295
|
- NumPy
|
|
299
|
-
- NGSolve (optional, for FEM coupling via
|
|
296
|
+
- NGSolve (optional, for FEM coupling via radia_ngsolve)
|
|
300
297
|
- PyVista (optional, for 3D visualization)
|
|
301
298
|
|
|
302
299
|
## Changes from Original Radia
|
|
@@ -348,7 +345,7 @@ See:
|
|
|
348
345
|
|
|
349
346
|
**This Fork**:
|
|
350
347
|
- OpenMP parallelization
|
|
351
|
-
- NGSolve C++ integration (
|
|
348
|
+
- NGSolve C++ integration (radia_ngsolve)
|
|
352
349
|
- Python 3.12 optimization
|
|
353
350
|
- Build system modernization
|
|
354
351
|
- PyVista integration
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
python/__init__.py,sha256=oUOAjf_vY8DNy5HRU7oArAMic8urvHCR9yHSi4HFkkQ,47
|
|
2
|
+
python/nastran_mesh_import.py,sha256=CSoVhZCXa85lPiTF2hlspE2clBKOD7-_sCp1bxu_IK0,18147
|
|
3
|
+
python/netgen_mesh_import.py,sha256=UopXk-5bbfj1j9_hyiq8jbjb4SQXnWaeuaC7TDf17wA,19872
|
|
4
|
+
python/rad_ngsolve.pyd,sha256=s5ZvpTIrjYeV_B3vQv5HrtP4u_RaPhvxuZf5aKv3oC0,566272
|
|
5
|
+
python/rad_ngsolve_fast.py,sha256=GkC7ruKy3MESHsO0iRSWsrgLU4-DPPgctOi6pPpsWg4,5675
|
|
6
|
+
python/radia_coil_builder.py,sha256=nQkiAbfhueNvvxUARHdPD0C68ImidHmUQv_q4RsImeY,11253
|
|
7
|
+
python/radia_field_cached.py,sha256=Bjw3ecNe3u7AAXnLob5m_tjYIY7HwB9DpgFg9a-aP_8,9509
|
|
8
|
+
python/radia_ngsolve.pyd,sha256=s5ZvpTIrjYeV_B3vQv5HrtP4u_RaPhvxuZf5aKv3oC0,566272
|
|
9
|
+
python/radia_ngsolve_field.py,sha256=suJr4wacfYFKOkyV-5AQuHWnW5rtUMb0gSSjq8VRSXc,10166
|
|
10
|
+
python/radia_ngsolve_utils.py,sha256=xZCR9DOIKMwdEjmC28rOXVZiWFY5BQYH2VfopfuVBps,8406
|
|
11
|
+
python/radia_pyvista_viewer.py,sha256=JS33Mx4azGI7hUX0bzefc6zJfhv6qfRjM3Kl1bE9Mjs,4275
|
|
12
|
+
python/radia_vtk_export.py,sha256=I8Vyyt9tky78Qw1xPru9f0Rii6QEmdEgTFjQtamyooc,6540
|
|
13
|
+
radia-1.3.4.dist-info/licenses/LICENSE,sha256=yaWxyzG9DpJ44dDNdGni4nukwiZ8pU-r_aW-1tYNAjk,4374
|
|
14
|
+
radia-1.3.4.dist-info/METADATA,sha256=iLmP3uISANgF67d-fTvmh17jl1YNvuHjiEcBvBRkQm0,13202
|
|
15
|
+
radia-1.3.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
radia-1.3.4.dist-info/top_level.txt,sha256=J-z0poNcsv31IHB413--iOY8LoHBKiTHeybHX3abokI,7
|
|
17
|
+
radia-1.3.4.dist-info/RECORD,,
|