インダクタンスを計算しよう（FEMM）

## はじめに

ゆっくりしていってね！！！

- [自己インダクタンスを理論式で計算しよう](https://qiita.com/ds54e/items/934bd2101ed4b7f6c0ec)
- [FEMMで計算しよう](https://qiita.com/ds54e/items/cdb015e4d0b6f9f91393) ← いまココ
- [FastHenryで計算しよう](https://qiita.com/ds54e/items/8640b62c32faffd34c80)
- Elmer FEM[^elmer]を使ってみよう
- Palace[^palace]で遊んでみよう（本命）

[^femm]: https://www.femm.info/wiki/HomePage
[^fasthenry]: https://www.fastfieldsolvers.com/default.asp
[^elmer]: https://www.elmerfem.org/blog/
[^palace]: https://awslabs.github.io/palace/stable/

## Finite Element Method Magnetics[^femm] とは

<table>
  <tr>
    <td>Finite Element Method Magnetics (FEMM) の紹介文を作ってください。対象読者は数値電磁界解析についてよく理解している技術者です。</td>
   </tr>
 <tr>
  
<td>
Finite Element Method Magnetics (FEMM) は、静磁場、静電場、直流伝導、ならびに時間調和磁場問題に特化した2次元および軸対称有限要素法 (FEM) ベースの解析ソフトウェアです。Windows環境で動作し、直感的なGUIと強力なスクリプト機能（Luaベース）を兼ね備えています。

FEMMは以下のような用途に適しています。

- 磁性材料や永久磁石を含む磁気回路の設計と解析  
- トランス、モータ、アクチュエータなどの電磁デバイスの性能評価  
- 電極構造や誘電体分布を伴う静電場解析  
- 直流抵抗や電流分布の評価（DC conduction）  
- 高周波磁界の損失やシールド効果の評価（時間調和解析）

無料で提供されており、教育機関や研究機関、個人による設計・評価ツールとして広く利用されています。
  </tr>
</table>

……だってばよ[^dattebayo]！！！！！！
（ChatGPTさま しゅきしゅきだいしゅき[^shuki]、ちゅっちゅっちゅ）

[^dattebayo]: [ナルトがいつも語尾につける『～だってばよ』ってどこの方言ですか？](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1179321621)
[^shuki]: [しゅきしゅきだいしゅき！！ OPムービー](https://www.nicovideo.jp/watch/sm22765434)


## 円形コイルの自己インダクタンス

円形コイルの電磁界解析を行うためのLuaスクリプトです[^lua]。

[^lua]: ChatGPTは使っていません！！天然温泉源泉100％かけ流しのオリジナルスクリプトです！！

```lua
-- File name
ROOT_DIR = ""
SIM_NAME = "circle"
FEM_FILE = ROOT_DIR .. SIM_NAME .. ".fem"

-- Problem definition
UNITS = "meters"
TYPE = "axi"
PRECISION = 1e-12
FREQ = 100e3

-- Coil
RW = 0.4e-3 -- Radius of wire
N = 1 -- Number of turns
R = 20e-3 -- Radius of coil
H = 20e-3 -- Height of coil
COPPER_CONDUCTIVITY = 56
RESOLUTION_WIRE = 20

-- Boundary condition
R_IN = H * 4 -- Radius of interior region
R_EX = R_IN / 10 -- Radius of exterior region
RESOLUTION_AIR = 100


function main()
  showconsole()
  clearconsole()
  run_magnetic_analysis()
end


function run_magnetic_analysis()
  local MAGNETIC = 0
  local CURRENT = 1
  local AUTO = 1

  -- Create a project
  newdocument(MAGNETIC)
  mi_saveas(FEM_FILE)

  mi_probdef(FREQ, UNITS, TYPE, PRECISION)
  mi_addmaterial("Air", 1, 1, 0, 0, 0)
  mi_addmaterial("Copper", 1, 1, 0, 0, COPPER_CONDUCTIVITY)
  print(format("f = %.1e Hz", FREQ))

  -- Add a current source and a coil
  mi_addcircprop("I1", 0, 1)

  add_cylindrical_coil(R, H, N, RW, 0, "I1", RESOLUTION_WIRE)
  add_region_kelvin(R_IN, R_EX, AUTO, 0)
  mi_zoomnatural()

  -- Run the simulation
  mi_modifycircprop("I1", CURRENT, 1)
  mi_analyze()

  -- Get the simulation result
  mi_loadsolution()
  mi_zoomnatural()

  -- Calculate R+L
  local current, volts = mo_getcircuitproperties("I1")
  local r = re(volts) -- Resistance
  local l = im(volts) / (2*PI*FREQ) -- Inductance
  print(format("R = %.1e Ohm, L = %.1e Henry", r, l))

  mi_saveas(FEM_FILE)
end


function add_cylindrical_coil(radius, height, n_turns, rw, z, circuit, resolution)
  local MANUAL = 0
  local mesh_size = rw / resolution
  local hu = height / n_turns
  local center = 0
  local bottom = 0
  local top = 0
  for i = 1, n_turns do
    center = z + hu/2 + hu*(i - 1)
    bottom = center - rw
    top = center + rw
    mi_addnode(radius, bottom)
    mi_addnode(radius, top)
    mi_addarc(radius, bottom, radius, top, 180, 1)
    mi_addarc(radius, top, radius, bottom, 180, 1)
    mi_addblocklabel(radius, center)
    mi_selectlabel(radius, center)
    mi_setblockprop("Copper", MANUAL, mesh_size, circuit, 0, 0, 0)
  end
end


function add_region_kelvin(rin, rex, auto, resolution)
  local PERIODIC = 4
  local MANUAL = 0
  local AUTO = 1

  mi_deleteboundprop("Periodic")
  mi_addboundprop("Periodic", 0, 0, 0, 0 , 0, 0, 0, PERIODIC)

  -- Add an interior region
  add_boundary(0, rin)
  if auto then
    add_region(0, rin, AUTO, 0)
  else
    add_region(0, rin, MANUAL, rin/resolution)
  end

  -- Add an exterior region
  add_boundary(rin + rex, rex)
  add_region(rin + rex, rex, AUTO, 0)

  mi_defineouterspace(rin + rex, rex, rin)
  mi_attachouterspace()
end

function add_boundary(center, radius)
  local bottom = center - radius
  local top = center + radius
  mi_addnode(0, bottom)
  mi_addnode(0, top)
  mi_addarc(0, bottom, 0, top, 180, 1)
  mi_addsegment(0, bottom, 0, top)
  mi_selectarcsegment(-radius, center)
  mi_setarcsegmentprop(1, "Periodic")
end

function add_region(center, radius, auto, mesh_size)
  local xl = radius / 10
  local yl = center - 0.9 * radius
  mi_addblocklabel(xl, yl)
  mi_selectlabel(xl, yl)
  mi_setblockprop("Air", auto, mesh_size, "", 0, 0, 0)
end

-- Call main function
main()
```

上記をFEMMで実行すると、以下のような自己インダクタンスと抵抗値が得られます。

$$\\begin{align}
&L = 11.1\ \mathrm{nH}
&R = 7.07\ \mathrm{m \Omega}
\\end{align}
$$

![Screenshot 2025-04-20 174135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/863735/c9701273-fb61-4cc2-b29b-1a2be193e208.png)

## 結果の比較

|手法|自己インダクタンス|(A)との差|
|---|---|---|
|(A) 円環状導線の理論式|11.3 nH|0 %|
|(B) 多角形近似（相互インダクタンスの総和）|10.4 nH|-8 %|
|(C) FEMM|11.1 nH|-2 %|

|手法|抵抗 (f=100kHz)|(C)との差|
|---|---|---|
|(A) 円環状導線の理論式|NA|NA|
|(B) 多角形近似|NA|NA|
|(C) FEMM|7.07 mΩ|0 %|


## おわりに

FEMMは、ネット上で多くの方々に使われている大人気ソフトウェア[^sample]です！！
……ってことでですね、あなたも使おうFEMM！！ ウチも、やったんだからさ[^akane]！！！

- [Testes_int’s diary](https://testes-int.hatenablog.com/entry/2025/03/04/155439)
- [@yashiro_ld](https://x.com/yashiro_ld/status/1593530065257902081)
- [@Gluenyan](https://x.com/Gluenyan/status/1856287347949891714)
- [taikikusohamu](https://zenn.dev/taiki_astro/articles/9b64d49558e176)
- [inahoi開発メモ](https://inahoi.hatenablog.com/entry/2023/06/25/140406)
- [めかラボ](https://motor-actuator.com/entry/howtouse_femm)
- [Seagull Lab](http://yossi-okamoto.net/Seagull_Lab/FEMM/index.html)

[^sample]: ※顧客満足度No.1 ※当社調べ ※サンプル数（N = 7）
[^akane]: [茜ちゃんがクソゲーを広める動画のまとめ](https://www.youtube.com/watch?v=w7BPeIq7gUE)