# EMSOJson(EMSolution Outout Json)

EMSOJsonとは
EMSolutionの出力ファイル(outputファイル)の中に出力される各種計算値を，JSONフォーマットの別ファイル( output.json )として作成する機能です．
EMSOJsonに対応したバージョンのEMSolutionを使えば，今までと同じようにEMSolutionを実行するだけで，このJSONフォーマットのファイルが作成されます．
説明の都合上，出力されるJSONフォーマットのファイル( output.json )を， EMSOJsonデータ 呼ぶことにします．

注釈

EMSOJsonで出力される各種計算値は，有効桁数11桁で出力されます．

JSONフォーマットは，構造的(階層的)なデータを記載するための汎用的なフォーマットです．
C++/C#/Pythonなどの各種プログラミング言語で幅広く使われています．
FirefoxやChromeなどのWebブラウザでも，プラグインを入れることで，JSONフォーマットのファイルを読み込み，階層的なデータを確認することもできます．
JSONフォーマットのファイルの読み込み方
JSONフォーマットのファイルは，各種プログラミング言語で簡単にデータを読み込むことができます．
例えば，全世界でデータ処理を行うのに幅広く使われているプログラミング言語Pythonを使ってみます．

    import json # jsonモジュールを読み込み

    fin = open("output.json", encoding="utf-8") # output.jsonファイルを指定
    js = json.load(fin) # output.jsonファイルを読み込み

たったこれだけです．これだけで，JSONフォーマットのEMSOJsonデータを読み込むことができます．
読み込んだEMSOJsonデータは，変数jsに代入されています．
変数jsの中身を調べてみましょう．

    >>> js.keys() # js辞書型変数のキーの一覧の取得
    dict_keys(['FORCE_J_B', 'HEAT', 'POWER_SOURCES', 'SOURCES'])

Pythonでは，読み込んだJSONファイルのデータを，辞書型(Dictionary型)の変数として代入します．
つまり，変数jsは辞書型の変数ということになります．
辞書型の変数は，キーと呼ばれる指示子(本マニュアルではキーではなく タグ と呼ぶことにします）を指定すると，それに応じた値を取得することができます．
値が，さらに辞書型の変数であることもあり，これによって，構造的なデータを表すことができます．
Pythonの場合，辞書型の変数に .keys()と付けることで，全てのタグを取得することができます．
上記のEMSOJsonデータでは，

- FORCE_J_B
- HEAT
- POWER_SOURCES
- SOURCES

タグのデータを持ってることになります．
但し，.keys()を付けて取得される辞書型変数のキーの一覧のデータのままでは使いにくいです．
そこで通常は，list()関数を使って，キーの一覧をリスト型にデータ変換します．

    >>> list(js.keys()) # 辞書型変数のキーの一覧をリストに変換
    ['FORCE_J_B', 'HEAT', 'POWER_SOURCES', 'SOURCES']

さらに， SOURCES タグの持つ第2タグの一覧を取得してみましょう．

    >>> sources = js["SOURCES"] # SOURCESタグのデータの取得
    >>> list(sourcs.keys()) # SOURCEタグの第2タグの一覧の取得
    ['AMPLITUDE', 'FLUX', 'VOLTAGE']

SOURCES タグは，下記に示す第2タグのデータを持っていることが分かります．

- AMPLITUDE
- FLUX
- VOLTAGE

実際の使い方
実際にEMSOJsonデータを使う場合は，前もって，必要とするデータが決まっていることが大半です．
例えば，

- 回転機のトルクの値を使いたい
- 物性番号毎のジュール損を知りたい

などです．
回転機のトルクならば，電磁力を求めれば良いので， FORCE_NODAL第1タグ を使い，ジュール損ならば， HEAT第1タグ を使うことになります．
さらに，それぞれ， FORCE や， JOULE などの第2タグも必要となります．
詳細は，マニュアルの個別の項目をご覧下さい．
3番目のタグは物性番号 を表します．物性番号は文字列として（例えば物性番号100は，文字列"100"）使って下さい．
特定のデータでは，物性番号以外に，

- TOTAL（総和）
- STATOR（固定部の総和）
- ROTOR（可動部の総和）

の第3タグも使うことができます．

    force100 = js["FORCE_NODAL"]["FORCE"]["100"] # 物性番号100の電磁力の取得
    total = js["FORCE_NODAL"]["FORCE"]["TOTAL"] # 電磁力の総和
    stator = js["FORCE_NODAL"]["FORCE"]["STATOR"] # 固定部全体の電磁力
    rotor = js["FORCE_NODAL"]["FORCE"]["ROTOR"] # 可動部全体の電磁力

ただし，

- 積分空間磁場（B_INTEGタグ）
- 閉曲面をプレート要素以外で定義した場合の鎖交磁束（MAG_FLUXタグ）

などは3番目のタグを持ちません．
これはEMSolutionの仕様に基づくものです．
取得されるデータ形式
EMSOJsonデータから，タグを使って取得されるデータは，全て 配列 となっています．
これは，取得されるデータがベクトル値であることではなく， ステップ番号ぶんのデータ であることを意味します．
つまり，静磁場計算のように1ステップの計算と，過渡計算の結果や，AC計算の結果を同じ扱いとするためです．
従って，静磁場解析の結果であっても，取得されるデータは個数1個の配列となります．

    >>> voltage1 = js["SOURCES"]["VOLTAGE"]["1"]    # ソース1の電圧の取得
    >>> voltage1
    [2.79630752556]                         # 個数1個の配列

積分空間磁場(B_INTEGタグ)や，電磁力(FORCE_NODALタグ)のように，計算値そのものがベクトル値の場合は，取得されるデータは，配列(ベクトル値)の配列となります．

    >>> force1 = js["FORCE_J_B"]["FORCE"]["1"]      # 物性番号1のローレンツ力の取得
    >>> force1
    [[3365.65502603, 2070.81716324, 0.00150366357714, 0.000613122214318, -0.000841380874604, -0.000719091229351]]
    # 6成分のベクトル(配列)の個数1個の配列(配列の配列)

プレーンテキストへの変換
「JSONフォーマットのデータが使いやすいのは分かるが，今までデータ処理に使っていたプログラムを流用したい」
などの理由で，プレーンテキストが必要となるケースもあると思います．
そのようなケースであれば，EMSOJsonデータからプレーンテキストに変換するスクリプトを作成するのも一つの手です．
全ての計算値に対応するのも可能ですが，都合上，電磁力のプレーンテキストのみ変換するPythonスクリプトを以下に示します．
プレーンテキストの出力形式をどのようにするべきかですが，暫定的に，
1行目に，総ステップ数と総ブロック数（物性番号 + ROTOR + STATOR + TOTAL）
2行目にブロックの名称（物性番号，ROTOR, STATOR, TOTAL）
3行目以降に，各ブロック毎に，計算値を1行ずつステップ数ぶんだけ出力
とすることにします．

    import json

    fin = open("output.json", encoding="utf-8")
    js = json.load(fin)
    force = js["FORCE_NODAL"]["FORCE"] # 電磁力データを取得
    IDs = list(force.keys()) # ブロック名称を取得
    nsteps = len(force[IDs[0]]) # 総ステップ数を取得
    nvecs = len(force[IDs[0]][0]) # ベクトル成分の個数を取得

    fout = open("force.txt", "w") # 出力ファイル
    fout.write("%d %d\n" % (nsteps, len(IDs))) # 1行目出力

    for ID in IDs: # 2行目出力
        fout.write(" %s" % ID)
    fout.write("\n")

    for ID in IDs: # 各ブロック毎に
        for j in range(nsteps): # 各ステップ毎に
            for k in range(nvecs): # 全てのベクトル成分
                fout.write(" %18.11e" % (force[ID][j][k]))
            fout.write("\n")
    fout.close()

上記のEMSOJsonデータは，過渡解析の計算結果であり，force[ID]で得られる計算データが，配列(ベクトル)の配列(ステップ)となっていることに注意して下さい．
j番目のステップ(0ベース)のi番目のベクトル成分(同じく0ベース)は
force[ID][j][i]
となります．
上記のPythonスクリプトを実行すると，EMSOJsonデータから抽出した電磁力のデータを，下記のようなプレーンテキストで出力することができます．

    16 7
     1 2 21 3 ROTOR STATOR TOTAL
     -4.64331688739e-05 -4.90365956827e-05  0.00000000000e+00  1.47109787048e-07 -1.39299506622e-07 -4.56748885475e-09
     -4.55550674994e-05 -4.98400075648e-05  0.00000000000e+00  1.49520022694e-07 -1.36665202498e-07 -4.56937932982e-09
    ...

上記のPythonスクリプトは，任意のMSOJsonデータに適用可能です．
他の計算値に対しても，同様のスクリプトを簡単に作成することができます．