2021年3月23日 (火)

四分環の重なり判定 -1-

四分環の説明図

当初は、抵抗パターンを構成するピースの1つとして半環(上図参照)を使うつもりでいたのですが、四分環に変更しました(半環、四分環という名前はこのソフトの中で勝手に付けたものです)。変更した理由は次の通りです。

下図で、左側のトリミング・パッドの付け根(赤丸)は直角になっており、その箇所がホットスポットになる恐れが有ります。短期的には問題無くても、長期的な経年劣化の原因になるかも知れません。付け根をカーブにしたのが右側です。これにより経年劣化を抑制することが期待できます。そのカーブを表現するには、半環ではなく四分環の方が良いので四分環に変更しました。

トリミング・パッドの図

現在、四分環どうしの重なりを検出するルーチンで苦しんでいます。四分環は環を4等分したものなので、図の A ~ B に有るような4種類となります。図では A に対する A ~ B の重なり具合が示されています。同様のことを B に対する重なり、 C に対する重なり、そして D に対する重なりについて判定することになります。ウンザリです。共有できるルーチンを模索しています。

四分環どうしの重なり判定の参考図

2021年3月19日 (金)

梯子型パターンのトリミング

図1のような抵抗もラダー抵抗と呼ぶのかどうか知りませんが、ここでは梯子型と呼ぶことにします。その梯子型薄膜抵抗をトリミングした時の変化量について考察したいと思います。

薄膜抵抗の前に、個別の抵抗器を繋いだ図1の抵抗値変化を確認しておきましょう。図1の縦の抵抗で、一番左が7段目、一番右が0段目とします。7段目から順に取り外した時、 A・B 間の抵抗値の変化は表1のようになります。

A B Rtop
図1
表1:個別抵抗器の合成
Rtop=2.5Rtop=3.0Rtop=3.5
段数抵抗値変化量抵抗値変化量抵抗値変化量
36.81937.81938.819
33.2184.00133.3874.41633.5434.838
28.9544.33228.9824.40329.0074.468
24.5764.38924.5814.40024.5854.411
20.1804.39820.1814.40020.1814.418
15.7814.40015.7814.40015.7814.400
11.3814.40011.3814.40011.3814.400
6.9814.4006.9814.4006.9814.400

順次抵抗を取り外した時、初めの段から最後の段まで抵抗値変化量は同じなのが好ましいのですが、 Rtop によっては最後の1段目を取り外した時の変化量が他の段の時とは異なることが有ります。表1から分かるように、 Rtop が異なっても、7段目から2段目までは取り外した時の抵抗値変化はほぼ同じですが、最後の1段目を取り外した時は変化量が Rtop によって異なっています。表からは Rtop=3 の時、どの段数を取り外した時も同じ程度の変化量であることが分かります。

さて、薄膜抵抗でも同じことが言えるでしょうか? 薄膜抵抗のパターン図を図2、図3に示します。薄膜抵抗の場合は、7段目の位置によって違いが有るので2種類について計算しました。図中の赤丸部分のパターン幅を top幅と呼ぶことにします。

梯子型薄膜抵抗
図2
梯子型薄膜抵抗
図3

計算結果を表2、表3に示します。表2では top幅 50um の時、変化量の差が小さくなっています。また、表3では top幅 40um の時に差が小さくなっています。つまり、 top幅をそれらの値にするのが良いということになります。

表2:梯子型薄膜抵抗のトリミング変化量
top幅=40top幅=50top幅=70
段数抵抗値変化量抵抗値変化量抵抗値変化量
41.63341.15940.633
36.4745.15936.3964.76336.2984.334
32.0014.47431.9874.40831.9704.329
27.3544.64727.3524.63627.3484.621
22.3215.03322.3215.03122.325.028
17.6754.64617.6754.64517.6754.645
12.7064.96912.7064.969112.7064.969
8.5384.1688.5384.1688.5384.168

表3:梯子型薄膜抵抗のトリミング変化量
top幅=30top幅=40top幅=50
段数抵抗値変化量抵抗値変化量抵抗値変化量
41.04440.97139.922
36.0584.98635.93825.03335.8584.064
30.8745.18530.8545.08430.8415.017
26.2564.61826.2524.60226.2504.591
21.6334.62321.6324.62021.6324.618
16.6225.01116.7134.91916.6225.010
11.9444.67811.9444.76911.9444.678
8.1763.7688.1763.7688.1763.768

表2・表3では、7段目をトリミングした時の変化量が他の段数の変化量より小さくなっています。特に表3(図3に対応)は、その傾向が強く出ています。図2・図3は7段目の位置が違っています。この部分を工夫することで7段目の変化量を他の段に近付けることが出来るかも知れませが、今回は試していません。

ところで、このカテゴリーの最初の記事でも書いていますが、何十年も前に計算した時は、1つの答えが出るのに2~3時間かかっていました。それが、今回のソフトだと一瞬で答えが出るのには驚きました。 CPU が光速になったり、外部記憶装置を使わずにメモリのみで計算出来たりのお蔭です。それで、上記のような実験もお気軽に出来るのです。

2021年3月16日 (火)

まるでアセンブラ

境界要素法の実装は、本に載っているのを参考にするのですぐに終わるだろうと思っていたにも関わらず、だいぶ手こずることになりました。それは、参考にしたコードが Basic で書かれており GOTO のオンパレードで、制御構造を読み解くのが難しかったためです。その変態ぶりは下記の通りです。(行番号は一部省略)

        FOR I = 1 to N
          FOR J = 1 TO N
            IF (式) THEN 2200
            IF (式) THEN 2150
            ・・・
            GOTO 2220
2150        FOR K = 2 TO M
              IF (式) THEN 2190
              ・・・
              GOTO 2200
2190        NEXT K
2200        ・・・
2220        IF (式) THEN 2330
            ・・・
            IF (式) THEN 2370
            GOSUB 3000
            ・・・
            GOTO 2430
2330        GOSUB 3500
            ・・・
            GOTO 2430
2370        GOSUB 3500
            ・・・
2430      NEXT J
        NEXT I

これを JavaScript の for 文と if 文に置き換えるのが上手く出来ずに、バグ取りに何日も掛かってしまいました。

このコードは、まるでアセンブラです。私は、アセンブラは 680X0 を少しカジッた程度で、自分でコードを書いたことは無いのですが、あるプログラムの逆アセンブルコードを調べたことが有ります。余談ですが、 C で書いたプログラムをコンパイルしたものだと、そのアセンブラコードから元の C コードが推測出来たものです。アセンブラのコードは JMPBRA があちこちに出て来る訳ですが、上記 Basic のコードもまるでアセンブラコードを読んでいる気分になりました。当時、アセンブラコードを読むのは嫌いではなかったし、今でも(680X0 の)アセンブラは好きな言語なのですが、今回の Basic コードにはウンザリしました。

とにかく、 JavaScript に正しく移植出来、境界要素法の計算が出来るようになって一安心です。

2021年3月14日 (日)

境界要素法が計算可能になりました

境界要素法が計算可能になりました。ただし、半環には未対応です。前回の記事にも有る参考書の計算例を試したところ、表のようになりました。

全流量の比較
内側(流入)外側(流出)
参考書\(392.9\)\(-393.8\)
自作\(392.9\)\(-393.9\)

前回、答えが合わなかった原因は、やはり for ループの範囲指定の間違いでした。参考にしたコードは何十年も前の参考書に載っていた Basic のコードなのですが、 for ループは次のように記述されます。

	REM Basic
	FOR I=1 TO N

	// JavaScript
	for (i = 0; i < n; i++)

この場合、 Basic は N も実行するのに対して、 JavaScript は n を実行しません。まぁ、これは書き方の問題で、 i <= n と書けば良いことなのですが、配列のインデックスとの絡みで i < n と書きたいのです。 Basic は配列が 1 から始まり N で終わるのに対して、 JavaScript は 0 から始まり n - 1 で終わるので上記コードのような書き方をしたい訳です。この違いには気を付けていたのですが、それでも間違いを混入させてしまいました。また、 Basic の配列で H(1) とあるのを JavaScript の配列 H[0] とせずに、うっかりそのまま H[1] とした箇所も有りました。とにかく、それらを潰して行ってやっと正しい計算が出来るようになりました。半環には未対応ですけど。

参考書との答え合わせの他に次の計算も確認しました。

抵抗パターン

上図は正方形が1個、2個、3個のパターンです。当然、正解は 1, 2, 3 ですが、計算結果は図に表示している通りで、どれもおよそ 0.02 程度の誤差に収まっています。満足出来る結果だと思います。

今回のソフトで一番計算したかったのは次のパターンです。

抵抗パターン

計算結果はおよそ 7.91 となっています。個別の抵抗器を繋いで、このパターン図のような抵抗を構成したもの(*)は、補正無しの場合、およそ 5.45 となります。両者の間には 2.46 の差が有ることが分かります。個別抵抗器を繋いだものは、繋ぎ目を補正することになりますが、それでも、 2.46 の差を埋めることは難しいでしょう。まぁ、本ソフトが正しいという前提での話しですが。

(*):まずは抵抗パターン・エディタの作成(薄膜抵抗計算ソフト)参照

上図で、梯子部分に黒線が入っていますが、これはトリミングのつもりで描いたものです。梯子部分を順次削除して計算することで、トリミングでの抵抗値変化を求めることが出来るようになっています。(抵抗値変化自体は手で計算することになります)

次は、半環への対応です(四分環になるかも)。

2021年3月13日 (土)

境界要素法プログラムが少し改善

境界要素法の計算がおかしいという件ですが、調べていると、境界が複数有る場合に対応していないことが発覚しました。ただし、計算がおかしいのはこれとは別の問題です。とにかく、参考書に複数境界のコードも載っていたので、そちらを参考にして書き直しました。今まで間違っていた箇所が、書き直しによって正されることも期待しています。

参考書のその箇所には計算例も載っていたので、参考書の値と自分の計算結果を比較して、プログラムが正しく実装されているかの確認をしたのですが、答えはズレています。ただ、前回よりは多少マシになりました。

参考書の計算例は次のようなものです。

抵抗パターン

半径 \(2\) と \(10\) の2つの円で囲まれた領域が抵抗パターンになります。つまり、2つの円が境界になっています。そして、内側の円が \(100\mathrm{V}\), 外側が \(0\mathrm{V}\) という設定です(単位の \(\mathrm{V}\) はどうでも良いのですが)。参考書の計算例を表に示します。

参考書の計算例
内側(流入)外側(流出)
流量密度\(31.28\)\(-6.27\)
境界要素長\(0.785\)\(3.925\)
境界要素数\(16\)\(16\)
全流量\(392.9\)\(-393.8\)

各節点について境界要素法で出て来る値は流量密度になっています。流量密度は各節点で多少の差は有りますが、ほぼ上記表の通りです。それらに境界要素の長さを掛けて流入・流出ごとに全節点の和を取ることで、全流入量、全流出量が求まります。表に有る通り、全流入・流出量がほぼ同じ値になっていることから、この値は信憑性が高いと判断できます。なお、流出はマイナスになっており、これも納得の結果です。

上記の表から抵抗値を求めることが出来ます。 \(R=V/I\) に \(V=100\), \(I=393.4\) を代入して \(R=0.254\) となります( \(I=393.4\) は流入・流出の平均)。これは抵抗パターンが正方形のとき対辺間の抵抗値を \(1\) としたときに、上記円環の抵抗値が \(0.254\) になるということを意味しています。つまり、この値は正方形パターン何個分の抵抗であるかを表しています。

抵抗パターン

さて、書き直したプログラムですが、計算結果は参考書とは違っています。未だ何か間違っているのでしょう。ただし、まったくデタラメというわけでもなく、多少は改善されたようにも思います。各境界の節点列の開始付近と終了付近で流量が大きくズレていますが、途中の流量は参考書に近い値になっています。 for ループの範囲指定が間違っているのかも知れません。そこら辺を調べてみます。

«google でビリヤード?