femagtools 1.8.13__py3-none-any.whl → 1.8.15__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 +36 -9
- femagtools/femag.py +8 -1
- femagtools/fsl.py +31 -37
- femagtools/isa7.py +16 -0
- femagtools/job.py +9 -0
- femagtools/machine/__init__.py +7 -38
- femagtools/machine/afpm.py +12 -2
- femagtools/machine/effloss.py +7 -8
- 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/plot/wdg.py +26 -5
- 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/windings.py +32 -14
- {femagtools-1.8.13.dist-info → femagtools-1.8.15.dist-info}/METADATA +31 -2
- {femagtools-1.8.13.dist-info → femagtools-1.8.15.dist-info}/RECORD +34 -35
- {femagtools-1.8.13.dist-info → femagtools-1.8.15.dist-info}/WHEEL +1 -1
- femagtools-1.8.15.dist-info/licenses/LICENSE +26 -0
- tests/test_femag.py +1 -1
- tests/test_fsl.py +5 -5
- tests/test_windings.py +11 -0
- 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.15.dist-info}/entry_points.txt +0 -0
- {femagtools-1.8.13.dist-info → femagtools-1.8.15.dist-info}/top_level.txt +0 -0
femagtools/__init__.py
CHANGED
femagtools/bch.py
CHANGED
@@ -115,6 +115,22 @@ def losses_mapping_external_rotor(losses):
|
|
115
115
|
pass
|
116
116
|
return d
|
117
117
|
|
118
|
+
def _convert(obj):
|
119
|
+
"""make dict jsonizable"""
|
120
|
+
if isinstance(obj, dict):
|
121
|
+
return {k: _convert(v) for k, v in obj.items()}
|
122
|
+
elif isinstance(obj, (np.float32, np.float64)):
|
123
|
+
return float(obj)
|
124
|
+
elif isinstance(obj, list):
|
125
|
+
return [_convert(k) for k in obj]
|
126
|
+
elif isinstance(obj, tuple):
|
127
|
+
return tuple(_convert(k) for k in obj)
|
128
|
+
elif isinstance(obj, np.ndarray):
|
129
|
+
return obj.tolist()
|
130
|
+
elif isinstance(obj, (np.int32, np.int64)):
|
131
|
+
return int(obj)
|
132
|
+
else:
|
133
|
+
return obj
|
118
134
|
|
119
135
|
def _readSections(f):
|
120
136
|
"""return list of bch sections
|
@@ -404,6 +420,11 @@ class Reader:
|
|
404
420
|
self.windings[w[0]]['N'].append(w[2])
|
405
421
|
self.windings[w[0]]['R'].append(w[3]/1e3)
|
406
422
|
self.windings[w[0]]['PHI'].append(w[4])
|
423
|
+
# check if external rotor
|
424
|
+
if hasattr(self, "machine"):
|
425
|
+
if "fc_radius" in self.machine:
|
426
|
+
if np.mean(self.windings[1]["R"]) < self.machine["fc_radius"]:
|
427
|
+
self.external_rotor = True
|
407
428
|
|
408
429
|
def __read_winding_factors(self, content):
|
409
430
|
"read winding factors section"
|
@@ -1058,11 +1079,14 @@ class Reader:
|
|
1058
1079
|
e.g. : idList[-450, -350, -250, -150, -50, 0]
|
1059
1080
|
idList[-500, -400, -300, -200, -100, 0, 0]
|
1060
1081
|
'''
|
1061
|
-
if list(idList).count(0) > 1:
|
1082
|
+
if list(idList).count(0) > 1: # femag may write duplicate id==0 values
|
1062
1083
|
idList = idList[:-1]
|
1063
1084
|
diff = np.floor(np.abs(np.diff(idList)))
|
1064
|
-
|
1065
|
-
|
1085
|
+
maxdiff = np.max(diff)
|
1086
|
+
# also remove samples that are close
|
1087
|
+
if n := np.trim_zeros(np.diff(
|
1088
|
+
np.round(diff/maxdiff, 2))).size:
|
1089
|
+
return idList[:-n]
|
1066
1090
|
return idList
|
1067
1091
|
|
1068
1092
|
def __read_psidq(self, content):
|
@@ -1183,10 +1207,7 @@ class Reader:
|
|
1183
1207
|
m = []
|
1184
1208
|
subregs = [name.split()[-1]
|
1185
1209
|
for name in content[2].split('\t') if name][2:]
|
1186
|
-
|
1187
|
-
if 'Iron' in subregs and \
|
1188
|
-
'Rotor' in subregs:
|
1189
|
-
self.external_rotor = True
|
1210
|
+
|
1190
1211
|
logger.info("Stator Subregions: %s", subregs)
|
1191
1212
|
speed = float(content[0].split()[-1])/60.
|
1192
1213
|
logger.info('losses for speed %f', speed)
|
@@ -1396,8 +1417,8 @@ class Reader:
|
|
1396
1417
|
pass
|
1397
1418
|
|
1398
1419
|
try:
|
1399
|
-
self.dqPar['psid'] = np.cos(gamma)*emf/w1
|
1400
|
-
self.dqPar['psiq'] = -np.sin(gamma)*emf/w1
|
1420
|
+
self.dqPar['psid'] = list(np.cos(gamma)*emf/w1)
|
1421
|
+
self.dqPar['psiq'] = list(-np.sin(gamma)*emf/w1)
|
1401
1422
|
except UnboundLocalError:
|
1402
1423
|
try:
|
1403
1424
|
self.dqPar['psid'] = [self.dqPar['psim'][0]]
|
@@ -1405,6 +1426,8 @@ class Reader:
|
|
1405
1426
|
self.dqPar['i1'][-1]]
|
1406
1427
|
except KeyError:
|
1407
1428
|
pass
|
1429
|
+
|
1430
|
+
self.dqPar = _convert(self.dqPar)
|
1408
1431
|
return # end of first section
|
1409
1432
|
|
1410
1433
|
# second DQ-Parameter section
|
@@ -1476,6 +1499,7 @@ class Reader:
|
|
1476
1499
|
self.dqPar['u1'].insert(0, self.dqPar.get('up0', 0))
|
1477
1500
|
except:
|
1478
1501
|
pass
|
1502
|
+
self.dqPar = _convert(self.dqPar)
|
1479
1503
|
|
1480
1504
|
def __read_weights(self, content):
|
1481
1505
|
# Stator-Iron - Conductors - Magnets
|
@@ -1845,6 +1869,9 @@ def read(filename):
|
|
1845
1869
|
|
1846
1870
|
if __name__ == "__main__":
|
1847
1871
|
import json
|
1872
|
+
logging.basicConfig(level=logging.INFO,
|
1873
|
+
format='%(asctime)s %(message)s')
|
1874
|
+
|
1848
1875
|
if len(sys.argv) == 2:
|
1849
1876
|
filename = sys.argv[1]
|
1850
1877
|
else:
|
femagtools/femag.py
CHANGED
@@ -153,7 +153,7 @@ class BaseFemag(object):
|
|
153
153
|
dest = dir if dir else self.workdir
|
154
154
|
if isinstance(feloss, (int, float)):
|
155
155
|
try:
|
156
|
-
feloss = {1: 'jordan', 11: 'bertotti'}[int(feloss)]
|
156
|
+
feloss = {1: 'jordan', 2: "steinmetz", 10:"modified steinmetz", 11: 'bertotti'}[int(feloss)]
|
157
157
|
except KeyError:
|
158
158
|
feloss = ''
|
159
159
|
return [self.magnetizingCurves.writefile(m[0], dest,
|
@@ -188,6 +188,11 @@ class BaseFemag(object):
|
|
188
188
|
recsin = simulation.get('recsin', '')
|
189
189
|
feloss = simulation.get('calc_fe_loss', '')
|
190
190
|
self.copy_magnetizing_curves(self.model, recsin=recsin, feloss=feloss)
|
191
|
+
|
192
|
+
if feloss and \
|
193
|
+
int(feloss) in (1, 2):
|
194
|
+
simulation["calc_fe_loss"] = 1
|
195
|
+
|
191
196
|
try:
|
192
197
|
if 'wdgdef' in self.model.winding:
|
193
198
|
self.model.winding['wdgfile'] = self.create_wdg_def(
|
@@ -485,6 +490,8 @@ class BaseFemag(object):
|
|
485
490
|
|
486
491
|
if len(ops) != len(bch.losses):
|
487
492
|
magn_losses.insert(0, magn_losses[0])
|
493
|
+
|
494
|
+
magn_losses = [float(i) for i in magn_losses]
|
488
495
|
try:
|
489
496
|
for i in range(len(bch.losses)):
|
490
497
|
bch.losses[i].update({"magnetH": magn_losses[i]})
|
femagtools/fsl.py
CHANGED
@@ -287,20 +287,12 @@ class Builder:
|
|
287
287
|
if 'dxf' in rotmodel:
|
288
288
|
return mcv + ['ndt(agndst)'] + rotmodel['dxf']['fsl']
|
289
289
|
templ = 'rot_hsm'
|
290
|
-
if templ == 'rotorKs2':
|
291
|
-
if 'dxf' in rotmodel:
|
292
|
-
return mcv + ['ndt(agndst)'] + rotmodel['dxf']['fsl']
|
293
|
-
templ = 'rotorKs2'
|
294
290
|
rotmodel.update(model.rotor[templ])
|
295
291
|
return mcv + culosses + self.render_rotor(rotmodel, templ)
|
296
292
|
|
297
293
|
def create_rotor_winding(self, model):
|
298
|
-
if 'ecSimulation' in model.stator:
|
299
|
-
return self.render_rotor(model.rotor, 'rotor_winding_ks2_ecSimulation')
|
300
294
|
if hasattr(model, 'rotor') and model.rotortype() == 'EESM':
|
301
295
|
return self.render_rotor(model.rotor, 'rotor_winding')
|
302
|
-
if hasattr(model, 'rotor') and model.rotortype() == 'rotorKs2':
|
303
|
-
return self.render_rotor(model.rotor, 'rotor_winding_ks2')
|
304
296
|
return []
|
305
297
|
|
306
298
|
def prepare_magnet(self, model):
|
@@ -444,25 +436,38 @@ class Builder:
|
|
444
436
|
return self.__render(windings, 'cu_losses')
|
445
437
|
|
446
438
|
def create_fe_losses(self, model):
|
447
|
-
|
439
|
+
fe_losses = []
|
440
|
+
fe_losses_items = (
|
441
|
+
'ffactor', 'cw', 'ch', 'hyscoef',
|
442
|
+
'edycof', 'indcof', 'fillfact',
|
443
|
+
'fillfac', 'basfreq', 'basind',
|
444
|
+
'ffactor')
|
445
|
+
|
446
|
+
part = 'stator'
|
447
|
+
if model.get(part, 0):
|
448
|
+
submod = model.get(part)
|
449
|
+
if any([submod.get(k, 0) for k in fe_losses_items]):
|
450
|
+
if submod.get('fillfac', 0):
|
451
|
+
submod['fillfact'] = submod['fillfac']
|
452
|
+
fe_losses += self.__render(submod, 'FE-losses')
|
453
|
+
fe_losses.append('pre_models("FE-Losses-1")')
|
454
|
+
|
455
|
+
for part in ('rotor', 'commutator', 'magnet'):
|
448
456
|
if model.get(part, 0):
|
449
457
|
submod = model.get(part)
|
450
|
-
if any(submod.get(k, 0) for k in
|
451
|
-
'ffactor', 'cw', 'ch', 'hyscoef',
|
452
|
-
'edycof', 'indcof', 'fillfact',
|
453
|
-
'fillfac','basfreq', 'basind',
|
454
|
-
'ffactor')):
|
458
|
+
if any([submod.get(k, 0) for k in fe_losses_items]):
|
455
459
|
if submod.get('fillfac', 0):
|
456
460
|
submod['fillfact'] = submod['fillfac']
|
457
|
-
|
458
|
-
|
461
|
+
fe_losses += self.__render(submod, 'FE-losses')
|
462
|
+
fe_losses.append('pre_models("FE-Losses-2")')
|
463
|
+
return fe_losses
|
459
464
|
|
460
465
|
def create_gen_winding(self, model):
|
461
466
|
try:
|
462
467
|
model.winding['wire'].update(
|
463
468
|
{"num_layers": model.winding["num_layers"]})
|
464
469
|
genwdg = self.__render(model.winding,
|
465
|
-
|
470
|
+
'gen_' + model.winding['wire'].get('name'))
|
466
471
|
except:
|
467
472
|
genwdg = self.__render(model, 'gen_winding')
|
468
473
|
|
@@ -514,11 +519,8 @@ class Builder:
|
|
514
519
|
params['nodedist'] = fmt.get('nodedist', 1)
|
515
520
|
params['full_model'] = fmt.get('full_model', False)
|
516
521
|
params['EESM'] = fmt.get('type', 'PMSM') == 'EESM'
|
517
|
-
params['rotorKs2'] = fmt.get('type', 'PMSM') == 'rotorKs2'
|
518
522
|
if params['EESM']:
|
519
523
|
model.rotor['EESM'] = {}
|
520
|
-
if params['rotorKs2']:
|
521
|
-
model.rotor['rotorKs2'] = {}
|
522
524
|
conv = convert(fname, **params)
|
523
525
|
|
524
526
|
model.set_value('poles', conv.get('num_poles'))
|
@@ -561,8 +563,6 @@ class Builder:
|
|
561
563
|
if not (hasattr(model, 'magnet') or hasattr(model, 'rotor')):
|
562
564
|
if params['EESM']:
|
563
565
|
setattr(model, 'rotor', {})
|
564
|
-
elif params['rotorKs2']:
|
565
|
-
setattr(model, 'rotor', {})
|
566
566
|
else:
|
567
567
|
setattr(model, 'magnet', {})
|
568
568
|
|
@@ -672,20 +672,14 @@ class Builder:
|
|
672
672
|
self.mesh_airgap(model) +
|
673
673
|
self.create_connect_models(model) +
|
674
674
|
self.create_rotor_winding(model))
|
675
|
-
if 'statorRing' in model.stator
|
676
|
-
return (self.create_new_model(model) +
|
677
|
-
self.create_cu_losses(windings, condMat, ignore_material) +
|
678
|
-
self.create_fe_losses(model) +
|
679
|
-
rotor +
|
680
|
-
self.create_stator_model(model) +
|
681
|
-
self.create_rotor_winding(model))
|
682
|
-
if 'ecSimulation' in model.stator:
|
675
|
+
if 'statorRing' in model.stator:
|
683
676
|
return (self.create_new_model(model) +
|
684
677
|
self.create_cu_losses(windings, condMat, ignore_material) +
|
685
678
|
self.create_fe_losses(model) +
|
686
679
|
rotor +
|
687
680
|
self.create_stator_model(model) +
|
688
681
|
self.create_rotor_winding(model))
|
682
|
+
|
689
683
|
return (self.create_new_model(model) +
|
690
684
|
self.create_cu_losses(windings, condMat, ignore_material) +
|
691
685
|
self.create_fe_losses(model) +
|
@@ -696,7 +690,6 @@ class Builder:
|
|
696
690
|
self.create_connect_models(model) +
|
697
691
|
self.create_rotor_winding(model)) + \
|
698
692
|
self.create_thermal_properties(model)
|
699
|
-
|
700
693
|
return (self.open_model(model) +
|
701
694
|
self.create_fe_losses(model) +
|
702
695
|
self.create_magnet(model, magnetMat))
|
@@ -757,6 +750,11 @@ class Builder:
|
|
757
750
|
if sim.get('airgap_induc', 0) else [])
|
758
751
|
displ_stator_rotor = self.create_displ_stator_rotor(
|
759
752
|
sim.get('eccentricity', {}))
|
753
|
+
# sliding band
|
754
|
+
sliding_band = []
|
755
|
+
if sim.get("sliding", 0):
|
756
|
+
sliding_band = [f'save_model("cont")',
|
757
|
+
f'enable_sliding()']
|
760
758
|
revert_displ = []
|
761
759
|
if displ_stator_rotor:
|
762
760
|
sim['eval_force'] = 1
|
@@ -776,6 +774,7 @@ class Builder:
|
|
776
774
|
sim.noload_ex_cur = sim.get('nload_ex_cur')
|
777
775
|
felosses = custom_fefunc + self.create_fe_losses(sim)
|
778
776
|
fslcalc = (displ_stator_rotor
|
777
|
+
+ sliding_band
|
779
778
|
+ self.__render(sim, sim.get('calculationMode'))
|
780
779
|
+ airgap_induc + revert_displ
|
781
780
|
+ ['save_model("cont")'])
|
@@ -789,12 +788,6 @@ class Builder:
|
|
789
788
|
else:
|
790
789
|
plots = []
|
791
790
|
|
792
|
-
if sim.get('calculationMode') in ('cogg_calc',
|
793
|
-
'ld_lq_fast',
|
794
|
-
'pm_sym_loss',
|
795
|
-
'torq_calc',
|
796
|
-
'psd_psq_fast'):
|
797
|
-
return felosses + fslcalc + self.__render(sim, 'plots')
|
798
791
|
return felosses + fslcalc + plots
|
799
792
|
|
800
793
|
def create_shortcircuit(self, model):
|
@@ -883,6 +876,7 @@ class Builder:
|
|
883
876
|
self.fsl_stator = True
|
884
877
|
if magnet:
|
885
878
|
self.fsl_rotor = True
|
879
|
+
|
886
880
|
return template.render_unicode(model=model).split('\n')
|
887
881
|
|
888
882
|
def render_template(self, content_template, parameters):
|
femagtools/isa7.py
CHANGED
@@ -1035,16 +1035,28 @@ class Isa7(object):
|
|
1035
1035
|
def get_mass(self):
|
1036
1036
|
""" return mass (in kg) of material conductors, iron, magnets
|
1037
1037
|
"""
|
1038
|
+
masse_rotor_yoke = 0
|
1039
|
+
section_rotor_yoke = 0
|
1038
1040
|
try:
|
1039
1041
|
return self.mass
|
1040
1042
|
except AttributeError:
|
1041
1043
|
self.mass = [{'iron': 0, 'conductors': 0, 'magnets': 0},
|
1042
1044
|
{'iron': 0, 'conductors': 0, 'magnets': 0}]
|
1043
1045
|
scf = self.scale_factor()
|
1046
|
+
for se in self.subregions:
|
1047
|
+
if se.name == 'Bar':
|
1048
|
+
r = 1 # as rotor bar is inside
|
1049
|
+
spw = self.CU_SPEZ_WEIGHT*1e3
|
1050
|
+
l = 1 #self.PS_LENGTH_CU[r]*1e-2
|
1051
|
+
slf = 1 #self.PS_FILFACTOR_CU[r]
|
1052
|
+
self.mass[r]['conductors'] += scf*se.area()*self.arm_length*spw*l*slf
|
1044
1053
|
for se in self.superelements:
|
1054
|
+
winding_detected=0
|
1055
|
+
lamination_detected=0
|
1045
1056
|
r = 0 if se.outside else 1
|
1046
1057
|
if se.subregion:
|
1047
1058
|
if se.subregion.winding:
|
1059
|
+
winding_detected=1
|
1048
1060
|
spw = self.CU_SPEZ_WEIGHT*1e3
|
1049
1061
|
l = self.PS_LENGTH_CU[r]*1e-2
|
1050
1062
|
slf = self.PS_FILFACTOR_CU[r]
|
@@ -1052,6 +1064,7 @@ class Isa7(object):
|
|
1052
1064
|
continue
|
1053
1065
|
|
1054
1066
|
if se.mcvtype or se.elements[0].is_lamination():
|
1067
|
+
lamination_detected=1
|
1055
1068
|
try:
|
1056
1069
|
spw = self.iron_loss_coefficients[se.mcvtype-1][
|
1057
1070
|
'spec_weight']*1e3 # kg/m³
|
@@ -1062,6 +1075,9 @@ class Isa7(object):
|
|
1062
1075
|
fillfact = 1
|
1063
1076
|
#logger.warning('missing iron losscoeffs using defaults')
|
1064
1077
|
m = scf*self.arm_length*se.area()*spw*fillfact
|
1078
|
+
if r == 1:
|
1079
|
+
masse_rotor_yoke += m
|
1080
|
+
section_rotor_yoke += se.area()
|
1065
1081
|
self.mass[r]['iron'] += m
|
1066
1082
|
else:
|
1067
1083
|
try:
|
femagtools/job.py
CHANGED
@@ -146,6 +146,15 @@ class Task(object):
|
|
146
146
|
result = dict(error=msg)
|
147
147
|
return result
|
148
148
|
|
149
|
+
def read_nc(self):
|
150
|
+
"read most recent NC file and return result"
|
151
|
+
basedir = pathlib.Path(self.directory)
|
152
|
+
ncfiles = sorted(basedir.glob('*.nc'))
|
153
|
+
if not ncfiles:
|
154
|
+
return None
|
155
|
+
import femagtools.nc
|
156
|
+
return femagtools.nc.read(ncfiles[-1])
|
157
|
+
|
149
158
|
def readErrorMessage(self, html=True):
|
150
159
|
errstr = ""
|
151
160
|
if html:
|
femagtools/machine/__init__.py
CHANGED
@@ -38,6 +38,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
38
38
|
opts['rotor_mass'] = rlfe*eecpars['rotor_mass']
|
39
39
|
except KeyError:
|
40
40
|
pass
|
41
|
+
|
41
42
|
if 'ldq' in eecpars or 'psidq' in eecpars: # this is a PM (or EESM)
|
42
43
|
try:
|
43
44
|
dqpars = eecpars['ldq']
|
@@ -81,7 +82,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
81
82
|
losses=losses,
|
82
83
|
id=np.array(dqp['id'])/rwdg,
|
83
84
|
iq=np.array(dqp['iq'])/rwdg,
|
84
|
-
tcu1=temp[0],
|
85
|
+
tcu1=temp[0], tmag=temp[1],
|
85
86
|
**opts)
|
86
87
|
else:
|
87
88
|
beta = dqp['beta']
|
@@ -95,7 +96,7 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
95
96
|
losses=losses,
|
96
97
|
beta=beta,
|
97
98
|
i1=i1,
|
98
|
-
tcu1=temp[0],
|
99
|
+
tcu1=temp[0], tmag=temp[1],
|
99
100
|
**opts)
|
100
101
|
return machine
|
101
102
|
|
@@ -113,40 +114,6 @@ def create_from_eecpars(temp, eecpars, lfe=1, wdg=1):
|
|
113
114
|
pars['psi'] = [psi*rwdg*rlfe for psi in pars['psi']]
|
114
115
|
pars['tcu1'] = temp[0]
|
115
116
|
pars['tcu2'] = temp[1]
|
116
|
-
|
117
|
-
pars.update(opts)
|
118
|
-
return InductionMachine(pars)
|
119
|
-
|
120
|
-
|
121
|
-
def create_from_eecpars_im(temp, eecpars, lfe=1, wdg=1):
|
122
|
-
rlfe = lfe
|
123
|
-
rwdg = wdg
|
124
|
-
|
125
|
-
eecpars_new=eecpars['opResults']
|
126
|
-
opts = {k: eecpars_new[k] for k in ('zeta1', 'gam', 'kh', 'kpfe',
|
127
|
-
'kfric_b', 'kpmag') if k in eecpars_new}
|
128
|
-
|
129
|
-
pars = copy.deepcopy(eecpars_new)
|
130
|
-
|
131
|
-
pars['r1'] = rlfe*rwdg**2*pars.get('r1', 0)
|
132
|
-
pars['lsigma1'] = rlfe*pars['lsigma1']
|
133
|
-
pars['lsigma2'] = rlfe*pars['lsigma2']
|
134
|
-
pars['psiref'] = rwdg*rlfe*pars['psiref']
|
135
|
-
pars['u1ref'] = rwdg*rlfe*pars['u1ref']
|
136
|
-
pars['r2'] = rlfe*pars['r2']
|
137
|
-
pars['fec'] = rlfe*pars['fec']
|
138
|
-
pars['fee'] = rlfe*pars['fee']
|
139
|
-
pars['im'] = [im/rwdg for im in pars['im']]
|
140
|
-
pars['psi'] = [psi*rwdg*rlfe for psi in pars['psi']]
|
141
|
-
pars['tcu1'] = temp[0]
|
142
|
-
pars['tcu2'] = temp[1]
|
143
|
-
pars['nmax'] = eecpars['op']['nmax']
|
144
|
-
pars['umax'] = eecpars['op']['umax']
|
145
|
-
#pars['u1'] = eecpars['genDesign']['u1']
|
146
|
-
pars['Tmax'] = eecpars['op']['Tmax']
|
147
|
-
pars['p'] = eecpars['genDesign']['p']
|
148
|
-
pars['m'] = eecpars['genDesign']['m']
|
149
|
-
|
150
117
|
pars.update(opts)
|
151
118
|
return InductionMachine(pars)
|
152
119
|
|
@@ -179,7 +146,8 @@ def create(bch, r1, ls, lfe=1, wdg=1):
|
|
179
146
|
if 'ex_current' in bch.machine:
|
180
147
|
raise ValueError("not yet implemented for EESM")
|
181
148
|
machine = PmRelMachinePsidq(m, p, psid, psiq, r1*rlfe*rwdg**2,
|
182
|
-
id, iq, ls*rwdg**2, losses=losses
|
149
|
+
id, iq, ls*rwdg**2, losses=losses,
|
150
|
+
tmag=bch.magnet.get('Tmag', 20))
|
183
151
|
try:
|
184
152
|
machine.rotor_mass = rlfe*np.sum(bch.weights[1])
|
185
153
|
except (IndexError, AttributeError):
|
@@ -204,7 +172,8 @@ def create(bch, r1, ls, lfe=1, wdg=1):
|
|
204
172
|
machine = PmRelMachineLdq(m, p, psid=psid, psiq=psiq,
|
205
173
|
r1=r1*rlfe*rwdg**2,
|
206
174
|
i1=i1, beta=beta, ls=ls*rwdg**2,
|
207
|
-
losses=losses
|
175
|
+
losses=losses,
|
176
|
+
tmag=bch.magnet.get('Tmag', 20))
|
208
177
|
try:
|
209
178
|
machine.rotor_mass = rlfe*np.sum(bch.weights[1])
|
210
179
|
except (IndexError, AttributeError):
|
femagtools/machine/afpm.py
CHANGED
@@ -213,6 +213,9 @@ def parident(workdir, engine, temp, machine,
|
|
213
213
|
if np.isscalar(machine['magnet'][slotmodel]['rel_magn_width']):
|
214
214
|
num_slices = kwargs.get('num_slices', 3)
|
215
215
|
rmagw = num_slices*[machine['magnet'][slotmodel]['rel_magn_width']]
|
216
|
+
elif len(machine['magnet'][slotmodel]['rel_magn_width']) == 1:
|
217
|
+
num_slices = kwargs.get('num_slices', 3)
|
218
|
+
rmagw = num_slices*machine['magnet'][slotmodel]['rel_magn_width']
|
216
219
|
else:
|
217
220
|
rmagw = machine['magnet'][slotmodel]['rel_magn_width']
|
218
221
|
num_slices = len(rmagw)
|
@@ -543,13 +546,18 @@ def process(lfe, pole_width, machine, bch):
|
|
543
546
|
nsegx = machine['magnet'].get('num_segments', 1)
|
544
547
|
if type(nsegx) == int:
|
545
548
|
nsegx = [nsegx]*len(bch)
|
549
|
+
elif len(nsegx) == 1 and len(nsegx) < len(bch):
|
550
|
+
nsegx = nsegx*len(bch)
|
551
|
+
else:
|
552
|
+
pass
|
546
553
|
for nx, b in zip(nsegx, bch):
|
547
554
|
pm = b['losses'][0]['magnet_data']
|
548
555
|
magloss = ecloss.MagnLoss(magnet_data=[pm])
|
549
556
|
ml = magloss.calc_losses_ialh2(nsegx=nx)
|
550
|
-
b[
|
557
|
+
b["losses"][-1].update({k: ml[0]})
|
551
558
|
else:
|
552
559
|
k = 'magnetJ'
|
560
|
+
|
553
561
|
if len(pole_width) > 1:
|
554
562
|
maglosses = _integrate1d(radius, scale_factor*np.array(
|
555
563
|
[b['losses'][-1][k]/lz
|
@@ -1025,7 +1033,9 @@ class AFPM:
|
|
1025
1033
|
machine['magnet'][slotmodel]['rel_magn_width'])
|
1026
1034
|
if np.isscalar(machine['magnet'][slotmodel]['rel_magn_width']):
|
1027
1035
|
rmagw = num_slices*[machine['magnet'][slotmodel]['rel_magn_width']]
|
1028
|
-
|
1036
|
+
elif len(machine['magnet'][slotmodel]['rel_magn_width']) == 1:
|
1037
|
+
rmagw = num_slices*machine['magnet'][slotmodel]['rel_magn_width']
|
1038
|
+
else:
|
1029
1039
|
rmagw = machine['magnet'][slotmodel]['rel_magn_width']
|
1030
1040
|
num_slices = len(rmagw)
|
1031
1041
|
|
femagtools/machine/effloss.py
CHANGED
@@ -262,6 +262,9 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
262
262
|
nt = []
|
263
263
|
if isinstance(m, (SynchronousMachineLdq, SynchronousMachinePsidq)):
|
264
264
|
iq, id, iex = m.iqd_torque(T[-1])
|
265
|
+
i1max = betai1(iq, id)[1]
|
266
|
+
w1type, tmax = m.w1_imax_umax(i1max, u1)
|
267
|
+
pmax = tmax*w1type/m.p
|
265
268
|
else:
|
266
269
|
iq, id = m.iqd_torque(T[-1])
|
267
270
|
|
@@ -270,12 +273,9 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
270
273
|
for nx in n:
|
271
274
|
w1 = 2*np.pi*nx*m.p
|
272
275
|
if isinstance(m, (SynchronousMachineLdq, SynchronousMachinePsidq)):
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
else:
|
277
|
-
iq, id, iex, tq = m.iqd_torque_umax(
|
278
|
-
T[-1], w1, u1)
|
276
|
+
tq = T[-1]
|
277
|
+
if tq*w1/m.p > pmax:
|
278
|
+
tq = pmax/w1*m.p
|
279
279
|
else:
|
280
280
|
iq, id, tq = m.iqd_imax_umax(i1max, w1, u1, T[-1],
|
281
281
|
with_tmech=with_tmech,
|
@@ -289,7 +289,6 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
289
289
|
raise ValueError("Speed, Torque Mesh is empty")
|
290
290
|
nsamples = len(n)
|
291
291
|
ntmesh = np.array(nt).T
|
292
|
-
|
293
292
|
logger.info("total speed,torque samples %s", ntmesh.shape)
|
294
293
|
if isinstance(m, (PmRelMachine, SynchronousMachine)):
|
295
294
|
if num_proc > 1:
|
@@ -371,7 +370,7 @@ def efficiency_losses_map(eecpars, u1, T, temp, n, npoints=(60, 40),
|
|
371
370
|
plfe1 = m.kpfe*m.iqd_plfe1(*iqd, f1)
|
372
371
|
plfe2 = m.kpfe*m.iqd_plfe2(*iqd, f1)
|
373
372
|
plmag = np.zeros_like(plfe2)
|
374
|
-
plcu1 = m.iqd_plcu1(iqd[0], iqd[1],
|
373
|
+
plcu1 = m.iqd_plcu1(iqd[0], iqd[1], f1)
|
375
374
|
try:
|
376
375
|
plcu1_dc = m.iqd_plcu1(iqd[0], iqd[1],
|
377
376
|
np.array([0.0 for i in f1])).tolist()
|