Skip to content

Commit 3e1c6e3

Browse files
committed
fix: fixes the bug reported in issue #70 (#71)
* Fixing the bug with the bi-planar factory function, which was using the wrong input_args structure. * Added regression test. * Adding additional export step, for debugging purposes.
1 parent eb3ab03 commit 3e1c6e3

File tree

6 files changed

+139
-3
lines changed

6 files changed

+139
-3
lines changed

pyCoilGen/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Magnetic Field Coil Generator for Python."""
22
# Semantic Versioning according to https://semver.org/spec/v2.0.0.html
3-
__version__ = "0.2.1" # Fix level, due to bugfix, issue #68
3+
__version__ = "0.2.2" # Fix level, due to bugfix, issue #70

pyCoilGen/mesh_factory/build_biplanar_mesh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def create_bi_planar_mesh(input_args):
113113
Used when 'input_args.coil_mesh_file' is 'create bi-planar mesh'.
114114
"""
115115
log.debug("Creating bi-planar mesh with '%s'", input_args.biplanar_mesh_parameter_list)
116-
mesh_data = build_biplanar_mesh(*input_args.planar_mesh_parameter_list)
116+
mesh_data = build_biplanar_mesh(*input_args.biplanar_mesh_parameter_list)
117117
coil_mesh = create_unique_noded_mesh(mesh_data)
118118
return coil_mesh
119119

pyCoilGen/pyCoilGen_release.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ def pyCoilGen(log, input_args=None):
153153
timer.stop()
154154
runpoint_tag = '02'
155155

156+
if get_level() >= DEBUG_VERBOSE:
157+
# Export data
158+
print('Exporting initial data:')
159+
timer.start()
160+
export_data(solution)
161+
timer.stop()
162+
156163
# Define the target field
157164
print('Define the target field:')
158165
timer.start()

pytest.ini

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[pytest]
2-
pythonpath = .
2+
pythonpath = .
3+
python_files = test_*.py regression_*.py

scratchpad/issue70.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# System imports
2+
import sys
3+
4+
# Logging
5+
import logging
6+
7+
# Debugging imports
8+
# Add the sub_functions directory to the Python module search path
9+
from pathlib import Path
10+
sub_functions_path = Path(__file__).resolve().parent / '..'
11+
sys.path.append(str(sub_functions_path))
12+
13+
# Local imports
14+
from pyCoilGen.pyCoilGen_release import pyCoilGen
15+
from pyCoilGen.sub_functions.constants import DEBUG_BASIC, DEBUG_VERBOSE
16+
17+
if __name__ == '__main__':
18+
# Set up logging
19+
log = logging.getLogger(__name__)
20+
logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
21+
# logging.basicConfig(level=logging.INFO)
22+
23+
arg_dict = {
24+
'field_shape_function': 'x', # definition of the target field
25+
26+
# 'coil_mesh_file': 'bi_planer_rectangles_width_1000mm_distance_500mm.stl',
27+
'coil_mesh': 'create bi-planar mesh',
28+
'biplanar_mesh_parameter_list': [1.0, 1.0, # planar_height, planar_width of the planar mesh.
29+
20, 20, # num_lateral_divisions, num_longitudinal_divisions
30+
0.0, 1.0, 0.0, # target_normal_x, target_normal_y, target_normal_z
31+
0, 0, 0, # center_position_x, center_position_y, center_position_z
32+
0.5], # plane_distance (`float`): Distance between the two planes.
33+
34+
'target_mesh_file': 'none',
35+
'secondary_target_mesh_file': 'none',
36+
'secondary_target_weight': 0.5,
37+
'target_region_radius': 0.1, # in meter
38+
# 'target_region_resolution': 10, # MATLAB 10 is the default
39+
'use_only_target_mesh_verts': False,
40+
'sf_source_file': 'none',
41+
# the number of potential steps that determines the later number of windings (Stream function discretization)
42+
'levels': 14,
43+
# a potential offset value for the minimal and maximal contour potential ; must be between 0 and 1
44+
'pot_offset_factor': 0.25,
45+
'surface_is_cylinder_flag': True,
46+
# the width for the interconnections are interconnected; in meter
47+
'interconnection_cut_width': 0.05,
48+
# the length for which overlapping return paths will be shifted along the surface normals; in meter
49+
'normal_shift_length': 0.01,
50+
'iteration_num_mesh_refinement': 0, # 1, # the number of refinements for the mesh;
51+
'set_roi_into_mesh_center': True,
52+
'force_cut_selection': ['high'],
53+
# Specify one of the three ways the level sets are calculated: "primary","combined", or "independent"
54+
'level_set_method': 'primary',
55+
'skip_postprocessing': False,
56+
'skip_inductance_calculation': False,
57+
'tikhonov_reg_factor': 10, # Tikhonov regularization factor for the SF optimization
58+
59+
'output_directory': 'images/issue70', # [Current directory]
60+
# 'project_name': 'issue70',
61+
'project_name': 'biplanar_xgradient_Tj',
62+
'persistence_dir': 'debug',
63+
'debug': DEBUG_BASIC,
64+
}
65+
66+
result = pyCoilGen(log, arg_dict)

tests/regression_issue70.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import numpy as np
2+
3+
# Test support
4+
from pytest import approx
5+
6+
# Local import
7+
from pyCoilGen.sub_functions.data_structures import DataStructure
8+
9+
# Function under test
10+
from pyCoilGen.mesh_factory import load_mesh_factory_plugins
11+
12+
13+
def test_issue70():
14+
15+
planar_height = 0.75
16+
planar_width = 0.85
17+
num_lateral_divisions = 20
18+
num_longitudinal_divisions = 25
19+
target_normal_x = 0.0
20+
target_normal_y = 1.0
21+
target_normal_z = 0.0
22+
center_position_x = 0
23+
center_position_y = 0
24+
center_position_z = 0
25+
plane_distance = 0.5
26+
27+
28+
input_args = DataStructure(coil_mesh='create bi-planar mesh',
29+
biplanar_mesh_parameter_list=[planar_height, planar_width,
30+
num_lateral_divisions, num_longitudinal_divisions,
31+
target_normal_x, target_normal_y, target_normal_z,
32+
center_position_x, center_position_y, center_position_z,
33+
plane_distance],
34+
)
35+
36+
print(f"input_args.coil_mesh => {input_args.coil_mesh}")
37+
plugin_name = input_args.coil_mesh.replace(' ', '_').replace('-', '_')
38+
plugins = load_mesh_factory_plugins()
39+
found = False
40+
for plugin in plugins:
41+
mesh_creation_function = getattr(plugin, plugin_name, None)
42+
if mesh_creation_function:
43+
coil_mesh = mesh_creation_function(input_args)
44+
found = True
45+
break
46+
47+
assert found
48+
49+
# Min x is -0.5 width
50+
assert np.min(coil_mesh.v[:, 0]) == approx(-planar_width/2.0)
51+
# Max x is 0.5 width
52+
assert np.max(coil_mesh.v[:, 0]) == approx(planar_width/2.0)
53+
54+
# Min y is -0.5 height
55+
assert np.min(coil_mesh.v[:, 1]) == approx(-plane_distance/2.0)
56+
# Max y is 0.5 height
57+
assert np.max(coil_mesh.v[:, 1]) == approx(plane_distance/2.0)
58+
59+
# Min z is 0
60+
assert np.min(coil_mesh.v[:, 2]) == -planar_height/2.0
61+
# Max z is 0
62+
assert np.max(coil_mesh.v[:, 2]) == planar_height/2.0

0 commit comments

Comments
 (0)