Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions README.md
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure that the rest of the document is still coherent. For instance, the nest paragraph says:

The tested input step files have been generated with FreeCAD. The geometrical entities within the step file must be separated in layers. The operations which are performed of the different layers depend on their name.

Is this still correct?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It must refer to material references in new json file. I have just changed it

Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,26 @@ Install requirements with

## Usage

Step2gmsh requires two diferent files:
- A json file where material properties are described for each geometry
- A step file with all the geometry info

Both files must have the same label and share folder path.
An example of those files can be found in [Five wires case](testData/five_wires/)

Launch from command line as

```shell
python src/step2gmsh.py <-i path_to_step_file>
```

The tested input step files have been generated with [FreeCAD](https://www.freecad.org/). The geometrical entities within the step file must be separated in layers. The operations which are performed of the different layers depend on their name.
The tested input step files have been generated with [FreeCAD](https://www.freecad.org/). The geometrical entities within the step file must be separated in layers. The operations performed on the different layers depend on their material asignment registered in the json file.

- A layer named `Conductor_N` with `N` being an integer represents a perfect conductor. `Conductor_0` is a special case of which represents the ground and defines the global domain. For layers named `Conductor_N` with `N` different to zero their areas will be substracted from the computational domain and removed.
- Layers named as `Dielectric_N` are used to identify regions which will have a material assigned.
- A layer with a `PEC material`, represent a perfect conductor. In case one of the layers surrounds the rest of elements, it will be asigned as ground and defines the global domain for the rest of conductors. Internally, this will be represented as Conductor_0. The areas of the rest of conductors different to zero will be substracted from the computational domain and removed. In open cases, Conductor_0 is just another conductor and the domain is defined using the bounding box of the layers.
- Layers registered as `Dielectric` are used to identify regions which will have a material assigned.
- Open and semi-open problems can be defined using a single layer called `OpenBoundary`.

Below is shown an example of a closed case with 6 conductors and 5 dielectrics, the external boundary corresponds to `Conductor_0`. The case is modeled with FreeCAD and can be found in the `testData/five_wires` folder together with the exported as a step file. The resulting mesh after applying `step2gmsh` is shown below.
Below is shown an example of a closed case with 6 conductors and 5 dielectrics, the external boundary corresponds to `Conductor_0`. The case is modeled with FreeCAD and can be found in the [testData/five_wires](testData/five_wires/) folder together with the exported as a step file. The resulting mesh after applying `step2gmsh` is shown below.

![Five wires example as modeled with FreeCAD](doc/fig/five_wires_freecad.png)
![Five wires example meshed with gmsh](doc/fig/five_wires_gmsh.png)
Expand Down
23 changes: 22 additions & 1 deletion test/test_mesher.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,34 @@ def test_lansink2024_single_wire_multipolar(self):
'OpenBoundary_0',
'Vacuum_0', 'Vacuum_1']
expectedEntities = [1, 1, 1,
1,
1, 1]
self.assertEqual(sorted(pGNames), sorted(expectedNames))

for idx, name in enumerate(expectedNames):
self.assertEqual(self.countEntitiesInPhysicalGroupWithName(name), expectedEntities[idx], name)

def test_unshielded_nesting(self):
caseName = 'UnshieldedNested'
Mesher().meshFromStep(self.inputFileFromCaseName(caseName), caseName)

#gmsh.write(caseName + '.msh')
#gmsh.write(caseName + '.vtk')

pGs = gmsh.model.getPhysicalGroups()
pGNames = [gmsh.model.getPhysicalName(*pG) for pG in pGs]
expectedNames = ['Conductor_0',
'Conductor_1',
'Conductor_2',
'OpenBoundary_0',
'Vacuum_0', 'Vacuum_1']
expectedEntities = [2, 1, 1,
1,
2, 1]
self.assertEqual(sorted(pGNames), sorted(expectedNames))

for idx, name in enumerate(expectedNames):
self.assertEqual(self.countEntitiesInPhysicalGroupWithName(name), expectedEntities[idx], name)


if __name__ == '__main__':
unittest.main()
Binary file added testData/UnshieldedNested/UnshieldedNested.FCStd
Binary file not shown.
22 changes: 22 additions & 0 deletions testData/UnshieldedNested/UnshieldedNested.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"CrossSection":[
{
"name":"Conductor_2",
"material":{
"type":"PEC"
}
},
{
"name":"Conductor_1",
"material":{
"type":"PEC"
}
},
{
"name":"ExtraConductor",
"material":{
"type":"PEC"
}
}
]
}
230 changes: 230 additions & 0 deletions testData/UnshieldedNested/UnshieldedNested.step
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('FreeCAD Model'),'2;1');
FILE_NAME('Open CASCADE Shape Model','2025-10-14T12:52:45',(''),(''),
'Open CASCADE STEP processor 7.8','FreeCAD','Unknown');
FILE_SCHEMA(('AUTOMOTIVE_DESIGN { 1 0 10303 214 1 1 1 1 }'));
ENDSEC;
DATA;
#1 = APPLICATION_PROTOCOL_DEFINITION('international standard',
'automotive_design',2000,#2);
#2 = APPLICATION_CONTEXT(
'core data for automotive mechanical design processes');
#3 = SHAPE_DEFINITION_REPRESENTATION(#4,#10);
#4 = PRODUCT_DEFINITION_SHAPE('','',#5);
#5 = PRODUCT_DEFINITION('design','',#6,#9);
#6 = PRODUCT_DEFINITION_FORMATION('','',#7);
#7 = PRODUCT('nested_coax','nested_coax','',(#8));
#8 = PRODUCT_CONTEXT('',#2,'mechanical');
#9 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#10 = SHAPE_REPRESENTATION('',(#11,#15,#19,#23),#27);
#11 = AXIS2_PLACEMENT_3D('',#12,#13,#14);
#12 = CARTESIAN_POINT('',(0.,0.,0.));
#13 = DIRECTION('',(0.,0.,1.));
#14 = DIRECTION('',(1.,0.,-0.));
#15 = AXIS2_PLACEMENT_3D('',#16,#17,#18);
#16 = CARTESIAN_POINT('',(0.,0.,0.));
#17 = DIRECTION('',(0.,0.,1.));
#18 = DIRECTION('',(1.,0.,0.));
#19 = AXIS2_PLACEMENT_3D('',#20,#21,#22);
#20 = CARTESIAN_POINT('',(0.,0.,0.));
#21 = DIRECTION('',(0.,0.,1.));
#22 = DIRECTION('',(1.,0.,0.));
#23 = AXIS2_PLACEMENT_3D('',#24,#25,#26);
#24 = CARTESIAN_POINT('',(5.,0.,0.));
#25 = DIRECTION('',(0.,0.,1.));
#26 = DIRECTION('',(1.,0.,0.));
#27 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#31)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#28,#29,#30)) REPRESENTATION_CONTEXT('Context #1',
'3D Context with UNIT and UNCERTAINTY') );
#28 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#29 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#30 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#31 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#28,
'distance_accuracy_value','confusion accuracy');
#32 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#7));
#33 = SHAPE_DEFINITION_REPRESENTATION(#34,#40);
#34 = PRODUCT_DEFINITION_SHAPE('','',#35);
#35 = PRODUCT_DEFINITION('design','',#36,#39);
#36 = PRODUCT_DEFINITION_FORMATION('','',#37);
#37 = PRODUCT('Conductor_1','Conductor_1','',(#38));
#38 = PRODUCT_CONTEXT('',#2,'mechanical');
#39 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#40 = MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#11,#41),#71);
#41 = SHELL_BASED_SURFACE_MODEL('',(#42));
#42 = OPEN_SHELL('',(#43));
#43 = ADVANCED_FACE('',(#44,#55),#66,.T.);
#44 = FACE_BOUND('',#45,.T.);
#45 = EDGE_LOOP('',(#46));
#46 = ORIENTED_EDGE('',*,*,#47,.T.);
#47 = EDGE_CURVE('',#48,#48,#50,.T.);
#48 = VERTEX_POINT('',#49);
#49 = CARTESIAN_POINT('',(2.8,0.,0.));
#50 = CIRCLE('',#51,2.8);
#51 = AXIS2_PLACEMENT_3D('',#52,#53,#54);
#52 = CARTESIAN_POINT('',(0.,0.,0.));
#53 = DIRECTION('',(0.,0.,1.));
#54 = DIRECTION('',(1.,0.,0.));
#55 = FACE_BOUND('',#56,.T.);
#56 = EDGE_LOOP('',(#57));
#57 = ORIENTED_EDGE('',*,*,#58,.F.);
#58 = EDGE_CURVE('',#59,#59,#61,.T.);
#59 = VERTEX_POINT('',#60);
#60 = CARTESIAN_POINT('',(2.4,0.,0.));
#61 = CIRCLE('',#62,2.4);
#62 = AXIS2_PLACEMENT_3D('',#63,#64,#65);
#63 = CARTESIAN_POINT('',(0.,0.,0.));
#64 = DIRECTION('',(0.,0.,1.));
#65 = DIRECTION('',(1.,0.,0.));
#66 = PLANE('',#67);
#67 = AXIS2_PLACEMENT_3D('',#68,#69,#70);
#68 = CARTESIAN_POINT('',(-2.441857379535E-16,1.29885370033E-16,0.));
#69 = DIRECTION('',(0.,0.,1.));
#70 = DIRECTION('',(1.,0.,0.));
#71 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#75)) GLOBAL_UNIT_ASSIGNED_CONTEXT(
(#72,#73,#74)) REPRESENTATION_CONTEXT('Context #1',
'3D Context with UNIT and UNCERTAINTY') );
#72 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#73 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#74 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#75 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#72,
'distance_accuracy_value','confusion accuracy');
#76 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#77,#79);
#77 = ( REPRESENTATION_RELATIONSHIP('','',#40,#10)
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#78)
SHAPE_REPRESENTATION_RELATIONSHIP() );
#78 = ITEM_DEFINED_TRANSFORMATION('','',#11,#15);
#79 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#80);
#80 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('1','Conductor_1','',#5,#35,$);
#81 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#37));
#82 = SHAPE_DEFINITION_REPRESENTATION(#83,#89);
#83 = PRODUCT_DEFINITION_SHAPE('','',#84);
#84 = PRODUCT_DEFINITION('design','',#85,#88);
#85 = PRODUCT_DEFINITION_FORMATION('','',#86);
#86 = PRODUCT('Conductor_2','Conductor_2','',(#87));
#87 = PRODUCT_CONTEXT('',#2,'mechanical');
#88 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#89 = MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#11,#90),#109);
#90 = SHELL_BASED_SURFACE_MODEL('',(#91));
#91 = OPEN_SHELL('',(#92));
#92 = ADVANCED_FACE('',(#93),#104,.T.);
#93 = FACE_BOUND('',#94,.T.);
#94 = EDGE_LOOP('',(#95));
#95 = ORIENTED_EDGE('',*,*,#96,.T.);
#96 = EDGE_CURVE('',#97,#97,#99,.T.);
#97 = VERTEX_POINT('',#98);
#98 = CARTESIAN_POINT('',(1.,0.,0.));
#99 = CIRCLE('',#100,1.);
#100 = AXIS2_PLACEMENT_3D('',#101,#102,#103);
#101 = CARTESIAN_POINT('',(0.,0.,0.));
#102 = DIRECTION('',(0.,0.,1.));
#103 = DIRECTION('',(1.,0.,-0.));
#104 = PLANE('',#105);
#105 = AXIS2_PLACEMENT_3D('',#106,#107,#108);
#106 = CARTESIAN_POINT('',(-6.409875621279E-17,1.910944170279E-18,0.));
#107 = DIRECTION('',(0.,0.,1.));
#108 = DIRECTION('',(1.,0.,-0.));
#109 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#113)) GLOBAL_UNIT_ASSIGNED_CONTEXT
((#110,#111,#112)) REPRESENTATION_CONTEXT('Context #1',
'3D Context with UNIT and UNCERTAINTY') );
#110 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#111 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#112 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#113 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#110,
'distance_accuracy_value','confusion accuracy');
#114 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#115,#117);
#115 = ( REPRESENTATION_RELATIONSHIP('','',#89,#10)
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#116)
SHAPE_REPRESENTATION_RELATIONSHIP() );
#116 = ITEM_DEFINED_TRANSFORMATION('','',#11,#19);
#117 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#118
);
#118 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('2','Conductor_2','',#5,#84,$);
#119 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#86));
#120 = SHAPE_DEFINITION_REPRESENTATION(#121,#127);
#121 = PRODUCT_DEFINITION_SHAPE('','',#122);
#122 = PRODUCT_DEFINITION('design','',#123,#126);
#123 = PRODUCT_DEFINITION_FORMATION('','',#124);
#124 = PRODUCT('ExtraConductor','ExtraConductor','',(#125));
#125 = PRODUCT_CONTEXT('',#2,'mechanical');
#126 = PRODUCT_DEFINITION_CONTEXT('part definition',#2,'design');
#127 = MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#11,#128),#147);
#128 = SHELL_BASED_SURFACE_MODEL('',(#129));
#129 = OPEN_SHELL('',(#130));
#130 = ADVANCED_FACE('',(#131),#142,.T.);
#131 = FACE_BOUND('',#132,.T.);
#132 = EDGE_LOOP('',(#133));
#133 = ORIENTED_EDGE('',*,*,#134,.T.);
#134 = EDGE_CURVE('',#135,#135,#137,.T.);
#135 = VERTEX_POINT('',#136);
#136 = CARTESIAN_POINT('',(1.,0.,0.));
#137 = CIRCLE('',#138,1.);
#138 = AXIS2_PLACEMENT_3D('',#139,#140,#141);
#139 = CARTESIAN_POINT('',(0.,0.,0.));
#140 = DIRECTION('',(0.,0.,1.));
#141 = DIRECTION('',(1.,0.,0.));
#142 = PLANE('',#143);
#143 = AXIS2_PLACEMENT_3D('',#144,#145,#146);
#144 = CARTESIAN_POINT('',(-6.409875621279E-17,1.910944170279E-18,0.));
#145 = DIRECTION('',(0.,0.,1.));
#146 = DIRECTION('',(1.,0.,0.));
#147 = ( GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#151)) GLOBAL_UNIT_ASSIGNED_CONTEXT
((#148,#149,#150)) REPRESENTATION_CONTEXT('Context #1',
'3D Context with UNIT and UNCERTAINTY') );
#148 = ( LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.) );
#149 = ( NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.) );
#150 = ( NAMED_UNIT(*) SI_UNIT($,.STERADIAN.) SOLID_ANGLE_UNIT() );
#151 = UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-07),#148,
'distance_accuracy_value','confusion accuracy');
#152 = CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#153,#155);
#153 = ( REPRESENTATION_RELATIONSHIP('','',#127,#10)
REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#154)
SHAPE_REPRESENTATION_RELATIONSHIP() );
#154 = ITEM_DEFINED_TRANSFORMATION('','',#11,#23);
#155 = PRODUCT_DEFINITION_SHAPE('Placement','Placement of an item',#156
);
#156 = NEXT_ASSEMBLY_USAGE_OCCURRENCE('3','ExtraConductor','',#5,#122,$
);
#157 = PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#124));
#158 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#159)
,#109);
#159 = STYLED_ITEM('color',(#160),#92);
#160 = PRESENTATION_STYLE_ASSIGNMENT((#161,#167));
#161 = SURFACE_STYLE_USAGE(.BOTH.,#162);
#162 = SURFACE_SIDE_STYLE('',(#163));
#163 = SURFACE_STYLE_FILL_AREA(#164);
#164 = FILL_AREA_STYLE('',(#165));
#165 = FILL_AREA_STYLE_COLOUR('',#166);
#166 = COLOUR_RGB('',0.800000010877,0.800000010877,0.800000010877);
#167 = CURVE_STYLE('',#168,POSITIVE_LENGTH_MEASURE(0.1),#169);
#168 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
#169 = COLOUR_RGB('',9.803921802644E-02,9.803921802644E-02,
9.803921802644E-02);
#170 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#171)
,#147);
#171 = STYLED_ITEM('color',(#172),#130);
#172 = PRESENTATION_STYLE_ASSIGNMENT((#173,#178));
#173 = SURFACE_STYLE_USAGE(.BOTH.,#174);
#174 = SURFACE_SIDE_STYLE('',(#175));
#175 = SURFACE_STYLE_FILL_AREA(#176);
#176 = FILL_AREA_STYLE('',(#177));
#177 = FILL_AREA_STYLE_COLOUR('',#166);
#178 = CURVE_STYLE('',#179,POSITIVE_LENGTH_MEASURE(0.1),#169);
#179 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
#180 = MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#181)
,#71);
#181 = STYLED_ITEM('color',(#182),#43);
#182 = PRESENTATION_STYLE_ASSIGNMENT((#183,#188));
#183 = SURFACE_STYLE_USAGE(.BOTH.,#184);
#184 = SURFACE_SIDE_STYLE('',(#185));
#185 = SURFACE_STYLE_FILL_AREA(#186);
#186 = FILL_AREA_STYLE('',(#187));
#187 = FILL_AREA_STYLE_COLOUR('',#166);
#188 = CURVE_STYLE('',#189,POSITIVE_LENGTH_MEASURE(0.1),#169);
#189 = DRAUGHTING_PRE_DEFINED_CURVE_FONT('continuous');
ENDSEC;
END-ISO-10303-21;