<jupyter_start><jupyter_text>Parameter Variation and OptimizationCreate a machine with 4 poles:<jupyter_code>machine = dict(
    name="PM-4-130",
    lfe=0.1,
    poles=4,
    outer_diam=0.13,
    bore_diam=0.07,
    inner_diam=0.015,
    airgap=0.0015,
     
    stator=dict(
        num_slots=12,
        rlength=1.0,
        statorRotor3=dict(
            slot_height=0.02,
            slot_h1=0.002,
            slot_h2=0.004,
            slot_r1=0.0,
            slot_r2=0.0,
            wedge_width1=0.0,
            wedge_width2=0.0,
            middle_line=0,
            tooth_width=0.009,
            slot_top_sh=0,
            slot_width=0.003)
    ),

    magnet=dict(
        magnetSector=dict(
            magn_num=1,
            magn_width_pct=0.6,
            magn_height=0.005,
            magn_shape=0.02,
            bridge_height=0,
            magn_type=2,
            condshaft_r=0.02,
            magn_ori=1,
            magn_rfe=0.0,
            bridge_width=0,
            magn_len=1)
    ),

    windings=dict(
        num_phases=3,
        num_wires=20,
        coil_span=3.0,
        num_layers=1)
)<jupyter_output><empty_output><jupyter_text>Use a pm_sym_fast calculation at a rotor speed of 5000 1/min:<jupyter_code>operatingConditions = dict(
    speed=5000.0 / 60,
    calculationMode="pm_sym_fast",
    num_move_steps=49,
    magn_temp=20.0,
    wind_temp=60,
    current=28.284,
    angl_i_up=0.0)<jupyter_output><empty_output><jupyter_text>Define the variation parameters with their ranges and number of steps:<jupyter_code>decision_vars = [
        {"steps": 5, "bounds": [3e-3, 8e-3],
         "name": "stator.statorRotor3.slot_width",
         "label": "Slot Width/m"},
        {"steps": 5, "bounds": [0.72, 0.85],
         "name": "magnet.magnetSector.magn_width_pct",
         "label": "Rel. Magnet Width"},
        {"steps": 5, "bounds": [0.024, 0.0335],
         "name": "magnet.magnetSector.magn_shape",
         "label": "Magnet Shape/m"}
    ]<jupyter_output><empty_output><jupyter_text>Define the objective parameters:<jupyter_code>objective_vars = [
        {"name": "dqPar.torque[-1]",
         "label": "Load Torque/Nm"},
        {"name": "torque[0].ripple",
         "label": "Cogging Torque/Nm"},
        {"name": "torque[-1].ripple",
         "label": "Torque Ripple/Nm"}
    ]<jupyter_output><empty_output><jupyter_text>Combine the objective and variation parameters and set the population size which is in this case the upper limit of the bucket size (ie. the number of parallel calculations):<jupyter_code>parvardef = {
    "objective_vars": objective_vars,
    "population_size": 20,
    "decision_vars": decision_vars
}<jupyter_output><empty_output><jupyter_text>Use logging to get a feedback during the calculation:<jupyter_code>import logging
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(message)s')<jupyter_output><empty_output><jupyter_text>Setup up an engine the drives the calculation. Here we chose a multi-core calculation:<jupyter_code>from femagtools.multiproc import Engine
engine = Engine()<jupyter_output><empty_output><jupyter_text>Define the working directory:<jupyter_code>import os
userdir = os.path.expanduser('~')
workdir = os.path.join(userdir, 'parvar2')
try:
    os.makedirs(workdir)
except OSError:
    pass<jupyter_output><empty_output><jupyter_text>Start the parameter variation with the total 125 FE calculations (duration on a Linux i7 laptop with 4 cores: 30min):<jupyter_code>import femagtools.grid
parvar = femagtools.grid.Grid(workdir)
results = parvar(parvardef, machine, operatingConditions, engine)<jupyter_output>2018-11-10 14:38:18,837 STEPS [5, 5, 5]
2018-11-10 14:38:18,839 Decision Vars: ['stator.statorRotor3.slot_width', 'magnet.magnetSector.magn_width_pct', 'magnet.magnetSector.magn_shape']
2018-11-10 14:38:18,841 bounds lower: (0.003, 0.72, 0.024)  upper: (0.008, 0.85, 0.0335)
2018-11-10 14:38:18,843 ........ 1 / 7
2018-11-10 14:38:18,844 Prepare: stator.statorRotor3.slot_width = 0.003
2018-11-10 14:38:18,845 Prepare: magnet.magnetSector.magn_width_pct = 0.72
2018-11-10 14:38:18,847 Prepare: magnet.magnetSector.magn_shape = 0.024
2018-11-10 14:38:18,848 prepare [0.003 0.72  0.024]
2018-11-10 14:38:18,865 use template new_model.mako
2018-11-10 14:38:18,892 use template cu_losses.mako
2018-11-10 14:38:18,906 use template statorRotor3.mako
2018-11-10 14:38:18,913 use template gen_winding.mako
2018-11-10 14:38:18,925 use template magnetSector.mako
2018-11-10 14:38:18,926 use template cu_losses.mako
2018-11-10 14:38:18,936 use template pm_sym_fast.mako
2018-11-10 14:38:18,947 use template plot[...]<jupyter_text>Print the results in table form:<jupyter_code>import numpy as np
x = femagtools.grid.create_parameter_range(results['x'])
f = np.reshape(results['f'], (np.shape(results['f'])[0], np.shape(x)[0]))

# print header
print(' '.join(['{:15}'.format(s)
                for s in [d['label']
                          for d in parvardef['decision_vars']] +
                [o['label']
                 for o in parvardef['objective_vars']]]))
print()
# print values in table format
for l in np.hstack((x, f.T)):
    print(' '.join(['{:15.4f}'.format(x) for x in l]))<jupyter_output>Slot Width/m    Rel. Magnet Width Magnet Shape/m  Load Torque/Nm  Cogging Torque/Nm Torque Ripple/Nm

         0.0030          0.7200          0.0240         13.8000          0.0664          0.4070
         0.0043          0.7200          0.0240         13.6000          0.1467          0.5060
         0.0055          0.7200          0.0240         13.4000          0.2798          0.6300
         0.0067          0.7200          0.0240         13.2000          0.4200          0.8020
         0.0080          0.7200          0.0240         12.9000          0.5493          1.0030
         0.0030          0.7525          0.0240         13.9000          0.0811          0.2010
         0.0043          0.7525          0.0240         13.8000          0.1113          0.2670
         0.0055          0.7525          0.0240         13.6000          0.1317          0.3500
         0.0067          0.7525          0.0240         13.3000          0.1561          0.4240
         0.0080          0.7525   [...]<jupyter_text>The next step will be the creation of the pareto sets. Before doing that we must define the optimization criteria. We want all values be minimize with the exception of the torque:<jupyter_code>parvardef['objective_vars'][0]['sign']=-1<jupyter_output><empty_output><jupyter_text>Now we are ready to create the pareto sets:<jupyter_code>import femagtools.moproblem
import femagtools.moo

size = np.shape(f)[1]
prob = femagtools.moproblem.FemagMoProblem(parvardef['decision_vars'],
                                           parvardef['objective_vars'])

pop = femagtools.moo.Population(prob, size)
signs = [o.get('sign', 1)
         for o in parvardef['objective_vars']]
pop.populate(x, f, signs)
                               
px = pop.get_ranked_decisions()
po = pop.get_ranked_objectives(signs)
#
fp = dict()
xp = dict()
for k in po:
    #print("k {} len {}".format(k, len(pareto[k])))
    fp[k] = np.array(po[k]).T
    xp[k] = np.array(px[k]).T

for k in xp:
    xp[k] = [xp[k][0]*1e3, xp[k][1], xp[k][2]*1e3]<jupyter_output>2018-11-10 15:09:05,411 Decision Vars: ['stator.statorRotor3.slot_width', 'magnet.magnetSector.magn_width_pct', 'magnet.magnetSector.magn_shape']
2018-11-10 15:09:05,413 bounds lower: (0.003, 0.72, 0.024)  upper: (0.008, 0.85, 0.0335)<jupyter_text>Show the results of the pareto front<jupyter_code>np.concatenate((np.array(xp[0]), fp[0])).T<jupyter_output><empty_output><jupyter_text>Display a 3D scatter plot with all results and the pareto front:<jupyter_code>import matplotlib.pyplot as pl
import matplotlib.colors
import matplotlib.cm
import mpl_toolkits.mplot3d as mpl

cm = pl.get_cmap('jet')
cNorm = matplotlib.colors.Normalize(vmin=0, vmax=max(fp.keys()))
scalarMap = matplotlib.cm.ScalarMappable(norm=cNorm, cmap=cm)

fig = pl.figure()
ax = fig.add_subplot(111, projection='3d')
for k in fp:
    ax.scatter(fp[k][0], fp[k][1], fp[k][2], color=scalarMap.to_rgba(k))
ax.plot(fp[0][0], fp[0][1], fp[0][2],
        color='red', linewidth=3, label='Pareto Front')
ax.set_xlabel(parvardef['objective_vars'][0]['label'])
ax.set_ylabel(parvardef['objective_vars'][1]['label'])
ax.set_zlabel(parvardef['objective_vars'][2]['label'])

pl.legend()
pl.show()
pl.plot(fp[0][0], fp[0][2], 'o')
pl.show()<jupyter_output><empty_output><jupyter_text>With multi objective optimization<jupyter_code>import femagtools.opt
import femagtools.condor

workdir = os.path.join(userdir, 'opti')
try:
    os.makedirs(workdir)
except OSError:
    pass

parvardef['population_size'] = 32

parvardef['decision_vars'][0]['desc'] = 'Slot width/mm' 
parvardef['decision_vars'][1]['desc'] = 'rel. Magn. width' 
parvardef['decision_vars'][2]['desc'] = 'Magn. Shape/mm' 
parvardef['objective_vars'][0]['desc'] = 'Load Torque/Nm' 
parvardef['objective_vars'][1]['desc'] = 'Cogging Torque/Nm' 
parvardef['objective_vars'][2]['desc'] = 'Torque Ripple/Nm' 

engine = femagtools.condor.Engine()
opt = femagtools.opt.Optimizer(workdir, magnetizingCurves=dict(), magnetMat=dict())
num_generations = 3
results = opt.optimize(num_generations, parvardef, machine, operatingConditions, engine)
pl.plot([t for t in results['f'][0] if t>0], [p for p in results['f'][2] if p>0], 'o')
pl.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1399281335869795, 'fraction_numerical': 0.09300359332065103, 'mean_word_length': 3.0388390951771234, 'pattern_counts': {'":': 21, '<': 58, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '15', 'dir': 'jupyter-structured-clean-dedup', 'id': '612670', 'license': 'BSD-2-Clause', 'n_tokens_mistral': 4005, 'n_tokens_neox': 3515, 'n_words': 678, 'path': 'notebooks/ParameterVariationAndOptimization.ipynb', 'repo_name': 'sasrigais/femagtools', 'size': '9462'}