femagtools 1.8.6__py3-none-any.whl → 1.8.7__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- femagtools/__init__.py +1 -1
- femagtools/bch.py +11 -7
- femagtools/femag.py +8 -70
- femagtools/fsl.py +6 -3
- femagtools/isa7.py +47 -3
- femagtools/losscoeffs.py +29 -3
- femagtools/machine/afpm.py +15 -6
- femagtools/mcv.py +162 -7
- femagtools/parstudy.py +3 -1
- femagtools/plot/bch.py +126 -44
- femagtools/plot/nc.py +13 -0
- femagtools/shortcircuit.py +378 -0
- femagtools/templates/psi-torq-rem-rot.mako +127 -0
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/METADATA +1 -1
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/RECORD +20 -18
- tests/test_nc.py +11 -0
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/LICENSE +0 -0
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/WHEEL +0 -0
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.6.dist-info → femagtools-1.8.7.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/bch.py
CHANGED
@@ -1057,10 +1057,11 @@ class Reader:
|
|
1057
1057
|
e.g. : idList[-450, -350, -250, -150, -50, 0]
|
1058
1058
|
idList[-500, -400, -300, -200, -100, 0, 0]
|
1059
1059
|
'''
|
1060
|
-
|
1061
|
-
if idList[-1] == 0 and len(idList) > 2 and \
|
1062
|
-
diff[-1] == 0:
|
1060
|
+
if list(idList).count(0) > 1: # femag writes duplicate id==0 values
|
1063
1061
|
idList = idList[:-1]
|
1062
|
+
diff = np.floor(np.abs(np.diff(idList)))
|
1063
|
+
if n := np.trim_zeros(np.diff(diff)).size:
|
1064
|
+
idList = idList[:-n]
|
1064
1065
|
return idList
|
1065
1066
|
|
1066
1067
|
def __read_psidq(self, content):
|
@@ -1085,8 +1086,7 @@ class Reader:
|
|
1085
1086
|
ncols = ncols-1
|
1086
1087
|
|
1087
1088
|
id = np.reshape(m[0], (-1, ncols)).T[0]
|
1088
|
-
|
1089
|
-
id = self.__removeTrailingZero(id)
|
1089
|
+
id = self.__removeTrailingZero(id)
|
1090
1090
|
nrows = len(id)
|
1091
1091
|
if nrows > 1 and id[nrows-1] < id[nrows-2]:
|
1092
1092
|
nrows = nrows-1
|
@@ -1121,8 +1121,7 @@ class Reader:
|
|
1121
1121
|
ncols = ncols-1
|
1122
1122
|
|
1123
1123
|
id = np.reshape(m[0], (-1, ncols)).T[0]
|
1124
|
-
|
1125
|
-
id = self.__removeTrailingZero(id)
|
1124
|
+
id = self.__removeTrailingZero(id)
|
1126
1125
|
nrows = len(id)
|
1127
1126
|
if nrows > 1 and id[nrows-1] < id[nrows-2]:
|
1128
1127
|
nrows = nrows-1
|
@@ -1610,6 +1609,11 @@ class Reader:
|
|
1610
1609
|
losses['staza'] = floatnan(rec[0])
|
1611
1610
|
losses['stajo'] = floatnan(rec[1])
|
1612
1611
|
losses['total'] += losses['staza']+losses['stajo']
|
1612
|
+
|
1613
|
+
elif content[i+1].split() == ['Iron', '----']:
|
1614
|
+
losses['rotfe'] = sum([floatnan(x) for x in rec])
|
1615
|
+
losses['total'] += losses['rotfe']
|
1616
|
+
|
1613
1617
|
else:
|
1614
1618
|
losses['rotfe'] = floatnan(rec[1])
|
1615
1619
|
losses['total'] += losses['rotfe']
|
femagtools/femag.py
CHANGED
@@ -61,43 +61,6 @@ def handle_process_output(filedes, outfile, log):
|
|
61
61
|
pass
|
62
62
|
|
63
63
|
|
64
|
-
def get_shortCircuit_parameters(bch, nload):
|
65
|
-
try:
|
66
|
-
if nload < 0:
|
67
|
-
nload = 0
|
68
|
-
if nload > 2:
|
69
|
-
nload = 2
|
70
|
-
if nload > 0:
|
71
|
-
dqld = bch.dqPar['ld']
|
72
|
-
dqlq = bch.dqPar['lq']
|
73
|
-
dqpsim = bch.dqPar['psim']
|
74
|
-
if len(dqld) <= nload or len(dqlq) <= nload or len(dqpsim) <= nload:
|
75
|
-
ld = dqld[-1]/bch.armatureLength
|
76
|
-
lq = dqlq[-1]/bch.armatureLength
|
77
|
-
psim = dqpsim[-1]/bch.armatureLength
|
78
|
-
else:
|
79
|
-
ld = dqld[nload-1]/bch.armatureLength
|
80
|
-
lq = dqlq[nload-1]/bch.armatureLength
|
81
|
-
psim = dqpsim[nload-1]/bch.armatureLength
|
82
|
-
else:
|
83
|
-
ld = bch.machine['ld']/bch.armatureLength
|
84
|
-
lq = bch.machine['lq']/bch.armatureLength
|
85
|
-
psim = bch.machine['psim']/bch.armatureLength
|
86
|
-
return dict(
|
87
|
-
r1=bch.machine['r1'],
|
88
|
-
ld=ld,
|
89
|
-
lq=lq,
|
90
|
-
psim=psim,
|
91
|
-
num_pol_pair=bch.machine['p'],
|
92
|
-
fc_radius=bch.machine['fc_radius'],
|
93
|
-
lfe=bch.armatureLength/1e3,
|
94
|
-
pocfilename=bch.machine['pocfile'],
|
95
|
-
num_par_wdgs=bch.machine.get('num_par_wdgs', 0),
|
96
|
-
calculationMode='shortcircuit')
|
97
|
-
except (KeyError, AttributeError, IndexError):
|
98
|
-
raise FemagError("missing pm/Rel-Sim results")
|
99
|
-
|
100
|
-
|
101
64
|
def set_magnet_properties(model, simulation, magnets):
|
102
65
|
"""set temperature adapted magnet properties"""
|
103
66
|
if not hasattr(model, 'magnet'):
|
@@ -449,7 +412,7 @@ class BaseFemag(object):
|
|
449
412
|
|
450
413
|
return list(pathlib.Path(self.workdir).glob('*.PROT'))[0].stem
|
451
414
|
|
452
|
-
def readResult(self, simulation, bch=None):
|
415
|
+
def readResult(self, machine, simulation, bch=None):
|
453
416
|
if simulation:
|
454
417
|
if simulation['calculationMode'] == "fieldcalc":
|
455
418
|
nc = self.read_nc()
|
@@ -495,38 +458,11 @@ class BaseFemag(object):
|
|
495
458
|
if simulation['calculationMode'] == 'pm_sym_fast' or \
|
496
459
|
simulation['calculationMode'] == 'torq_calc':
|
497
460
|
if simulation.get('shortCircuit', False):
|
498
|
-
|
499
|
-
simulation.update(
|
500
|
-
get_shortCircuit_parameters(bch,
|
501
|
-
simulation.get('initial', 2)))
|
502
|
-
|
503
|
-
builder = femagtools.fsl.Builder(self.templatedirs)
|
461
|
+
from .shortcircuit import shortcircuit
|
504
462
|
set_magnet_properties(self.model, simulation, self.magnets)
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
with open(os.path.join(self.workdir, fslfile), 'w') as f:
|
509
|
-
f.write('\n'.join(fslcmds))
|
510
|
-
self.run(fslfile) #, options?
|
511
|
-
bchfile = self.get_bch_file(self.modelname)
|
512
|
-
if bchfile:
|
513
|
-
bchsc = femagtools.bch.Reader()
|
514
|
-
logger.info("Read BCH {}".format(bchfile))
|
515
|
-
with io.open(bchfile, encoding='latin1',
|
516
|
-
errors='ignore') as f:
|
517
|
-
bchsc.read(f)
|
518
|
-
bch.scData = bchsc.scData
|
519
|
-
for w in bch.flux:
|
520
|
-
try:
|
521
|
-
bch.flux[w] += bchsc.flux[w]
|
522
|
-
bch.flux_fft[w] += bchsc.flux_fft[w]
|
523
|
-
except (KeyError, IndexError):
|
524
|
-
logging.debug(
|
525
|
-
"No additional flux data in sc simulation")
|
526
|
-
break
|
527
|
-
|
528
|
-
bch.torque += bchsc.torque
|
529
|
-
bch.demag += bchsc.demag
|
463
|
+
bch.scData = shortcircuit(self, machine, bch, simulation)
|
464
|
+
#bch.torque += bchsc.torque
|
465
|
+
#bch.demag += bchsc.demag
|
530
466
|
|
531
467
|
if 'airgap_induc' in simulation:
|
532
468
|
try:
|
@@ -699,8 +635,9 @@ class Femag(BaseFemag):
|
|
699
635
|
setattr(self, "dy2", machine['stator']['dy2'])
|
700
636
|
except:
|
701
637
|
pass
|
638
|
+
|
702
639
|
if simulation:
|
703
|
-
return self.readResult(simulation)
|
640
|
+
return self.readResult(machine, simulation)
|
704
641
|
|
705
642
|
return {'status': 'ok', 'message': self.modelname,
|
706
643
|
'model': self.model.props()}
|
@@ -801,6 +738,7 @@ class ZmqFemag(BaseFemag):
|
|
801
738
|
def subscribe(self, notify):
|
802
739
|
"""attaches a notify function"""
|
803
740
|
logger.info("Subscribe on '%s' port %d", self.femaghost, self.port+1)
|
741
|
+
femagtools.zmq.SubscriberTask.clear()
|
804
742
|
if self.subscriber is None:
|
805
743
|
# progress/xyplot at a configured timestep published
|
806
744
|
header = [b'progress', b'xyplot', b'license']
|
femagtools/fsl.py
CHANGED
@@ -227,7 +227,7 @@ class Builder:
|
|
227
227
|
# obsolete
|
228
228
|
th_props = [' ']
|
229
229
|
try:
|
230
|
-
logger.
|
230
|
+
logger.debug(model.magnet)
|
231
231
|
th_props = [f'rotor_density = {model["magnet"]["density"]}',
|
232
232
|
f'rotor_thcond = {model["magnet"]["thcond"]}',
|
233
233
|
f'rotor_thcap = {model["magnet"]["thcap"]}'
|
@@ -750,8 +750,11 @@ class Builder:
|
|
750
750
|
sim['eccentricity'])
|
751
751
|
|
752
752
|
if sim.get('calculationMode') == 'pm_sym_f_cur':
|
753
|
-
if 'nload_ex_cur'
|
754
|
-
sim
|
753
|
+
if sim.get('nload_ex_cur', ''): # convert obsolete key
|
754
|
+
if isinstance(sim, dict):
|
755
|
+
sim['noload_ex_cur'] = sim.pop('nload_ex_cur')
|
756
|
+
else:
|
757
|
+
sim.noload_ex_cur = sim.get('nload_ex_cur')
|
755
758
|
felosses = custom_fefunc + self.create_fe_losses(sim)
|
756
759
|
fslcalc = (displ_stator_rotor
|
757
760
|
+ self.__render(sim, sim.get('calculationMode'))
|
femagtools/isa7.py
CHANGED
@@ -1418,6 +1418,13 @@ class Element(BaseEntity):
|
|
1418
1418
|
"""return True if the element has lamination properties"""
|
1419
1419
|
return self.reluc != (1.0, 1.0) and self.mag == (0.0, 0.0)
|
1420
1420
|
|
1421
|
+
def remanence(self, temperature=20):
|
1422
|
+
"""return remanence Brx, Bry at element
|
1423
|
+
Arguments:
|
1424
|
+
temperature: (float) temperature in °C"""
|
1425
|
+
br_temp_corr = 1. + self.br_temp_coef*(temperature - 20.)
|
1426
|
+
return self.mag[0]*br_temp_corr, self.mag[1]*br_temp_corr
|
1427
|
+
|
1421
1428
|
def demagnetization(self, temperature=20):
|
1422
1429
|
"""return demagnetization Hx, Hy of this element"""
|
1423
1430
|
return self.demag_b(self.flux_density(cosys='polar'), temperature)
|
@@ -1429,9 +1436,9 @@ class Element(BaseEntity):
|
|
1429
1436
|
# assume polar coordinates of b
|
1430
1437
|
pos = np.arctan2(self.center[1], self.center[0])
|
1431
1438
|
#pos = 0 # cartesian
|
1432
|
-
|
1433
|
-
magn = np.sqrt(
|
1434
|
-
alfa = np.arctan2(
|
1439
|
+
mag = self.remanence(temperature)
|
1440
|
+
magn = np.sqrt(mag[0]**2 + mag[1]**2)
|
1441
|
+
alfa = np.arctan2(mag[1], mag[0]) - pos
|
1435
1442
|
b1, b2 = b
|
1436
1443
|
bpol = b1 * np.cos(alfa) + b2 * np.sin(alfa)
|
1437
1444
|
reluc = abs(self.reluc[0]) / (4*np.pi*1e-7 * 1000)
|
@@ -1505,6 +1512,43 @@ class SuperElement(BaseEntity):
|
|
1505
1512
|
"""return area of this superelement"""
|
1506
1513
|
return sum([e.area for e in self.elements])
|
1507
1514
|
|
1515
|
+
def get_rect_geom(self):
|
1516
|
+
"""return rectangle parameters of superelement:
|
1517
|
+
x0, y0: center coordinates
|
1518
|
+
w, h: width and height
|
1519
|
+
alpha: angle of main axis"""
|
1520
|
+
bxy = np.array([n.xy for b in self.nodechains
|
1521
|
+
for n in b.nodes[:-1]])
|
1522
|
+
# center
|
1523
|
+
cxy = np.mean(bxy, axis=0)
|
1524
|
+
# corner points: calculate angles
|
1525
|
+
b = np.vstack((bxy[-1], bxy, bxy[0]))
|
1526
|
+
a = np.arctan2(b[1:, 1]-b[:-1, 1],
|
1527
|
+
b[1:, 0]- b[:-1, 0])
|
1528
|
+
peaks = np.where(np.abs(np.diff(a)) > 1)[0]
|
1529
|
+
c = bxy[peaks]
|
1530
|
+
# width and height
|
1531
|
+
dxy = np.linalg.norm(np.vstack(
|
1532
|
+
(bxy[:-1, :] - bxy[1:, :],
|
1533
|
+
bxy[-1, :] - bxy[0, :])), axis=1)
|
1534
|
+
dc = (np.sum(dxy[peaks[0]:peaks[1]]),
|
1535
|
+
np.sum(dxy[peaks[1]:peaks[2]]),
|
1536
|
+
np.sum(dxy[peaks[2]:peaks[3]]),
|
1537
|
+
np.sum(np.hstack(
|
1538
|
+
(dxy[peaks[3]:], dxy[:peaks[0]]))))
|
1539
|
+
w = np.mean(np.sort(dc)[-2:])
|
1540
|
+
area = self.area()
|
1541
|
+
h = area/w
|
1542
|
+
# angle of main axis
|
1543
|
+
i = np.argmax(dc)
|
1544
|
+
c = np.vstack((c, c[0]))
|
1545
|
+
alpha = np.arctan2(c[i+1, 1]-c[i, 1], c[i+1, 0]-c[i, 0])
|
1546
|
+
if alpha < 0:
|
1547
|
+
alpha += np.pi
|
1548
|
+
return {'w': w, 'h': h, 'x0': cxy[0], 'y0': cxy[1],
|
1549
|
+
'area': area, 'alpha': alpha}
|
1550
|
+
|
1551
|
+
|
1508
1552
|
class SubRegion(BaseEntity):
|
1509
1553
|
def __init__(self, key, sr_type, color, name, nturns, curdir, wb_key,
|
1510
1554
|
superelements, nodechains):
|
femagtools/losscoeffs.py
CHANGED
@@ -20,6 +20,11 @@ def pfe_jordan(f, B, ch, fh, cw, fw, fb, fo, Bo):
|
|
20
20
|
def pfe_steinmetz(f, B, cw, fw, fb, fo, Bo):
|
21
21
|
return cw*(f/fo)**fw * (B/Bo)**fb
|
22
22
|
|
23
|
+
def pfe_modified_steinmetz(f, B, ch, cw, alpha, beta, fo, Bo):
|
24
|
+
return ch*(f/fo)*(B/Bo)**(alpha + B*beta) + cw*(f/fo)**2*(B/Bo)**2
|
25
|
+
|
26
|
+
def wbert(f, b, ch, cw, cx):
|
27
|
+
return (ch + cw*f)*b**2 + cx*f**0.5*b**1.5
|
23
28
|
|
24
29
|
def fitsteinmetz(f, B, losses, Bo, fo, alpha0=1.0):
|
25
30
|
"""fit coeffs of
|
@@ -56,6 +61,30 @@ def fitsteinmetz(f, B, losses, Bo, fo, alpha0=1.0):
|
|
56
61
|
fbx, y, (1.0, 1.0, 2.0))
|
57
62
|
return fitp
|
58
63
|
|
64
|
+
def fit_modified_steinmetz(f, B, losses, Bo, fo):
|
65
|
+
"""fit coeffs of modifeld steinmetz
|
66
|
+
losses(f,B)=ch*(f/fo)*(B/Bo)**(alpha + B*beta) + cw*(f/fo)**2*(B/Bo)**2
|
67
|
+
returns (ch, cw, alpha, beta)
|
68
|
+
"""
|
69
|
+
pfe = losses
|
70
|
+
z = []
|
71
|
+
for i, fx in enumerate(f):
|
72
|
+
if fx:
|
73
|
+
if isinstance(B[0], float):
|
74
|
+
z += [(fx, bx, y)
|
75
|
+
for bx, y in zip(B, pfe[i])
|
76
|
+
if y]
|
77
|
+
else:
|
78
|
+
z += [(fx, bx, y)
|
79
|
+
for bx, y in zip(B[i], pfe[i])
|
80
|
+
if y]
|
81
|
+
|
82
|
+
fbx = np.array(z).T[0:2]
|
83
|
+
y = np.array(z).T[2]
|
84
|
+
fitp, cov = so.curve_fit(lambda x, ch, cw, alpha, beta: pfe_modified_steinmetz(
|
85
|
+
x[0], x[1], ch, cw, alpha, beta, fo, Bo),
|
86
|
+
fbx, y, (1.0, 1.0, 1.0, 1.0))
|
87
|
+
return fitp
|
59
88
|
|
60
89
|
def fitjordan(f, B, losses, Bo, fo):
|
61
90
|
"""fit coeffs of
|
@@ -115,9 +144,6 @@ def fit_bertotti(f, B, losses):
|
|
115
144
|
if j > 2:
|
116
145
|
v.append(np.array((f[i0:j+i0], bb, y)).T.tolist())
|
117
146
|
|
118
|
-
def wbert(f, b, ch, cw, cx):
|
119
|
-
return (ch + cw*f)*b**2 + cx*f**0.5*b**1.5
|
120
|
-
|
121
147
|
z = np.array([b for a in v for b in a]).T
|
122
148
|
fbx = z[0:2]
|
123
149
|
y = z[2]
|
femagtools/machine/afpm.py
CHANGED
@@ -687,9 +687,9 @@ def _draw_vertical_slots(ax,
|
|
687
687
|
beta0 = np.linspace(n*taus + taus/2+alpha[0], (n+1)*taus, 5)
|
688
688
|
beta1 = np.linspace(n*taus + taus/2+alpha[1], (n+1)*taus, 5)
|
689
689
|
xr = np.concatenate((
|
690
|
-
r[0]*np.cos(beta0), r[1]*np.cos(beta1[::-1])))
|
690
|
+
r[0]*np.cos(beta0), r[1]*np.cos(beta1[::-1])))+xoff
|
691
691
|
yr = np.concatenate((
|
692
|
-
r[0]*np.sin(beta0), r[1]*np.sin(beta1[::-1])))
|
692
|
+
r[0]*np.sin(beta0), r[1]*np.sin(beta1[::-1])))+yoff
|
693
693
|
ax.fill(xr, yr, color=color[0])
|
694
694
|
|
695
695
|
|
@@ -707,7 +707,10 @@ def vertical_plot(machine, ax):
|
|
707
707
|
model_type = machine['afmtype'][0:4]
|
708
708
|
dy1 = machine['outer_diam']*1e3
|
709
709
|
dy2 = machine['inner_diam']*1e3
|
710
|
-
|
710
|
+
try:
|
711
|
+
rel_magn_width = max(machine['magnet']['afm_rotor']['rel_magn_width'])
|
712
|
+
except TypeError:
|
713
|
+
rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
|
711
714
|
Q = machine['stator']['num_slots']
|
712
715
|
slot_width = machine['stator']['afm_stator']['slot_width']*1e3
|
713
716
|
poles = machine['poles']
|
@@ -856,7 +859,10 @@ def horizontal_plot(machine, ax):
|
|
856
859
|
model_type = machine['afmtype'][0:4]
|
857
860
|
dy1 = machine['outer_diam']*1e3
|
858
861
|
dy2 = machine['inner_diam']*1e3
|
859
|
-
|
862
|
+
try:
|
863
|
+
rel_magn_width = max(machine['magnet']['afm_rotor']['rel_magn_width'])
|
864
|
+
except TypeError:
|
865
|
+
rel_magn_width = machine['magnet']['afm_rotor']['rel_magn_width']
|
860
866
|
magn_height = machine['magnet']['afm_rotor']['magn_height']*1e3
|
861
867
|
magn_yoke_height = machine['magnet']['afm_rotor']['yoke_height']*1e3
|
862
868
|
|
@@ -988,8 +994,11 @@ class AFPM:
|
|
988
994
|
|
989
995
|
machine['pole_width'] = np.pi * machine['inner_diam']/machine['poles']
|
990
996
|
machine['lfe'] = machine['outer_diam'] - machine['inner_diam']
|
991
|
-
|
992
|
-
machine['magnet']['afm_rotor']['rel_magn_width']
|
997
|
+
try:
|
998
|
+
machine['magnet']['afm_rotor']['rel_magn_width'] = max(
|
999
|
+
machine['magnet']['afm_rotor']['rel_magn_width'])
|
1000
|
+
except TypeError:
|
1001
|
+
pass
|
993
1002
|
|
994
1003
|
simulation['skew_displ'] = (simulation.get('skew_angle', 0)/180 * np.pi
|
995
1004
|
* machine['inner_diam'])
|
femagtools/mcv.py
CHANGED
@@ -298,6 +298,8 @@ class Mcv(object):
|
|
298
298
|
# {'ch': 0, 'cw': 0, 'ch_freq':0, 'cw_freq':0}
|
299
299
|
self.bertotti = {}
|
300
300
|
# {'ch': 0, 'cw': 0, 'ce':0, 'ch_freq':0, 'cw_freq':0}
|
301
|
+
self.steinmetz_modified = {}
|
302
|
+
# {'ch': 0, 'cw': 0, 'ch_freq': 1, 'b_beta_coeff': 0, 'cw_freq': 2, 'b_coeff': 2}
|
301
303
|
self.MC1_FE_SPEZ_WEIGTH = 7.65
|
302
304
|
self.MC1_FE_SAT_MAGNETIZATION = 2.15
|
303
305
|
|
@@ -359,7 +361,7 @@ class Mcv(object):
|
|
359
361
|
for k in wtrans:
|
360
362
|
if wtrans[k] in data.keys():
|
361
363
|
self.__setattr__(k, data[wtrans[k]])
|
362
|
-
for k in ('bertotti', 'jordan', 'steinmetz'):
|
364
|
+
for k in ('bertotti', 'jordan', 'steinmetz', 'steinmetz_modified'):
|
363
365
|
if k in data:
|
364
366
|
self.__setattr__(k, data[k])
|
365
367
|
self.curve = data['curve']
|
@@ -374,6 +376,13 @@ class Mcv(object):
|
|
374
376
|
# assume jordan iron loss parameters
|
375
377
|
for k in self.jordan:
|
376
378
|
self.jordan[k] = getattr(self, transl[k])
|
379
|
+
# set loss coeffs when existing
|
380
|
+
try:
|
381
|
+
for k in ('bertotti', 'jordan', 'steinmetz', 'steinmetz_modified'):
|
382
|
+
if k in data:
|
383
|
+
self.__setattr__(k, data[k])
|
384
|
+
except:
|
385
|
+
pass
|
377
386
|
return
|
378
387
|
|
379
388
|
def rtrimValueList(self, vlist):
|
@@ -489,14 +498,24 @@ class Writer(Mcv):
|
|
489
498
|
feloss: (str) iron loss method (bertotti, jordan)
|
490
499
|
"""
|
491
500
|
curve = self._prepare(fillfac, recsin)
|
501
|
+
write_losses = True
|
492
502
|
try:
|
493
503
|
if feloss.lower() == 'bertotti':
|
494
504
|
for k in self.bertotti:
|
495
505
|
setattr(self, transl[k], self.bertotti[k])
|
496
|
-
|
497
|
-
|
506
|
+
write_losses = False
|
507
|
+
elif feloss.lower() == 'jordan':
|
498
508
|
for k in self.jordan:
|
499
509
|
setattr(self, transl[k], self.jordan[k])
|
510
|
+
write_losses = False
|
511
|
+
elif feloss.lower() == 'steinmetz':
|
512
|
+
for k in self.steinmetz:
|
513
|
+
setattr(self, transl[k], self.steinmetz[k])
|
514
|
+
write_losses = False
|
515
|
+
elif feloss.lower() == 'modified steinmetz':
|
516
|
+
for k in self.steinmetz_modified:
|
517
|
+
setattr(self, transl[k], self.steinmetz_modified[k])
|
518
|
+
write_losses = False
|
500
519
|
except AttributeError as e:
|
501
520
|
logger.warning("%s", e)
|
502
521
|
pass
|
@@ -578,7 +597,7 @@ class Writer(Mcv):
|
|
578
597
|
self.writeBlock([self.mc1_angle[K], self.mc1_db2[K]])
|
579
598
|
|
580
599
|
try:
|
581
|
-
if not (self.mc1_ch_factor or self.mc1_cw_factor) and self.losses:
|
600
|
+
if not (self.mc1_ch_factor or self.mc1_cw_factor) and self.losses and write_losses:
|
582
601
|
# fit loss parameters
|
583
602
|
pfe = self.losses['pfe']
|
584
603
|
f = self.losses['f']
|
@@ -611,12 +630,24 @@ class Writer(Mcv):
|
|
611
630
|
float(self.mc1_fe_spez_weigth),
|
612
631
|
float(self.mc1_fe_sat_magnetization)])
|
613
632
|
|
633
|
+
logger.info(f"fo = {float(self.mc1_base_frequency)}")
|
634
|
+
logger.info(f"Bo = {float(self.mc1_base_induction)}")
|
635
|
+
logger.info(f"ch = {float(self.mc1_ch_factor)}")
|
636
|
+
logger.info(f"cw = {float(self.mc1_cw_factor)}")
|
637
|
+
logger.info(f"ch_freq = {float(self.mc1_ch_freq_factor)}")
|
638
|
+
logger.info(f"cw_freq = {float(self.mc1_cw_freq_factor)}")
|
639
|
+
logger.info(f"b_coeff = {float(self.mc1_induction_factor)}")
|
640
|
+
logger.info(f"fr_spez_weight = {float(self.mc1_fe_spez_weigth)}")
|
641
|
+
logger.info(f"fe_sat_magnetization = {float(self.mc1_fe_sat_magnetization)}")
|
642
|
+
|
614
643
|
if not hasattr(self, 'losses') or not self.losses:
|
615
644
|
# new variables: ce factor for bertotti losses
|
616
645
|
# b_beta_coeff for modified steinmetz
|
617
646
|
try:
|
618
647
|
self.writeBlock([float(self.mc1_ce_factor),
|
619
648
|
float(self.mc1_induction_beta_factor)])
|
649
|
+
logger.info(f"ce = {float(self.mc1_ce_factor)}")
|
650
|
+
logger.info(f"b_beta_coeff = {float(self.mc1_induction_beta_factor)}")
|
620
651
|
except:
|
621
652
|
pass
|
622
653
|
return
|
@@ -677,13 +708,18 @@ class Writer(Mcv):
|
|
677
708
|
[0.0]*(M_LOSS_INDUCT - len(pl)))
|
678
709
|
self.writeBlock(float(f))
|
679
710
|
nrec += 1
|
680
|
-
|
681
|
-
|
682
|
-
|
711
|
+
|
712
|
+
if write_losses:
|
713
|
+
for m in range(M_LOSS_FREQ - nrec):
|
714
|
+
self.writeBlock([0.0]*M_LOSS_INDUCT)
|
715
|
+
self.writeBlock(0.0)
|
683
716
|
|
684
717
|
self.writeBlock([self.losses['cw'], self.losses['cw_freq'],
|
685
718
|
self.losses['b_coeff'], self.losses['fo'],
|
686
719
|
self.losses['Bo']])
|
720
|
+
logger.info("losses_cw = %f, losses_cw_freq = %f, losses_b_coeff = %f, losses_fo = %f, losses_Bo = %f",
|
721
|
+
self.losses['cw'], self.losses['cw_freq'],
|
722
|
+
self.losses['b_coeff'], self.losses['fo'], self.losses['Bo'])
|
687
723
|
self.writeBlock([1])
|
688
724
|
logger.info('Losses n freq %d n ind %d', nfreq, nind)
|
689
725
|
except Exception as e:
|
@@ -1175,6 +1211,125 @@ class MagnetizingCurve(object):
|
|
1175
1211
|
losses['fo'] = self.mcv[m]['fo']
|
1176
1212
|
|
1177
1213
|
|
1214
|
+
class MCVconvert:
|
1215
|
+
def __init__(self, bhdata):
|
1216
|
+
self.steinmetz = dict(cw=0, cw_freq=0, b_coeff=0)
|
1217
|
+
self.jordan = dict(ch=0, ch_freq=0, cw=0, cw_freq=0, b_coeff=0)
|
1218
|
+
self.bertotti = dict(ch=0, cw=0, ce=0)
|
1219
|
+
self.steinmetz_modified = dict(ch=0, cw=0, ch_freq=1, b_beta_coeff=0, cw_freq=2, b_coeff=2)
|
1220
|
+
self.losscalc = None
|
1221
|
+
|
1222
|
+
B = []
|
1223
|
+
f = [50.0, 100.0, 200.0, 400.0, 1000.0, 2000.0]
|
1224
|
+
pfe = []
|
1225
|
+
jordan = False
|
1226
|
+
bertotti = False
|
1227
|
+
modified_steinmetz = False
|
1228
|
+
flag = False
|
1229
|
+
|
1230
|
+
if "losses" in bhdata:
|
1231
|
+
# test if any nan in data
|
1232
|
+
for i in ("B", "f"):
|
1233
|
+
if np.any(np.isnan(bhdata["losses"][i])) or \
|
1234
|
+
np.any(np.isnan(bhdata["losses"][i])):
|
1235
|
+
flag = True
|
1236
|
+
for i in bhdata["losses"]['pfe']:
|
1237
|
+
if np.any(np.isnan(i)):
|
1238
|
+
flag = True
|
1239
|
+
|
1240
|
+
if 'losses' not in bhdata or flag:
|
1241
|
+
# check steinmetz or jordan
|
1242
|
+
bhdata.update({"losses": {"pfe": [], "f":[], "B": []}})
|
1243
|
+
B = bhdata["curve"][-1]["bi"]
|
1244
|
+
if "ch" in bhdata:
|
1245
|
+
|
1246
|
+
if "ce" in bhdata:
|
1247
|
+
if bhdata['ce'] > 1e-15:
|
1248
|
+
bertotti = True
|
1249
|
+
|
1250
|
+
if bhdata["ch"] > 1e-15 and bhdata['ce'] < 1e-15:
|
1251
|
+
jordan = True
|
1252
|
+
|
1253
|
+
else:
|
1254
|
+
jordan = True
|
1255
|
+
|
1256
|
+
#if (conditions for modified steinmetz):
|
1257
|
+
# modified_steinmetz = True
|
1258
|
+
|
1259
|
+
if jordan:
|
1260
|
+
self.losscalc = 'jordan'
|
1261
|
+
logger.info("calculating based on jordan...")
|
1262
|
+
for i in f:
|
1263
|
+
pfe.append(lc.pfe_jordan(i, np.array(B), bhdata['ch'], bhdata['ch_freq'], bhdata['cw'],
|
1264
|
+
bhdata['cw_freq'], bhdata['b_coeff'], 50, 1.5))
|
1265
|
+
|
1266
|
+
elif bertotti:
|
1267
|
+
self.losscalc = 'bertotti'
|
1268
|
+
logger.info("calculating based on bertotti")
|
1269
|
+
for i in f:
|
1270
|
+
pfe.append(lc.wbert(i, np.array(B), bhdata['ch'], bhdata['cw'], bhdata['ce']))
|
1271
|
+
|
1272
|
+
elif modified_steinmetz:
|
1273
|
+
self.losscalc = 'modified steinmetz'
|
1274
|
+
logger.info("calculating based on modified steinmetz...")
|
1275
|
+
for i in f:
|
1276
|
+
pfe.append(lc.pfe_modified_steinmetz(i, np.array(B), bhdata['ch'], bhdata['cw'], bhdata['b_coeff'], bhdata['b_beta_coeff'], 1, 1))
|
1277
|
+
|
1278
|
+
else: # steinmetz
|
1279
|
+
self.losscalc = 'steinmetz'
|
1280
|
+
logger.info("calculating based on steinmetz...")
|
1281
|
+
for i in f:
|
1282
|
+
pfe.append(lc.pfe_steinmetz(i, np.array(B), bhdata['cw'],
|
1283
|
+
bhdata['cw_freq'], bhdata['b_coeff'], 50, 1.5))
|
1284
|
+
bhdata['losses']['pfe'] = pfe
|
1285
|
+
bhdata['losses']['B'] = B
|
1286
|
+
bhdata['losses']['f'] = f
|
1287
|
+
|
1288
|
+
idx = 0
|
1289
|
+
for i, j in enumerate(bhdata['losses']['f']):
|
1290
|
+
if j == 0:
|
1291
|
+
idx = i
|
1292
|
+
break
|
1293
|
+
idx = idx - 1
|
1294
|
+
z = lc.fitsteinmetz(bhdata['losses']['f'][0:idx],
|
1295
|
+
bhdata['losses']['B'],
|
1296
|
+
bhdata['losses']['pfe'][0:idx],
|
1297
|
+
1.5,
|
1298
|
+
50)
|
1299
|
+
|
1300
|
+
for i, j in enumerate(self.steinmetz):
|
1301
|
+
self.steinmetz[j] = z[i]
|
1302
|
+
self.steinmetz.update({"Bo": 1.5, "fo": 50})
|
1303
|
+
|
1304
|
+
z = lc.fitjordan(bhdata['losses']['f'][0:idx],
|
1305
|
+
bhdata['losses']['B'],
|
1306
|
+
bhdata['losses']['pfe'][0:idx],
|
1307
|
+
1.5,
|
1308
|
+
50)
|
1309
|
+
|
1310
|
+
for i, j in enumerate(self.jordan):
|
1311
|
+
self.jordan[j] = z[i]
|
1312
|
+
self.jordan.update({"Bo": 1.5, "fo": 50})
|
1313
|
+
|
1314
|
+
z = lc.fit_bertotti(bhdata['losses']['f'][0:idx],
|
1315
|
+
bhdata['losses']['B'],
|
1316
|
+
bhdata['losses']['pfe'][0:idx])
|
1317
|
+
|
1318
|
+
for i, j in enumerate(self.bertotti):
|
1319
|
+
self.bertotti[j] = z[i]
|
1320
|
+
self.bertotti.update({"Bo": 1, "fo": 1, "alpha": 2.0, "ch_freq": 1.0, "cw_freq": 2.0, "b_coeff": 2.0})
|
1321
|
+
|
1322
|
+
z = lc.fit_modified_steinmetz(bhdata['losses']['f'][0:idx],
|
1323
|
+
bhdata['losses']['B'],
|
1324
|
+
bhdata['losses']['pfe'][0:idx], 1, 1)
|
1325
|
+
|
1326
|
+
for i,j in enumerate(self.steinmetz_modified):
|
1327
|
+
self.steinmetz_modified[j] = z[i]
|
1328
|
+
self.steinmetz_modified.update({"Bo": 1, "fo": 1})
|
1329
|
+
|
1330
|
+
bhdata['losses']['pfe'] = np.transpose(bhdata['losses']['pfe']).tolist() #len(B) rows and len(f) columns
|
1331
|
+
|
1332
|
+
|
1178
1333
|
def read(filename):
|
1179
1334
|
"""read MC/MCV file and return mc dict"""
|
1180
1335
|
mcv = Reader()
|
femagtools/parstudy.py
CHANGED
@@ -6,6 +6,7 @@ import scipy as sc
|
|
6
6
|
import logging
|
7
7
|
import glob
|
8
8
|
import os
|
9
|
+
import re
|
9
10
|
import time
|
10
11
|
import shutil
|
11
12
|
import functools
|
@@ -172,7 +173,8 @@ class ParameterStudy(object):
|
|
172
173
|
else:
|
173
174
|
workdir = pathlib.Path(self.femag.workdir)
|
174
175
|
for d in workdir.glob('[0-9]*'):
|
175
|
-
|
176
|
+
if re.search(r'^\d+$', d.name):
|
177
|
+
shutil.rmtree(d)
|
176
178
|
|
177
179
|
extra_result_files = []
|
178
180
|
if simulation.get('airgap_induc', False):
|