femagtools 1.8.2__tar.gz → 1.8.3__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (229) hide show
  1. {femagtools-1.8.2/src/femagtools.egg-info → femagtools-1.8.3}/PKG-INFO +3 -3
  2. {femagtools-1.8.2 → femagtools-1.8.3}/pyproject.toml +1 -1
  3. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/__init__.py +1 -1
  4. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/area.py +65 -0
  5. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/conv.py +5 -0
  6. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/converter.py +34 -1
  7. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/functions.py +14 -6
  8. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/geom.py +12 -12
  9. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/journal.py +1 -1
  10. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/symmetry.py +28 -8
  11. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/femag.py +64 -61
  12. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/fsl.py +5 -2
  13. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/isa7.py +3 -2
  14. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/afpm.py +43 -23
  15. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/effloss.py +29 -18
  16. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/sizing.py +4 -3
  17. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/sm.py +34 -36
  18. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/mcv.py +56 -26
  19. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/multiproc.py +79 -80
  20. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/parstudy.py +10 -4
  21. femagtools-1.8.3/src/femagtools/semi_fea.py +108 -0
  22. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/basic_modpar.mako +0 -3
  23. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/fe-contr.mako +18 -18
  24. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/ld_lq_fast.mako +3 -0
  25. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/mult_cal_fast.mako +3 -0
  26. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/pm_sym_f_cur.mako +4 -1
  27. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/pm_sym_fast.mako +3 -0
  28. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/pm_sym_loss.mako +3 -0
  29. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/psd_psq_fast.mako +3 -0
  30. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/torq_calc.mako +3 -0
  31. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/tks.py +23 -20
  32. femagtools-1.8.3/src/femagtools/zmq.py +213 -0
  33. {femagtools-1.8.2 → femagtools-1.8.3/src/femagtools.egg-info}/PKG-INFO +3 -3
  34. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools.egg-info/SOURCES.txt +2 -0
  35. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools.egg-info/requires.txt +1 -1
  36. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_afpm.py +15 -6
  37. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_femag.py +1 -1
  38. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_fsl.py +4 -4
  39. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_mcv.py +20 -14
  40. {femagtools-1.8.2 → femagtools-1.8.3}/LICENSE +0 -0
  41. {femagtools-1.8.2 → femagtools-1.8.3}/MANIFEST.in +0 -0
  42. {femagtools-1.8.2 → femagtools-1.8.3}/README.md +0 -0
  43. {femagtools-1.8.2 → femagtools-1.8.3}/setup.cfg +0 -0
  44. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/airgap.py +0 -0
  45. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/amazon.py +0 -0
  46. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/amela.py +0 -0
  47. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/asm.py +0 -0
  48. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/bch.py +0 -0
  49. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/bchxml.py +0 -0
  50. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/condor.py +0 -0
  51. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/conductor.py +0 -0
  52. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/config.py +0 -0
  53. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/convert.py +0 -0
  54. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dakota.py +0 -0
  55. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dakota_femag.py +0 -0
  56. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dakotaout.py +0 -0
  57. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/docker.py +0 -0
  58. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/__init__.py +0 -0
  59. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/areabuilder.py +0 -0
  60. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/concat.py +0 -0
  61. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/corner.py +0 -0
  62. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/dumprenderer.py +0 -0
  63. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/dxfparser.py +0 -0
  64. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/femparser.py +0 -0
  65. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/fslrenderer.py +0 -0
  66. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/machine.py +0 -0
  67. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/plotrenderer.py +0 -0
  68. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/shape.py +0 -0
  69. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/dxfsl/svgparser.py +0 -0
  70. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/ecloss.py +0 -0
  71. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/erg.py +0 -0
  72. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/forcedens.py +0 -0
  73. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/getset.py +0 -0
  74. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/gmsh.py +0 -0
  75. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/google.py +0 -0
  76. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/grid.py +0 -0
  77. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/heat_source_network.py +0 -0
  78. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/hxy.py +0 -0
  79. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/jhb.py +0 -0
  80. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/job.py +0 -0
  81. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/losscoeffs.py +0 -0
  82. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/__init__.py +0 -0
  83. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/im.py +0 -0
  84. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/pm.py +0 -0
  85. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/machine/utils.py +0 -0
  86. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/magnet.py +0 -0
  87. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/me.py +0 -0
  88. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/model.py +0 -0
  89. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/__init__.py +0 -0
  90. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/algorithm.py +0 -0
  91. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/population.py +0 -0
  92. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/problem.py +0 -0
  93. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/test/AlgorithmTest.py +0 -0
  94. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/test/PopulationTest.py +0 -0
  95. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moo/test/ProblemTest.py +0 -0
  96. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/moproblem.py +0 -0
  97. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/mxw2msh.py +0 -0
  98. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/nc.py +0 -0
  99. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/netlist.py +0 -0
  100. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/ntib.py +0 -0
  101. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/opt.py +0 -0
  102. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/__init__.py +0 -0
  103. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/bch.py +0 -0
  104. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/char.py +0 -0
  105. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/fieldlines.py +0 -0
  106. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/fluxdens.py +0 -0
  107. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/forcedens.py +0 -0
  108. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/mcv.py +0 -0
  109. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/nc.py +0 -0
  110. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/phasor.py +0 -0
  111. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/plot/wdg.py +0 -0
  112. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/poc.py +0 -0
  113. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/svgfsl/converter.py +0 -0
  114. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/FE-losses.mako +0 -0
  115. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/afm_rotor.mako +0 -0
  116. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/afm_stator.mako +0 -0
  117. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/airgapinduc.mako +0 -0
  118. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/asyn_motor.mako +0 -0
  119. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/bertotti.mako +0 -0
  120. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/calc_field_ts.mako +0 -0
  121. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/calc_therm_field.mako +0 -0
  122. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/cogg_calc.mako +0 -0
  123. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/colorgrad.mako +0 -0
  124. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/com_motor_sim.mako +0 -0
  125. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/conduct-data.mako +0 -0
  126. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/connect_models.mako +0 -0
  127. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/cu_losses.mako +0 -0
  128. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/displ_stator_rotor.mako +0 -0
  129. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/ec-rotorbar.mako +0 -0
  130. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/fieldcalc.mako +0 -0
  131. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/gen_hairpin_winding.mako +0 -0
  132. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/gen_winding.mako +0 -0
  133. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/inductances.mako +0 -0
  134. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/leak_dist_wind.mako +0 -0
  135. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/leak_evol_wind.mako +0 -0
  136. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/leak_tooth_wind.mako +0 -0
  137. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnet-data.mako +0 -0
  138. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetFC2.mako +0 -0
  139. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIron.mako +0 -0
  140. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIron2.mako +0 -0
  141. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIron3.mako +0 -0
  142. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIron4.mako +0 -0
  143. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIron5.mako +0 -0
  144. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetIronV.mako +0 -0
  145. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetSector.mako +0 -0
  146. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetSectorLinear.mako +0 -0
  147. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetShell.mako +0 -0
  148. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/magnetShell2.mako +0 -0
  149. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/mesh-airgap.mako +0 -0
  150. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/modal_analysis.mako +0 -0
  151. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/modified_steinmetz.mako +0 -0
  152. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/new_model.mako +0 -0
  153. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/noloadflux-rot.mako +0 -0
  154. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/noloadflux.mako +0 -0
  155. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/noloadfluxdc.mako +0 -0
  156. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/open.mako +0 -0
  157. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/plots.mako +0 -0
  158. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/prepare_thermal.mako +0 -0
  159. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/ring.mako +0 -0
  160. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/rot_hsm.mako +0 -0
  161. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/rotorAsyn.mako +0 -0
  162. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/rotorKs2.mako +0 -0
  163. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/rotor_msh.mako +0 -0
  164. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/rotor_winding.mako +0 -0
  165. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/shortcircuit.mako +0 -0
  166. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/srm.mako +0 -0
  167. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/stator1.mako +0 -0
  168. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/stator2.mako +0 -0
  169. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/stator3Linear.mako +0 -0
  170. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/stator4.mako +0 -0
  171. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/statorBG.mako +0 -0
  172. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/statorRing.mako +0 -0
  173. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/statorRotor3.mako +0 -0
  174. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/stator_msh.mako +0 -0
  175. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/therm-dynamic.mako +0 -0
  176. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/templates/therm_static.mako +0 -0
  177. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/ts.py +0 -0
  178. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/utils.py +0 -0
  179. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/vbf.py +0 -0
  180. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/vtu.py +0 -0
  181. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools/windings.py +0 -0
  182. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools.egg-info/dependency_links.txt +0 -0
  183. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools.egg-info/entry_points.txt +0 -0
  184. {femagtools-1.8.2 → femagtools-1.8.3}/src/femagtools.egg-info/top_level.txt +0 -0
  185. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/__init__.py +0 -0
  186. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/engines/__init__.py +0 -0
  187. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/engines/test_amazon.py +0 -0
  188. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/engines/test_config.py +0 -0
  189. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/geom/__init__.py +0 -0
  190. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/geom/test_functions.py +0 -0
  191. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/geom/test_point_inside.py +0 -0
  192. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/moo/__init__.py +0 -0
  193. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/moo/test_algorithm.py +0 -0
  194. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/moo/test_population.py +0 -0
  195. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/moo/test_problem.py +0 -0
  196. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_airgap_induction.py +0 -0
  197. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_amela.py +0 -0
  198. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_asm.py +0 -0
  199. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_bchreader.py +0 -0
  200. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_conductor.py +0 -0
  201. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_convert.py +0 -0
  202. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_dxfsl.py +0 -0
  203. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_effloss.py +0 -0
  204. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_erg.py +0 -0
  205. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_forcedens.py +0 -0
  206. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_heat_source_network.py +0 -0
  207. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_hxy.py +0 -0
  208. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_im.py +0 -0
  209. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_isa7.py +0 -0
  210. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_jhb.py +0 -0
  211. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_job.py +0 -0
  212. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_losscoeffs.py +0 -0
  213. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_machine.py +0 -0
  214. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_magncurv.py +0 -0
  215. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_magnet.py +0 -0
  216. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_mcvreader.py +0 -0
  217. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_me.py +0 -0
  218. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_model.py +0 -0
  219. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_nc.py +0 -0
  220. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_parident.py +0 -0
  221. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_parstudy.py +0 -0
  222. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_pocfile.py +0 -0
  223. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_sizing.py +0 -0
  224. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_sm.py +0 -0
  225. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_tksreader.py +0 -0
  226. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_ts.py +0 -0
  227. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_vbfreader.py +0 -0
  228. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_vtu.py +0 -0
  229. {femagtools-1.8.2 → femagtools-1.8.3}/src/tests/test_windings.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: femagtools
3
- Version: 1.8.2
3
+ Version: 1.8.3
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
@@ -37,7 +37,7 @@ Classifier: Topic :: Scientific/Engineering
37
37
  Requires-Python: >=3.7
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
- Requires-Dist: numpy<=1.26.4
40
+ Requires-Dist: numpy
41
41
  Requires-Dist: scipy
42
42
  Requires-Dist: mako
43
43
  Requires-Dist: six
@@ -22,7 +22,7 @@ classifiers = [
22
22
  "Topic :: Scientific/Engineering"
23
23
  ]
24
24
  dependencies = [
25
- 'numpy<=1.26.4', # lmfit restriction
25
+ 'numpy',
26
26
  'scipy',
27
27
  'mako',
28
28
  'six',
@@ -2,7 +2,7 @@
2
2
 
3
3
  """
4
4
  __title__ = 'femagtools'
5
- __version__ = '1.8.2'
5
+ __version__ = '1.8.3'
6
6
  __author__ = 'Ronald Tanner'
7
7
  __license__ = 'BSD'
8
8
  __copyright__ = 'Copyright 2023-2024 Gamma Technology'
@@ -12,6 +12,7 @@ import numpy as np
12
12
  import networkx as nx
13
13
  import logging
14
14
  from .functions import less_equal, less, greater_equal, greater
15
+ from .functions import greater_angle, less_angle
15
16
  from .functions import distance, alpha_angle, alpha_line, min_angle, max_angle
16
17
  from .functions import point, line_m, line_n, intersect_point, points_are_close
17
18
  from .functions import middle_angle, part_of_circle, is_same_angle
@@ -75,6 +76,10 @@ class Area(object):
75
76
  self.start = 0.0
76
77
  self.sym_startangle = 0.0
77
78
  self.sym_endangle = 0.0
79
+ self.sym_upper_left_dist = None
80
+ self.sym_upper_right_dist = None
81
+ self.sym_lower_left_dist = None
82
+ self.sym_lower_right_dist = None
78
83
  self.sym_type = 0
79
84
  self.symmetry = 0
80
85
  self.sym_tolerance = sym_tolerance
@@ -674,6 +679,66 @@ class Area(object):
674
679
  return True
675
680
  return False
676
681
 
682
+ def set_symmetry_parameter(self, center):
683
+ all_list = [(distance(center, n), alpha_line(center, n))
684
+ for n in self.list_of_nodes()]
685
+ mid = middle_angle(self.min_angle, self.max_angle)
686
+ left_list = [(d, a) for d, a in all_list if greater_angle(a, mid)]
687
+ right_list = [(d, a) for d, a in all_list if less_angle(a, mid)]
688
+ left_list.sort()
689
+ right_list.sort()
690
+
691
+ if left_list:
692
+ l_low_d, l_low_a = left_list[0]
693
+ l_up_d, l_up_a = left_list[-1]
694
+ else:
695
+ l_low_d = self.min_dist
696
+ l_up_d = self.max_dist
697
+ if right_list:
698
+ r_low_d, r_low_a = right_list[0]
699
+ r_up_d, r_up_a = right_list[-1]
700
+ else:
701
+ r_low_d = self.min_dist
702
+ r_up_d = self.max_dist
703
+ self.sym_upper_left_dist = l_up_d
704
+ self.sym_upper_right_dist = r_up_d
705
+ self.sym_lower_left_dist = l_low_d
706
+ self.sym_lower_right_dist = r_low_d
707
+
708
+ def is_symmetry_equal(self, area):
709
+ logger.debug("check area %s -- %s", self.get_id(), area.get_id())
710
+
711
+ bad = False
712
+ if not np.isclose(self.sym_lower_left_dist, area.sym_lower_left_dist,
713
+ rtol=5e-1, atol=5e-1):
714
+ logger.debug("Lower left: %s != %s",
715
+ self.sym_lower_left_dist,
716
+ area.sym_lower_left_dist)
717
+ bad = True
718
+
719
+ if not np.isclose(self.sym_lower_right_dist, area.sym_lower_right_dist,
720
+ rtol=5e-1, atol=5e-1):
721
+ logger.debug("Lower right: %s != %s",
722
+ self.sym_lower_right_dist,
723
+ area.sym_lower_right_dist)
724
+ bad = True
725
+
726
+ if not np.isclose(self.sym_upper_left_dist, area.sym_upper_left_dist,
727
+ rtol=5e-1, atol=5e-1):
728
+ logger.debug("Upper left: %s != %s",
729
+ self.sym_upper_left_dist,
730
+ area.sym_upper_left_dist)
731
+ bad = True
732
+
733
+ if not np.isclose(self.sym_upper_right_dist, area.sym_upper_right_dist,
734
+ rtol=5e-1, atol=5e-1):
735
+ logger.debug("Upper right: %s != %s",
736
+ self.sym_upper_right_dist,
737
+ area.sym_upper_right_dist)
738
+ bad = True
739
+
740
+ return not bad
741
+
677
742
  def increment(self, a):
678
743
  if self.is_identical(a):
679
744
  return
@@ -115,6 +115,10 @@ def main():
115
115
  help='create fsl',
116
116
  dest='write_fsl',
117
117
  action="store_true")
118
+ argparser.add_argument('--fsl_single',
119
+ help='create separate fsl for rotor and stator',
120
+ dest='write_fsl_single',
121
+ action="store_true")
118
122
  argparser.add_argument('-v', '--view',
119
123
  help='show a view only',
120
124
  dest='view',
@@ -242,6 +246,7 @@ def main():
242
246
  show_areas=args.show_areas,
243
247
  small_plots=args.small_plots,
244
248
  write_fsl=args.write_fsl,
249
+ write_fsl_single=args.write_fsl_single,
245
250
  write_png=args.write_png,
246
251
  write_id=args.write_id,
247
252
  debug_mode=args.debugger,
@@ -335,6 +335,7 @@ def convert(dxfile,
335
335
  show_areas=False,
336
336
  small_plots=False,
337
337
  write_fsl=True,
338
+ write_fsl_single=False,
338
339
  write_png=False,
339
340
  write_id=False,
340
341
  full_model=False,
@@ -388,6 +389,9 @@ def convert(dxfile,
388
389
  split_ini = False
389
390
  split_cpy = split
390
391
 
392
+ if write_fsl_single:
393
+ write_fsl = True
394
+
391
395
  try:
392
396
  if input_file.suffix in ['.fem', '.FEM']:
393
397
  from .femparser import femshapes
@@ -719,6 +723,14 @@ def convert(dxfile,
719
723
  fslrenderer = FslRenderer(basename, mtype)
720
724
  inner = fslrenderer.render(machine_inner, inner=True)
721
725
  outer = fslrenderer.render(machine_outer, outer=True)
726
+ if write_fsl_single:
727
+ inner_single = fslrenderer.render(machine_inner, inner=True,
728
+ standalone=True)
729
+ outer_single = fslrenderer.render(machine_outer, outer=True,
730
+ standalone=True)
731
+ else:
732
+ inner_single = None
733
+ outer_single = None
722
734
  if full_model:
723
735
  params['num_sl_gen'] = params.get('tot_num_slot', 0)
724
736
  params['agndst'] = agndst(params.get('da1'),
@@ -729,10 +741,18 @@ def convert(dxfile,
729
741
 
730
742
  if params['external_rotor']:
731
743
  conv['fsl_rotor'] = outer
744
+ if outer_single:
745
+ conv['fsl_rotor_single'] = outer_single
732
746
  conv['fsl_stator'] = inner
747
+ if inner_single:
748
+ conv['fsl_stator_single'] = inner_single
733
749
  else:
734
750
  conv['fsl_rotor'] = inner
751
+ if inner_single:
752
+ conv['fsl_rotor_single'] = inner_single
735
753
  conv['fsl_stator'] = outer
754
+ if outer_single:
755
+ conv['fsl_stator_single'] = outer_single
736
756
 
737
757
  conv['fsl'] = fslrenderer.render_main(
738
758
  machine_inner, machine_outer,
@@ -875,11 +895,24 @@ def convert(dxfile,
875
895
  if write_fsl:
876
896
  logger.debug("Write fsl")
877
897
  if conv and conv['fsl']:
878
- with io.open(basename + '.fsl', 'w', encoding='utf-8') as f:
898
+ with io.open(basename + '.fsl', 'w',
899
+ encoding='utf-8') as f:
879
900
  f.write('\n'.join(conv['fsl']))
880
901
  else:
881
902
  logger.warning("No fsl data available")
882
903
 
904
+ if conv:
905
+ if conv.get('fsl_rotor_single', None):
906
+ with io.open(basename + '_ROTOR.fsl', 'w',
907
+ encoding='utf-8') as f:
908
+ f.write('\n'.join(conv['fsl_rotor_single']))
909
+ del conv['fsl_rotor_single']
910
+ if conv.get('fsl_stator_single', None):
911
+ with io.open(basename + '_STATOR.fsl', 'w',
912
+ encoding='utf-8') as f:
913
+ f.write('\n'.join(conv['fsl_stator_single']))
914
+ del conv['fsl_stator_single']
915
+
883
916
  conv['name'] = basename
884
917
  t = timer.stop("-- all done in %0.4f seconds --", info=True)
885
918
  journal.put('time_total', t)
@@ -85,16 +85,24 @@ def alpha_angle(startangle, endangle):
85
85
  return angle - 2.0*np.pi
86
86
 
87
87
 
88
- def max_angle(alpha1, alpha2):
88
+ def less_angle(alpha1, alpha2):
89
89
  angle = alpha_angle(alpha1, alpha2)
90
- if angle < np.pi or angle > 2.0*np.pi:
91
- return alpha2
92
- return alpha1
90
+ return (angle < np.pi or angle > 2.0*np.pi)
93
91
 
94
92
 
95
- def min_angle(alpha1, alpha2):
93
+ def greater_angle(alpha1, alpha2):
96
94
  angle = alpha_angle(alpha1, alpha2)
97
- if angle < np.pi or angle > 2.0*np.pi:
95
+ return not (angle < np.pi or angle > 2.0*np.pi)
96
+
97
+
98
+ def max_angle(alpha1, alpha2):
99
+ if greater_angle(alpha1, alpha2):
100
+ return alpha1
101
+ return alpha2
102
+
103
+
104
+ def min_angle(alpha1, alpha2):
105
+ if less_angle(alpha1, alpha2):
98
106
  return alpha1
99
107
  return alpha2
100
108
 
@@ -1986,7 +1986,7 @@ class Geometry(object):
1986
1986
  startangle=0.0,
1987
1987
  endangle=np.pi/2)
1988
1988
 
1989
- elif np.isclose(width, height*2, self.rtol, self.atol):
1989
+ elif np.isclose(width, height*2, rtol=1e-2, atol=1e-2):
1990
1990
  radius = width/2
1991
1991
  self.set_center([mm[1]-height, mm[2]])
1992
1992
  logger.info("check for half machine")
@@ -2005,7 +2005,7 @@ class Geometry(object):
2005
2005
  startangle=np.pi,
2006
2006
  endangle=0.0)
2007
2007
 
2008
- elif np.isclose(width*2, height, self.rtol, self.atol):
2008
+ elif np.isclose(width*2, height, rtol=1e-2, atol=1e-2):
2009
2009
  radius = width
2010
2010
  logger.info("check for half machine")
2011
2011
  self.set_center([mm[1], mm[3]-width])
@@ -2409,31 +2409,31 @@ class Geometry(object):
2409
2409
  logger.debug("end check_airgap: return %s", len(area_id_list) > 1)
2410
2410
  return len(area_id_list) > 1 # bad
2411
2411
 
2412
- def is_border_line(self, center, startangle, endangle, e, atol):
2412
+ def is_border_line(self, center, startangle, endangle, e, rtol=1e-3, atol=1e-3):
2413
2413
  if isinstance(e, Line):
2414
2414
  if np.isclose(startangle, endangle):
2415
2415
  return False # full
2416
2416
 
2417
2417
  if points_are_close(center, e.p1):
2418
2418
  angle_p2 = alpha_line(center, e.p2)
2419
- if np.isclose(startangle, angle_p2, 1e-3, atol):
2419
+ if np.isclose(startangle, angle_p2, rtol=rtol, atol=atol):
2420
2420
  return True
2421
- return np.isclose(endangle, angle_p2, 1e-3, atol)
2421
+ return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
2422
2422
 
2423
2423
  if points_are_close(center, e.p2):
2424
2424
  angle_p1 = alpha_line(center, e.p1)
2425
- if np.isclose(startangle, angle_p1, 1e-3, atol):
2425
+ if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
2426
2426
  return True
2427
- return np.isclose(endangle, angle_p1, 1e-3, atol)
2427
+ return np.isclose(endangle, angle_p1, rtol=rtol, atol=atol)
2428
2428
 
2429
2429
  angle_p1 = alpha_line(center, e.p1)
2430
- if np.isclose(startangle, angle_p1, 1e-3, atol):
2430
+ if np.isclose(startangle, angle_p1, rtol=rtol, atol=atol):
2431
2431
  angle_p2 = alpha_line(center, e.p2)
2432
- return np.isclose(startangle, angle_p2, 1e-3, atol)
2432
+ return np.isclose(startangle, angle_p2, rtol=rtol, atol=atol)
2433
2433
 
2434
- if np.isclose(endangle, angle_p1, 1e-3, atol):
2434
+ if np.isclose(endangle, angle_p1, rtol=rtol, atol=atol):
2435
2435
  angle_p2 = alpha_line(center, e.p2)
2436
- return np.isclose(endangle, angle_p2, 1e-3, atol)
2436
+ return np.isclose(endangle, angle_p2, rtol=rtol, atol=atol)
2437
2437
  return False
2438
2438
 
2439
2439
  def get_gaplist(self, center):
@@ -2457,7 +2457,7 @@ class Geometry(object):
2457
2457
  """
2458
2458
  gaplist = []
2459
2459
  for e in self.elements(Shape):
2460
- if not self.is_border_line(center, startangle, endangle, e, atol):
2460
+ if not self.is_border_line(center, startangle, endangle, e, atol=atol):
2461
2461
  gaplist += [e.minmax_from_center(center)]
2462
2462
  else:
2463
2463
  min_r, max_r = e.minmax_from_center(center)
@@ -18,7 +18,7 @@ logger = logging.getLogger('femagtools.journal')
18
18
  journal = None
19
19
 
20
20
  #############################
21
- # concat #
21
+ # journal #
22
22
  #############################
23
23
 
24
24
 
@@ -102,6 +102,7 @@ class Symmetry(object):
102
102
  a.get_mid_angle(self.geom.center)))
103
103
 
104
104
  def area_list_entry(self, a):
105
+ a.set_symmetry_parameter(self.geom.center)
105
106
  return (round(a.get_alpha(self.geom.center), 3),
106
107
  round(a.min_dist, 1),
107
108
  round(a.height, 1),
@@ -124,19 +125,34 @@ class Symmetry(object):
124
125
  equal_areas = [(a0_mid_angle, a0)]
125
126
  check_rslt = []
126
127
  for a1_alpha, a1_min_dist, a1_height, a1_mid_angle, a1 in areas[1:]:
127
- if self.equal_area(a0_min_dist, a0_height, a0_alpha,
128
- a1_min_dist, a1_height, a1_alpha,
129
- rtol=0.001, atol=0.05):
128
+ if (self.equal_area(a0_min_dist, a0_height, a0_alpha,
129
+ a1_min_dist, a1_height, a1_alpha,
130
+ rtol=0.001, atol=0.05)):
130
131
  a0_min_dist = (a0_min_dist + a1_min_dist) / 2
131
132
  a0_height = (a0_height + a1_height) / 2
132
133
  a0_alpha = (a0_alpha + a1_alpha) / 2
133
134
  equal_areas.append((a1_mid_angle, a1))
134
135
  else:
135
- rslt = self.check_delta(equal_areas)
136
- areasize = a0.area_size()
137
- rslt['area'] = a0
138
- rslt['areasize'] = areasize
139
- check_rslt.append((areasize, rslt))
136
+ # alpha Wechsel
137
+ id_list = []
138
+ for i in range(len(equal_areas)):
139
+ mid_angle0, area0 = equal_areas[i]
140
+ if area0.get_id() in id_list:
141
+ continue
142
+ equal_areas_check = [(mid_angle0, area0)]
143
+ for mid_angle1, area1 in equal_areas[i+1:]:
144
+ if area1.get_id() in id_list:
145
+ continue
146
+ if area0.is_symmetry_equal(area1):
147
+ equal_areas_check.append((mid_angle1, area1))
148
+ id_list.append(area1.get_id())
149
+
150
+ rslt = self.check_delta(equal_areas_check)
151
+ areasize = a0.area_size()
152
+ rslt['area'] = a0
153
+ rslt['areasize'] = areasize
154
+ check_rslt.append((areasize, rslt))
155
+
140
156
  equal_areas = [(a1_mid_angle, a1)]
141
157
  a0_min_dist = a1_min_dist
142
158
  a0_height = a1_height
@@ -154,6 +170,7 @@ class Symmetry(object):
154
170
  if inside:
155
171
  areas = [self.area_list_entry(a) for a in self.geom.list_of_areas()
156
172
  if not a.close_to_ag]
173
+ areas.sort(reverse=True)
157
174
  else:
158
175
  areas = self.build_area_list((AREA.TYPE_WINDINGS,))
159
176
 
@@ -228,6 +245,8 @@ class Symmetry(object):
228
245
  return 0
229
246
 
230
247
  check_rslt = self.build_results(areas)
248
+ logger.debug("%s results available", len(check_rslt))
249
+ [logger.debug("Result: %s", rslt) for rslt in check_rslt]
231
250
 
232
251
  parts, start_delta = self.get_symmetry_parts(check_rslt)
233
252
  if parts < 2:
@@ -248,6 +267,7 @@ class Symmetry(object):
248
267
  result = {'areas': len(area_list),
249
268
  'startdelta': 0.0,
250
269
  'slices': None}
270
+ result['area_id_list'] = [a.get_id() for m, a in area_list]
251
271
  if not area_list:
252
272
  logger.debug("end of check_delta: no areas")
253
273
  return result
@@ -27,6 +27,7 @@ import femagtools.fsl
27
27
  import femagtools.config
28
28
  import femagtools.ecloss
29
29
  import femagtools.forcedens
30
+ import femagtools.zmq
30
31
 
31
32
  from femagtools import ntib
32
33
 
@@ -180,15 +181,22 @@ class BaseFemag(object):
180
181
  def copy_winding_file(self, name, wdg):
181
182
  wdg.write(name, self.workdir)
182
183
 
183
- def copy_magnetizing_curves(self, model, dir=None, recsin=''):
184
+ def copy_magnetizing_curves(self, model, dir=None, recsin='', feloss=''):
184
185
  """extract mc names from model and write files into workdir or dir if given
185
186
 
186
187
  Return:
187
188
  list of extracted mc names (:obj:`list`)
188
189
  """
189
190
  dest = dir if dir else self.workdir
191
+ if isinstance(feloss, (int, float)):
192
+ try:
193
+ feloss = {1: 'jordan', 11: 'bertotti'}[int(feloss)]
194
+ except KeyError:
195
+ feloss = ''
190
196
  return [self.magnetizingCurves.writefile(m[0], dest,
191
- fillfac=m[1], recsin=recsin)
197
+ fillfac=m[1],
198
+ recsin=recsin,
199
+ feloss=feloss)
192
200
  for m in model.set_magcurves(
193
201
  self.magnetizingCurves, self.magnets)]
194
202
 
@@ -212,9 +220,11 @@ class BaseFemag(object):
212
220
  self.model = femagtools.model.MachineModel(machine)
213
221
  self.modelname = self.model.name
214
222
  recsin = ''
223
+ feloss = ''
215
224
  if simulation:
216
225
  recsin = simulation.get('recsin', '')
217
- self.copy_magnetizing_curves(self.model, recsin=recsin)
226
+ feloss = simulation.get('calc_fe_loss', '')
227
+ self.copy_magnetizing_curves(self.model, recsin=recsin, feloss=feloss)
218
228
  try:
219
229
  if 'wdgdef' in self.model.winding:
220
230
  self.model.winding['wdgfile'] = self.create_wdg_def(
@@ -429,12 +439,15 @@ class BaseFemag(object):
429
439
  """
430
440
  Read the modelname from the Femag Log file
431
441
  """
432
- with open(os.path.join(self.workdir, 'FEMAG-FSL.log')) as f:
433
- for l in f:
434
- if l.startswith('New model') or l.startswith('Load model'):
435
- return l.split('"')[1]
442
+ try:
443
+ with open(os.path.join(self.workdir, 'FEMAG-FSL.log')) as f:
444
+ for l in f:
445
+ if l.startswith('New model') or l.startswith('Load model'):
446
+ return l.split('"')[1]
447
+ except FileNotFoundError:
448
+ pass
436
449
 
437
- raise ValueError(f"Model not found in {self.workdir}/'FEMAG-FSL.log'")
450
+ return list(pathlib.Path(self.workdir).glob('*.PROT'))[0].stem
438
451
 
439
452
  def readResult(self, simulation, bch=None):
440
453
  if simulation:
@@ -715,55 +728,6 @@ class FemagTask(threading.Thread):
715
728
  self.returncode = self.proc.wait()
716
729
 
717
730
 
718
- class SubscriberTask(threading.Thread):
719
- def __init__(self, port, host, notify):
720
- threading.Thread.__init__(self)
721
- context = zmq.Context.instance()
722
- self.subscriber = context.socket(zmq.SUB)
723
- if not host:
724
- host = 'localhost'
725
- self.subscriber.connect(f'tcp://{host}:{port}')
726
- self.subscriber.setsockopt(zmq.SUBSCRIBE, b'')
727
- self.controller = zmq.Context.instance().socket(zmq.PULL)
728
- self.controller_url = 'inproc://publisher'
729
- self.controller.bind(self.controller_url)
730
- self.poller = zmq.Poller()
731
- self.poller.register(self.subscriber, zmq.POLLIN)
732
- self.poller.register(self.controller, zmq.POLLIN)
733
- self.logger = logger
734
- self.notify = notify
735
-
736
- def stop(self):
737
- socket = zmq.Context.instance().socket(zmq.PUSH)
738
- socket.connect(self.controller_url)
739
- socket.send(b"quit")
740
- socket.close()
741
-
742
- def run(self):
743
- self.logger.info("subscriber is ready")
744
- while True:
745
- socks = dict(self.poller.poll())
746
- if socks.get(self.subscriber) == zmq.POLLIN:
747
- try:
748
- response = self.subscriber.recv_multipart()
749
- # Sometimes femag send messages with only len = 1. These messages must be ignored
750
- if len(response) < 2:
751
- continue
752
- self.notify([s.decode('latin1') for s in response])
753
-
754
- except Exception:
755
- self.logger.error(
756
- "error in subscription message processing", exc_info=True)
757
-
758
- if socks.get(self.controller) == zmq.POLLIN:
759
- req = self.controller.recv()
760
- self.logger.info("subscriber %s", req)
761
- break
762
- self.subscriber.close()
763
- self.controller.close()
764
- self.logger.debug("subscriber stopped")
765
-
766
-
767
731
  class ZmqFemag(BaseFemag):
768
732
  """Invoke and control execution of FEMAG with ZeroMQ
769
733
 
@@ -838,8 +802,8 @@ class ZmqFemag(BaseFemag):
838
802
  """attaches a notify function"""
839
803
  logger.info("Subscribe on '%s' port %d", self.femaghost, self.port+1)
840
804
  if self.subscriber is None:
841
- self.subscriber = SubscriberTask(
842
- self.port+1, self.femaghost, notify)
805
+ self.subscriber = femagtools.zmq.SubscriberTask(
806
+ port=self.port+1, host=self.femaghost, notify=notify)
843
807
  self.subscriber.start()
844
808
  else:
845
809
  # reattach?
@@ -1149,6 +1113,38 @@ class ZmqFemag(BaseFemag):
1149
1113
  logger.warning(response[0])
1150
1114
  return [s.decode('latin1') for s in response]
1151
1115
 
1116
+ def airgap_flux_density(self, pmod):
1117
+ # try to read bag.dat
1118
+ agr = self.getfile("bag.dat")
1119
+ status = json.loads(agr[0])['status']
1120
+ if status == 'ok':
1121
+ datfile = os.path.join(self.workdir, 'bag.dat')
1122
+ with open(datfile, 'wb') as bagfile:
1123
+ bagfile.write(agr[1])
1124
+ agi = ag.read(datfile, pmod)
1125
+ else:
1126
+ import numpy as np
1127
+ # try to read model file (TODO download with getfile)
1128
+ nc = self.read_nc()
1129
+ ag_elmnts = nc.airgap_center_elements
1130
+ logger.info("Airgap elements %d scale_factor %f",
1131
+ len(ag_elmnts), nc.scale_factor())
1132
+ if len(ag_elmnts) < 1:
1133
+ raise ValueError("Missing airgap elements")
1134
+ scf = 360/nc.scale_factor()/ag_elmnts[-1].center[0]
1135
+ pos = np.array([e.center[0]*scf for e in ag_elmnts])
1136
+ bxy = np.array([e.flux_density() for e in ag_elmnts]).T
1137
+ if np.max(bxy[0]) > np.max(bxy[1]):
1138
+ agi = ag.fft(pos, bxy[0], pmod)
1139
+ else:
1140
+ agi = ag.fft(pos, bxy[1], pmod)
1141
+ return dict(Bamp=agi['Bamp'],
1142
+ phi0=agi['phi0'],
1143
+ angle=agi['pos'],
1144
+ angle_fft=agi['pos'],
1145
+ B=agi['B'],
1146
+ B_fft=agi['B_fft'])
1147
+
1152
1148
  def interrupt(self):
1153
1149
  """send push message to control port to stop current calculation"""
1154
1150
  context = zmq.Context.instance()
@@ -1165,7 +1161,7 @@ class ZmqFemag(BaseFemag):
1165
1161
  wdg.write(name, self.workdir)
1166
1162
  self.upload(os.path.join(self.workdir, name+'.WID'))
1167
1163
 
1168
- def copy_magnetizing_curves(self, model, dir=None, recsin=''):
1164
+ def copy_magnetizing_curves(self, model, dir=None, recsin='', feloss=''):
1169
1165
  """extract mc names from model and write files into workdir or dir if given
1170
1166
  and upload to Femag
1171
1167
 
@@ -1175,9 +1171,16 @@ class ZmqFemag(BaseFemag):
1175
1171
  dest = dir if dir else self.workdir
1176
1172
  mc_names = [m for m in model.set_magcurves(
1177
1173
  self.magnetizingCurves, self.magnets)]
1174
+ if isinstance(feloss, (int, float)):
1175
+ try:
1176
+ feloss = {1: 'jordan', 11: 'bertotti'}[int(feloss)]
1177
+ except KeyError:
1178
+ feloss = ''
1178
1179
  for m in mc_names:
1179
1180
  f = self.magnetizingCurves.writefile(m[0], dest,
1180
- fillfac=m[1], recsin=recsin)
1181
+ fillfac=m[1],
1182
+ recsin=recsin,
1183
+ feloss=feloss)
1181
1184
  self.upload(os.path.join(dest, f))
1182
1185
  return mc_names
1183
1186
 
@@ -556,7 +556,7 @@ class Builder:
556
556
  if 'fsl_rotor' in conv:
557
557
  self.fsl_rotor = True
558
558
  th_props = ['']
559
- logger.info(model['magnet'])
559
+ logger.debug(model['magnet'])
560
560
  if hasattr(model, 'magnet'):
561
561
  if model['magnet'].get('thcond', 0):
562
562
  th_props = [f'rotor_density = {model["magnet"]["density"]}',
@@ -730,7 +730,7 @@ class Builder:
730
730
  custom_fefunc = ['']
731
731
  if pfefunc:
732
732
  sim['loss_funct'] = 1 # 3?
733
- if pfefunc == 'bertotti' or 'modified_steinmetz':
733
+ if pfefunc in ('bertotti', 'modified_steinmetz'):
734
734
  custom_fefunc = self.__render(sim['PVFE_FSL'], pfefunc)
735
735
  else:
736
736
  custom_fefunc = pfefunc.split('\n')
@@ -750,6 +750,9 @@ class Builder:
750
750
  revert_displ = self.create_displ_stator_rotor(
751
751
  sim['eccentricity'])
752
752
 
753
+ if sim.get('calculationMode') == 'pm_sym_f_cur':
754
+ if 'nload_ex_cur' in sim.keys(): # convert obsolete key
755
+ sim['noload_ex_cur'] = sim.pop('nload_ex_cur')
753
756
  felosses = custom_fefunc + self.create_fe_losses(sim)
754
757
  fslcalc = (displ_stator_rotor
755
758
  + self.__render(sim, sim.get('calculationMode'))
@@ -815,8 +815,9 @@ class Isa7(object):
815
815
  airgap_positions.append(axy[0][0])
816
816
  self.airgap_center_elements.append(se.elements)
817
817
 
818
- if len(self.airgap_center_elements) == 1:
819
- self.airgap_center_elements = self.airgap_center_elements[0]
818
+ if self.airgap_center_elements:
819
+ # TODO check airgap center
820
+ self.airgap_center_elements = self.airgap_center_elements[-1]
820
821
  if horiz:
821
822
  airgap_positions.append(np.min(nxy[:, 1]))
822
823
  else: