import femagtools

"""
Explanation: Model Creation and FEMAG Invocation
There are several ways to run FEMAG with femagtools: either using an existing FSL script or
 - by using a parametrized stator and magnet model or a user specified FSL fragment
 - by using an existing I7/A7 model file
optionally in combination with one of the 7 FE simulation functions: cogg_calc, pm_rel_sim_fast, pm_sym_loss, mult_cal_fast, torq_calc, ld_lq_fast, psd_psq_fast.
End of explanation
"""


femagtools.create_fsl('PM_270_L8')

"""
Explanation: Create the FSL command by referencing a model name:
End of explanation
"""


with open('femag.fsl', 'w') as f:
    f.write('\n'.join(femagtools.create_fsl('PM_270_L8')))

"""
Explanation: This produces a list of FSL commands which can be written to a file:
End of explanation
"""


machine = {
    "name": "PM 270 L8",
    "desc": "PM Motor 270mm 8 poles VMAGN",
    "poles": 8,
    "outer_diam": 0.26924,
    "bore_diam": 0.16192,
    "inner_diam": 0.11064,
    "airgap": 0.00075,
    "lfe": 0.08356,
    "stator": {
        "num_slots": 48,
        "mcvkey_yoke": 'M270-35A',
        "statorRotor3": {
            "slot_height": 0.0335,
            "slot_h1": 0.001,
            "slot_h2": 0.0,
            "slot_width": 0.00193,
            "slot_r1": 0.0001,
            "slot_r2": 0.00282,
            "wedge_width1": 0.00295,
            "wedge_width2": 0.0,
            "middle_line": 0.0,
            "tooth_width": 0.0,
            "slot_top_sh": 0.0}
    },
    "magnet": {
        "mcvkey_yoke": 'M270-35A',
        "nodedist": 4,
        "magnetIronV": {
            "magn_angle": 145.0,
            "magn_height": 0.00648,
            "magn_width": 0.018,
            "condshaft_r": 0.05532,
            "magn_num": 1.0,
            "air_triangle": 1,
            "iron_hs": 0.0,
            "gap_ma_iron": 0.0002,
            "iron_height": 0.00261,
            "magn_rem": 1.2,
            "iron_shape": 0.0802
        }
    },
    "windings": {
        "num_phases": 3,
        "num_layers": 1,
        "num_wires": 9,
        "coil_span": 6.0,
        "cufilfact": 0.4,
        "culength": 1.4,
        "slot_indul": 0.5e-3
    }
}

"""
Explanation: Note: The explicit creation of an FSL file is often not necessary. 
The FSL commands to build a FEMAG model can be generated from parameterized stator and magnet models. This is done by setting up a dict variable that contains a general set of parameters together with the stator, magnet and winding dicts:
End of explanation
"""


import pathlib
workdir = pathlib.Path.home() / 'femag'
fslfile = workdir / 'femag.fsl'
fslfile.write_text('\n'.join(femagtools.create_fsl(machine)))
femag = femagtools.femag.Femag(workdir, magnetizingCurves='.')
femag.run(str(fslfile), options=['-g'])

"""
Explanation: Using this model description it is possible to create the FSL file by a set of pre-defined templates. To do so we first chose a working directory and set the directory of the MC/MCV files using the parameter 'magnetizingCurves':
End of explanation
"""


simulation = {
    "angl_i_up": -30.0,
    "calculationMode": "pm_sym_fast",
    "num_move_steps": 0,
    "wind_temp": 60.0,
    "magn_temp": 60.0,
    "current": 150.0,
    "speed": 50.0,
    "airgap_induc": True
}

"""
Explanation: To invoke a FE calculation an additional dict must be setup:
End of explanation
"""


import logging
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(message)s')

"""
Explanation: If we want to receive some feedback a logger would be useful:
End of explanation
"""


r = femag(machine,
          simulation, options=['-g'])

r.machine['p']

"""
Explanation: Now we can invoke FEMAG without creating an FSL file. The Femag object knows how to handle this:
End of explanation
"""


r.machine['torque']

"""
Explanation: After a calculation has finished we can examine all the BCH values which are included in the result 'r'. For example the torque:
End of explanation
"""


airgap = femag.read_airgap_induction()

"""
Explanation: If we had set the parameter 'airgap_induc' to True we can read the produced airgap values:
End of explanation
"""


import matplotlib.pylab as plt
import femagtools.plot
femagtools.plot.airgap(airgap)
plt.show()

"""
Explanation: and create a nice plot including the base harmonic:
End of explanation
"""


femagtools.plot.pmrelsim(r)
plt.show()

"""
Explanation: We can even create a graphical report of the results:
End of explanation
"""


machine['magnet'] = dict(
        mcvkey_yoke='M270-35A',
        spokefml=dict(
            magn_height=0.008,
            shaft_diam=0.01,
            slot_width=0.004,
            magn_width=0.022
        )
)

"""
Explanation: Model creation with user specific model
A user specific model is based on a FSL file that includes the necessary nodechain and material definitions. This script can then be included in the magnet dict of the machine. In the following example the file is named 'spokefml.fsl':
End of explanation
"""


fslfile = workdir / 'femag.fsl'
fslfile.write_text('\n'.join(femagtools.create_fsl(machine)))
femag.run(str(fslfile), options=['-g'])

"""
Explanation: The FSL fragment should make use of the globally defined variables as described in the femagtools documentation.
End of explanation
"""


nc = femag.read_nc()
femagtools.plot.spel(nc)

"""
Explanation: The resulting geometry can be plotted:
End of explanation
"""


