femagtools 1.8.13__py3-none-any.whl → 1.8.14__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.
- femagtools/__init__.py +1 -1
- femagtools/bch.py +30 -5
- femagtools/femag.py +2 -0
- femagtools/fsl.py +31 -37
- femagtools/isa7.py +16 -0
- femagtools/job.py +9 -0
- femagtools/machine/__init__.py +7 -38
- femagtools/machine/effloss.py +6 -7
- femagtools/machine/im.py +57 -26
- femagtools/machine/pm.py +2 -1
- femagtools/machine/sizing.py +92 -7
- femagtools/machine/sm.py +5 -1
- femagtools/machine/utils.py +37 -14
- femagtools/multiproc.py +6 -0
- femagtools/parstudy.py +1 -1
- femagtools/templates/FE-losses.mako +0 -3
- femagtools/templates/ec-rotorbar.mako +1 -2
- femagtools/templates/ld_lq_fast.mako +1 -1
- femagtools/templates/mesh-airgap.mako +0 -1
- femagtools/templates/noloadflux-rot.mako +5 -32
- femagtools/templates/statorRing.mako +1 -1
- femagtools/utils.py +5 -1
- {femagtools-1.8.13.dist-info → femagtools-1.8.14.dist-info}/METADATA +31 -2
- {femagtools-1.8.13.dist-info → femagtools-1.8.14.dist-info}/RECORD +30 -31
- {femagtools-1.8.13.dist-info → femagtools-1.8.14.dist-info}/WHEEL +1 -1
- femagtools-1.8.14.dist-info/licenses/LICENSE +26 -0
- tests/test_femag.py +1 -1
- tests/test_fsl.py +5 -5
- femagtools/templates/rotor_winding_ks2.mako +0 -44
- femagtools/templates/rotor_winding_ks2_ecSimulation.mako +0 -44
- {femagtools-1.8.13.dist-info → femagtools-1.8.14.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.13.dist-info → femagtools-1.8.14.dist-info}/top_level.txt +0 -0
femagtools/machine/sizing.py
CHANGED
@@ -381,7 +381,7 @@ def get_stator_dimensions(par, slots=[]):
|
|
381
381
|
Da2 = Da1-2*airgap
|
382
382
|
r = dict(
|
383
383
|
lfe=round(lfe, 3),
|
384
|
-
Dy1=round(Dy1, 3),
|
384
|
+
Dy1=round(Dy1, 3),
|
385
385
|
Da1=round(Da1, 4),
|
386
386
|
Da2=round(Da2, 4),
|
387
387
|
ans=round(ans, 6),
|
@@ -546,9 +546,10 @@ def get_interior_magnet_dimensions(I1, N, kw, psi1, lfe, Da2, par):
|
|
546
546
|
iron_shape=Da2/2))
|
547
547
|
|
548
548
|
|
549
|
-
def get_im_rotor_dimensions(A, Da2, psi1, lfe, par, rtype='
|
549
|
+
def get_im_rotor_dimensions(A, Da2, psi1, lfe, par, rtype='statorRotor3'):
|
550
550
|
r = dict()
|
551
551
|
r['Da2'] = Da2
|
552
|
+
r['rotorfilfact']=0.95
|
552
553
|
if 'Q2' not in par:
|
553
554
|
r['num_slots'] = _rotor_slots(par['Q1'], par['p'])[0]
|
554
555
|
else:
|
@@ -568,15 +569,42 @@ def get_im_rotor_dimensions(A, Da2, psi1, lfe, par, rtype='rotorKs2'):
|
|
568
569
|
taup = np.pi * Da2/(2*par['p'])
|
569
570
|
hyr = psi1/2/lfe*par['By']
|
570
571
|
r['Dy2'] = round(Da2 - 2*hr - 2*hyr, 4)
|
571
|
-
logger.info("Dy2 %f Da2 %f hys %f hr %f",
|
572
|
-
r['Dy2']*1e3, Da2*1e3, hyr*1e3, hr*1e3)
|
573
572
|
slotwidth = 1e-3
|
574
573
|
Q2 = r['num_slots']
|
575
574
|
r1 = wr/2-slotwidth
|
576
575
|
r2 = (Da2/2-hr-hs1)*np.tan(alfar)
|
576
|
+
|
577
577
|
logger.info("Dy2 %f Da2 %f hys %f hr %f",
|
578
578
|
r['Dy2']*1e3, Da2*1e3, hyr*1e3, hr*1e3)
|
579
|
-
|
579
|
+
|
580
|
+
# End-ring calculation
|
581
|
+
Ir_total_estimated = A * np.pi * Da2 / (2 * par['p'])
|
582
|
+
Ibar_eff = Ir_total_estimated / r['num_slots']
|
583
|
+
|
584
|
+
if r['num_slots'] > 0:
|
585
|
+
sin_term = np.sin(np.pi / r['num_slots'])
|
586
|
+
if sin_term != 0:
|
587
|
+
Iring_max_eff = Ibar_eff / (2 * sin_term)
|
588
|
+
else:
|
589
|
+
Iring_max_eff = 0
|
590
|
+
else:
|
591
|
+
Iring_max_eff = 0
|
592
|
+
if 'Jring' not in par:
|
593
|
+
par['Jring'] = par.get('J', 4e6)
|
594
|
+
|
595
|
+
Jring = par['Jring']
|
596
|
+
|
597
|
+
if 'kfilling_ring' not in par:
|
598
|
+
par['kfilling_ring'] = 1.0
|
599
|
+
|
600
|
+
kfilling_ring = par['kfilling_ring']
|
601
|
+
|
602
|
+
if Jring * kfilling_ring > 0:
|
603
|
+
Aring = Iring_max_eff / (Jring * kfilling_ring)
|
604
|
+
else:
|
605
|
+
Aring = 0
|
606
|
+
|
607
|
+
"""if rtype == 'statorRotor3':
|
580
608
|
r['statorRotor3'] = dict(
|
581
609
|
slot_width=slotwidth,
|
582
610
|
tooth_width=round(wt, 4),
|
@@ -589,6 +617,18 @@ def get_im_rotor_dimensions(A, Da2, psi1, lfe, par, rtype='rotorKs2'):
|
|
589
617
|
wedge_width1=0,
|
590
618
|
wedge_width2=0,
|
591
619
|
middle_line=0)
|
620
|
+
r['statorRotor3'] = dict(
|
621
|
+
slot_width=1e-3,
|
622
|
+
tooth_width=0,
|
623
|
+
slot_height=0.0157,
|
624
|
+
slot_top_sh=0,
|
625
|
+
slot_h1=0.5e-3,
|
626
|
+
slot_h2=2.2e-3,
|
627
|
+
slot_r1=2.2e-3,
|
628
|
+
slot_r2=1e-3,
|
629
|
+
wedge_width1=1e-3,
|
630
|
+
wedge_width2=0,
|
631
|
+
middle_line=0)
|
592
632
|
elif rtype == 'rotorAsyn':
|
593
633
|
r['rotorAsyn'] = dict(
|
594
634
|
slot_bs2=0.1e-3,
|
@@ -612,8 +652,52 @@ def get_im_rotor_dimensions(A, Da2, psi1, lfe, par, rtype='rotorKs2'):
|
|
612
652
|
slot_h2=0,
|
613
653
|
slot_r1=1e-3, # r1,
|
614
654
|
slot_r2=1e-3, # r2,
|
655
|
+
middle_line=0)"""
|
656
|
+
|
657
|
+
all_rotor_types = {}
|
658
|
+
|
659
|
+
all_rotor_types['statorRotor3'] = dict(
|
660
|
+
slot_width=slotwidth,
|
661
|
+
tooth_width=round(wt, 4),
|
662
|
+
slot_height=round(hr+r2, 4),
|
663
|
+
slot_top_sh=1.0,
|
664
|
+
slot_h1=round(hs1, 4),
|
665
|
+
slot_h2=round(hs1+r1, 4),
|
666
|
+
slot_r1=round(r1, 4),
|
667
|
+
slot_r2=round(r2),
|
668
|
+
wedge_width1=0,
|
669
|
+
wedge_width2=0,
|
615
670
|
middle_line=0)
|
616
671
|
|
672
|
+
all_rotor_types['rotorAsyn'] = dict(
|
673
|
+
slot_bs2=0.1e-3,
|
674
|
+
slot_hs2=0.5e-3,
|
675
|
+
slot_b32=0.0,
|
676
|
+
slot_h32=0.0,
|
677
|
+
slot_b42=0.0,
|
678
|
+
slot_h42=0.0,
|
679
|
+
slot_b52=round(wr, 4),
|
680
|
+
slot_b62=3e-3,
|
681
|
+
slot_h52=2.5e-3,
|
682
|
+
slot_h62=round(hr, 4),
|
683
|
+
slot_h72=2e-3
|
684
|
+
)
|
685
|
+
|
686
|
+
all_rotor_types['rotorKs2'] = dict(
|
687
|
+
slot_angle=round(2 * alfar * 180 / np.pi, 2),
|
688
|
+
slot_height=round(hr + r1 + r2, 4),
|
689
|
+
slot_topwidth=round(wr, 4),
|
690
|
+
slot_width=slotwidth,
|
691
|
+
slot_h1=hs1,
|
692
|
+
slot_h2=0,
|
693
|
+
slot_r1=1e-3, # r1,
|
694
|
+
slot_r2=1e-3, # r2,
|
695
|
+
middle_line=0
|
696
|
+
)
|
697
|
+
|
698
|
+
|
699
|
+
r.update(all_rotor_types)
|
700
|
+
r['Aring'] = Aring
|
617
701
|
return r
|
618
702
|
|
619
703
|
|
@@ -949,7 +1033,7 @@ def im(pnom: float, speed: float, p: int, **kwargs) -> dict:
|
|
949
1033
|
slots = []
|
950
1034
|
r = get_stator_dimensions(par, slots=slots)
|
951
1035
|
# rotor parameters
|
952
|
-
rtype = kwargs.get('rtype', '
|
1036
|
+
rtype = kwargs.get('rtype', 'statorRotor3')
|
953
1037
|
r['rotor'] = get_im_rotor_dimensions(
|
954
1038
|
par['cos_phi']*r['A'], r['Da2'], r['psi1'], r['lfe'],
|
955
1039
|
par, rtype=rtype)
|
@@ -987,12 +1071,13 @@ def eesm(pnom: float, speed: float, p: int, **kwargs) -> dict:
|
|
987
1071
|
r['name'] = f"EESM-{r['poles']}"
|
988
1072
|
return r
|
989
1073
|
|
1074
|
+
|
990
1075
|
if __name__ == "__main__":
|
991
1076
|
# sizing example with SPM
|
992
1077
|
pnom = 10e3 # shaft power in W
|
993
1078
|
speed = 4400/60 # speed in 1/s
|
994
1079
|
p = 4 # number of pole pairs
|
995
|
-
udc = 600 # DC voltage in V
|
1080
|
+
udc = 600 # DC voltage in V
|
996
1081
|
|
997
1082
|
r = spm(pnom, speed, p, udc=udc)
|
998
1083
|
|
femagtools/machine/sm.py
CHANGED
@@ -7,7 +7,7 @@ import pathlib
|
|
7
7
|
import numpy as np
|
8
8
|
import scipy.optimize as so
|
9
9
|
import scipy.interpolate as ip
|
10
|
-
from .utils import skin_resistance, wdg_resistance, betai1, iqd, KTH, create_wdg
|
10
|
+
from .utils import skin_resistance, wdg_resistance, betai1, iqd, KTH, create_wdg, loss_models
|
11
11
|
from .. import parstudy, windings
|
12
12
|
import femagtools.bch
|
13
13
|
|
@@ -50,6 +50,7 @@ def parident(workdir, engine, machine,
|
|
50
50
|
beta_max: maximal current angle (default 0°)
|
51
51
|
num_move_steps: number of move steps
|
52
52
|
cmd: femag command (default None, platform executable)
|
53
|
+
feloss: jordan, steinmetz, modified steinmetz, bertotti
|
53
54
|
"""
|
54
55
|
cmd = kwargs.get('cmd', None)
|
55
56
|
|
@@ -125,6 +126,9 @@ def parident(workdir, engine, machine,
|
|
125
126
|
period_frac=kwargs.get('period_frac', 6),
|
126
127
|
speed=kwargs.get('speed', 50))
|
127
128
|
|
129
|
+
if kwargs.get("feloss", 0):
|
130
|
+
simulation["feloss"] = kwargs["feloss"]
|
131
|
+
machine["calc_fe_loss"] = loss_models[kwargs["feloss"].lower()]
|
128
132
|
###self.cleanup() # remove previously created files in workdir
|
129
133
|
results = parvar(parvardef, machine, simulation, engine)
|
130
134
|
b = results['f'][-1]
|
femagtools/machine/utils.py
CHANGED
@@ -8,9 +8,16 @@ import numpy.linalg as la
|
|
8
8
|
import scipy.interpolate as ip
|
9
9
|
import logging
|
10
10
|
from .. import parstudy, windings
|
11
|
+
from ..model import MachineModel
|
11
12
|
|
12
13
|
logger = logging.getLogger(__name__)
|
13
14
|
|
15
|
+
loss_models = {
|
16
|
+
"modified steinmetz": 10,
|
17
|
+
"bertotti": 11,
|
18
|
+
"jordan": 1,
|
19
|
+
"steinmetz": 1
|
20
|
+
}
|
14
21
|
|
15
22
|
def K(d):
|
16
23
|
"""space phasor transformation matrix
|
@@ -369,6 +376,7 @@ def dqparident(workdir, engine, temp, machine,
|
|
369
376
|
period_frac: (int) fraction of rotating angle (default 6)
|
370
377
|
dqtype: (str) type of identification: 'ldq' (default), 'psidq'
|
371
378
|
cmd: femag executable
|
379
|
+
feloss: jordan, steinmetz, modified steinmetz, bertotti
|
372
380
|
"""
|
373
381
|
import pathlib
|
374
382
|
|
@@ -390,21 +398,25 @@ def dqparident(workdir, engine, temp, machine,
|
|
390
398
|
else:
|
391
399
|
fcu = 0.42
|
392
400
|
|
393
|
-
try:
|
394
|
-
from ..model import MachineModel
|
401
|
+
try:
|
395
402
|
wdg = create_wdg(machine)
|
396
|
-
Q1 = wdg.Q
|
397
|
-
model = MachineModel(machine)
|
398
|
-
Jmax = 30e6 # max current density in A/m2
|
399
|
-
Acu = fcu*model.slot_area() # approx. copper area of one slot
|
400
|
-
i1_max = round(g*Acu/wdg.l/N*Jmax/10)*10
|
401
403
|
except KeyError:
|
402
|
-
|
403
|
-
|
404
|
+
pass
|
405
|
+
model = MachineModel(machine)
|
406
|
+
if kwargs.get('i1_max', 0):
|
404
407
|
i1_max = kwargs['i1_max']
|
408
|
+
else:
|
409
|
+
try: # calc basic dimensions if not fsl or dxf model
|
410
|
+
Jmax = 30e6 # max current density in A/m2
|
411
|
+
Acu = fcu*model.slot_area() # approx. copper area of one slot
|
412
|
+
i1_max = round(g*Acu/wdg.l/N*Jmax/10)*10
|
413
|
+
except KeyError:
|
414
|
+
raise ValueError('i1_max missing')
|
405
415
|
|
406
416
|
# winding resistance
|
407
417
|
try:
|
418
|
+
da1 = machine['bore_diam']
|
419
|
+
hs = model.slot_height()
|
408
420
|
if 'wire_gauge' in machine[wdgk]:
|
409
421
|
aw = machine[wdgk]['wire_gauge']
|
410
422
|
elif 'dia_wire' in machine[wdgk]:
|
@@ -412,10 +424,10 @@ def dqparident(workdir, engine, temp, machine,
|
|
412
424
|
elif ('wire_width' in machine[wdgk]) and ('wire_height' in machine[wdgk]):
|
413
425
|
aw = machine[wdgk]['wire_width']*machine[wdgk]['wire_height']
|
414
426
|
else: # wire diameter from slot area
|
415
|
-
|
427
|
+
Q1 = wdg.Q
|
416
428
|
aw = 0.75 * fcu * np.pi*da1*hs/Q1/wdg.l/N
|
417
|
-
r1 = wdg_resistance(wdg, N, g, aw, da1, hs, lfe)
|
418
|
-
except (NameError, KeyError):
|
429
|
+
r1 = float(wdg_resistance(wdg, N, g, aw, da1, hs, lfe))
|
430
|
+
except (NameError, KeyError) as ex:
|
419
431
|
r1 = 0 # cannot calc winding resistance
|
420
432
|
|
421
433
|
n = len(temp)
|
@@ -483,6 +495,10 @@ def dqparident(workdir, engine, temp, machine,
|
|
483
495
|
speed=kwargs.get('speed', defspeed),
|
484
496
|
period_frac=period_frac)
|
485
497
|
|
498
|
+
if kwargs.get("feloss", 0):
|
499
|
+
simulation["feloss"] = kwargs["feloss"]
|
500
|
+
machine["calc_fe_loss"] = loss_models[kwargs["feloss"].lower()]
|
501
|
+
|
486
502
|
# TODO: cleanup() # remove previously created files in workdir
|
487
503
|
# start calculation
|
488
504
|
results = parvar(parvardef, machine, simulation, engine)
|
@@ -490,7 +506,6 @@ def dqparident(workdir, engine, temp, machine,
|
|
490
506
|
if 'poles' not in machine: # dxf model?
|
491
507
|
machine['poles'] = 2*results['f'][0]['machine']['p']
|
492
508
|
da1 = 2*results['f'][0]['machine']['fc_radius']
|
493
|
-
wdg = create_wdg(machine)
|
494
509
|
if 'bore_diam' in machine:
|
495
510
|
da1 = machine['bore_diam']
|
496
511
|
ls1 = 0
|
@@ -506,6 +521,14 @@ def dqparident(workdir, engine, temp, machine,
|
|
506
521
|
except KeyError:
|
507
522
|
rotor_mass = 0 # need femag classic > rel-9.3.x-48-gca42bbd0
|
508
523
|
|
524
|
+
if rotor_mass == 0:
|
525
|
+
try:
|
526
|
+
nc = parvar.femag.read_nc()
|
527
|
+
rotor_mass = float(sum(nc.get_mass()[1].values()))
|
528
|
+
logger.info("rotor mass from nc-file: %.1f kg", rotor_mass)
|
529
|
+
except StopIteration:
|
530
|
+
logger.warning("Could not read nc-file. Setting rotor_mass = 0!")
|
531
|
+
|
509
532
|
dq = []
|
510
533
|
if dqtype == 'ldq':
|
511
534
|
for i in range(0, len(results['f']), 2):
|
@@ -585,7 +608,7 @@ def dqparident(workdir, engine, temp, machine,
|
|
585
608
|
# diameter of wires
|
586
609
|
aw = fcu*asl/Q1/nlayers/N
|
587
610
|
hs = asl/(np.pi*da1/3)
|
588
|
-
dqpars['r1'] = wdg_resistance(wdg, N, g, aw, da1, hs, lfe)
|
611
|
+
dqpars['r1'] = float(wdg_resistance(wdg, N, g, aw, da1, hs, lfe))
|
589
612
|
|
590
613
|
if 'current_angles' in results['f'][0]:
|
591
614
|
dqpars['current_angles'] = results['f'][0]['current_angles']
|
femagtools/multiproc.py
CHANGED
@@ -235,6 +235,12 @@ class Engine:
|
|
235
235
|
self.pool = None # garbage collector deletes threads
|
236
236
|
return status
|
237
237
|
|
238
|
+
def read_nc(self):
|
239
|
+
"""return a generator object of nc list"""
|
240
|
+
for t in self.job.tasks:
|
241
|
+
yield t.read_nc()
|
242
|
+
return None
|
243
|
+
|
238
244
|
def stopThreads(self):
|
239
245
|
""" stop all running treads
|
240
246
|
"""
|
femagtools/parstudy.py
CHANGED
@@ -310,7 +310,7 @@ class ParameterStudy(object):
|
|
310
310
|
set_magnet_properties(model, fea, self.femag.magnets)
|
311
311
|
task.add_file(
|
312
312
|
'femag.fsl',
|
313
|
-
builder.create_model(model, self.femag.magnets) if not data_model_created else [] +
|
313
|
+
(builder.create_model(model, self.femag.magnets) if not data_model_created else []) +
|
314
314
|
builder.create_analysis(fea) +
|
315
315
|
['save_model("close")'],
|
316
316
|
append=data_model_created # model already created, append fsl
|
@@ -6,8 +6,7 @@ muer = 1
|
|
6
6
|
rel = 100
|
7
7
|
cur = {1, 0}
|
8
8
|
sigma1, sigma2 = get_dev_data( "cond_conduct" )
|
9
|
-
|
10
|
-
rotorbar = def_new_bar(xcoil,ycoil, "green", "U", cur[1],cur[2], "wi", -- xcoil and ycoil defined in rotor_winding_ks2.mako
|
9
|
+
rotorbar = def_new_bar(xb,yb, "green", "U", cur[1],cur[2], "wi",
|
11
10
|
sigma2, muer, rel, "polar", 0, 0)
|
12
11
|
Abar = get_sreg_data("area",rotorbar)
|
13
12
|
|
@@ -19,7 +19,6 @@ if not airgap_created then
|
|
19
19
|
end
|
20
20
|
x1, y1 = pr2c(r1, alfa)
|
21
21
|
n = math.floor(m.fc_radius*alfa/agndst + 1.5)
|
22
|
-
n = n/10 -- Otherwise stacking mesh error TODO find a better formula
|
23
22
|
nc_circle_m(r1, 0, x1, y1, 0.0, 0.0, n)
|
24
23
|
if(m.npols_gen == m.num_poles) then
|
25
24
|
nc_circle_m(x1, y1, r1, 0, 0.0, 0.0, n)
|
@@ -90,6 +90,7 @@ end
|
|
90
90
|
if nrot == nil then
|
91
91
|
nrot = nodes
|
92
92
|
end
|
93
|
+
nrot=1 -- otherwise too long and only 1 is needed to have results
|
93
94
|
curvec = {${','.join([str(x) for x in model['curvec']])}} -- A rms
|
94
95
|
|
95
96
|
print("\nNo load flux simulation (DC) with rotation\n")
|
@@ -106,13 +107,9 @@ rotate({
|
|
106
107
|
})
|
107
108
|
|
108
109
|
file_psi = io.open("psi-rot-mag.dat","w")
|
109
|
-
value={}
|
110
|
-
temp={}
|
111
110
|
for n=1,nrot+1 do
|
112
111
|
|
113
112
|
pos, bag = calc_field(phi, curvec, file_psi)
|
114
|
-
value[n]=#pos
|
115
|
-
temp[n]=pos
|
116
113
|
bags[n] = bag
|
117
114
|
phi = n*dphi
|
118
115
|
rotate({angle=phi, mode="absolute"})
|
@@ -120,40 +117,16 @@ end
|
|
120
117
|
rotate({mode = "reset"}) -- restore the initial state (discard any changes)
|
121
118
|
file_psi:close()
|
122
119
|
|
123
|
-
-- add otherwise nil value in bags[n][i][k]
|
124
|
-
for i=1, #value-1 do
|
125
|
-
if value[i]<value[i+1] then
|
126
|
-
num_pos=value[i]
|
127
|
-
end
|
128
|
-
end
|
129
|
-
-- end
|
130
|
-
|
131
|
-
--for i=1, #curvec do
|
132
|
-
-- bagfile = string.format("noloadbag-%d.dat", i)
|
133
|
-
-- file_bag = io.open(bagfile,"w")
|
134
|
-
-- for k = 1, num_pos do --#pos do -- add otherwise nil value in bags[n][i][k]
|
135
|
-
-- file_bag:write(string.format("%g ", pos[k]))
|
136
|
-
-- for n=1, nrot+1 do
|
137
|
-
-- file_bag:write(string.format("%g ",
|
138
|
-
-- bags[n][i][k])) -- Br, rotpos, cur, pos
|
139
|
-
-- end
|
140
|
-
-- file_bag:write("\n")
|
141
|
-
-- end
|
142
|
-
-- file_bag:close()
|
143
|
-
--end
|
144
|
-
|
145
|
-
-- add otherwise nil value in bags[n][i][k]
|
146
120
|
for i=1, #curvec do
|
147
121
|
bagfile = string.format("noloadbag-%d.dat", i)
|
148
122
|
file_bag = io.open(bagfile,"w")
|
149
|
-
for
|
150
|
-
|
151
|
-
|
152
|
-
file_bag:write(string.format("%g ", pos[k]))
|
123
|
+
for k = 1, #pos do
|
124
|
+
file_bag:write(string.format("%g ", pos[k]))
|
125
|
+
for n=1, nrot+1 do
|
153
126
|
file_bag:write(string.format("%g ",
|
154
127
|
bags[n][i][k])) -- Br, rotpos, cur, pos
|
155
128
|
end
|
156
129
|
file_bag:write("\n")
|
157
130
|
end
|
158
131
|
file_bag:close()
|
159
|
-
end
|
132
|
+
end
|
femagtools/utils.py
CHANGED
@@ -10,7 +10,10 @@ def fft(pos, y, pmod=0):
|
|
10
10
|
pmod: number of poles in model (ignored if 0)
|
11
11
|
"""
|
12
12
|
model_angle = pos[-1] - pos[0]
|
13
|
-
|
13
|
+
if 360/model_angle < 1:
|
14
|
+
ntiles=1
|
15
|
+
else:
|
16
|
+
ntiles = int(round(360/model_angle))
|
14
17
|
|
15
18
|
if pmod:
|
16
19
|
negative_periodic = pmod % 2
|
@@ -51,6 +54,7 @@ def fft(pos, y, pmod=0):
|
|
51
54
|
alfa0 = np.angle(Y[i])
|
52
55
|
alfa = np.angle(Y[:nmax])
|
53
56
|
|
57
|
+
|
54
58
|
return {'a': a, 'a0': a0, 'T0': T0, 'alfa0': alfa0,
|
55
59
|
'alfa': alfa,
|
56
60
|
'nue': (2*np.abs(Y[:nmax])/N).tolist(),
|
@@ -1,14 +1,42 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: femagtools
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.14
|
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
|
-
License
|
6
|
+
License: Copyright (c) 2016-2023, Semafor Informatik & Energie AG, Basel
|
7
|
+
Copyright (c) 2023-2024, Gamma Technology LLC
|
8
|
+
All rights reserved.
|
9
|
+
|
10
|
+
Redistribution and use in source and binary forms, with or without
|
11
|
+
modification, are permitted provided that the following conditions
|
12
|
+
are met:
|
13
|
+
|
14
|
+
Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
|
17
|
+
Redistributions in binary form must reproduce the above copyright notice,
|
18
|
+
this list of conditions and the following disclaimer in the documentation
|
19
|
+
and/or other materials provided with the distribution.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
23
|
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
24
|
+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
25
|
+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
26
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
27
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
30
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
31
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
32
|
+
|
7
33
|
Classifier: Programming Language :: Python :: 3
|
8
34
|
Classifier: Intended Audience :: Science/Research
|
35
|
+
Classifier: License :: OSI Approved :: BSD License
|
9
36
|
Classifier: Topic :: Scientific/Engineering
|
10
37
|
Requires-Python: >=3.7
|
11
38
|
Description-Content-Type: text/markdown
|
39
|
+
License-File: LICENSE
|
12
40
|
Requires-Dist: numpy
|
13
41
|
Requires-Dist: scipy
|
14
42
|
Requires-Dist: mako
|
@@ -36,6 +64,7 @@ Provides-Extra: test
|
|
36
64
|
Requires-Dist: pytest; extra == "test"
|
37
65
|
Provides-Extra: all
|
38
66
|
Requires-Dist: femagtools[dxfsl,meshio,mplot,svgfsl,test,vtk,zmq]; extra == "all"
|
67
|
+
Dynamic: license-file
|
39
68
|
|
40
69
|
|
41
70
|
# Introduction to Femagtools
|