fiqus 2024.7.0__py3-none-any.whl → 2024.12.1__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.
Files changed (69) hide show
  1. fiqus/MainFiQuS.py +290 -134
  2. fiqus/data/DataConductor.py +301 -301
  3. fiqus/data/DataFiQuS.py +128 -84
  4. fiqus/data/DataFiQuSCCT.py +150 -150
  5. fiqus/data/DataFiQuSConductor.py +84 -84
  6. fiqus/data/DataFiQuSConductorAC_Strand.py +565 -565
  7. fiqus/data/DataFiQuSMultipole.py +716 -42
  8. fiqus/data/DataFiQuSPancake3D.py +737 -278
  9. fiqus/data/DataMultipole.py +180 -15
  10. fiqus/data/DataRoxieParser.py +90 -51
  11. fiqus/data/DataSettings.py +121 -0
  12. fiqus/data/DataWindingsCCT.py +37 -37
  13. fiqus/data/RegionsModelFiQuS.py +18 -6
  14. fiqus/geom_generators/GeometryCCT.py +905 -905
  15. fiqus/geom_generators/GeometryConductorAC_Strand.py +1391 -1391
  16. fiqus/geom_generators/GeometryMultipole.py +1827 -227
  17. fiqus/geom_generators/GeometryPancake3D.py +316 -117
  18. fiqus/geom_generators/GeometryPancake3DUtils.py +549 -0
  19. fiqus/getdp_runners/RunGetdpCCT.py +4 -4
  20. fiqus/getdp_runners/RunGetdpConductorAC_Strand.py +201 -201
  21. fiqus/getdp_runners/RunGetdpMultipole.py +115 -42
  22. fiqus/getdp_runners/RunGetdpPancake3D.py +28 -6
  23. fiqus/mains/MainCCT.py +2 -2
  24. fiqus/mains/MainConductorAC_Strand.py +132 -132
  25. fiqus/mains/MainMultipole.py +113 -62
  26. fiqus/mains/MainPancake3D.py +63 -23
  27. fiqus/mesh_generators/MeshCCT.py +209 -209
  28. fiqus/mesh_generators/MeshConductorAC_Strand.py +656 -656
  29. fiqus/mesh_generators/MeshMultipole.py +1243 -181
  30. fiqus/mesh_generators/MeshPancake3D.py +275 -192
  31. fiqus/parsers/ParserCOND.py +825 -0
  32. fiqus/parsers/ParserDAT.py +16 -16
  33. fiqus/parsers/ParserGetDPOnSection.py +212 -212
  34. fiqus/parsers/ParserGetDPTimeTable.py +134 -134
  35. fiqus/parsers/ParserMSH.py +53 -53
  36. fiqus/parsers/ParserPOS.py +214 -214
  37. fiqus/parsers/ParserRES.py +142 -142
  38. fiqus/plotters/PlotPythonCCT.py +133 -133
  39. fiqus/plotters/PlotPythonConductorAC.py +855 -855
  40. fiqus/plotters/PlotPythonMultipole.py +18 -18
  41. fiqus/post_processors/PostProcessCCT.py +440 -440
  42. fiqus/post_processors/PostProcessConductorAC.py +49 -49
  43. fiqus/post_processors/PostProcessMultipole.py +353 -229
  44. fiqus/post_processors/PostProcessPancake3D.py +8 -13
  45. fiqus/pre_processors/PreProcessCCT.py +175 -175
  46. fiqus/pro_assemblers/ProAssembler.py +14 -6
  47. fiqus/pro_material_functions/ironBHcurves.pro +246 -246
  48. fiqus/pro_templates/combined/CCT_template.pro +274 -274
  49. fiqus/pro_templates/combined/ConductorAC_template.pro +1025 -1025
  50. fiqus/pro_templates/combined/Multipole_template.pro +1694 -126
  51. fiqus/pro_templates/combined/Pancake3D_template.pro +2294 -1103
  52. fiqus/pro_templates/combined/TSA_materials.pro +162 -0
  53. fiqus/pro_templates/combined/materials.pro +36 -18
  54. fiqus/utils/Utils.py +508 -110
  55. fiqus/utils/update_data_settings.py +33 -0
  56. fiqus-2024.12.1.dist-info/METADATA +132 -0
  57. fiqus-2024.12.1.dist-info/RECORD +84 -0
  58. {fiqus-2024.7.0.dist-info → fiqus-2024.12.1.dist-info}/WHEEL +1 -1
  59. tests/test_FiQuS.py +1 -1
  60. tests/test_geometry_generators.py +101 -2
  61. tests/test_mesh_generators.py +154 -1
  62. tests/test_solvers.py +115 -21
  63. tests/utils/fiqus_test_classes.py +85 -21
  64. tests/utils/generate_reference_files_ConductorAC.py +57 -57
  65. tests/utils/generate_reference_files_Pancake3D.py +4 -5
  66. tests/utils/helpers.py +97 -97
  67. fiqus-2024.7.0.dist-info/METADATA +0 -103
  68. fiqus-2024.7.0.dist-info/RECORD +0 -79
  69. {fiqus-2024.7.0.dist-info → fiqus-2024.12.1.dist-info}/top_level.txt +0 -0
@@ -107,7 +107,7 @@ class regions:
107
107
  # Initialize the regions model:
108
108
  self.rm = RegionsModelFiQuS.RegionsModel()
109
109
 
110
- # This is used because self.rm.powered is not initialized in
110
+ # This is used because self.rm.powered["Pancake3D"] is not initialized in
111
111
  # RegionsModelFiQuS.RegionsModel. It should be fixed in the future.
112
112
  self.rm.powered["Pancake3D"] = RegionsModelFiQuS.Powered()
113
113
 
@@ -254,12 +254,12 @@ class curve:
254
254
  boundingbox = list(map(operator.add, boundingbox1, boundingbox2))
255
255
  self.points.append(list(map(operator.truediv, boundingbox, (2, 2, 2))))
256
256
 
257
- # Round the point positions to the nearest multiple of self.geo.dimTol to avoid
257
+ # Round the point positions to the nearest multiple of self.geo.dimensionTolerance to avoid
258
258
  # numerical errors:
259
259
  for i in range(len(self.points)):
260
260
  for coord in range(3):
261
261
  self.points[i][coord] = (
262
- round(self.points[i][coord] / self.geo.dimTol) * self.geo.dimTol
262
+ round(self.points[i][coord] / self.geo.dimensionTolerance) * self.geo.dimensionTolerance
263
263
  )
264
264
 
265
265
  if self.isCircle():
@@ -297,11 +297,11 @@ class curve:
297
297
  # Calculate starting turn number (n1, float) and ending turn number (n2,
298
298
  # float): (note that they are float modulos of 1, and not the exact turn
299
299
  # numbers)
300
- self.n1 = (theta1 - self.geo.wi.theta_i) / 2 / math.pi
301
- self.n1 = round(self.n1 / self.geo.wi.turnTol) * self.geo.wi.turnTol
300
+ self.n1 = (theta1 - self.geo.winding.theta_i) / 2 / math.pi
301
+ self.n1 = round(self.n1 / self.geo.winding.turnTol) * self.geo.winding.turnTol
302
302
 
303
- self.n2 = (theta2 - self.geo.wi.theta_i) / 2 / math.pi
304
- self.n2 = round(self.n2 / self.geo.wi.turnTol) * self.geo.wi.turnTol
303
+ self.n2 = (theta2 - self.geo.winding.theta_i) / 2 / math.pi
304
+ self.n2 = round(self.n2 / self.geo.winding.turnTol) * self.geo.winding.turnTol
305
305
 
306
306
  def isAxial(self):
307
307
  """
@@ -312,7 +312,7 @@ class curve:
312
312
  :rtype: bool
313
313
  """
314
314
  return not math.isclose(
315
- self.points[0][2], self.points[1][2], abs_tol=self.geo.dimTol
315
+ self.points[0][2], self.points[1][2], abs_tol=self.geo.dimensionTolerance
316
316
  )
317
317
 
318
318
  def isHorizontal(self):
@@ -329,8 +329,8 @@ class curve:
329
329
  xcm = (self.points[0][0] + self.points[1][0]) / 2
330
330
  ycm = (self.points[0][1] + self.points[1][1]) / 2
331
331
 
332
- return math.isclose(cm[0], xcm, abs_tol=self.geo.dimTol) and math.isclose(
333
- cm[1], ycm, abs_tol=self.geo.dimTol
332
+ return math.isclose(cm[0], xcm, abs_tol=self.geo.dimensionTolerance) and math.isclose(
333
+ cm[1], ycm, abs_tol=self.geo.dimensionTolerance
334
334
  )
335
335
 
336
336
  def isCircle(self):
@@ -461,7 +461,7 @@ class Mesh(Base):
461
461
 
462
462
  # Start GMSH:
463
463
  self.gu = GmshUtils(self.mesh_folder)
464
- self.gu.initialize()
464
+ self.gu.initialize(verbosity_Gmsh=fdm.run.verbosity_Gmsh)
465
465
 
466
466
  self.contactLayerAndWindingRadialLines = [] # Store for strucured terminals
467
467
 
@@ -480,12 +480,12 @@ class Mesh(Base):
480
480
  # =============================================================================
481
481
  allWindingAndCLSurfaceTags = []
482
482
  allWindingAndCLLineTags = []
483
- for i in range(self.geo.N):
483
+ for i in range(self.geo.numberOfPancakes):
484
484
  # Get the volume tags:
485
- windingVolumeDimTags = self.dimTags[self.geo.wi.name + str(i + 1)]
485
+ windingVolumeDimTags = self.dimTags[self.geo.winding.name + str(i + 1)]
486
486
  windingVolumeTags = [dimTag[1] for dimTag in windingVolumeDimTags]
487
487
 
488
- contactLayerVolumeDimTags = self.dimTags[self.geo.ii.name + str(i + 1)]
488
+ contactLayerVolumeDimTags = self.dimTags[self.geo.contactLayer.name + str(i + 1)]
489
489
  contactLayerVolumeTags = [dimTag[1] for dimTag in contactLayerVolumeDimTags]
490
490
 
491
491
  # Get the surface and line tags:
@@ -523,7 +523,7 @@ class Mesh(Base):
523
523
  if lineTag not in allWindingAndCLLineTags:
524
524
  gmsh.model.mesh.setTransfiniteCurve(lineTag, 1)
525
525
 
526
- recombine = self.mesh.wi.elementType[0] in ["hexahedron", "prism"]
526
+ recombine = self.mesh.winding.elementType[0] in ["hexahedron", "prism"]
527
527
  for surfaceTag in notchSurfaceTags:
528
528
  if surfaceTag not in allWindingAndCLSurfaceTags:
529
529
  gmsh.model.mesh.setTransfiniteSurface(surfaceTag)
@@ -548,32 +548,32 @@ class Mesh(Base):
548
548
  # Winding and contact layer extrusions of the air:
549
549
  # Get the volume tags:
550
550
  airTopWindingExtrusionVolumeDimTags = self.dimTags[
551
- self.geo.ai.name + "-TopPancakeWindingExtursion"
551
+ self.geo.air.name + "-TopPancakeWindingExtursion"
552
552
  ]
553
553
 
554
554
  airTopContactLayerExtrusionVolumeDimTags = self.dimTags[
555
- self.geo.ai.name + "-TopPancakeContactLayerExtursion"
555
+ self.geo.air.name + "-TopPancakeContactLayerExtursion"
556
556
  ]
557
557
 
558
558
  airTopTerminalsExtrusionVolumeDimTags = self.dimTags[
559
- self.geo.ai.name + "-TopTerminalsExtrusion"
559
+ self.geo.air.name + "-TopTerminalsExtrusion"
560
560
  ]
561
561
 
562
562
  airBottomWindingExtrusionVolumeDimTags = self.dimTags[
563
- self.geo.ai.name + "-BottomPancakeWindingExtursion"
563
+ self.geo.air.name + "-BottomPancakeWindingExtursion"
564
564
  ]
565
565
 
566
566
  airBottomContactLayerExtrusionVolumeDimTags = self.dimTags[
567
- self.geo.ai.name + "-BottomPancakeContactLayerExtursion"
567
+ self.geo.air.name + "-BottomPancakeContactLayerExtursion"
568
568
  ]
569
569
 
570
570
  airBottomTerminalsExtrusionVolumeDimTags = self.dimTags[
571
- self.geo.ai.name + "-BottomTerminalsExtrusion"
571
+ self.geo.air.name + "-BottomTerminalsExtrusion"
572
572
  ]
573
573
 
574
574
  removedAirVolumeDimTags = []
575
575
  newAirVolumeDimTags = []
576
- if self.mesh.ai.structured:
576
+ if self.mesh.air.structured:
577
577
  # Then it means air type is cuboid!
578
578
  airTopWindingExtrusionVolumeTags = [
579
579
  dimTag[1] for dimTag in airTopWindingExtrusionVolumeDimTags
@@ -589,9 +589,9 @@ class Mesh(Base):
589
589
  ]
590
590
 
591
591
  # Calcualte axial number of elements for air:
592
- axialElementsPerLengthForWinding = min(self.mesh.wi.axne) / self.geo.wi.h
592
+ axialElementsPerLengthForWinding = min(self.mesh.winding.axialNumberOfElements) / self.geo.winding.height
593
593
  axneForAir = round(
594
- axialElementsPerLengthForWinding * self.geo.ai.margin + 1e-6
594
+ axialElementsPerLengthForWinding * self.geo.air.axialMargin + 1e-6
595
595
  )
596
596
 
597
597
  # Get the surface and line tags:
@@ -615,7 +615,7 @@ class Mesh(Base):
615
615
  airTopContactLayerExtrusionVolumeTags,
616
616
  airTopContactLayerExtrusionSurfaceTags,
617
617
  airTopContactLayerExtrusionLineTags,
618
- meshSettingIndex=self.geo.N - 1, # The last pancake coil
618
+ meshSettingIndex=self.geo.numberOfPancakes - 1, # The last pancake coil
619
619
  axialNumberOfElements=axneForAir,
620
620
  bumpCoefficient=1,
621
621
  )
@@ -647,18 +647,18 @@ class Mesh(Base):
647
647
  )
648
648
 
649
649
  # Structure tubes of the air:
650
- airOuterTubeVolumeDimTags = self.dimTags[self.geo.ai.name + "-OuterTube"]
650
+ airOuterTubeVolumeDimTags = self.dimTags[self.geo.air.name + "-OuterTube"]
651
651
  airOuterTubeVolumeTags = [dimTag[1] for dimTag in airOuterTubeVolumeDimTags]
652
652
 
653
653
  airTopTubeTerminalsVolumeDimTags = self.dimTags[
654
- self.geo.ai.name + "-TopTubeTerminalsExtrusion"
654
+ self.geo.air.name + "-TopTubeTerminalsExtrusion"
655
655
  ]
656
656
  airTopTubeTerminalsVolumeTags = [
657
657
  dimTag[1] for dimTag in airTopTubeTerminalsVolumeDimTags
658
658
  ]
659
659
 
660
660
  airBottomTubeTerminalsVolumeDimTags = self.dimTags[
661
- self.geo.ai.name + "-BottomTubeTerminalsExtrusion"
661
+ self.geo.air.name + "-BottomTubeTerminalsExtrusion"
662
662
  ]
663
663
  airBottomTubeTerminalsVolumeTags = [
664
664
  dimTag[1] for dimTag in airBottomTubeTerminalsVolumeDimTags
@@ -666,7 +666,7 @@ class Mesh(Base):
666
666
 
667
667
  # Structure inner cylinder of the air:
668
668
  airInnerCylinderVolumeDimTags = self.dimTags[
669
- self.geo.ai.name + "-InnerCylinder"
669
+ self.geo.air.name + "-InnerCylinder"
670
670
  ]
671
671
  airInnerCylinderVolumeTags = [
672
672
  dimTag[1] for dimTag in airInnerCylinderVolumeDimTags
@@ -674,19 +674,19 @@ class Mesh(Base):
674
674
 
675
675
  airTubesAndCylinders = airOuterTubeVolumeTags + airInnerCylinderVolumeTags
676
676
 
677
- if self.geo.ai.shellTransformation:
678
- shellVolumes = self.dimTags[self.geo.ai.shellVolumeName]
677
+ if self.geo.air.shellTransformation:
678
+ shellVolumes = self.dimTags[self.geo.air.shellVolumeName]
679
679
  shellVolumeTags = [dimTag[1] for dimTag in shellVolumes]
680
680
  airTubesAndCylinders.extend(shellVolumeTags)
681
681
 
682
- airRadialElementMultiplier = 1 / self.mesh.ai.radialElementSize
682
+ airRadialElementMultiplier = 1 / self.mesh.air.radialElementSize
683
683
  self.structure_tubes_and_cylinders(
684
684
  airTubesAndCylinders,
685
685
  radialElementMultiplier=airRadialElementMultiplier,
686
686
  )
687
687
 
688
- if self.mesh.ti.structured:
689
- terminalsRadialElementMultiplier = 1 / self.mesh.ti.radialElementSize
688
+ if self.mesh.terminals.structured:
689
+ terminalsRadialElementMultiplier = 1 / self.mesh.terminals.radialElementSize
690
690
 
691
691
  self.structure_tubes_and_cylinders(
692
692
  airTopTubeTerminalsVolumeTags + airBottomTubeTerminalsVolumeTags,
@@ -747,9 +747,9 @@ class Mesh(Base):
747
747
 
748
748
  # Fuse inner cylinder and outer tube part of air:
749
749
  airInnerCylinderVolumeDimTags = self.dimTags[
750
- self.geo.ai.name + "-InnerCylinder"
750
+ self.geo.air.name + "-InnerCylinder"
751
751
  ]
752
- if self.geo.N > 1:
752
+ if self.geo.numberOfPancakes > 1:
753
753
  # Fuse the first two and the last two volumes separately (due to cuts):
754
754
  firstTwoVolumes = airInnerCylinderVolumeDimTags[0:2]
755
755
  lastTwoVolumes = airInnerCylinderVolumeDimTags[-2:]
@@ -771,20 +771,20 @@ class Mesh(Base):
771
771
  removedAirVolumeDimTags.extend(
772
772
  airInnerCylinderVolumeDimTags + firstTwoVolumes + lastTwoVolumes
773
773
  )
774
- self.dimTags[self.geo.ai.name + "-InnerCylinder"] = [
774
+ self.dimTags[self.geo.air.name + "-InnerCylinder"] = [
775
775
  airInnerCylinderVolumeDimTag,
776
776
  airInnerCylinderVolumeDimTagFirst,
777
777
  airInnerCylinderVolumeDimTagLast,
778
778
  ]
779
779
  else:
780
780
  pass
781
- # self.dimTags[self.geo.ai.name + "-InnerCylinder"] = [
782
- # self.dimTags[self.geo.ai.name + "-InnerCylinder"][1],
783
- # self.dimTags[self.geo.ai.name + "-InnerCylinder"][0],
784
- # self.dimTags[self.geo.ai.name + "-InnerCylinder"][2],
781
+ # self.dimTags[self.geo.air.name + "-InnerCylinder"] = [
782
+ # self.dimTags[self.geo.air.name + "-InnerCylinder"][1],
783
+ # self.dimTags[self.geo.air.name + "-InnerCylinder"][0],
784
+ # self.dimTags[self.geo.air.name + "-InnerCylinder"][2],
785
785
  # ]
786
786
 
787
- airOuterTubeVolumeDimTags = self.dimTags[self.geo.ai.name + "-OuterTube"]
787
+ airOuterTubeVolumeDimTags = self.dimTags[self.geo.air.name + "-OuterTube"]
788
788
  airOuterTubeVolumeDimTag = Mesh.fuse_volumes(
789
789
  airOuterTubeVolumeDimTags,
790
790
  fuseSurfaces=True,
@@ -792,13 +792,13 @@ class Mesh(Base):
792
792
  )
793
793
  newAirOuterTubeVolumeDimTag = airOuterTubeVolumeDimTag
794
794
  removedAirVolumeDimTags.extend(airOuterTubeVolumeDimTags)
795
- self.dimTags[self.geo.ai.name + "-OuterTube"] = [newAirOuterTubeVolumeDimTag]
795
+ self.dimTags[self.geo.air.name + "-OuterTube"] = [newAirOuterTubeVolumeDimTag]
796
796
 
797
- if self.geo.ai.shellTransformation:
797
+ if self.geo.air.shellTransformation:
798
798
  # Fuse air shell volumes:
799
- if self.geo.ai.type == "cylinder":
799
+ if self.geo.air.type == "cylinder":
800
800
  removedShellVolumeDimTags = []
801
- shellVolumeDimTags = self.dimTags[self.geo.ai.shellVolumeName]
801
+ shellVolumeDimTags = self.dimTags[self.geo.air.shellVolumeName]
802
802
  shellVolumeDimTag = Mesh.fuse_volumes(
803
803
  shellVolumeDimTags,
804
804
  fuseSurfaces=True,
@@ -807,41 +807,41 @@ class Mesh(Base):
807
807
  removedShellVolumeDimTags.extend(shellVolumeDimTags)
808
808
  newShellVolumeDimTags = [shellVolumeDimTag]
809
809
  for removedDimTag in removedShellVolumeDimTags:
810
- self.dimTags[self.geo.ai.shellVolumeName].remove(removedDimTag)
811
- elif self.geo.ai.type == "cuboid":
810
+ self.dimTags[self.geo.air.shellVolumeName].remove(removedDimTag)
811
+ elif self.geo.air.type == "cuboid":
812
812
  # Unfortunately, surfaces cannot be combined for the cuboid type of air.
813
813
  # However, it doesn't affect the mesh quality that much.
814
814
  newShellVolumeDimTags = []
815
815
 
816
816
  shellPart1VolumeDimTag = Mesh.fuse_volumes(
817
- self.dimTags[self.geo.ai.shellVolumeName + "-Part1"],
817
+ self.dimTags[self.geo.air.shellVolumeName + "-Part1"],
818
818
  fuseSurfaces=False,
819
819
  )
820
- self.dimTags[self.geo.ai.shellVolumeName + "-Part1"] = [
820
+ self.dimTags[self.geo.air.shellVolumeName + "-Part1"] = [
821
821
  shellPart1VolumeDimTag
822
822
  ]
823
823
 
824
824
  shellPart2VolumeDimTag = Mesh.fuse_volumes(
825
- self.dimTags[self.geo.ai.shellVolumeName + "-Part2"],
825
+ self.dimTags[self.geo.air.shellVolumeName + "-Part2"],
826
826
  fuseSurfaces=False,
827
827
  )
828
- self.dimTags[self.geo.ai.shellVolumeName + "-Part2"] = [
828
+ self.dimTags[self.geo.air.shellVolumeName + "-Part2"] = [
829
829
  shellPart2VolumeDimTag
830
830
  ]
831
831
 
832
832
  shellPart3VolumeDimTag = Mesh.fuse_volumes(
833
- self.dimTags[self.geo.ai.shellVolumeName + "-Part3"],
833
+ self.dimTags[self.geo.air.shellVolumeName + "-Part3"],
834
834
  fuseSurfaces=False,
835
835
  )
836
- self.dimTags[self.geo.ai.shellVolumeName + "-Part3"] = [
836
+ self.dimTags[self.geo.air.shellVolumeName + "-Part3"] = [
837
837
  shellPart3VolumeDimTag
838
838
  ]
839
839
 
840
840
  shellPart4VolumeDimTag = Mesh.fuse_volumes(
841
- self.dimTags[self.geo.ai.shellVolumeName + "-Part4"],
841
+ self.dimTags[self.geo.air.shellVolumeName + "-Part4"],
842
842
  fuseSurfaces=False,
843
843
  )
844
- self.dimTags[self.geo.ai.shellVolumeName + "-Part4"] = [
844
+ self.dimTags[self.geo.air.shellVolumeName + "-Part4"] = [
845
845
  shellPart4VolumeDimTag
846
846
  ]
847
847
 
@@ -849,7 +849,7 @@ class Mesh(Base):
849
849
  # surface and that surface should be combined as well for high quality mesh.
850
850
  # However, it can be only done for cylinder type of air for now.
851
851
  # Get the combined boundary surfaces:
852
- if self.geo.ai.type == "cylinder":
852
+ if self.geo.air.type == "cylinder":
853
853
  (
854
854
  newAirOuterTubeVolumeDimTag,
855
855
  newShellVolumeDimTag,
@@ -859,18 +859,19 @@ class Mesh(Base):
859
859
  fuseOtherSurfaces=False,
860
860
  surfacesArePlane=False,
861
861
  )
862
- self.dimTags[self.geo.ai.name + "-OuterTube"] = [newAirOuterTubeVolumeDimTag]
862
+ self.dimTags[self.geo.air.name + "-OuterTube"] = [newAirOuterTubeVolumeDimTag]
863
+
863
864
  airOuterTubeVolumeDimTag = newAirOuterTubeVolumeDimTag
864
- self.dimTags[self.geo.ai.shellVolumeName].append(
865
+ self.dimTags[self.geo.air.shellVolumeName].append(
865
866
  newShellVolumeDimTag
866
867
  )
867
868
 
868
869
  newAirVolumeDimTags.append(newAirOuterTubeVolumeDimTag)
869
870
 
870
871
  # Update volume tags dictionary of air:
871
- self.dimTags[self.geo.ai.name] = list(
872
+ self.dimTags[self.geo.air.name] = list(
872
873
  (
873
- set(self.dimTags[self.geo.ai.name]) - set(removedAirVolumeDimTags)
874
+ set(self.dimTags[self.geo.air.name]) - set(removedAirVolumeDimTags)
874
875
  ).union(set(newAirVolumeDimTags))
875
876
  )
876
877
 
@@ -881,18 +882,18 @@ class Mesh(Base):
881
882
  # ==============================================================================
882
883
  # MESHING TERMINALS STARTS =====================================================
883
884
  # ==============================================================================
884
- if self.mesh.ti.structured:
885
+ if self.mesh.terminals.structured:
885
886
  # Structure tubes of the terminals:
886
- terminalOuterTubeVolumeDimTags = self.dimTags[self.geo.ti.o.name + "-Tube"]
887
+ terminalOuterTubeVolumeDimTags = self.dimTags[self.geo.terminals.outer.name + "-Tube"]
887
888
  terminalOuterTubeVolumeTags = [
888
889
  dimTag[1] for dimTag in terminalOuterTubeVolumeDimTags
889
890
  ]
890
- terminalInnerTubeVolumeDimTags = self.dimTags[self.geo.ti.i.name + "-Tube"]
891
+ terminalInnerTubeVolumeDimTags = self.dimTags[self.geo.terminals.inner.name + "-Tube"]
891
892
  terminalInnerTubeVolumeTags = [
892
893
  dimTag[1] for dimTag in terminalInnerTubeVolumeDimTags
893
894
  ]
894
895
 
895
- terminalsRadialElementMultiplier = 1 / self.mesh.ti.radialElementSize
896
+ terminalsRadialElementMultiplier = 1 / self.mesh.terminals.radialElementSize
896
897
  self.structure_tubes_and_cylinders(
897
898
  terminalOuterTubeVolumeTags + terminalInnerTubeVolumeTags,
898
899
  radialElementMultiplier=terminalsRadialElementMultiplier,
@@ -900,13 +901,13 @@ class Mesh(Base):
900
901
 
901
902
  # Structure nontube parts of the terminals:
902
903
  terminalOuterNonTubeVolumeDimTags = self.dimTags[
903
- self.geo.ti.o.name + "-Touching"
904
+ self.geo.terminals.outer.name + "-Touching"
904
905
  ]
905
906
  terminalOuterNonTubeVolumeTags = [
906
907
  dimTag[1] for dimTag in terminalOuterNonTubeVolumeDimTags
907
908
  ]
908
909
  terminalInnerNonTubeVolumeDimTags = self.dimTags[
909
- self.geo.ti.i.name + "-Touching"
910
+ self.geo.terminals.inner.name + "-Touching"
910
911
  ]
911
912
  terminalInnerNonTubeVolumeTags = [
912
913
  dimTag[1] for dimTag in terminalInnerNonTubeVolumeDimTags
@@ -928,7 +929,7 @@ class Mesh(Base):
928
929
  # Mesh fields for the air:
929
930
  # Meshes will grow as they get further from the field surfaces:
930
931
  fieldSurfacesDimTags = gmsh.model.getBoundary(
931
- self.dimTags[self.geo.wi.name], oriented=False, combined=True
932
+ self.dimTags[self.geo.winding.name], oriented=False, combined=True
932
933
  )
933
934
  fieldSurfacesTags = [dimTag[1] for dimTag in fieldSurfacesDimTags]
934
935
 
@@ -1032,19 +1033,19 @@ class Mesh(Base):
1032
1033
  # Create cuts:
1033
1034
  # This is required to make the air a simply connected domain. This is required
1034
1035
  # for the solution part. You can read more about Homology in GMSH documentation.
1035
- airTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ai.name]]
1036
+ airTags = [dimTag[1] for dimTag in self.dimTags[self.geo.air.name]]
1036
1037
 
1037
- if self.geo.ai.shellTransformation:
1038
+ if self.geo.air.shellTransformation:
1038
1039
  shellTags = [
1039
- dimTag[1] for dimTag in self.dimTags[self.geo.ai.shellVolumeName]
1040
+ dimTag[1] for dimTag in self.dimTags[self.geo.air.shellVolumeName]
1040
1041
  ]
1041
1042
  airTags.extend(shellTags)
1042
1043
 
1043
1044
  dummyAirRegion = gmsh.model.addPhysicalGroup(dim=3, tags=airTags)
1044
1045
  dummyAirRegionDimTag = (3, dummyAirRegion)
1045
1046
 
1046
- innerCylinderTags = [self.dimTags[self.geo.ai.name + "-InnerCylinder"][0][1]]
1047
- gapTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ai.name + "-Gap"]]
1047
+ innerCylinderTags = [self.dimTags[self.geo.air.name + "-InnerCylinder"][0][1]]
1048
+ gapTags = [dimTag[1] for dimTag in self.dimTags[self.geo.air.name + "-Gap"]]
1048
1049
  # Only remove every second gap:
1049
1050
  gapTags = gapTags[1::2]
1050
1051
 
@@ -1056,15 +1057,15 @@ class Mesh(Base):
1056
1057
  dummyAirRegionWithoutInnerCylinder,
1057
1058
  )
1058
1059
 
1059
- windingTags = [dimTag[1] for dimTag in self.dimTags[self.geo.wi.name]]
1060
+ windingTags = [dimTag[1] for dimTag in self.dimTags[self.geo.winding.name]]
1060
1061
  dummyWindingRegion = gmsh.model.addPhysicalGroup(dim=3, tags=windingTags)
1061
1062
  dummyWindingRegionDimTag = (3, dummyWindingRegion)
1062
1063
 
1063
- if self.geo.ii.tsa:
1064
+ if self.geo.contactLayer.thinShellApproximation:
1064
1065
  # Find all the contact layer surfaces:
1065
1066
  allWindingDimTags = []
1066
- for i in range(self.geo.N):
1067
- windingDimTags = self.dimTags[self.geo.wi.name + str(i + 1)]
1067
+ for i in range(self.geo.numberOfPancakes):
1068
+ windingDimTags = self.dimTags[self.geo.winding.name + str(i + 1)]
1068
1069
  allWindingDimTags.extend(windingDimTags)
1069
1070
 
1070
1071
  windingBoundarySurfaces = gmsh.model.getBoundary(
@@ -1096,7 +1097,7 @@ class Mesh(Base):
1096
1097
 
1097
1098
  # Get rid of surfaces that touch terminals:
1098
1099
  terminalSurfaces = gmsh.model.getBoundary(
1099
- self.dimTags[self.geo.ti.o.name] + self.dimTags[self.geo.ti.i.name],
1100
+ self.dimTags[self.geo.terminals.outer.name] + self.dimTags[self.geo.terminals.inner.name],
1100
1101
  combined=False,
1101
1102
  oriented=False,
1102
1103
  )
@@ -1111,11 +1112,11 @@ class Mesh(Base):
1111
1112
  dummyContactLayerRegionDimTag = (2, dummyContactLayerRegion)
1112
1113
 
1113
1114
  else:
1114
- contactLayerTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ii.name]]
1115
+ contactLayerTags = [dimTag[1] for dimTag in self.dimTags[self.geo.contactLayer.name]]
1115
1116
 
1116
1117
  # get rid of volumes that touch terminals:
1117
1118
  terminalSurfaces = gmsh.model.getBoundary(
1118
- self.dimTags[self.geo.ti.o.name] + self.dimTags[self.geo.ti.i.name],
1119
+ self.dimTags[self.geo.terminals.outer.name] + self.dimTags[self.geo.terminals.inner.name],
1119
1120
  combined=False,
1120
1121
  oriented=False,
1121
1122
  )
@@ -1146,40 +1147,41 @@ class Mesh(Base):
1146
1147
  dims=[1],
1147
1148
  )
1148
1149
 
1149
- # Second cohomology request (insulated cut for insulated coils):
1150
- if self.geo.N > 1:
1151
- gmsh.model.mesh.addHomologyRequest(
1152
- "Cohomology",
1153
- domainTags=[
1154
- dummyAirRegionWithoutInnerCylinder,
1155
- dummyContactLayerRegion,
1156
- ],
1157
- subdomainTags=[],
1158
- dims=[1],
1159
- )
1160
- else:
1150
+ if self.mesh.computeCohomologyForInsulating:
1151
+ # Second cohomology request (insulated cut for insulated coils):
1152
+ if self.geo.numberOfPancakes > 1:
1153
+ gmsh.model.mesh.addHomologyRequest(
1154
+ "Cohomology",
1155
+ domainTags=[
1156
+ dummyAirRegionWithoutInnerCylinder,
1157
+ dummyContactLayerRegion,
1158
+ ],
1159
+ subdomainTags=[],
1160
+ dims=[1],
1161
+ )
1162
+ else:
1163
+ gmsh.model.mesh.addHomologyRequest(
1164
+ "Cohomology",
1165
+ domainTags=[
1166
+ dummyAirRegion,
1167
+ dummyContactLayerRegion,
1168
+ ],
1169
+ subdomainTags=[],
1170
+ dims=[1],
1171
+ )
1172
+
1173
+ # Third cohomology request (for cuts between pancake coils):
1161
1174
  gmsh.model.mesh.addHomologyRequest(
1162
1175
  "Cohomology",
1163
1176
  domainTags=[
1164
1177
  dummyAirRegion,
1165
1178
  dummyContactLayerRegion,
1179
+ dummyWindingRegion,
1166
1180
  ],
1167
1181
  subdomainTags=[],
1168
1182
  dims=[1],
1169
1183
  )
1170
1184
 
1171
- # Third cohomology request (for cuts between pancake coils):
1172
- gmsh.model.mesh.addHomologyRequest(
1173
- "Cohomology",
1174
- domainTags=[
1175
- dummyAirRegion,
1176
- dummyContactLayerRegion,
1177
- dummyWindingRegion,
1178
- ],
1179
- subdomainTags=[],
1180
- dims=[1],
1181
- )
1182
-
1183
1185
  # Start logger:
1184
1186
  gmsh.logger.start()
1185
1187
 
@@ -1194,15 +1196,15 @@ class Mesh(Base):
1194
1196
  logger.warning(re.sub(r"Warning:\s+", "", line))
1195
1197
  gmsh.logger.stop()
1196
1198
 
1197
- if self.geo.N > 1:
1199
+ if self.geo.numberOfPancakes > 1:
1198
1200
  cutsDictionary = {
1199
- "H^1{1}": self.geo.ai.cutName,
1201
+ "H^1{1}": self.geo.air.cutName,
1200
1202
  "H^1{1,4,3}": "CutsBetweenPancakes",
1201
1203
  "H^1{2,4}": "CutsForPerfectInsulation",
1202
1204
  }
1203
1205
  else:
1204
1206
  cutsDictionary = {
1205
- "H^1{1}": self.geo.ai.cutName,
1207
+ "H^1{1}": self.geo.air.cutName,
1206
1208
  "H^1{1,4,3}": "CutsBetweenPancakes",
1207
1209
  "H^1{1,4}": "CutsForPerfectInsulation",
1208
1210
  }
@@ -1272,25 +1274,25 @@ class Mesh(Base):
1272
1274
  """
1273
1275
  # Transfinite settings:
1274
1276
  # Arc lenght of the innermost one turn of spiral:
1275
- if self.geo.ii.tsa:
1277
+ if self.geo.contactLayer.thinShellApproximation:
1276
1278
  oneTurnSpiralLength = curve.calculateSpiralArcLength(
1277
- self.geo.wi.r_i,
1278
- self.geo.wi.r_i
1279
- + self.geo.wi.t
1280
- + self.geo.ii.t * (self.geo.N - 1) / self.geo.N,
1279
+ self.geo.winding.innerRadius,
1280
+ self.geo.winding.innerRadius
1281
+ + self.geo.winding.thickness
1282
+ + self.geo.contactLayer.thickness * (self.geo.numberOfPancakes - 1) / self.geo.numberOfPancakes,
1281
1283
  0,
1282
1284
  2 * math.pi,
1283
1285
  )
1284
1286
  else:
1285
1287
  oneTurnSpiralLength = curve.calculateSpiralArcLength(
1286
- self.geo.wi.r_i,
1287
- self.geo.wi.r_i + self.geo.wi.t,
1288
+ self.geo.winding.innerRadius,
1289
+ self.geo.winding.innerRadius + self.geo.winding.thickness,
1288
1290
  0,
1289
1291
  2 * math.pi,
1290
1292
  )
1291
1293
 
1292
1294
  # Arc length of one element:
1293
- arcElementLength = oneTurnSpiralLength / self.mesh.wi.ane[meshSettingIndex]
1295
+ arcElementLength = oneTurnSpiralLength / self.mesh.winding.azimuthalNumberOfElementsPerTurn[meshSettingIndex]
1294
1296
 
1295
1297
  # Number of azimuthal elements per turn:
1296
1298
  arcNumElementsPerTurn = round(oneTurnSpiralLength / arcElementLength)
@@ -1303,17 +1305,17 @@ class Mesh(Base):
1303
1305
  if lineObject.type is curveType.horizontal:
1304
1306
  # The curve is horizontal, so radialNumberOfElementsPerTurn entry is
1305
1307
  # used.
1306
- if self.geo.ii.tsa:
1307
- numNodes = self.mesh.wi.rne[meshSettingIndex] + 1
1308
+ if self.geo.contactLayer.thinShellApproximation:
1309
+ numNodes = self.mesh.winding.radialNumberOfElementsPerTurn[meshSettingIndex] + 1
1308
1310
 
1309
1311
  else:
1310
1312
  if j == 0:
1311
1313
  # This line is the winding's horizontal line:
1312
- numNodes = self.mesh.wi.rne[meshSettingIndex] + 1
1314
+ numNodes = self.mesh.winding.radialNumberOfElementsPerTurn[meshSettingIndex] + 1
1313
1315
 
1314
1316
  else:
1315
1317
  # This line is the contact layer's horizontal line:
1316
- numNodes = self.mesh.ii.rne[meshSettingIndex] + 1
1318
+ numNodes = self.mesh.contactLayer.radialNumberOfElementsPerTurn[meshSettingIndex] + 1
1317
1319
 
1318
1320
  # Set transfinite curve:
1319
1321
  self.contactLayerAndWindingRadialLines.append(lineTag)
@@ -1322,12 +1324,12 @@ class Mesh(Base):
1322
1324
  elif lineObject.type is curveType.axial:
1323
1325
  # The curve is axial, so axialNumberOfElements entry is used.
1324
1326
  if axialNumberOfElements is None:
1325
- numNodes = self.mesh.wi.axne[meshSettingIndex] + 1
1327
+ numNodes = self.mesh.winding.axialNumberOfElements[meshSettingIndex] + 1
1326
1328
  else:
1327
1329
  numNodes = axialNumberOfElements + 1
1328
1330
 
1329
1331
  if bumpCoefficient is None:
1330
- bumpCoefficient = self.mesh.wi.axbc[meshSettingIndex]
1332
+ bumpCoefficient = self.mesh.winding.axialDistributionCoefficient[meshSettingIndex]
1331
1333
  gmsh.model.mesh.setTransfiniteCurve(
1332
1334
  lineTag, numNodes, meshType="Bump", coef=bumpCoefficient
1333
1335
  )
@@ -1345,7 +1347,7 @@ class Mesh(Base):
1345
1347
  lengthInTurns = 1 - lengthInTurns
1346
1348
 
1347
1349
  lengthInTurns = (
1348
- round(lengthInTurns / self.geo.wi.turnTol) * self.geo.wi.turnTol
1350
+ round(lengthInTurns / self.geo.winding.turnTol) * self.geo.winding.turnTol
1349
1351
  )
1350
1352
 
1351
1353
  arcNumEl = round(arcNumElementsPerTurn * lengthInTurns)
@@ -1360,10 +1362,10 @@ class Mesh(Base):
1360
1362
  # Make all the surfaces transfinite:
1361
1363
  gmsh.model.mesh.setTransfiniteSurface(surfTag)
1362
1364
 
1363
- if self.mesh.wi.elementType[meshSettingIndex] == "hexahedron":
1365
+ if self.mesh.winding.elementType[meshSettingIndex] == "hexahedron":
1364
1366
  # If the element type is hexahedron, recombine all the surfaces:
1365
1367
  gmsh.model.mesh.setRecombine(2, surfTag)
1366
- elif self.mesh.wi.elementType[meshSettingIndex] == "prism":
1368
+ elif self.mesh.winding.elementType[meshSettingIndex] == "prism":
1367
1369
  # If the element type is prism, recombine only the side surfaces:
1368
1370
  surfaceNormal = list(gmsh.model.getNormal(surfTag, [0.5, 0.5]))
1369
1371
  if abs(surfaceNormal[2]) < 1e-6:
@@ -1379,9 +1381,9 @@ class Mesh(Base):
1379
1381
  self, volumeTags, terminalNonTubeParts=False, radialElementMultiplier=1
1380
1382
  ):
1381
1383
  # Number of azimuthal elements per quarter:
1382
- arcNumElementsPerQuarter = int(self.mesh.wi.ane[0] / 4)
1384
+ arcNumElementsPerQuarter = int(self.mesh.winding.azimuthalNumberOfElementsPerTurn[0] / 4)
1383
1385
  radialNumberOfElementsPerLength = (
1384
- self.mesh.wi.rne[0] / self.geo.wi.t * radialElementMultiplier
1386
+ self.mesh.winding.radialNumberOfElementsPerTurn[0] / self.geo.winding.thickness * radialElementMultiplier
1385
1387
  )
1386
1388
 
1387
1389
  surfacesDimTags = gmsh.model.getBoundary(
@@ -1419,7 +1421,7 @@ class Mesh(Base):
1419
1421
  if terminalNonTubeParts:
1420
1422
  if curveTag not in self.contactLayerAndWindingRadialLines:
1421
1423
  numNodes = (
1422
- round(radialNumberOfElementsPerLength * self.geo.ti.i.t)
1424
+ round(radialNumberOfElementsPerLength * self.geo.terminals.inner.thickness)
1423
1425
  + 1
1424
1426
  )
1425
1427
  # Set transfinite curve:
@@ -1434,10 +1436,10 @@ class Mesh(Base):
1434
1436
 
1435
1437
  elif curveObject.type is curveType.axial:
1436
1438
  # The curve is axial, so axialNumberOfElements entry is used.
1437
- if math.isclose(curveObject.length, self.geo.wi.h, rel_tol=1e-7):
1438
- numNodes = min(self.mesh.wi.axne) + 1
1439
+ if math.isclose(curveObject.length, self.geo.winding.height, rel_tol=1e-7):
1440
+ numNodes = min(self.mesh.winding.axialNumberOfElements) + 1
1439
1441
  else:
1440
- axialElementsPerLength = min(self.mesh.wi.axne) / self.geo.wi.h
1442
+ axialElementsPerLength = min(self.mesh.winding.axialNumberOfElements) / self.geo.winding.height
1441
1443
  numNodes = (
1442
1444
  round(axialElementsPerLength * curveObject.length + 1e-6) + 1
1443
1445
  )
@@ -1452,7 +1454,7 @@ class Mesh(Base):
1452
1454
  lengthInTurns = 1 - lengthInTurns
1453
1455
 
1454
1456
  lengthInTurns = (
1455
- round(lengthInTurns / self.geo.wi.turnTol) * self.geo.wi.turnTol
1457
+ round(lengthInTurns / self.geo.winding.turnTol) * self.geo.winding.turnTol
1456
1458
  )
1457
1459
 
1458
1460
  arcNumEl = round(arcNumElementsPerQuarter * 4 * lengthInTurns)
@@ -1466,10 +1468,10 @@ class Mesh(Base):
1466
1468
  for surfaceTag in surfacesTags:
1467
1469
  # Make all the surfaces transfinite:
1468
1470
 
1469
- if self.mesh.wi.elementType[0] == "hexahedron":
1471
+ if self.mesh.winding.elementType[0] == "hexahedron":
1470
1472
  # If the element type is hexahedron, recombine all the surfaces:
1471
1473
  gmsh.model.mesh.setRecombine(2, surfaceTag)
1472
- elif self.mesh.wi.elementType[0] == "prism":
1474
+ elif self.mesh.winding.elementType[0] == "prism":
1473
1475
  # If the element type is prism, recombine only the side surfaces:
1474
1476
  surfaceNormal = list(gmsh.model.getNormal(surfaceTag, [0.5, 0.5]))
1475
1477
  if abs(surfaceNormal[2]) < 1e-5:
@@ -2076,10 +2078,12 @@ class Mesh(Base):
2076
2078
  return [(2, newSurfaceTag)]
2077
2079
  else:
2078
2080
  # Create a new single surface:
2081
+ # The order of tags seems to be important for the fuse method to work
2082
+ # and not crash with a segmentation fault.
2079
2083
  try:
2080
2084
  fuseResults = gmsh.model.occ.fuse(
2081
- [oldSurfaceDimTags[-1]],
2082
- oldSurfaceDimTags[0:-1],
2085
+ [oldSurfaceDimTags[0]],
2086
+ oldSurfaceDimTags[1:],
2083
2087
  removeObject=False,
2084
2088
  removeTool=False,
2085
2089
  )
@@ -2144,16 +2148,16 @@ class Mesh(Base):
2144
2148
  # ==============================================================================
2145
2149
  # WINDING AND CONTACT LAYER REGIONS START =========================================
2146
2150
  # ==============================================================================
2147
- if not self.geo.ii.tsa:
2148
- windingTags = [dimTag[1] for dimTag in self.dimTags[self.geo.wi.name]]
2151
+ if not self.geo.contactLayer.thinShellApproximation:
2152
+ windingTags = [dimTag[1] for dimTag in self.dimTags[self.geo.winding.name]]
2149
2153
  self.regions.addEntities(
2150
- self.geo.wi.name, windingTags, regionType.powered, entityType.vol
2154
+ self.geo.winding.name, windingTags, regionType.powered, entityType.vol
2151
2155
  )
2152
2156
 
2153
- insulatorTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ii.name]]
2157
+ insulatorTags = [dimTag[1] for dimTag in self.dimTags[self.geo.contactLayer.name]]
2154
2158
 
2155
2159
  terminalDimTags = (
2156
- self.dimTags[self.geo.ti.i.name] + self.dimTags[self.geo.ti.o.name]
2160
+ self.dimTags[self.geo.terminals.inner.name] + self.dimTags[self.geo.terminals.outer.name]
2157
2161
  )
2158
2162
  terminalAndNotchSurfaces = gmsh.model.getBoundary(
2159
2163
  terminalDimTags, combined=False, oriented=False
@@ -2185,7 +2189,7 @@ class Mesh(Base):
2185
2189
  contactLayer.append(insulatorTag)
2186
2190
 
2187
2191
  self.regions.addEntities(
2188
- self.geo.ii.name, contactLayer, regionType.insulator, entityType.vol
2192
+ self.geo.contactLayer.name, contactLayer, regionType.insulator, entityType.vol
2189
2193
  )
2190
2194
 
2191
2195
  self.regions.addEntities(
@@ -2200,9 +2204,9 @@ class Mesh(Base):
2200
2204
  # are created because of the TSA's pro file formulation.
2201
2205
 
2202
2206
  # find the smallest prime number that divides NofVolumes:
2203
- windingDimTags = self.dimTags[self.geo.wi.name + "1"]
2207
+ windingDimTags = self.dimTags[self.geo.winding.name + "1"]
2204
2208
  windingTags = [dimTag[1] for dimTag in windingDimTags]
2205
- NofVolumes = self.geo.wi.NofVolPerTurn
2209
+ NofVolumes = self.geo.winding.numberOfVolumesPerTurn
2206
2210
  smallest_prime_divisor = 2
2207
2211
  while NofVolumes % smallest_prime_divisor != 0:
2208
2212
  smallest_prime_divisor += 1
@@ -2215,7 +2219,7 @@ class Mesh(Base):
2215
2219
  NofSets = 2 * NofStacks
2216
2220
 
2217
2221
  allInnerTerminalSurfaces = gmsh.model.getBoundary(
2218
- self.dimTags[self.geo.ti.i.name] + self.dimTags["innerTransitionNotch"],
2222
+ self.dimTags[self.geo.terminals.inner.name] + self.dimTags["innerTransitionNotch"],
2219
2223
  combined=False,
2220
2224
  oriented=False,
2221
2225
  )
@@ -2240,8 +2244,8 @@ class Mesh(Base):
2240
2244
  finalWindingSets.append([])
2241
2245
  finalContactLayerSets.append([])
2242
2246
 
2243
- for i in range(self.geo.N):
2244
- windingDimTags = self.dimTags[self.geo.wi.name + str(i + 1)]
2247
+ for i in range(self.geo.numberOfPancakes):
2248
+ windingDimTags = self.dimTags[self.geo.winding.name + str(i + 1)]
2245
2249
  windingTags = [dimTag[1] for dimTag in windingDimTags]
2246
2250
 
2247
2251
  NofVolumes = len(windingDimTags)
@@ -2374,8 +2378,8 @@ class Mesh(Base):
2374
2378
 
2375
2379
  # Seperate transition layer:
2376
2380
  terminalAndNotchSurfaces = gmsh.model.getBoundary(
2377
- self.dimTags[self.geo.ti.i.name]
2378
- + self.dimTags[self.geo.ti.o.name]
2381
+ self.dimTags[self.geo.terminals.inner.name]
2382
+ + self.dimTags[self.geo.terminals.outer.name]
2379
2383
  + self.dimTags["innerTransitionNotch"]
2380
2384
  + self.dimTags["outerTransitionNotch"],
2381
2385
  combined=False,
@@ -2409,7 +2413,7 @@ class Mesh(Base):
2409
2413
  for j in range(NofSets):
2410
2414
  # Add winding volumes:
2411
2415
  self.regions.addEntities(
2412
- self.geo.wi.name + "-" + str(j + 1),
2416
+ self.geo.winding.name + "-" + str(j + 1),
2413
2417
  finalWindingSets[j],
2414
2418
  regionType.powered,
2415
2419
  entityType.vol,
@@ -2417,7 +2421,7 @@ class Mesh(Base):
2417
2421
 
2418
2422
  # Add insulator surfaces:
2419
2423
  self.regions.addEntities(
2420
- self.geo.ii.name + "-" + str(j + 1),
2424
+ self.geo.contactLayer.name + "-" + str(j + 1),
2421
2425
  contactLayerSets[j],
2422
2426
  regionType.insulator,
2423
2427
  entityType.surf,
@@ -2425,14 +2429,35 @@ class Mesh(Base):
2425
2429
  allContactLayerSurfacesForAllPancakes.extend(contactLayerSets[j])
2426
2430
 
2427
2431
  # Add terminal and winding contact layer:
2432
+ allContactLayerSurfacesForAllPancakes.extend(
2433
+ terminalWindingContactLayerSets[j]
2434
+ )
2435
+
2436
+ # Add intersection of transition notch boundary and WindingAndTerminalContactLayer:
2437
+ transitionNotchSurfaces = gmsh.model.getBoundary(
2438
+ self.dimTags["innerTransitionNotch"]
2439
+ + self.dimTags["outerTransitionNotch"],
2440
+ combined=False,
2441
+ oriented=False,
2442
+ recursive=False
2443
+ )
2444
+
2445
+ terminalContactLayerMinusNotch = set(terminalWindingContactLayerSets[j]).difference([tag for (dim, tag) in transitionNotchSurfaces])
2446
+
2428
2447
  self.regions.addEntities(
2429
- "WindingAndTerminalContactLayer" + "-" + str(j + 1),
2430
- terminalWindingContactLayerSets[j],
2448
+ "WindingAndTerminalContactLayerWithoutNotch" + "-" + str(j + 1),
2449
+ list(terminalContactLayerMinusNotch),
2431
2450
  regionType.insulator,
2432
2451
  entityType.surf,
2433
2452
  )
2434
- allContactLayerSurfacesForAllPancakes.extend(
2435
- terminalWindingContactLayerSets[j]
2453
+
2454
+ notchAndTerminalContactLayerIntersection = set([tag for (dim, tag) in transitionNotchSurfaces]).intersection(terminalWindingContactLayerSets[j])
2455
+
2456
+ self.regions.addEntities(
2457
+ "WindingAndTerminalContactLayerOnlyNotch" + "-" + str(j + 1),
2458
+ list(notchAndTerminalContactLayerIntersection),
2459
+ regionType.insulator,
2460
+ entityType.surf,
2436
2461
  )
2437
2462
 
2438
2463
  allContactLayerSurfacesForAllPancakes = list(
@@ -2501,23 +2526,23 @@ class Mesh(Base):
2501
2526
  # TERMINAL REGIONS START =======================================================
2502
2527
  # ==============================================================================
2503
2528
 
2504
- innerTerminalTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ti.i.name]]
2529
+ innerTerminalTags = [dimTag[1] for dimTag in self.dimTags[self.geo.terminals.inner.name]]
2505
2530
  self.regions.addEntities(
2506
- self.geo.ti.i.name, innerTerminalTags, regionType.powered, entityType.vol_in
2531
+ self.geo.terminals.inner.name, innerTerminalTags, regionType.powered, entityType.vol_in
2507
2532
  )
2508
- outerTerminalTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ti.o.name]]
2533
+ outerTerminalTags = [dimTag[1] for dimTag in self.dimTags[self.geo.terminals.outer.name]]
2509
2534
  self.regions.addEntities(
2510
- self.geo.ti.o.name,
2535
+ self.geo.terminals.outer.name,
2511
2536
  outerTerminalTags,
2512
2537
  regionType.powered,
2513
2538
  entityType.vol_out,
2514
2539
  )
2515
2540
 
2516
2541
  # Top and bottom terminal surfaces:
2517
- firstTerminalDimTags = self.dimTags[self.geo.ti.firstName]
2518
- lastTerminalDimTags = self.dimTags[self.geo.ti.lastName]
2542
+ firstTerminalDimTags = self.dimTags[self.geo.terminals.firstName]
2543
+ lastTerminalDimTags = self.dimTags[self.geo.terminals.lastName]
2519
2544
 
2520
- if self.mesh.ti.structured:
2545
+ if self.mesh.terminals.structured:
2521
2546
  topSurfaceDimTags = []
2522
2547
  for i in [1, 2, 3, 4]:
2523
2548
  lastTerminalSurfaces = gmsh.model.getBoundary(
@@ -2531,7 +2556,7 @@ class Mesh(Base):
2531
2556
  topSurfaceDimTags = [lastTerminalSurfaces[-1]]
2532
2557
  topSurfaceTags = [dimTag[1] for dimTag in topSurfaceDimTags]
2533
2558
 
2534
- if self.mesh.ti.structured:
2559
+ if self.mesh.terminals.structured:
2535
2560
  bottomSurfaceDimTags = []
2536
2561
  for i in [1, 2, 3, 4]:
2537
2562
  firstTerminalSurfaces = gmsh.model.getBoundary(
@@ -2558,17 +2583,17 @@ class Mesh(Base):
2558
2583
  entityType.surf_in,
2559
2584
  )
2560
2585
 
2561
- # if self.geo.ii.tsa:
2586
+ # if self.geo.contactLayer.tsa:
2562
2587
  # outerTerminalSurfaces = gmsh.model.getBoundary(
2563
- # self.dimTags[self.geo.ti.o.name], combined=True, oriented=False
2588
+ # self.dimTags[self.geo.terminals.o.name], combined=True, oriented=False
2564
2589
  # )
2565
2590
  # outerTerminalSurfaces = [dimTag[1] for dimTag in outerTerminalSurfaces]
2566
2591
  # innerTerminalSurfaces = gmsh.model.getBoundary(
2567
- # self.dimTags[self.geo.ti.i.name], combined=True, oriented=False
2592
+ # self.dimTags[self.geo.terminals.i.name], combined=True, oriented=False
2568
2593
  # )
2569
2594
  # innerTerminalSurfaces = [dimTag[1] for dimTag in innerTerminalSurfaces]
2570
2595
  # windingSurfaces = gmsh.model.getBoundary(
2571
- # self.dimTags[self.geo.wi.name] + self.dimTags[self.geo.ii.name],
2596
+ # self.dimTags[self.geo.winding.name] + self.dimTags[self.geo.contactLayer.name],
2572
2597
  # combined=True,
2573
2598
  # oriented=False,
2574
2599
  # )
@@ -2596,15 +2621,15 @@ class Mesh(Base):
2596
2621
  # ==============================================================================
2597
2622
  # AIR AND AIR SHELL REGIONS STARTS =============================================
2598
2623
  # ==============================================================================
2599
- airTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ai.name]]
2624
+ airTags = [dimTag[1] for dimTag in self.dimTags[self.geo.air.name]]
2600
2625
  self.regions.addEntities(
2601
- self.geo.ai.name, airTags, regionType.air, entityType.vol
2626
+ self.geo.air.name, airTags, regionType.air, entityType.vol
2602
2627
  )
2603
2628
 
2604
2629
  # Create a region with two points on air to be used in the pro file formulation:
2605
2630
  # To those points, Phi=0 boundary condition will be applied to set the gauge.
2606
2631
  outerAirSurfaces = gmsh.model.getBoundary(
2607
- self.dimTags[self.geo.ai.name + "-OuterTube"], combined=True, oriented=False
2632
+ self.dimTags[self.geo.air.name + "-OuterTube"], combined=True, oriented=False
2608
2633
  )
2609
2634
  outerAirSurface = outerAirSurfaces[-1]
2610
2635
  outerAirCurves = gmsh.model.getBoundary(
@@ -2623,7 +2648,7 @@ class Mesh(Base):
2623
2648
  )
2624
2649
 
2625
2650
  innerAirSurfaces = gmsh.model.getBoundary(
2626
- self.dimTags[self.geo.ai.name + "-InnerCylinder"],
2651
+ self.dimTags[self.geo.air.name + "-InnerCylinder"],
2627
2652
  combined=True,
2628
2653
  oriented=False,
2629
2654
  )
@@ -2643,36 +2668,36 @@ class Mesh(Base):
2643
2668
  entityType.point,
2644
2669
  )
2645
2670
 
2646
- if self.geo.ai.shellTransformation:
2647
- if self.geo.ai.type == "cylinder":
2671
+ if self.geo.air.shellTransformation:
2672
+ if self.geo.air.type == "cylinder":
2648
2673
  airShellTags = [
2649
- dimTag[1] for dimTag in self.dimTags[self.geo.ai.shellVolumeName]
2674
+ dimTag[1] for dimTag in self.dimTags[self.geo.air.shellVolumeName]
2650
2675
  ]
2651
2676
  self.regions.addEntities(
2652
- self.geo.ai.shellVolumeName,
2677
+ self.geo.air.shellVolumeName,
2653
2678
  airShellTags,
2654
2679
  regionType.air_far_field,
2655
2680
  entityType.vol,
2656
2681
  )
2657
- elif self.geo.ai.type == "cuboid":
2682
+ elif self.geo.air.type == "cuboid":
2658
2683
  airShell1Tags = [
2659
2684
  dimTag[1]
2660
- for dimTag in self.dimTags[self.geo.ai.shellVolumeName + "-Part1"]
2661
- + self.dimTags[self.geo.ai.shellVolumeName + "-Part3"]
2685
+ for dimTag in self.dimTags[self.geo.air.shellVolumeName + "-Part1"]
2686
+ + self.dimTags[self.geo.air.shellVolumeName + "-Part3"]
2662
2687
  ]
2663
2688
  airShell2Tags = [
2664
2689
  dimTag[1]
2665
- for dimTag in self.dimTags[self.geo.ai.shellVolumeName + "-Part2"]
2666
- + self.dimTags[self.geo.ai.shellVolumeName + "-Part4"]
2690
+ for dimTag in self.dimTags[self.geo.air.shellVolumeName + "-Part2"]
2691
+ + self.dimTags[self.geo.air.shellVolumeName + "-Part4"]
2667
2692
  ]
2668
2693
  self.regions.addEntities(
2669
- self.geo.ai.shellVolumeName + "-PartX",
2694
+ self.geo.air.shellVolumeName + "-PartX",
2670
2695
  airShell1Tags,
2671
2696
  regionType.air_far_field,
2672
2697
  entityType.vol,
2673
2698
  )
2674
2699
  self.regions.addEntities(
2675
- self.geo.ai.shellVolumeName + "-PartY",
2700
+ self.geo.air.shellVolumeName + "-PartY",
2676
2701
  airShell2Tags,
2677
2702
  regionType.air_far_field,
2678
2703
  entityType.vol,
@@ -2684,10 +2709,10 @@ class Mesh(Base):
2684
2709
  # ==============================================================================
2685
2710
  # CUTS STARTS ==================================================================
2686
2711
  # ==============================================================================
2687
- if self.geo.ai.cutName in self.dimTags:
2688
- cutTags = [dimTag[1] for dimTag in self.dimTags[self.geo.ai.cutName]]
2712
+ if self.geo.air.cutName in self.dimTags:
2713
+ cutTags = [dimTag[1] for dimTag in self.dimTags[self.geo.air.cutName]]
2689
2714
  self.regions.addEntities(
2690
- self.geo.ai.cutName, cutTags, regionType.air, entityType.cochain
2715
+ self.geo.air.cutName, cutTags, regionType.air, entityType.cochain
2691
2716
  )
2692
2717
 
2693
2718
  if "CutsForPerfectInsulation" in self.dimTags:
@@ -2710,10 +2735,10 @@ class Mesh(Base):
2710
2735
  # ==============================================================================
2711
2736
  # Pancake3D Boundary Surface:
2712
2737
  allPancakeVolumes = (
2713
- self.dimTags[self.geo.wi.name]
2714
- + self.dimTags[self.geo.ti.i.name]
2715
- + self.dimTags[self.geo.ti.o.name]
2716
- + self.dimTags[self.geo.ii.name]
2738
+ self.dimTags[self.geo.winding.name]
2739
+ + self.dimTags[self.geo.terminals.inner.name]
2740
+ + self.dimTags[self.geo.terminals.outer.name]
2741
+ + self.dimTags[self.geo.contactLayer.name]
2717
2742
  + self.dimTags["innerTransitionNotch"]
2718
2743
  + self.dimTags["outerTransitionNotch"]
2719
2744
  )
@@ -2733,12 +2758,70 @@ class Mesh(Base):
2733
2758
  entityType.surf,
2734
2759
  )
2735
2760
 
2736
- if not self.geo.ii.tsa:
2761
+ if self.geo.contactLayer.thinShellApproximation:
2762
+ # add non-winding boundary for convective cooling
2763
+ windingBoundaryDimTags = gmsh.model.getBoundary(
2764
+ [(3, tag) for tag in itertools.chain(*finalWindingSets)],
2765
+ combined=True,
2766
+ oriented=False,
2767
+ )
2768
+
2769
+ inner_terminal_and_transition_notch_all_boundaries = gmsh.model.getBoundary(
2770
+ self.dimTags[self.geo.terminals.inner.name] + self.dimTags["innerTransitionNotch"],
2771
+ combined=True,
2772
+ oriented=False
2773
+ )
2774
+
2775
+ inner_terminal_and_transition_notch_boundary_dim_tags = set(Pancake3DBoundaryDimTags).intersection(inner_terminal_and_transition_notch_all_boundaries)
2776
+ inner_terminal_and_transition_notch_boundary_tags = [dimTag[1] for dimTag in inner_terminal_and_transition_notch_boundary_dim_tags]
2777
+ self.regions.addEntities(
2778
+ f"{self.geo.pancakeBoundaryName}-InnerTerminalAndTransitionNotch",
2779
+ inner_terminal_and_transition_notch_boundary_tags,
2780
+ regionType.powered,
2781
+ entityType.surf_th,
2782
+ )
2783
+
2784
+ outer_terminal_and_transition_notch_all_boundaries = gmsh.model.getBoundary(
2785
+ self.dimTags[self.geo.terminals.outer.name] + self.dimTags["outerTransitionNotch"],
2786
+ combined=True,
2787
+ oriented=False
2788
+ )
2789
+
2790
+ outer_terminal_and_transition_notch_boundary_dim_tags = set(Pancake3DBoundaryDimTags).intersection(outer_terminal_and_transition_notch_all_boundaries)
2791
+ outer_terminal_and_transition_notch_boundary_tags = [dimTag[1] for dimTag in outer_terminal_and_transition_notch_boundary_dim_tags]
2792
+ self.regions.addEntities(
2793
+ f"{self.geo.pancakeBoundaryName}-outerTerminalAndTransitionNotch",
2794
+ outer_terminal_and_transition_notch_boundary_tags,
2795
+ regionType.powered,
2796
+ entityType.surf_th,
2797
+ )
2798
+
2799
+ # add pancake boundary for convective cooling following the winding numbering logic
2800
+ # computes the intersection between pancake boundary and the boundary of each winding group
2801
+ for j in range(NofSets):
2802
+
2803
+ windingBoundaryDimTags = gmsh.model.getBoundary(
2804
+ [(3, tag) for tag in finalWindingSets[j]],
2805
+ combined=True,
2806
+ oriented=False,
2807
+ )
2808
+
2809
+ windingBoundaryDimTags = set(windingBoundaryDimTags).intersection(Pancake3DBoundaryDimTags)
2810
+
2811
+ windingBoundaryTags = [dimTag[1] for dimTag in windingBoundaryDimTags]
2812
+ self.regions.addEntities(
2813
+ f"{self.geo.pancakeBoundaryName}-Winding{j+1}",
2814
+ windingBoundaryTags,
2815
+ regionType.powered,
2816
+ entityType.surf_th,
2817
+ )
2818
+
2819
+ if not self.geo.contactLayer.thinShellApproximation:
2737
2820
  # Pancake3D Boundary Surface with only winding and terminals:
2738
2821
  allPancakeVolumes = (
2739
- self.dimTags[self.geo.wi.name]
2740
- + self.dimTags[self.geo.ti.i.name]
2741
- + self.dimTags[self.geo.ti.o.name]
2822
+ self.dimTags[self.geo.winding.name]
2823
+ + self.dimTags[self.geo.terminals.inner.name]
2824
+ + self.dimTags[self.geo.terminals.outer.name]
2742
2825
  + self.dimTags["innerTransitionNotch"]
2743
2826
  + self.dimTags["outerTransitionNotch"]
2744
2827
  + [(3, tag) for tag in contactLayerBetweenTerminalsAndWinding]