femagtools 1.8.18__tar.gz → 1.8.19__tar.gz

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 (236) hide show
  1. {femagtools-1.8.18/src/femagtools.egg-info → femagtools-1.8.19}/PKG-INFO +1 -1
  2. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/__init__.py +1 -1
  3. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/bch.py +23 -6
  4. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/area.py +1 -1
  5. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/areabuilder.py +28 -12
  6. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/converter.py +2 -0
  7. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/fslrenderer.py +3 -0
  8. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/geom.py +64 -39
  9. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/machine.py +101 -2
  10. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/isa7.py +25 -22
  11. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/__init__.py +2 -2
  12. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/effloss.py +8 -0
  13. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/pm.py +16 -6
  14. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/sm.py +17 -6
  15. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/mcv.py +4 -1
  16. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/shortcircuit.py +8 -7
  17. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/psi-torq-rem.mako +4 -4
  18. femagtools-1.8.19/src/femagtools/templates/statorKS1.mako +43 -0
  19. {femagtools-1.8.18 → femagtools-1.8.19/src/femagtools.egg-info}/PKG-INFO +1 -1
  20. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools.egg-info/SOURCES.txt +1 -0
  21. {femagtools-1.8.18 → femagtools-1.8.19}/LICENSE +0 -0
  22. {femagtools-1.8.18 → femagtools-1.8.19}/MANIFEST.in +0 -0
  23. {femagtools-1.8.18 → femagtools-1.8.19}/README.md +0 -0
  24. {femagtools-1.8.18 → femagtools-1.8.19}/pyproject.toml +0 -0
  25. {femagtools-1.8.18 → femagtools-1.8.19}/setup.cfg +0 -0
  26. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/airgap.py +0 -0
  27. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/amazon.py +0 -0
  28. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/amela.py +0 -0
  29. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/asm.py +0 -0
  30. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/bchxml.py +0 -0
  31. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/condor.py +0 -0
  32. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/conductor.py +0 -0
  33. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/config.py +0 -0
  34. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/convert.py +0 -0
  35. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dakota.py +0 -0
  36. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dakota_femag.py +0 -0
  37. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dakotaout.py +0 -0
  38. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/docker.py +0 -0
  39. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/__init__.py +0 -0
  40. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/concat.py +0 -0
  41. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/conv.py +0 -0
  42. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/corner.py +0 -0
  43. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/dumprenderer.py +0 -0
  44. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/dxfparser.py +0 -0
  45. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/femparser.py +0 -0
  46. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/functions.py +0 -0
  47. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/journal.py +0 -0
  48. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/plotrenderer.py +0 -0
  49. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/shape.py +0 -0
  50. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/svgparser.py +0 -0
  51. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/dxfsl/symmetry.py +0 -0
  52. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/ecloss.py +0 -0
  53. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/erg.py +0 -0
  54. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/femag.py +0 -0
  55. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/forcedens.py +0 -0
  56. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/fsl.py +0 -0
  57. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/getset.py +0 -0
  58. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/gmsh.py +0 -0
  59. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/google.py +0 -0
  60. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/grid.py +0 -0
  61. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/heat_source_network.py +0 -0
  62. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/hxy.py +0 -0
  63. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/jhb.py +0 -0
  64. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/job.py +0 -0
  65. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/leakinduc.py +0 -0
  66. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/losscoeffs.py +0 -0
  67. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/afpm.py +0 -0
  68. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/im.py +0 -0
  69. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/sizing.py +0 -0
  70. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/machine/utils.py +0 -0
  71. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/magnet.py +0 -0
  72. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/me.py +0 -0
  73. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/model.py +0 -0
  74. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/__init__.py +0 -0
  75. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/algorithm.py +0 -0
  76. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/population.py +0 -0
  77. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/problem.py +0 -0
  78. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/test/AlgorithmTest.py +0 -0
  79. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/test/PopulationTest.py +0 -0
  80. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moo/test/ProblemTest.py +0 -0
  81. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/moproblem.py +0 -0
  82. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/multiproc.py +0 -0
  83. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/mxw2msh.py +0 -0
  84. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/nc.py +0 -0
  85. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/netlist.py +0 -0
  86. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/ntib.py +0 -0
  87. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/opt.py +0 -0
  88. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/parstudy.py +0 -0
  89. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/__init__.py +0 -0
  90. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/bch.py +0 -0
  91. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/char.py +0 -0
  92. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/fieldlines.py +0 -0
  93. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/fluxdens.py +0 -0
  94. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/forcedens.py +0 -0
  95. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/machine.py +0 -0
  96. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/mcv.py +0 -0
  97. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/nc.py +0 -0
  98. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/phasor.py +0 -0
  99. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/plot/wdg.py +0 -0
  100. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/poc.py +0 -0
  101. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/semi_fea.py +0 -0
  102. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/svgfsl/converter.py +0 -0
  103. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/FE-losses.mako +0 -0
  104. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/afm_rotor.mako +0 -0
  105. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/afm_stator.mako +0 -0
  106. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/airgapinduc.mako +0 -0
  107. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/asyn_motor.mako +0 -0
  108. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/basic_modpar.mako +0 -0
  109. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/bertotti.mako +0 -0
  110. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/calc_field_ts.mako +0 -0
  111. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/calc_therm_field.mako +0 -0
  112. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/cogg_calc.mako +0 -0
  113. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/colorgrad.mako +0 -0
  114. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/com_motor_sim.mako +0 -0
  115. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/conduct-data.mako +0 -0
  116. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/connect_models.mako +0 -0
  117. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/cu_losses.mako +0 -0
  118. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/displ_stator_rotor.mako +0 -0
  119. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/ec-rotorbar.mako +0 -0
  120. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/fe-contr.mako +0 -0
  121. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/fieldcalc.mako +0 -0
  122. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/gen_hairpin_winding.mako +0 -0
  123. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/gen_winding.mako +0 -0
  124. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/inductances.mako +0 -0
  125. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/ld_lq_fast.mako +0 -0
  126. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/leak_dist_wind.mako +0 -0
  127. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/leak_evol_wind.mako +0 -0
  128. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/leak_tooth_wind.mako +0 -0
  129. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnet-data.mako +0 -0
  130. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetFC2.mako +0 -0
  131. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIron.mako +0 -0
  132. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIron2.mako +0 -0
  133. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIron3.mako +0 -0
  134. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIron4.mako +0 -0
  135. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIron5.mako +0 -0
  136. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetIronV.mako +0 -0
  137. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetSector.mako +0 -0
  138. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetSectorLinear.mako +0 -0
  139. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetShell.mako +0 -0
  140. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/magnetShell2.mako +0 -0
  141. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/mesh-airgap.mako +0 -0
  142. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/modal_analysis.mako +0 -0
  143. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/modified_steinmetz.mako +0 -0
  144. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/mult_cal_fast.mako +0 -0
  145. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/new_model.mako +0 -0
  146. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/noloadflux-rot.mako +0 -0
  147. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/noloadflux.mako +0 -0
  148. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/noloadfluxdc.mako +0 -0
  149. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/open.mako +0 -0
  150. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/plots.mako +0 -0
  151. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/pm_sym_f_cur.mako +0 -0
  152. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/pm_sym_fast.mako +0 -0
  153. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/pm_sym_loss.mako +0 -0
  154. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/prepare_thermal.mako +0 -0
  155. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/psd_psq_fast.mako +0 -0
  156. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/psi-torq-rem-rot.mako +0 -0
  157. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/psi-torq-rot.mako +0 -0
  158. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/ring.mako +0 -0
  159. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/rot_hsm.mako +0 -0
  160. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/rotorAsyn.mako +0 -0
  161. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/rotorKs2.mako +0 -0
  162. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/rotor_msh.mako +0 -0
  163. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/rotor_winding.mako +0 -0
  164. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/shortcircuit.mako +0 -0
  165. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/srm.mako +0 -0
  166. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/stator1.mako +0 -0
  167. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/stator2.mako +0 -0
  168. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/stator3Linear.mako +0 -0
  169. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/stator4.mako +0 -0
  170. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/statorBG.mako +0 -0
  171. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/statorRing.mako +0 -0
  172. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/statorRotor3.mako +0 -0
  173. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/stator_msh.mako +0 -0
  174. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/therm-dynamic.mako +0 -0
  175. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/therm_static.mako +0 -0
  176. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/templates/torq_calc.mako +0 -0
  177. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/tks.py +0 -0
  178. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/ts.py +0 -0
  179. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/utils.py +0 -0
  180. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/vbf.py +0 -0
  181. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/vtu.py +0 -0
  182. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/windings.py +0 -0
  183. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools/zmq.py +0 -0
  184. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools.egg-info/dependency_links.txt +0 -0
  185. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools.egg-info/entry_points.txt +0 -0
  186. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools.egg-info/requires.txt +0 -0
  187. {femagtools-1.8.18 → femagtools-1.8.19}/src/femagtools.egg-info/top_level.txt +0 -0
  188. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/__init__.py +0 -0
  189. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/engines/__init__.py +0 -0
  190. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/engines/test_amazon.py +0 -0
  191. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/engines/test_config.py +0 -0
  192. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/geom/__init__.py +0 -0
  193. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/geom/test_functions.py +0 -0
  194. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/geom/test_point_inside.py +0 -0
  195. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/moo/__init__.py +0 -0
  196. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/moo/test_algorithm.py +0 -0
  197. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/moo/test_population.py +0 -0
  198. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/moo/test_problem.py +0 -0
  199. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_afpm.py +0 -0
  200. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_airgap_induction.py +0 -0
  201. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_amela.py +0 -0
  202. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_asm.py +0 -0
  203. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_bchreader.py +0 -0
  204. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_conductor.py +0 -0
  205. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_convert.py +0 -0
  206. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_dxfsl.py +0 -0
  207. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_effloss.py +0 -0
  208. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_erg.py +0 -0
  209. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_femag.py +0 -0
  210. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_forcedens.py +0 -0
  211. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_fsl.py +0 -0
  212. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_heat_source_network.py +0 -0
  213. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_hxy.py +0 -0
  214. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_im.py +0 -0
  215. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_isa7.py +0 -0
  216. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_jhb.py +0 -0
  217. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_job.py +0 -0
  218. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_losscoeffs.py +0 -0
  219. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_machine.py +0 -0
  220. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_magncurv.py +0 -0
  221. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_magnet.py +0 -0
  222. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_mcv.py +0 -0
  223. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_mcvreader.py +0 -0
  224. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_me.py +0 -0
  225. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_model.py +0 -0
  226. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_nc.py +0 -0
  227. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_parident.py +0 -0
  228. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_parstudy.py +0 -0
  229. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_pocfile.py +0 -0
  230. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_sizing.py +0 -0
  231. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_sm.py +0 -0
  232. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_tksreader.py +0 -0
  233. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_ts.py +0 -0
  234. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_vbfreader.py +0 -0
  235. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_vtu.py +0 -0
  236. {femagtools-1.8.18 → femagtools-1.8.19}/src/tests/test_windings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: femagtools
3
- Version: 1.8.18
3
+ Version: 1.8.19
4
4
  Summary: Python API for FEMAG
5
5
  Author-email: Ronald Tanner <tar@semafor.ch>, Dapu Zhang <dzhang@gtisoft.com>, Beat Holm <hob@semafor.ch>, Günther Amsler <amg@semafor.ch>, Nicolas Mauchle <mau@semafor.ch>
6
6
  License: Copyright (c) 2016-2023, Semafor Informatik & Energie AG, Basel
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.8.18'
5
+ __version__ = '1.8.19'
6
6
  __author__ = 'Ronald Tanner'
7
7
  __license__ = 'BSD'
8
8
  __copyright__ = 'Copyright 2023-2025 Gamma Technology'
@@ -271,7 +271,7 @@ class Reader:
271
271
  return self.flux[0]['displ'][1]-self.flux[0]['displ'][0]
272
272
  return None
273
273
 
274
- def read(self, content):
274
+ def read(self, content, **kwargs):
275
275
  """read bch file
276
276
 
277
277
  Args:
@@ -297,7 +297,10 @@ class Reader:
297
297
  if k == title2[:len(k)]:
298
298
  title = title2[:len(k)]
299
299
  if title in self.dispatch:
300
- self.dispatch[title](self, s)
300
+ if title == 'Airgap Induction Br':
301
+ self.dispatch[title](self, s, kwargs.get('ignore_airgap_induction_with_c_step_section', True))
302
+ else:
303
+ self.dispatch[title](self, s)
301
304
 
302
305
  if len(self.weights) > 0:
303
306
  w = list(zip(*self.weights))
@@ -887,7 +890,7 @@ class Reader:
887
890
  self.flux_fft[self.wdg] = []
888
891
  self.flux_fft[self.wdg].append(flux_fft)
889
892
 
890
- def __read_airgapInduction(self, content):
893
+ def __read_airgapInduction(self, content, ignore_c_step_section=True):
891
894
  "read and append airgapInduction section"
892
895
  import scipy.integrate as si
893
896
  import math
@@ -918,7 +921,9 @@ class Reader:
918
921
  i1beta = True
919
922
  continue
920
923
  if line.startswith("C_STEP"):
921
- return # ignore this section
924
+ if ignore_c_step_section:
925
+ return # ignore this section
926
+ continue
922
927
  try:
923
928
  rec = self.__findNums(line)
924
929
  if len(rec) == 10:
@@ -966,6 +971,10 @@ class Reader:
966
971
  self.airgapInduction['iq'] = iq
967
972
  self.airgapInduction['id'] = id
968
973
  nrows = len(self.airgapInduction['id'])
974
+ if not ignore_c_step_section:
975
+ # min 1 required (section with C_STEP)
976
+ nrows = max(1, nrows)
977
+ ncols = max(1, ncols)
969
978
 
970
979
  try:
971
980
  self.airgapInduction['an'] = [np.reshape(an[j][:nrows*ncols],
@@ -999,6 +1008,14 @@ class Reader:
999
1008
  [1:])
1000
1009
  self.airgapInduction['Bm'] = zip(*zip(*self.airgapInduction['Bm'])
1001
1010
  [1:])
1011
+ elif not ignore_c_step_section:
1012
+ # section with C_STEP and a single data linex
1013
+ self.airgapInduction['an'] = [self.airgapInduction['an'][i][0:]
1014
+ for i in range(4)]
1015
+ self.airgapInduction['bn'] = [self.airgapInduction['bn'][i][0:]
1016
+ for i in range(4)]
1017
+ self.airgapInduction['Ba'] = self.airgapInduction['Ba'][0:]
1018
+ self.airgapInduction['Bm'] = self.airgapInduction['Bm'][0:]
1002
1019
  except ValueError:
1003
1020
  print(self.airgapInduction['i1'])
1004
1021
 
@@ -1858,12 +1875,12 @@ class Reader:
1858
1875
  return self.__str__()
1859
1876
 
1860
1877
 
1861
- def read(filename):
1878
+ def read(filename, **kwargs):
1862
1879
  """Read BCH/BATCH results from file *filename*."""
1863
1880
  import io
1864
1881
  bchresults = Reader()
1865
1882
  with io.open(filename, encoding='latin1', errors='ignore') as f:
1866
- bchresults.read(f.readlines())
1883
+ bchresults.read(f.readlines(), **kwargs)
1867
1884
  return bchresults
1868
1885
 
1869
1886
 
@@ -1818,7 +1818,7 @@ class Area(object):
1818
1818
  logger.debug(">>> air is a circle")
1819
1819
  return self.type
1820
1820
 
1821
- self.set_close_to_start_end_angles(self, 0.0, alpha)
1821
+ self.set_close_to_start_end_angles(0.0, alpha)
1822
1822
 
1823
1823
  if self.is_magnet_rectangle():
1824
1824
  self.type = TYPE_MAGNET_RECT # magnet embedded
@@ -16,7 +16,7 @@ from femagtools.dxfsl.area import Area, TYPE_AIR
16
16
  from femagtools.dxfsl.functions import points_are_close, nodes_are_equal, distance
17
17
  from femagtools.dxfsl.functions import normalise_angle, positive_angle, point
18
18
  from femagtools.dxfsl.functions import alpha_line, alpha_points, alpha_angle
19
- from femagtools.dxfsl.functions import less, is_same_angle
19
+ from femagtools.dxfsl.functions import less, less_equal, greater, is_same_angle
20
20
  from femagtools.dxfsl.functions import Timer
21
21
  from femagtools.dxfsl.journal import getJournal
22
22
  import io
@@ -135,7 +135,7 @@ class EdgeInfo(object):
135
135
  self.angle = positive_angle(alpha_angle(start_angle, self.n1_angle_ingoing()))
136
136
  logger.debug("set_direction_angle: angle is %s", self.angle)
137
137
 
138
- if is_same_angle(0.0, self.angle, atol=0.008): # 1/2 degree
138
+ if is_same_angle(0.0, self.angle, atol=0.015): # 1/2 degree
139
139
  # reverse direction
140
140
  logger.debug("set_direction_angle: reverse direction( nearly 180 degrees)")
141
141
 
@@ -218,7 +218,7 @@ class EdgeInfo(object):
218
218
  myself_angle = self.angle
219
219
  other_angle = nbr_edge.angle
220
220
 
221
- if is_same_angle(0.0, myself_angle):
221
+ if is_same_angle(0.0, myself_angle, atol=0.015):
222
222
  # 360 or 0 degrees => turn 180 degrees
223
223
  logger.debug("-- ATTENTION: myself %s turns nearly 180 degrees", self.classname())
224
224
  logger.debug(" the angle is %s", myself_angle)
@@ -261,7 +261,7 @@ class EdgeInfo(object):
261
261
  logger.debug("#4: end of myself_direction_lefthand: ==> %s", left)
262
262
  return left
263
263
 
264
- if is_same_angle(0.0, other_angle, atol=0.008): # 1/2 degree
264
+ if is_same_angle(0.0, other_angle, atol=0.015): # 1/2 degree
265
265
  # 360 or 0 degrees => turn 180 degrees
266
266
  logger.debug("-- ATTENTION: other %s turns nearly 180 degrees", nbr_edge.classname())
267
267
  logger.debug(" the angle is %s", other_angle)
@@ -288,7 +288,7 @@ class EdgeInfo(object):
288
288
 
289
289
  logger.debug("-- angles: myself = %s, other = %s",
290
290
  myself_angle, other_angle)
291
- if not is_same_angle(myself_angle, other_angle, atol=0.008): # 1/2 degree
291
+ if not is_same_angle(myself_angle, other_angle, atol=0.015): # 1/2 degree
292
292
  logger.debug("-- angles are different")
293
293
  left = myself_angle > other_angle
294
294
  log_lefthand(left, self, nbr_edge)
@@ -778,7 +778,7 @@ class AreaBuilder(object):
778
778
  assert(self.geom.area_list)
779
779
  return self.get_lower_border_line()
780
780
 
781
- def close_outer_winding_areas(self):
781
+ def close_outer_winding_areas(self, color='red'):
782
782
  logger.debug("begin close_outer_winding_areas")
783
783
 
784
784
  airgap_line, airgap_el = self.get_outer_airgap_line()
@@ -787,6 +787,15 @@ class AreaBuilder(object):
787
787
  if len(airgap_line) < 5:
788
788
  return False
789
789
 
790
+ distlist = [distance(self.geom.center, n) for n in airgap_line]
791
+ min_dist = min(distlist)
792
+ max_dist = max(distlist)
793
+ geom_height = self.geom.max_radius - self.geom.min_radius
794
+ line_height = max_dist - min_dist
795
+ if line_height < geom_height * 0.2:
796
+ return 0
797
+
798
+ logger.debug("NODES: %s TO %s", airgap_line[0], airgap_line[-1])
790
799
  n1 = None
791
800
  dist_n1 = 0.0
792
801
 
@@ -795,22 +804,29 @@ class AreaBuilder(object):
795
804
  dist_prev = distance(self.geom.center, n_prev)
796
805
  alpha_prev = alpha_line(self.geom.center, n_prev)
797
806
  alpha_start = alpha_prev
798
-
799
807
  lines_created = 0
808
+ dist_ag = self.geom.min_radius
809
+ logger.debug("MIN RADIUS DIST: %s",dist_ag)
800
810
  for n in airgap_line[1:]:
801
811
  dist = distance(self.geom.center, n)
802
812
  alpha = alpha_line(self.geom.center, n)
813
+ logger.debug("Node %s, dist=%s, alpha=%s", n, dist, alpha)
803
814
  if not n1:
804
- if dist > dist_prev and alpha < alpha_prev:
805
- n1 = n_prev
806
- dist_n1 = dist_prev
815
+ logger.debug("Previous, dist=%s, alpha=%s", dist_prev, alpha_prev)
816
+ if greater(dist_prev, dist_ag, rtol=1e-3, atol=1e-3):
817
+ if greater(dist, dist_prev, rtol=1e-3, atol=1e-3) and \
818
+ less(alpha, alpha_prev, rtol=1e-4, atol=1e-5):
819
+ n1 = n_prev
820
+ dist_n1 = dist_prev
821
+ logger.debug("NODE1: %s (%s)", n1, dist_n1)
807
822
  else:
808
- if np.isclose(dist_n1, dist, rtol=1e-3, atol=1e-3):
823
+ if less_equal(dist, dist_n1, rtol=1e-3, atol=1e-2):
824
+ logger.debug("NODE2: %s (%s)", n, dist)
809
825
  line = Line(Element(start=n1, end=n))
810
826
  if e_prev.intersect_line(line):
811
827
  logger.debug("___LINE NOT POSSIBLE___")
812
828
  else:
813
- self.geom.add_line(n1, n, color='red')
829
+ self.geom.add_line(n1, n, color=color)
814
830
  lines_created += 1
815
831
  n1 = None
816
832
  dist_n1 = 0.0
@@ -286,6 +286,8 @@ def build_machine_stator(machine, inner, mindist, plt, EESM=False, single=False)
286
286
  machine_temp.create_mirror_lines_outside_windings()
287
287
  else:
288
288
  machine_temp = machine
289
+ if machine_temp.has_windings_in_the_middle():
290
+ machine_temp.create_mirror_lines_outside_windings()
289
291
 
290
292
  if machine_temp.geom.reduce_element_nodes(mindist):
291
293
  machine_temp.rebuild_subregions(EESM, single=single)
@@ -256,6 +256,9 @@ class FslRenderer(object):
256
256
  'if mcvkey_yoke == nil then',
257
257
  ' mcvkey_yoke = "dummy"',
258
258
  ' ur = 1000.0',
259
+ ' else if mcvkey_teeth == nil then',
260
+ ' mcvkey_teeth = mcvkey_yoke',
261
+ 'end',
259
262
  'end',
260
263
  'x0_iron_tooth, y0_iron_tooth = 0.0, 0.0',
261
264
  'x0_iron_yoke, y0_iron_yoke = 0.0, 0.0',
@@ -1182,7 +1182,7 @@ class Geometry(object):
1182
1182
  nx.set_edge_attributes(self.g, False, 1)
1183
1183
  nx.set_edge_attributes(self.g, False, 2)
1184
1184
 
1185
- def create_list_of_areas(self, main=False, delete=False):
1185
+ def create_list_of_areas(self, main=False, delete=False, nolog=True):
1186
1186
  """ return list of areas for each node and their neighbors
1187
1187
  """
1188
1188
  if delete: # clear list of areas
@@ -1193,7 +1193,7 @@ class Geometry(object):
1193
1193
  # list already available
1194
1194
  return
1195
1195
 
1196
- areabuilder = AreaBuilder(geom=self)
1196
+ areabuilder = AreaBuilder(geom=self, nolog=nolog)
1197
1197
  areabuilder.create_list_of_areas(main=main)
1198
1198
  self.area_list = areabuilder.area_list
1199
1199
  logger.debug("area list created")
@@ -3337,6 +3337,31 @@ class Geometry(object):
3337
3337
  return [a for a in self.list_of_areas()
3338
3338
  if a.is_type(type)]
3339
3339
 
3340
+ def is_tooth(self, a, windings, wdg_min_dist, wdg_max_dist):
3341
+ if a.around_windings(windings, self):
3342
+ if a.close_to_ag:
3343
+ return True
3344
+ if self.is_inner:
3345
+ if greater(a.min_dist, wdg_min_dist, atol=1e-1):
3346
+ return True
3347
+ else:
3348
+ if less(a.max_dist, wdg_max_dist, atol=1e-1):
3349
+ return True
3350
+ return False
3351
+
3352
+ def between_airgap_and_winding(self, a,
3353
+ wdg_min_angle,
3354
+ wdg_max_angle,
3355
+ wdg_min_dist,
3356
+ wdg_max_dist):
3357
+ if greater_equal(a.min_angle, wdg_min_angle) and \
3358
+ less_equal(a.max_angle, wdg_max_angle):
3359
+ if self.is_inner:
3360
+ return less_equal(wdg_max_dist, a.min_dist)
3361
+ else:
3362
+ return less_equal(a.max_dist, wdg_min_dist)
3363
+ return False
3364
+
3340
3365
  def collect_windings(self):
3341
3366
  logger.debug("begin of collect_windings")
3342
3367
  good_windings = self.get_windings(AREA.TYPE_WINDINGS)
@@ -3409,7 +3434,7 @@ class Geometry(object):
3409
3434
  max_size, max_w = windings_surface[0]
3410
3435
  for sz, w in windings_surface[1:]:
3411
3436
  logger.debug("winding size = %s", sz)
3412
- if sz / max_size < 0.70:
3437
+ if sz / max_size < 0.60:
3413
3438
  w.set_type(AREA.TYPE_AIR)
3414
3439
  if sz / max_size < 0.2:
3415
3440
  windings_found -= 1
@@ -3459,7 +3484,7 @@ class Geometry(object):
3459
3484
  air_areas = [a for a in self.list_of_areas()
3460
3485
  if a.is_type(AREA.TYPE_AIR_OR_IRON)]
3461
3486
  for a in air_areas:
3462
- if a.around_windings(windings, self):
3487
+ if a.around_windings(windings, self) and less(a.min_dist, wdg_max_dist - 0.5):
3463
3488
  logger.debug("Area %s", a.identifier())
3464
3489
  logger.debug(" - air-angle min/max = %s/%s",
3465
3490
  a.min_air_angle,
@@ -3481,7 +3506,6 @@ class Geometry(object):
3481
3506
  a.close_to_ag):
3482
3507
  a.set_type(AREA.TYPE_AIR) # air
3483
3508
  continue
3484
-
3485
3509
  a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3486
3510
  continue
3487
3511
 
@@ -3510,14 +3534,28 @@ class Geometry(object):
3510
3534
  a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3511
3535
  else:
3512
3536
  logger.debug("#5 not around windings")
3513
- a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3537
+ if self.between_airgap_and_winding(a,
3538
+ wdg_min_angle, wdg_max_angle,
3539
+ wdg_min_dist, wdg_max_dist):
3540
+ a.set_type(AREA.TYPE_AIR) # air
3541
+ else:
3542
+ if self.is_inner:
3543
+ if greater(a.min_dist, wdg_min_dist, atol=1e-1):
3544
+ a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3545
+ else:
3546
+ a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
3547
+ else:
3548
+ if less(a.max_dist, wdg_max_dist, atol=1e-1):
3549
+ a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3550
+ else:
3551
+ a.set_type(AREA.TYPE_YOKE) # iron shaft (Joch)
3514
3552
 
3515
3553
  # yoke or shaft ?
3516
3554
  iron_areas = [a for a in self.list_of_areas()
3517
3555
  if a.is_type(AREA.TYPE_YOKE)]
3518
3556
  for a in iron_areas:
3519
3557
  if a.around_windings(windings, self):
3520
- if less(a.min_dist, wdg_max_dist):
3558
+ if less(a.min_dist, wdg_max_dist - 0.5):
3521
3559
  if less_equal(a.max_dist, wdg_max_dist):
3522
3560
  a.set_type(AREA.TYPE_TOOTH) # iron shaft (Zahn)
3523
3561
  else:
@@ -3922,6 +3960,15 @@ class Geometry(object):
3922
3960
  area.mark_airgap_corners(start_cp, end_cp)
3923
3961
  return
3924
3962
 
3963
+ def get_areas_of_type(self, types=()):
3964
+ return [area for area in self.list_of_areas()
3965
+ if area.type in types]
3966
+
3967
+ def get_areas_of_irons(self):
3968
+ return self.get_areas_of_type((AREA.TYPE_IRON,
3969
+ AREA.TYPE_YOKE,
3970
+ AREA.TYPE_TOOTH,))
3971
+
3925
3972
  def num_areas_of_type(self, types=()):
3926
3973
  return len([area for area in self.list_of_areas()
3927
3974
  if area.type in types])
@@ -4268,6 +4315,16 @@ class Geometry(object):
4268
4315
  for e in self.elements():
4269
4316
  e.adjust_points()
4270
4317
 
4318
+ def split_with_point(self, p):
4319
+ for e in self.elements(Shape):
4320
+ elements = e.split([p])
4321
+ if elements:
4322
+ self.remove_edge(e)
4323
+ for e in elements:
4324
+ self.add_element(e, rtol=self.rtol, atol=self.atol)
4325
+ return True
4326
+ return False
4327
+
4271
4328
  def split_and_get_intersect_points(self, el, aktion=True, include_end=True):
4272
4329
  logger.debug("begin of split_and_get_intersect_points")
4273
4330
  rtol = 1e-03
@@ -4424,38 +4481,6 @@ class Geometry(object):
4424
4481
  builder = AreaBuilder(geom=self)
4425
4482
  return builder.create_inner_corner_auxiliary_areas(startangle, endangle)
4426
4483
 
4427
- def analyse_airgap_line(self, inner):
4428
- if inner: # TODO
4429
- return False
4430
-
4431
- areas = self.list_of_areas()
4432
- builder = AreaBuilder(geom=self)
4433
- ag_nodes, ag_el = builder.get_outer_airgap_line()
4434
- if not ag_nodes:
4435
- logger.warning("Fatal: No nodes found")
4436
- return False
4437
-
4438
- distlist = [distance(self.center, n) for n in ag_nodes]
4439
- min_dist = min(distlist)
4440
- max_dist = max(distlist)
4441
- logger.debug("Airgap min/max from center: %s/%s", min_dist, max_dist)
4442
- for a in areas:
4443
- logger.debug("%s: min/max from center: %s/%s", a.identifier(), a.min_dist, a.max_dist)
4444
- logger.debug("%s: min/max x: %s/%s, y: %s/%s",
4445
- a.identifier(),
4446
- a.min_x, a.max_x,
4447
- a.min_y, a.max_y)
4448
- if less_equal(a.min_x, -min_dist) and greater_equal(a.max_x, min_dist) and \
4449
- less_equal(a.min_y, -min_dist) and greater_equal(a.max_y, min_dist):
4450
- logger.debug("%s: around center", a.identifier())
4451
- continue
4452
- if np.isclose(a.min_dist, min_dist, rtol=1e-3, atol=1e-2):
4453
- continue
4454
- if less_equal(a.max_dist, max_dist, rtol=1e-3, atol=1e-2):
4455
- return False
4456
-
4457
- return builder.close_outer_winding_areas()
4458
-
4459
4484
  def adjust_outer_hull_for_symmetry(self):
4460
4485
  logger.debug("adjust_outer_hull_for_symmetry()")
4461
4486
  areas = self.list_of_areas()
@@ -646,7 +646,7 @@ class Machine(object):
646
646
  self.geom.set_virtual_start_end_corners()
647
647
 
648
648
  self.geom.looking_for_corners()
649
- create_areas = self.geom.analyse_airgap_line(is_inner)
649
+ create_areas = self.geom.close_outer_winding_areas()
650
650
  if self.geom.adjust_outer_hull_for_symmetry():
651
651
  create_areas = True
652
652
 
@@ -1284,6 +1284,30 @@ class Machine(object):
1284
1284
  def search_critical_elements(self, mindist):
1285
1285
  self.geom.search_critical_elements(mindist)
1286
1286
 
1287
+ def create_arc_element(self,
1288
+ radius,
1289
+ startangle,
1290
+ endangle):
1291
+ arc = Arc(Element(center=self.center,
1292
+ radius=radius,
1293
+ start_angle=startangle*180/np.pi,
1294
+ end_angle=endangle*180/np.pi),
1295
+ color='darkred',
1296
+ linestyle='dotted')
1297
+
1298
+ node1 = self.geom.find_the_node(arc.p1)
1299
+ if node1 is None:
1300
+ self.geom.split_with_point(arc.p1)
1301
+ node1 = self.geom.find_the_node(arc.p1)
1302
+ node2 = self.geom.find_the_node(arc.p2)
1303
+ if node2 is None:
1304
+ self.geom.split_with_point(arc.p2)
1305
+ node2 = self.geom.find_the_node(arc.p2)
1306
+ assert(node1 is not None)
1307
+ assert(node2 is not None)
1308
+ logger.debug("ARC Node1=%s, Node2=%s", node1, node2)
1309
+ self.geom.add_element(arc, rtol=1e-3, atol=1e-3)
1310
+
1287
1311
  def create_arc(self, radius,
1288
1312
  color='red', linestyle='dotted',
1289
1313
  attr=None):
@@ -1344,6 +1368,79 @@ class Machine(object):
1344
1368
  self.endangle)
1345
1369
  return self.geom.possible_magnet_in_the_middle(midangle)
1346
1370
 
1371
+ def separate_tooth_and_yoke(self, midangle):
1372
+ logger.debug("begin separate_tooth_and_yoke")
1373
+ wdg_list = self.geom.get_areas_of_type((AREA.TYPE_WINDINGS,))
1374
+ wdg_max_dist = 0.0
1375
+ wdg = None
1376
+ for w in wdg_list:
1377
+ if w.max_dist > wdg_max_dist:
1378
+ wdg_max_dist = w.max_dist
1379
+ wdg = w
1380
+
1381
+ tooth_list = self.geom.get_areas_of_type((AREA.TYPE_TOOTH,))
1382
+ tooth_max_dist = 0.0
1383
+ for tooth in tooth_list:
1384
+ tooth_max_dist = max(tooth_max_dist, tooth.max_dist)
1385
+ tooth_height = tooth_max_dist - self.geom.min_radius
1386
+ wdg_height = wdg_max_dist - self.geom.min_radius
1387
+
1388
+ logger.debug("HEIGHT TOOTH=%s, WINDINGS=%s", tooth_height, wdg_height)
1389
+
1390
+ if greater_equal(tooth_height, wdg_height * 0.9) and \
1391
+ less_equal(tooth_height, wdg_height * 1.1):
1392
+ logger.debug("Tooths are ok")
1393
+ return False # tooth ok
1394
+
1395
+ iron_list = self.geom.get_areas_of_irons()
1396
+ tooth_list = [iron for iron in iron_list
1397
+ if iron.close_to_ag and greater(iron.max_dist, wdg_max_dist, rtol=1e-2, atol=1e-2)]
1398
+ logger.debug("max winding dist = %s", wdg_max_dist)
1399
+ logger.debug("tooths = %s", len(tooth_list))
1400
+ wdg_nodes = [(distance(self.center, n), n) for n in wdg.list_of_nodes()]
1401
+ wdg_nodes.sort(reverse=True)
1402
+
1403
+ top_nodes = []
1404
+ other_nodes = []
1405
+ for d, n in wdg_nodes:
1406
+ if np.isclose(d, wdg.max_dist, rtol=1e-2, atol=1e-1):
1407
+ top_nodes.append((alpha_line(self.center, n), d, n))
1408
+ else:
1409
+ other_nodes.append((d, alpha_line(self.center, n), n))
1410
+
1411
+ a_right, d_right, n_right = (None, None, None)
1412
+ a_left, d_left, n_left = (None, None, None)
1413
+
1414
+ if not top_nodes:
1415
+ other_nodes.sort(reverse=True)
1416
+ for d, a, n in other_nodes:
1417
+ if a > midangle:
1418
+ if not a_left:
1419
+ a_left = a
1420
+ d_left = d
1421
+ n_left = n
1422
+ else:
1423
+ if not a_right:
1424
+ a_right = a
1425
+ d_right = d
1426
+ n_right = n
1427
+ if a_left and a_right:
1428
+ break
1429
+ if not (a_left and a_right):
1430
+ logger.debug("end separate_tooth_and_yoke: no arcs possible")
1431
+ return False # bad luck
1432
+ else:
1433
+ top_nodes.sort()
1434
+ a_right, d_right, n_right = top_nodes[0]
1435
+ a_left, d_left, n_left = top_nodes[0-1]
1436
+ node_right = self.geom.find_the_node(n_right)
1437
+ node_left = self.geom.find_the_node(n_left)
1438
+
1439
+ self.create_arc_element(d_right, self.startangle, a_right)
1440
+ self.create_arc_element(d_left, a_left, self.endangle)
1441
+ logger.debug("end separate_tooth_and_yoke")
1442
+ return True
1443
+
1347
1444
  def create_mirror_lines_outside_windings(self):
1348
1445
  logger.debug("create_mirror_lines_outside_windings")
1349
1446
 
@@ -1351,6 +1448,9 @@ class Machine(object):
1351
1448
  logger.debug("end create_mirror_lines_outside_windings: not done")
1352
1449
  return
1353
1450
 
1451
+ midangle = middle_angle(self.startangle, self.endangle)
1452
+ self.separate_tooth_and_yoke(midangle)
1453
+
1354
1454
  radius = self.radius+10
1355
1455
  ag_list = self.geom.detect_airgaps(self.center,
1356
1456
  self.startangle, self.endangle,
@@ -1359,7 +1459,6 @@ class Machine(object):
1359
1459
  radius_list = [(ag[0], (ag[0] + ag[1]) / 2, ag[1]) for ag in ag_list]
1360
1460
  radius_list.sort(reverse=True)
1361
1461
 
1362
- midangle = middle_angle(self.startangle, self.endangle)
1363
1462
  line = Line(
1364
1463
  Element(start=self.center,
1365
1464
  end=point(self.center, radius, midangle)))
@@ -1359,28 +1359,31 @@ class Isa7(object):
1359
1359
  # prep dictionary for the loss calculation
1360
1360
  pm_data = []
1361
1361
  for i, se in enumerate(mag_spels):
1362
- ecp = [e.center for e in se.elements]
1363
- geometry = se.get_rect_geom()
1364
-
1365
- #= np.moveaxis(bxy, 1, 0)
1366
- pd = dict(name='pm_data_se' + str(se.key),
1367
- hm=geometry['h'],
1368
- wm=geometry['w'],
1369
- lm=self.arm_length,
1370
- alpha=geometry['alpha'],
1371
- ls=self.arm_length,
1372
- sigma=cond,
1373
- mur=mur,
1374
- loadcase=ibeta,
1375
- numpoles=poles,
1376
- elcp=transform_coord(geometry, ecp),
1377
- area=se.area(),
1378
- spel_key=se.key)
1379
- if ibeta != None:
1380
- pd.update({'bl': self.get_magnet_flux_density(se, icur, ibeta)})
1381
- pd.update(pos)
1382
-
1383
- pm_data.append(pd)
1362
+ try:
1363
+ ecp = [e.center for e in se.elements]
1364
+ geometry = se.get_rect_geom()
1365
+
1366
+ #= np.moveaxis(bxy, 1, 0)
1367
+ pd = dict(name='pm_data_se' + str(se.key),
1368
+ hm=geometry['h'],
1369
+ wm=geometry['w'],
1370
+ lm=self.arm_length,
1371
+ alpha=geometry['alpha'],
1372
+ ls=self.arm_length,
1373
+ sigma=cond,
1374
+ mur=mur,
1375
+ loadcase=ibeta,
1376
+ numpoles=poles,
1377
+ elcp=transform_coord(geometry, ecp),
1378
+ area=se.area(),
1379
+ spel_key=se.key)
1380
+ if ibeta != None:
1381
+ pd.update({'bl': self.get_magnet_flux_density(se, icur, ibeta)})
1382
+ pd.update(pos)
1383
+
1384
+ pm_data.append(pd)
1385
+ except IndexError as e:
1386
+ logger.warning("se %d magnet geometry ignored: %s", i, e)
1384
1387
  return pm_data
1385
1388
 
1386
1389
  def get_magnet_flux_density(self, se, icur, ibeta) -> list:
@@ -32,7 +32,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
32
32
  PM, EESM or IM"""
33
33
  rlfe = lfe
34
34
  rwdg = wdg
35
- opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe',
35
+ opts = {k: eecpars[k] for k in ('zeta1', 'gam', 'kh', 'kpfe', 'kpfe_s', 'kpfe_r',
36
36
  'kfric_b', 'kpmag') if k in eecpars}
37
37
  try:
38
38
  opts['rotor_mass'] = rlfe*eecpars['rotor_mass']
@@ -51,7 +51,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
51
51
  smpars = copy.deepcopy(eecpars)
52
52
  smpars['tcu1'] = temp[0]
53
53
  smpars['tcu2'] = temp[1]
54
- # external inductances
54
+ # external inductances
55
55
  opts["ls"] = eecpars.get('ls1', 0)*rwdg**2
56
56
  if 'ldq' in smpars:
57
57
  machine = SynchronousMachineLdq(smpars, lfe=rlfe, wdg=rwdg, **opts)
@@ -372,6 +372,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
372
372
  if isinstance(m, PmRelMachine):
373
373
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
374
374
  plfe2 = m.kpfe*m.iqd_plfe2(iqd[0], iqd[1], f1)
375
+ if hasattr(m, 'kpfe_s'):
376
+ plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
377
+ if hasattr(m, 'kpfe_r'):
378
+ plfe2 = m.kpfe_r*m.iqd_plfe2(iqd[0], iqd[1], f1)
375
379
  plmag = m.kpmag*m.iqd_plmag(iqd[0], iqd[1], f1)
376
380
  plcu1 = m.iqd_plcu1(iqd[0], iqd[1], 2*np.pi*f1)
377
381
  plcu2 = m.iqd_plcu2(*iqd)
@@ -385,6 +389,10 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
385
389
  elif isinstance(m, SynchronousMachine):
386
390
  plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
387
391
  plfe2 = m.kpfe*m.iqd_plfe2(*iqd, f1)
392
+ if hasattr(m, 'kpfe_s'):
393
+ plfe1 = m.kpfe_s*m.iqd_plfe1(*iqd, f1)
394
+ if hasattr(m, 'kpfe_r'):
395
+ plfe2 = m.kpfe_r*m.iqd_plfe2(*iqd, f1)
388
396
  plmag = np.zeros_like(plfe2)
389
397
  plcu1 = m.iqd_plcu1(iqd[0], iqd[1], f1)
390
398
  try: