Exemplo n.º 1
0
        /// <summary>
        /// 誘電体のボックス装荷導波管
        /// </summary>
        /// <param name="probNo"></param>
        /// <param name="WaveguideWidth"></param>
        /// <param name="timeLoopCnt"></param>
        /// <param name="timeDelta"></param>
        /// <param name="gaussianT0"></param>
        /// <param name="gaussianTp"></param>
        /// <param name="NormalizedFreqSrc"></param>
        /// <param name="NormalizedFreq1"></param>
        /// <param name="NormalizedFreq2"></param>
        /// <param name="GraphFreqInterval"></param>
        /// <param name="WaveModeDv"></param>
        /// <param name="World"></param>
        /// <param name="FieldValId"></param>
        /// <param name="FieldLoopId"></param>
        /// <param name="FieldForceBcId"></param>
        /// <param name="FieldPortBcIdList"></param>
        /// <param name="VIdRefList"></param>
        /// <param name="Medias"></param>
        /// <param name="LoopDic"></param>
        /// <param name="EdgeDic"></param>
        /// <param name="isCadShow"></param>
        /// <param name="CadDrawerAry"></param>
        /// <param name="Camera"></param>
        /// <returns></returns>
        public static bool SetProblem(
            int probNo,
            ref double WaveguideWidth,
            ref int timeLoopCnt,
            ref double timeDelta,
            ref double gaussianT0,
            ref double gaussianTp,
            ref double NormalizedFreqSrc,
            ref double NormalizedFreq1,
            ref double NormalizedFreq2,
            ref double GraphFreqInterval,
            ref WgUtil.WaveModeDV WaveModeDv,
             ref CFieldWorld World,
            ref uint FieldValId,
            ref uint FieldLoopId,
            ref uint FieldForceBcId,
            ref IList<uint> FieldPortBcIdList,
            ref IList<uint> VIdRefList,
            ref IList<MediaInfo> Medias,
            ref Dictionary<uint, wg2d.World.Loop> LoopDic,
            ref Dictionary<uint, wg2d.World.Edge> EdgeDic,
            ref bool isCadShow,
            ref CDrawerArray CadDrawerAry,
            ref CCamera Camera
            )
        {
            WaveguideWidth = 3.0e-3 * 20 * 4;

            // 誘電体のボックス装荷導波管
            // メッシュの分割長さ
            //double meshL = WaveguideWidth * 0.05;
            //double meshL = WaveguideWidth * 0.10;
            double meshL = WaveguideWidth * 0.09;

            // 導波管不連続領域の長さ
            double inputWgLength = 1.0 * WaveguideWidth;
            double disconWgWidth = (10.0 / 20.0) * WaveguideWidth;
            double dielectricBoxWidth = (7.0 / 20.0) * WaveguideWidth;
            double dielectricBoxHeight = (6.0 / 20.0) * WaveguideWidth;
            double disconLength = (19.0 / 20.0) * WaveguideWidth;
            // 形状設定で使用する単位長さ
            double unitLen = WaveguideWidth / 20.0;
            // 励振位置
            double srcPosX = 5 * unitLen;
            // 観測点
            int port1OfsX = 5;
            int port2OfsX = 5;
            double port1PosX = srcPosX + port1OfsX * unitLen;
            double port1PosY = WaveguideWidth * 0.5;
            double port2PosX = inputWgLength * 2 + disconLength - port2OfsX * unitLen;
            double port2PosY = WaveguideWidth * 0.5;

            // 時間領域
            //double courantNumber = 0.5;
            double courantNumber = 0.5;
            //timeLoopCnt = 3000;
            timeLoopCnt = 3000;
            // 時刻刻み
            timeDelta = courantNumber * meshL / (c0 * Math.Sqrt(2.0));

            // モード計算規格化周波数(搬送波規格化周波数)
            //NormalizedFreqSrc = 2.0;
            //NormalizedFreqSrc = 1.5;
            NormalizedFreqSrc = 2.0; // 正弦波変調ガウシアンパルス

            /*
            // ガウシアンパルス
            //gaussianT0 = 30 * timeDelta;
            //gaussianT0 = 40 * timeDelta;
            gaussianT0 = 20 * timeDelta;
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0) * 4.0);
             */

            // 正弦波変調ガウシアンパルス
            // 波数
            double k0Src = NormalizedFreqSrc * pi / WaveguideWidth;
            // 波長
            double waveLengthSrc = 2.0 * pi / k0Src;
            // 周波数
            double freqSrc = c0 / waveLengthSrc;
            // 角周波数
            double omegaSrc = 2.0 * pi * freqSrc;
            // 搬送波の振動回数
            int nCycle = 5;
            //gaussianT0 = (1.0 / freqSrc) * nCycle / 2;
            //gaussianT0 = 0.5 * (1.0 / freqSrc) * nCycle / 2;
            gaussianT0 = 0.67 * (1.0 / freqSrc) * nCycle / 2;
            gaussianTp = gaussianT0 / (2.0 * Math.Sqrt(2.0 * Math.Log(2.0)));

            // 周波数領域
            NormalizedFreq1 = 1.0;
            //NormalizedFreq2 = 2.0;
            NormalizedFreq2 = 3.0;
            GraphFreqInterval = 0.2;

            // ポート数
            const int portCnt = 2;

            // 媒質リスト作成
            MediaInfo mediaVacumn = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { 1.0, 0.0, 0.0 },
                   { 0.0, 1.0, 0.0 },
                   { 0.0, 0.0, 1.0 }
                }
            );
            MediaInfo mediaDielectricBox = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { 2.62,  0.0,  0.0 },
                   {  0.0, 2.62,  0.0 },
                   {  0.0,  0.0, 2.62 }
                }
            );
            Medias.Add(mediaVacumn);
            Medias.Add(mediaDielectricBox);

            // 図面作成、メッシュ生成
            uint baseId = 0;
            CIDConvEAMshCad conv = null;
            using (CCadObj2D cad2d = new CCadObj2D())
            {
                //------------------------------------------------------------------
                // 図面作成
                //------------------------------------------------------------------
                double yOfs_cutoffWg = (WaveguideWidth - disconWgWidth) * 0.5;
                {
                    // ループ1
                    IList<CVector2D> pts = new List<CVector2D>();
                    pts.Add(new CVector2D(0.0, WaveguideWidth));  // 頂点1
                    pts.Add(new CVector2D(0.0, 0.0)); // 頂点2
                    pts.Add(new CVector2D(srcPosX, 0.0)); // 頂点3
                    pts.Add(new CVector2D(inputWgLength, 0.0)); // 頂点4
                    pts.Add(new CVector2D(inputWgLength, yOfs_cutoffWg)); // 頂点5
                    pts.Add(new CVector2D(inputWgLength + disconLength, yOfs_cutoffWg)); // 頂点6
                    pts.Add(new CVector2D(inputWgLength + disconLength, 0.0)); // 頂点7
                    pts.Add(new CVector2D(inputWgLength * 2 + disconLength, 0.0)); // 頂点8
                    pts.Add(new CVector2D(inputWgLength * 2 + disconLength, WaveguideWidth)); // 頂点9
                    pts.Add(new CVector2D(inputWgLength + disconLength, WaveguideWidth)); // 頂点10
                    pts.Add(new CVector2D(inputWgLength + disconLength, yOfs_cutoffWg + disconWgWidth)); // 頂点11
                    pts.Add(new CVector2D(inputWgLength, yOfs_cutoffWg + disconWgWidth)); // 頂点12
                    pts.Add(new CVector2D(inputWgLength, WaveguideWidth)); // 頂点13
                    pts.Add(new CVector2D(srcPosX, WaveguideWidth)); // 頂点14
                    uint lId1 = cad2d.AddPolygon(pts).id_l_add;
                    uint lId2 = cad2d.ConnectVertex_Line(3, 14).id_l_add;
                    System.Diagnostics.Debug.Assert(lId1 == 1);
                    System.Diagnostics.Debug.Assert(lId2 == 2);
                }
                {
                    // ループ2
                    // ループの親ID
                    uint parent_id_l_cad = 2;
                    IList<CVector2D> pts = new List<CVector2D>();
                    double x1_dielectricBox = inputWgLength + (disconLength - dielectricBoxWidth) * 0.5;
                    double y1_dielectricBox = yOfs_cutoffWg + (disconWgWidth - dielectricBoxHeight) * 0.5;
                    pts.Add(new CVector2D(x1_dielectricBox, y1_dielectricBox + dielectricBoxHeight)); // 頂点15
                    pts.Add(new CVector2D(x1_dielectricBox, y1_dielectricBox)); // 頂点16
                    pts.Add(new CVector2D(x1_dielectricBox + dielectricBoxWidth, y1_dielectricBox)); // 頂点17
                    pts.Add(new CVector2D(x1_dielectricBox + dielectricBoxWidth, y1_dielectricBox + dielectricBoxHeight)); // 頂点18
                    uint id_l_add_cad = cad2d.AddPolygon(pts, parent_id_l_cad).id_l_add;
                    System.Diagnostics.Debug.Assert(id_l_add_cad == 3);
                }
                {
                    uint parent_id_l_cad = 2;
                    // 観測点
                    cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port1PosX, port1PosY)); // 頂点19
                    cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port2PosX, port2PosY)); // 頂点20
                 }

                //isCadShow = true;
                // 図面表示
                if (isCadShow)
                {
                    CadDrawerAry.Clear();
                    CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                    CadDrawerAry.InitTrans(Camera);
                    return true;
                }

                /*
                 // 図面表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                CadDrawerAry.InitTrans(Camera);
                 */

                /*
                // メッシュ表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawerMsh2D(new CMesher2D(cad2d, meshL)));
                CadDrawerAry.InitTrans(Camera);
                */

                //------------------------------------------------------------------
                // メッシュ作成
                //------------------------------------------------------------------
                // メッシュを作成し、ワールド座標系にセットする
                World.Clear();
                using (CMesher2D mesher2d = new CMesher2D(cad2d, meshL))
                {
                    baseId = World.AddMesh(mesher2d);
                    conv = World.GetIDConverter(baseId);
                }
            }
            // 界の値を扱うバッファ?を生成する。
            // フィールド値IDが返却される。
            //    要素の次元: 2次元 界: 複素数スカラー 微分タイプ: 値 要素セグメント: 角節点
            FieldValId = World.MakeField_FieldElemDim(baseId, 2,
                FIELD_TYPE.ZSCALAR, FIELD_DERIVATION_TYPE.VALUE, ELSEG_TYPE.CORNER);

            // 領域
            //   ワールド座標系のループIDを取得
            //   媒質をループ単位で指定する
            FieldLoopId = 0;
            {
                // ワールド座標系のループIDを取得
                uint[] loopId_cad_list  = {1, 2, 3};
                int[] mediaIndex_list = new int[loopId_cad_list.Length];
                mediaIndex_list[0] = Medias.IndexOf(mediaVacumn);
                mediaIndex_list[1] = Medias.IndexOf(mediaVacumn);
                mediaIndex_list[2] = Medias.IndexOf(mediaDielectricBox);

                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    uint loopId_cad = loopId_cad_list[i];
                    int mediaIndex = mediaIndex_list[i];
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                    {
                        wg2d.World.Loop loop = new wg2d.World.Loop();
                        loop.Set(lId1, mediaIndex);
                        LoopDic.Add(lId1, loop);
                    }
                }
                //System.Diagnostics.Debug.WriteLine("lId:" + lId1);
                FieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
            }

            // 境界条件を設定する
            //   固定境界条件(強制境界)
            //   ワールド座標系の辺IDを取得
            //   媒質は指定しない
            FieldForceBcId = 0;
            {
                uint[] eId_cad_list = {2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14};
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                }
                // フィールドIDを取得
                FieldForceBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldForceBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
            }
            // 開口条件
            //   ワールド座標系の辺IDを取得
            //   辺単位で媒質を指定する
            FieldPortBcIdList.Clear();
            uint[] eId_cad_port = { 1, 8, 15 };
            for (int portIndex = 0; portIndex < (portCnt + 1); portIndex++) // ポート + 励振境界
            {
                uint eId_cad = eId_cad_port[portIndex];
                uint eId;
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                aEA.Add(eId);
                {
                    wg2d.World.Edge edge = new wg2d.World.Edge();
                    edge.Set(eId, Medias.IndexOf(mediaVacumn));
                    EdgeDic.Add(eId, edge);
                }
                uint workFieldPortBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldPortBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
                FieldPortBcIdList.Add(workFieldPortBcId);
            }

            // 観測点
            VIdRefList.Clear();
            uint[] vId_cad_refPort = { 19, 20 };
            foreach (uint vId_cad in vId_cad_refPort)
            {
                uint vId = conv.GetIdEA_fromCad(vId_cad, CAD_ELEM_TYPE.VERTEX);
                VIdRefList.Add(vId);
            }

            return true;
        }
Exemplo n.º 2
0
        /// <summary>
        /// 導波管ベンド
        /// </summary>
        /// <param name="probNo"></param>
        /// <param name="WaveguideWidth"></param>
        /// <param name="timeLoopCnt"></param>
        /// <param name="timeDelta"></param>
        /// <param name="gaussianT0"></param>
        /// <param name="gaussianTp"></param>
        /// <param name="NormalizedFreqSrc"></param>
        /// <param name="NormalizedFreq1"></param>
        /// <param name="NormalizedFreq2"></param>
        /// <param name="GraphFreqInterval"></param>
        /// <param name="WaveModeDv"></param>
        /// <param name="World"></param>
        /// <param name="FieldValId"></param>
        /// <param name="FieldLoopId"></param>
        /// <param name="FieldForceBcId"></param>
        /// <param name="FieldPmlLoopIdList"></param>
        /// <param name="PmlStPosXList"></param>
        /// <param name="FieldPortSrcBcId"></param>
        /// <param name="VIdRefList"></param>
        /// <param name="Medias"></param>
        /// <param name="LoopDic"></param>
        /// <param name="EdgeDic"></param>
        /// <param name="isCadShow"></param>
        /// <param name="CadDrawerAry"></param>
        /// <param name="Camera"></param>
        /// <returns></returns>
        public static bool SetProblem(
            int probNo,
            ref double WaveguideWidth,
            ref bool isPCWaveguide,
            ref double latticeA,
            ref int timeLoopCnt,
            ref double timeDelta,
            ref double gaussianT0,
            ref double gaussianTp,
            ref double NormalizedFreqSrc,
            ref double NormalizedFreq1,
            ref double NormalizedFreq2,
            ref double GraphFreqInterval,
            ref WgUtil.WaveModeDV WaveModeDv,
             ref CFieldWorld World,
            ref uint FieldValId,
            ref uint FieldLoopId,
            ref uint FieldForceBcId,
            ref IList<uint> FieldPmlLoopIdList,
            ref IList<bool> IsPmlYDirectionList,
            ref IList<double> PmlStPosXList,
            ref IList<double> PmlLengthList,
            ref uint FieldPortSrcBcId,
            ref IList<uint> VIdRefList,
            ref IList<MediaInfo> Medias,
            ref Dictionary<uint, wg2d.World.Loop> LoopDic,
            ref Dictionary<uint, wg2d.World.Edge> EdgeDic,
            ref bool isCadShow,
            ref CDrawerArray CadDrawerAry,
            ref CCamera Camera
            )
        {
            WaveguideWidth = 3.0e-3 * 20 * 4;

            // 導波管ベンド
            // メッシュの分割長さ
            //double meshL = WaveguideWidth * 0.05;
            //double meshL = WaveguideWidth * 0.10;
            //double meshL = WaveguideWidth * 0.09;
            double meshL = WaveguideWidth * 0.04;

            // 入力部の長さ
            //double inputWGLength = 1.0 * WaveguideWidth;
            double inputWGLength = 2.0 * WaveguideWidth;
            // 形状設定で使用する単位長さ
            double unitLen = WaveguideWidth / 20.0;
            // PMLの長さ
            //double pmlLength = 10 * unitLen;
            double pmlLength = 12 * unitLen;

            // 励振位置
            double srcPosX = pmlLength + 5 * unitLen;
            // 観測点
            int port1OfsX = 5;
            int port2OfsY = 5;
            double port1PosX = srcPosX + port1OfsX * unitLen;
            double port1PosY = WaveguideWidth * 0.5;
            double port2PosX = pmlLength + inputWGLength + WaveguideWidth * 0.5;
            double port2PosY = -inputWGLength + port2OfsY * unitLen;

            // 時間領域
            //double courantNumber = 0.5;
            double courantNumber = 0.5;
            //timeLoopCnt = 3000;
            timeLoopCnt = 3000;
            // 時刻刻み
            timeDelta = courantNumber * meshL / (c0 * Math.Sqrt(2.0));

            // モード計算規格化周波数(搬送波規格化周波数)
            //NormalizedFreqSrc = 2.0;
            //NormalizedFreqSrc = 1.5; // ガウシアンパルス
            NormalizedFreqSrc = 2.0; // 正弦波変調ガウシアンパルス

            /*
            // ガウシアンパルス
            //gaussianT0 = 30 * timeDelta;
            //gaussianT0 = 40 * timeDelta;
            //gaussianT0 = 20 * timeDelta;
            gaussianT0 = 45 * timeDelta;
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0) * 4.0);
             */

            // 正弦波変調ガウシアンパルス
            // 波数
            double k0Src = NormalizedFreqSrc * pi / WaveguideWidth;
            // 波長
            double waveLengthSrc = 2.0 * pi / k0Src;
            // 周波数
            double freqSrc = c0 / waveLengthSrc;
            // 角周波数
            double omegaSrc = 2.0 * pi * freqSrc;
            // 搬送波の振動回数
            int nCycle = 5;
            //gaussianT0 = (1.0 / freqSrc) * nCycle / 2;
            //gaussianT0 = 0.5 * (1.0 / freqSrc) * nCycle / 2;
            //gaussianT0 = 0.67 * (1.0 / freqSrc) * nCycle / 2;
            gaussianT0 = 0.65 * (1.0 / freqSrc) * nCycle / 2;
            gaussianTp = gaussianT0 / (2.0 * Math.Sqrt(2.0 * Math.Log(2.0)));

            // 周波数領域
            NormalizedFreq1 = 1.0;
            NormalizedFreq2 = 2.0;
            GraphFreqInterval = 0.2;

            // ポート数
            const int portCnt = 2;

            // 媒質リスト作成
            MediaInfo mediaVacumn = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { 1.0, 0.0, 0.0 },
                   { 0.0, 1.0, 0.0 },
                   { 0.0, 0.0, 1.0 }
                }
            );
            Medias.Add(mediaVacumn);

            // 図面作成、メッシュ生成
            // 全ループ数
            uint loopCnt_cad = 2 + portCnt;
            // ポート1のPML領域ループリスト
            uint[] port1_pml_loopIds_cad = { 1 };
            // ポート2のPML領域ループリスト
            uint[] port2_pml_loopIds_cad = { 4 };
            // PML開始位置X座標
            double[] pmlStPosX_list = { pmlLength, -inputWGLength }; // ポート2はY方向PMLでY座標を格納
            // Y方向PML?
            bool[] isPmlYDirection_list = { false, true };
            // 観測点頂点ID
            uint[] portRef_vIds_cad = new uint[portCnt];
            // 励振面の辺ID
            uint eId_cad_src = 14;
            // ポート2
            double port2_X1 = pmlLength + inputWGLength;
            uint baseId = 0;
            CIDConvEAMshCad conv = null;
            using (CCadObj2D cad2d = new CCadObj2D())
            {
                //------------------------------------------------------------------
                // 図面作成
                //------------------------------------------------------------------
                IList<CVector2D> pts = new List<CVector2D>();
                pts.Add(new CVector2D(0.0, WaveguideWidth));  // 頂点1
                pts.Add(new CVector2D(0.0, 0.0)); // 頂点2
                pts.Add(new CVector2D(pmlLength, 0.0)); // 頂点3
                pts.Add(new CVector2D(srcPosX, 0.0)); // 頂点4
                pts.Add(new CVector2D(port2_X1, 0.0)); // 頂点5
                pts.Add(new CVector2D(port2_X1, -inputWGLength)); // 頂点6
                pts.Add(new CVector2D(port2_X1, -inputWGLength - pmlLength)); // 頂点7
                pts.Add(new CVector2D(port2_X1 + WaveguideWidth, -inputWGLength - pmlLength)); // 頂点8
                pts.Add(new CVector2D(port2_X1 + WaveguideWidth, -inputWGLength)); // 頂点9
                pts.Add(new CVector2D(port2_X1 + WaveguideWidth, WaveguideWidth)); // 頂点10
                pts.Add(new CVector2D(srcPosX, WaveguideWidth)); // 頂点11
                pts.Add(new CVector2D(pmlLength, WaveguideWidth)); // 頂点12
                uint lId1 = cad2d.AddPolygon(pts).id_l_add;
                uint lId2 = cad2d.ConnectVertex_Line(3, 12).id_l_add;
                uint lId3 = cad2d.ConnectVertex_Line(4, 11).id_l_add;
                uint lId4 = cad2d.ConnectVertex_Line(6, 9).id_l_add;
                // 観測点
                portRef_vIds_cad[0] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, lId3, new CVector2D(port1PosX, port1PosY)).id_v_add; // 頂点13
                portRef_vIds_cad[1] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, lId3, new CVector2D(port2PosX, port2PosY)).id_v_add; // 頂点14
                // check
                foreach (uint vId in portRef_vIds_cad)
                {
                    System.Diagnostics.Debug.Assert(vId != 0);
                }

                //isCadShow = true;
                // 図面表示
                if (isCadShow)
                {
                    // PML領域に色を付ける
                    uint[][] port_pml_loopIds_cad_list = { port1_pml_loopIds_cad, port2_pml_loopIds_cad };
                    for (int portIndex = 0; portIndex < portCnt; portIndex++)
                    {
                        uint[] work_lId_list = port_pml_loopIds_cad_list[portIndex];
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 0.5, 0.5, 0.5 });
                        }
                    }
                    // 境界の辺に色を付ける
                    {
                        uint[] work_eId_list = { eId_cad_src };
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 0.8, 0.0, 0.0 });
                        }
                    }
                    /*
                    // DEBUG
                    {
                        uint[] work_eId_list = {2, 3, 4, 5, 6, 8, 9, 10, 11, 12};
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 1.0, 1.0, 1.0 });
                        }
                    }
                     */

                    CadDrawerAry.Clear();
                    CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                    CadDrawerAry.InitTrans(Camera);
                    return true;
                }

                /*
                 // 図面表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                CadDrawerAry.InitTrans(Camera);
                 */

                /*
                // メッシュ表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawerMsh2D(new CMesher2D(cad2d, meshL)));
                CadDrawerAry.InitTrans(Camera);
                */

                //------------------------------------------------------------------
                // メッシュ作成
                //------------------------------------------------------------------
                // メッシュを作成し、ワールド座標系にセットする
                World.Clear();
                using (CMesher2D mesher2d = new CMesher2D(cad2d, meshL))
                {
                    baseId = World.AddMesh(mesher2d);
                    conv = World.GetIDConverter(baseId);
                }
            }
            // 界の値を扱うバッファ?を生成する。
            // フィールド値IDが返却される。
            //    要素の次元: 2次元 界: 複素数スカラー 微分タイプ: 値 要素セグメント: 角節点
            FieldValId = World.MakeField_FieldElemDim(baseId, 2,
                FIELD_TYPE.ZSCALAR, FIELD_DERIVATION_TYPE.VALUE, ELSEG_TYPE.CORNER);

            // 領域
            //   ワールド座標系のループIDを取得
            //   媒質をループ単位で指定する
            FieldLoopId = 0;
            {
                // ワールド座標系のループIDを取得
                uint[] loopId_cad_list  = new uint[loopCnt_cad];
                for (int i = 0; i < loopCnt_cad; i++)
                {
                    loopId_cad_list[i] = (uint)(i + 1);
                }
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint loopId_cad in loopId_cad_list)
                {
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                    {
                        wg2d.World.Loop loop = new wg2d.World.Loop();
                        loop.Set(lId1, Medias.IndexOf(mediaVacumn));
                        LoopDic.Add(lId1, loop);
                    }
                }
                //System.Diagnostics.Debug.WriteLine("lId:" + lId1);
                FieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
            }
            // PML領域
            FieldPmlLoopIdList.Clear();
            IsPmlYDirectionList.Clear();
            PmlStPosXList.Clear();
            PmlLengthList.Clear();
            uint[][] loopId_cad_list_pml = { port1_pml_loopIds_cad, port2_pml_loopIds_cad };
            for (int portIndex = 0; portIndex < portCnt; portIndex++)
            {
                uint[] loopId_cad_list = loopId_cad_list_pml[portIndex];
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint loopId_cad in loopId_cad_list)
                {
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                }
                uint workFieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
                FieldPmlLoopIdList.Add(workFieldLoopId);
                // Y方向PML?
                bool isPmlYDirection = isPmlYDirection_list[portIndex];
                IsPmlYDirectionList.Add(isPmlYDirection);
                // PML開始位置
                double pmlStPosX = pmlStPosX_list[portIndex];
                PmlStPosXList.Add(pmlStPosX);
                // PML長さ
                PmlLengthList.Add(pmlLength);
            }

            // 境界条件を設定する
            //   固定境界条件(強制境界)
            //   ワールド座標系の辺IDを取得
            //   媒質は指定しない
            FieldForceBcId = 0;
            {
                uint[] eId_cad_list = {2, 3, 4, 5, 6, 8, 9, 10, 11, 12}; // PML終端磁気壁
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                }
                // フィールドIDを取得
                FieldForceBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldForceBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
            }
            // 開口条件
            //   ワールド座標系の辺IDを取得
            //   辺単位で媒質を指定する
            FieldPortSrcBcId = 0;
            {
                // PMLを用いる場合は、励振面のみ
                uint eId_cad = eId_cad_src;
                uint eId;
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                aEA.Add(eId);
                {
                    wg2d.World.Edge edge = new wg2d.World.Edge();
                    edge.Set(eId, Medias.IndexOf(mediaVacumn));
                    EdgeDic.Add(eId, edge);
                }
                uint workFieldPortBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldPortBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
                FieldPortSrcBcId = workFieldPortBcId;
            }

            // 観測点
            VIdRefList.Clear();
            uint[] vId_cad_refPort = portRef_vIds_cad;
            foreach (uint vId_cad in vId_cad_refPort)
            {
                uint vId = conv.GetIdEA_fromCad(vId_cad, CAD_ELEM_TYPE.VERTEX);
                VIdRefList.Add(vId);
            }

            return true;
        }
Exemplo n.º 3
0
        /// <summary>
        /// フォトニック結晶導波路 直線
        /// </summary>
        /// <param name="probNo"></param>
        /// <param name="WaveguideWidth"></param>
        /// <param name="timeLoopCnt"></param>
        /// <param name="timeDelta"></param>
        /// <param name="gaussianT0"></param>
        /// <param name="gaussianTp"></param>
        /// <param name="NormalizedFreqSrc"></param>
        /// <param name="NormalizedFreq1"></param>
        /// <param name="NormalizedFreq2"></param>
        /// <param name="GraphFreqInterval"></param>
        /// <param name="WaveModeDv"></param>
        /// <param name="World"></param>
        /// <param name="FieldValId"></param>
        /// <param name="FieldLoopId"></param>
        /// <param name="FieldForceBcId"></param>
        /// <param name="FieldPmlLoopIdList"></param>
        /// <param name="PmlStPosXList"></param>
        /// <param name="FieldPortSrcBcId"></param>
        /// <param name="VIdRefList"></param>
        /// <param name="Medias"></param>
        /// <param name="LoopDic"></param>
        /// <param name="EdgeDic"></param>
        /// <param name="isCadShow"></param>
        /// <param name="CadDrawerAry"></param>
        /// <param name="Camera"></param>
        /// <returns></returns>
        public static bool SetProblem(
            int probNo,
            ref double WaveguideWidth,
            ref bool isPCWaveguide,
            ref double latticeA,
            ref int timeLoopCnt,
            ref double timeDelta,
            ref double gaussianT0,
            ref double gaussianTp,
            ref double NormalizedFreqSrc,
            ref double NormalizedFreq1,
            ref double NormalizedFreq2,
            ref double GraphFreqInterval,
            ref WgUtil.WaveModeDV WaveModeDv,
             ref CFieldWorld World,
            ref uint FieldValId,
            ref uint FieldLoopId,
            ref uint FieldForceBcId,
            ref IList<uint> FieldPmlLoopIdList,
            ref IList<bool> IsPmlYDirectionList,
            ref IList<double> PmlStPosXList,
            ref IList<double> PmlLengthList,
            ref uint FieldPortSrcBcId,
            ref IList<uint> VIdRefList,
            ref IList<MediaInfo> Medias,
            ref Dictionary<uint, wg2d.World.Loop> LoopDic,
            ref Dictionary<uint, wg2d.World.Edge> EdgeDic,
            ref bool isCadShow,
            ref CDrawerArray CadDrawerAry,
            ref CCamera Camera
            )
        {
            WaveguideWidth = 1.0e-3 * 240;
            isPCWaveguide = true;
            latticeA = 0.0;

            // フォトニック結晶導波路 直線
            // メッシュの分割長さ
            //double meshL = WaveguideWidth * 0.05;
            double meshL = WaveguideWidth * 0.02;
            //double meshL = WaveguideWidth * 0.03;

            /////////////////////////////////////////////
            // フォトニック導波路
            // ロッドの数(半分)
            const int rodCntHalf = 5;
            //const int rodCntHalf = 3;
            // 欠陥ロッド数
            const int defectRodCnt = 1;
            // 格子数
            const int latticeCnt = rodCntHalf * 2 + defectRodCnt;
            // 格子定数
            latticeA = WaveguideWidth / (double)latticeCnt;
            // 周期構造距離
            double periodicDistance = latticeA;
            // ロッドの半径
            double rodRadius = 0.18 * latticeA;
            // ロッドの比誘電率
            double rodEps = 3.4 * 3.4;
            // ロッドの円周分割数
            const int rodCircleDiv = 8;
            // ロッドの半径の分割数
            const int rodRadiusDiv = 1;
            /////////////////////////////////////////////

            // PMLの長さ
            //double pmlLength = 5 * periodicDistance;
            //double pmlLength = 10 * periodicDistance;
            double pmlLength = 6 * periodicDistance;
            // 導波管不連続領域の長さ
            double disconLength = 10 * periodicDistance;
            disconLength += 2.0 * pmlLength;

            // 励振位置
            //double srcPosX = pmlLength + 4.5 * periodicDistance;
            double srcPosX = pmlLength + 1.5 * periodicDistance;
            // 観測点
            double port1PosX = srcPosX + 1.5 * periodicDistance;
            double port1PosY = WaveguideWidth * 0.5;
            double port2PosX = disconLength - pmlLength - 1.0 * periodicDistance;
            double port2PosY = WaveguideWidth * 0.5;

            // 時間領域
            //double courantNumber = 0.5;
            double courantNumber = 0.5;
            //timeLoopCnt = 100000;
            timeLoopCnt = 3000;
            // 時刻刻み
            timeDelta = courantNumber * (WaveguideWidth * 0.02) / (c0 * Math.Sqrt(2.0));

            // モード計算規格化周波数(搬送波規格化周波数)
            // フォトニック結晶導波路の場合、a/λを規格化周波数とする
            //NormalizedFreqSrc = 0.400;
            NormalizedFreqSrc = 0.400;
            NormalizedFreqSrc *= (2.0 * WaveguideWidth) / latticeA;
            Console.WriteLine("NormalizedFreqSrc: {0}", NormalizedFreqSrc);

            // 周波数領域
            NormalizedFreq1 = 0.300;//0.302;
            NormalizedFreq2 = 0.440;//0.443;
            GraphFreqInterval = 0.02;
            NormalizedFreq1 *= (2.0 * WaveguideWidth) / latticeA;
            NormalizedFreq2 *= (2.0 * WaveguideWidth) / latticeA;
            GraphFreqInterval *= (2.0 * WaveguideWidth) / latticeA;

            /*
            // ガウシアンパルス
            //gaussianT0 = 30 * timeDelta;
            //gaussianT0 = 40 * timeDelta;
            gaussianT0 = 20 * timeDelta;
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0) * 4.0);
             */

            // 正弦波変調ガウシアンパルス
            // 波数
            double k0Src = NormalizedFreqSrc * pi / WaveguideWidth;
            // 波長
            double waveLengthSrc = 2.0 * pi / k0Src;
            // 周波数
            double freqSrc = c0 / waveLengthSrc;
            // 角周波数
            double omegaSrc = 2.0 * pi * freqSrc;
            // 搬送波のバンド幅
            double k0BandWidthSrc = (NormalizedFreq2 - NormalizedFreq1) *pi / WaveguideWidth; ;
            double waveLengthBandWidthSrc = 2.0 * pi / k0BandWidthSrc;
            double freqBandWidthSrc = c0 / waveLengthBandWidthSrc;
            gaussianT0 = (1.0 / freqBandWidthSrc);
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0));

            // ポート数
            const int portCnt = 2;

            // 媒質リスト作成
            double claddingP = 1.0;
            double claddingQ = 1.0;
            double coreP = 1.0;
            double coreQ = 1.0;

            // 媒質リスト作成
            {
                // TEモード
                claddingP = 1.0;
                claddingQ = 1.0;
                coreP = 1.0;
                coreQ = rodEps;
            }
            MediaInfo mediaCladding = new MediaInfo
            (
                new double[3, 3]
                        {
                           { claddingP,       0.0,       0.0 },
                           {       0.0, claddingP,       0.0 },
                           {       0.0,       0.0, claddingP }
                        },
                new double[3, 3]
                        {
                           { claddingQ,       0.0,       0.0 },
                           {       0.0, claddingQ,       0.0 },
                           {       0.0,       0.0, claddingQ }
                        }
            );
            MediaInfo mediaCore = new MediaInfo
            (
                new double[3, 3]
                        {
                           { coreP,   0.0,   0.0 },
                           {   0.0, coreP,   0.0 },
                           {   0.0,   0.0, coreP }
                        },
                new double[3, 3]
                        {
                           { coreQ,   0.0,   0.0 },
                           {   0.0, coreQ,   0.0 },
                           {   0.0,   0.0, coreQ }
                        }
            );
            Medias.Add(mediaCladding);
            Medias.Add(mediaCore);

            // 図面作成、メッシュ生成
            // 全ループ数
            uint loopCnt_cad = 2 + portCnt;
            // ポート1のPML領域ループリスト
            uint[] port1_pml_loopIds_cad = { 1 };
            // ポート2のPML領域ループリスト
            uint[] port2_pml_loopIds_cad = { 4 };
            // PML開始位置X座標
            double[] pmlStPosX_list = { pmlLength, (disconLength - pmlLength) };
            // 観測点頂点ID
            uint[] portRef_vIds_cad = new uint[portCnt];
            // 励振面の辺ID
            uint[] eId_cad_src_list = new uint[1 + 3 * (2 * rodCntHalf)];
            uint[] core_eId_cad_src_list = new uint[2 * (2 * rodCntHalf)];
            eId_cad_src_list[0] = 12;
            for (int i = 0; i < 3 * (2 * rodCntHalf); i++)
            {
                eId_cad_src_list[1 + i] = (uint)(14 + (3 * (2 * rodCntHalf) - 1) - i);
            }
            for (int i = 0; i < (2 * rodCntHalf); i++)
            {
                uint eId1 = eId_cad_src_list[1 + i * 3];
                uint eId2 = eId_cad_src_list[1 + i * 3 + 1];
                uint eId3 = eId_cad_src_list[1 + i * 3 + 2];
                core_eId_cad_src_list[i * 2] = eId1;
                core_eId_cad_src_list[i * 2 + 1] = eId2;
            }
            // ロッドのループIDリスト
            IList<uint> rodLoopIds = new List<uint>();
            // ロッドのループIDリスト(PML領域)
            IList<uint> rodLoopIds_port1_pml = new List<uint>();
            IList<uint> rodLoopIds_port2_pml = new List<uint>();
            uint baseId = 0;
            CIDConvEAMshCad conv = null;
            using (CCadObj2D cad2d = new CCadObj2D())
            {
                //------------------------------------------------------------------
                // 図面作成
                //------------------------------------------------------------------
                IList<CVector2D> pts = new List<CVector2D>();
                pts.Add(new CVector2D(0.0, WaveguideWidth));  // 頂点1
                pts.Add(new CVector2D(0.0, 0.0)); // 頂点2
                pts.Add(new CVector2D(pmlLength, 0.0)); // 頂点3
                pts.Add(new CVector2D(srcPosX, 0.0)); // 頂点4
                pts.Add(new CVector2D(disconLength - pmlLength, 0.0)); // 頂点5
                pts.Add(new CVector2D(disconLength, 0.0)); // 頂点6
                pts.Add(new CVector2D(disconLength, WaveguideWidth)); // 頂点7
                pts.Add(new CVector2D(disconLength - pmlLength, WaveguideWidth)); // 頂点8
                pts.Add(new CVector2D(srcPosX, WaveguideWidth)); // 頂点9
                pts.Add(new CVector2D(pmlLength, WaveguideWidth)); // 頂点10
                uint lId1 = cad2d.AddPolygon(pts).id_l_add;
                uint lId2 = cad2d.ConnectVertex_Line(3, 10).id_l_add;
                uint lId3 = cad2d.ConnectVertex_Line(4, 9).id_l_add;
                uint lId4 = cad2d.ConnectVertex_Line(5, 8).id_l_add;
                // 観測点
                portRef_vIds_cad[0] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, lId3, new CVector2D(port1PosX, port1PosY)).id_v_add; // 頂点11
                portRef_vIds_cad[1] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, lId3, new CVector2D(port2PosX, port2PosY)).id_v_add; // 頂点12
                // check
                foreach (uint vId in portRef_vIds_cad)
                {
                    System.Diagnostics.Debug.Assert(vId != 0);
                }

                {
                    double workX = srcPosX;
                    IList<uint> work_vIds = new List<uint>();
                    IList<uint> work_vIds_center = new List<uint>();
                    for (int row = (rodCntHalf * 2 + defectRodCnt - 1); row >= 0; row--)
                    {
                        if (row >= (rodCntHalf) && row < (rodCntHalf + defectRodCnt))
                        {
                            // 欠陥部
                            continue;
                        }

                        uint parent_eId = eId_cad_src_list[0]; // 先頭の辺のID
                        double workY1 = row * latticeA + 0.5 * latticeA + rodRadius;
                        double workY2 = row * latticeA + 0.5 * latticeA - rodRadius;
                        uint vId1 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(workX, workY1)).id_v_add;
                        uint vId_center = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(workX, (workY1 + workY2) * 0.5)).id_v_add;
                        uint vId2 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(workX, workY2)).id_v_add;
                        System.Diagnostics.Debug.Assert(vId1 != 0);
                        System.Diagnostics.Debug.Assert(vId2 != 0);

                        work_vIds.Add(vId1);
                        work_vIds_center.Add(vId_center);
                        work_vIds.Add(vId2);
                    }
                    uint[] work_vIdAry = work_vIds.ToArray();
                    uint[] work_vIdAry_center = work_vIds_center.ToArray();
                    // 境界の右側半円
                    for (int row = (rodCntHalf * 2 + defectRodCnt - 1), vIndex = 0; row >= 0; row--)
                    {
                        if (row >= (rodCntHalf) && row < (rodCntHalf + defectRodCnt))
                        {
                            // 欠陥部
                            continue;
                        }
                        uint parent_lId = 3;
                        double workY1 = row * latticeA + 0.5 * latticeA - rodRadius * 0.5;
                        double workY2 = row * latticeA + 0.5 * latticeA + rodRadius * 0.5;
                        uint vId1 = work_vIdAry[vIndex * 2 + 1];
                        uint vId2 = work_vIdAry[vIndex * 2];
                        uint vId_center = work_vIds_center[vIndex];
                        uint lId = WgCadUtil.AddLeftRod(cad2d, parent_lId, vId1, vId_center, vId2, workX, (workY1 + workY2) * 0.5, rodRadius, rodCircleDiv, 1);
                        rodLoopIds.Add(lId);
                        vIndex++;
                    }
                    // 境界の左側半円
                    for (int row = (rodCntHalf * 2 + defectRodCnt - 1), vIndex = 0; row >= 0; row--)
                    {
                        if (row >= (rodCntHalf) && row < (rodCntHalf + defectRodCnt))
                        {
                            // 欠陥部
                            continue;
                        }
                        uint parent_lId = 2;
                        double workY1 = row * latticeA + 0.5 * latticeA - rodRadius * 0.5;
                        double workY2 = row * latticeA + 0.5 * latticeA + rodRadius * 0.5;
                        uint vId1 = work_vIdAry[vIndex * 2];
                        uint vId2 = work_vIdAry[vIndex * 2 + 1];
                        uint vId_center = work_vIds_center[vIndex];
                        uint lId = WgCadUtil.AddRightRod(cad2d, parent_lId, vId1, vId_center, vId2, workX, (workY1 + workY2) * 0.5, rodRadius, rodCircleDiv, 1);
                        rodLoopIds.Add(lId);
                        vIndex++;
                    }
                }

                //////////////////////////////////////////////////////////
                // ロッド追加
                int colCntX = (int)Math.Round(disconLength / periodicDistance);
                for (int col = 0; col < colCntX; col++)
                {
                    uint baseLoopId = 0;
                    double x1 = col * periodicDistance;
                    double x2 = (col + 1) * periodicDistance;
                    if (x1 < srcPosX && x2 > srcPosX)
                    {
                        continue;
                    }

                    for (int row = 0; row < (rodCntHalf * 2 + defectRodCnt); row++)
                    {
                        int pmlWgNo = 0;
                        if (x1 < (pmlLength - Constants.PrecisionLowerLimit))
                        {
                            pmlWgNo = 1;
                            baseLoopId = 1;
                        }
                        else if (x1 >= (pmlLength - Constants.PrecisionLowerLimit) && x1 < (srcPosX - Constants.PrecisionLowerLimit))
                        {
                            baseLoopId = 2;
                        }
                        else if (x1 >= (srcPosX - Constants.PrecisionLowerLimit) && x1 < (disconLength - pmlLength - Constants.PrecisionLowerLimit))
                        {
                            baseLoopId = 3;
                        }
                        else
                        {
                            pmlWgNo = 2;
                            baseLoopId = 4;
                        }
                        if (row >= (rodCntHalf) && row < (rodCntHalf + defectRodCnt)) continue; // 欠陥部
                        double x0 = col * periodicDistance + periodicDistance * 0.5;
                        double y0 = WaveguideWidth - row * latticeA - latticeA * 0.5;
                        uint lId = WgCadUtil.AddRod(cad2d, baseLoopId, x0, y0, rodRadius, rodCircleDiv, rodRadiusDiv);
                        rodLoopIds.Add(lId);
                        if (pmlWgNo == 1)
                        {
                            rodLoopIds_port1_pml.Add(lId);
                        }
                        else if (pmlWgNo == 2)
                        {
                            rodLoopIds_port2_pml.Add(lId);
                        }
                    }
                }

                //isCadShow = true;
                // 図面表示
                if (isCadShow)
                {
                    // PML領域に色を付ける
                    uint[][] port_pml_loopIds_cad_list = { port1_pml_loopIds_cad, port2_pml_loopIds_cad };
                    for (int portIndex = 0; portIndex < portCnt; portIndex++)
                    {
                        uint[] work_lId_list = port_pml_loopIds_cad_list[portIndex];
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 0.5, 0.5, 0.5 });
                        }
                    }
                    // 誘電体ロッドに色を付ける
                    {
                        uint[] work_lId_list = rodLoopIds.ToArray();
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 1.0, 0.5, 0.0 });
                        }
                    }
                    // 境界の辺に色を付ける
                    {
                        uint[] work_eId_list = eId_cad_src_list;
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 0.8, 0.0, 0.0 });
                        }
                    }
                    // 境界の誘電体スラブの辺
                    {
                        uint[] work_port_core_eIds = core_eId_cad_src_list;
                        foreach (uint eId in work_port_core_eIds)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 0.0, 0.0, 1.0 });
                        }
                    }

                    /*
                    // DEBUG
                    {
                        uint[] work_eId_list = { 2, 3, 4, 5, 7, 8, 9, 10 };
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 1.0, 1.0, 1.0 });
                        }
                    }
                     */

                    CadDrawerAry.Clear();
                    CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                    CadDrawerAry.InitTrans(Camera);
                    return true;
                }

                /*
                 // 図面表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                CadDrawerAry.InitTrans(Camera);
                 */

                /*
                // メッシュ表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawerMsh2D(new CMesher2D(cad2d, meshL)));
                CadDrawerAry.InitTrans(Camera);
                */

                //------------------------------------------------------------------
                // メッシュ作成
                //------------------------------------------------------------------
                // メッシュを作成し、ワールド座標系にセットする
                World.Clear();
                using (CMesher2D mesher2d = new CMesher2D(cad2d, meshL))
                {
                    baseId = World.AddMesh(mesher2d);
                    conv = World.GetIDConverter(baseId);
                }
            }
            // 界の値を扱うバッファ?を生成する。
            // フィールド値IDが返却される。
            //    要素の次元: 2次元 界: 複素数スカラー 微分タイプ: 値 要素セグメント: 角節点
            FieldValId = World.MakeField_FieldElemDim(baseId, 2,
                FIELD_TYPE.ZSCALAR, FIELD_DERIVATION_TYPE.VALUE, ELSEG_TYPE.CORNER);

            // 領域
            //   ワールド座標系のループIDを取得
            //   媒質をループ単位で指定する
            FieldLoopId = 0;
            {
                // ワールド座標系のループIDを取得
                uint[] loopId_cad_list = new uint[loopCnt_cad + rodLoopIds.Count];
                for (int i = 0; i < loopCnt_cad; i++)
                {
                    loopId_cad_list[i] = (uint)(i + 1);
                }
                for (int i = 0; i < rodLoopIds.Count; i++)
                {
                    loopId_cad_list[i + loopCnt_cad] = rodLoopIds[i];
                }
                int[] mediaIndex_list = new int[loopCnt_cad + rodLoopIds.Count];
                for (int i = 0; i < loopCnt_cad; i++)
                {
                    mediaIndex_list[i] = Medias.IndexOf(mediaCladding);
                }
                for (int i = 0; i < rodLoopIds.Count; i++)
                {
                    mediaIndex_list[i + loopCnt_cad] = Medias.IndexOf(mediaCore);
                }

                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    uint loopId_cad = loopId_cad_list[i];
                    int mediaIndex = mediaIndex_list[i];
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                    {
                        wg2d.World.Loop loop = new wg2d.World.Loop();
                        loop.Set(lId1, mediaIndex);
                        LoopDic.Add(lId1, loop);
                    }
                }
                //System.Diagnostics.Debug.WriteLine("lId:" + lId1);
                FieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
            }

            // PML領域
            FieldPmlLoopIdList.Clear();
            IsPmlYDirectionList.Clear();
            PmlStPosXList.Clear();
            PmlLengthList.Clear();
            uint[][] loopId_cad_list_pml = new uint[portCnt][];
            // ポート1PML
            loopId_cad_list_pml[0] = new uint[port1_pml_loopIds_cad.Length + rodLoopIds_port1_pml.Count];
            port1_pml_loopIds_cad.CopyTo(loopId_cad_list_pml[0], 0);
            rodLoopIds_port1_pml.CopyTo(loopId_cad_list_pml[0], port1_pml_loopIds_cad.Length);
            // ポート2 PML
            loopId_cad_list_pml[1] = new uint[port2_pml_loopIds_cad.Length + rodLoopIds_port2_pml.Count];
            port2_pml_loopIds_cad.CopyTo(loopId_cad_list_pml[1], 0);
            rodLoopIds_port2_pml.CopyTo(loopId_cad_list_pml[1], port2_pml_loopIds_cad.Length);
            for (int portIndex = 0; portIndex < portCnt; portIndex++)
            {
                uint[] loopId_cad_list = loopId_cad_list_pml[portIndex];
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint loopId_cad in loopId_cad_list)
                {
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                }
                uint workFieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
                FieldPmlLoopIdList.Add(workFieldLoopId);
                // Y方向PML?
                bool isPmlYDirection = false;
                IsPmlYDirectionList.Add(isPmlYDirection);
                // PML開始位置
                double pmlStPosX = pmlStPosX_list[portIndex];
                PmlStPosXList.Add(pmlStPosX);
                // PML長さ
                PmlLengthList.Add(pmlLength);
            }

            // 境界条件を設定する
            //   固定境界条件(強制境界)
            //   ワールド座標系の辺IDを取得
            //   媒質は指定しない
            FieldForceBcId = 0;
            {
                uint[] eId_cad_list = { 2, 3, 4, 5, 7, 8, 9, 10 }; // PML終端磁気壁
                //uint[] eId_cad_list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // PML終端電気壁
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                }
                // フィールドIDを取得
                FieldForceBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldForceBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
            }
            // 開口条件
            //   ワールド座標系の辺IDを取得
            //   辺単位で媒質を指定する
            FieldPortSrcBcId = 0;
            {
                // PMLを用いる場合は、励振面のみ
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_src_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                    {
                        wg2d.World.Edge edge = new wg2d.World.Edge();
                        int mediaIndex = Medias.IndexOf(mediaCladding);
                        if (core_eId_cad_src_list.Contains(eId_cad))
                        {
                            mediaIndex = Medias.IndexOf(mediaCore);
                        }
                        edge.Set(eId, mediaIndex);
                        EdgeDic.Add(eId, edge);
                    }
                }
                uint workFieldPortBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldPortBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
                FieldPortSrcBcId = workFieldPortBcId;
            }

            // 観測点
            VIdRefList.Clear();
            uint[] vId_cad_refPort = portRef_vIds_cad;
            foreach (uint vId_cad in vId_cad_refPort)
            {
                uint vId = conv.GetIdEA_fromCad(vId_cad, CAD_ELEM_TYPE.VERTEX);
                VIdRefList.Add(vId);
            }

            return true;
        }
Exemplo n.º 4
0
        /// <summary>
        /// 誘電体スラブ導波路グレーティング
        /// </summary>
        /// <param name="probNo"></param>
        /// <param name="WaveguideWidth"></param>
        /// <param name="timeLoopCnt"></param>
        /// <param name="timeDelta"></param>
        /// <param name="gaussianT0"></param>
        /// <param name="gaussianTp"></param>
        /// <param name="NormalizedFreqSrc"></param>
        /// <param name="NormalizedFreq1"></param>
        /// <param name="NormalizedFreq2"></param>
        /// <param name="GraphFreqInterval"></param>
        /// <param name="WaveModeDv"></param>
        /// <param name="World"></param>
        /// <param name="FieldValId"></param>
        /// <param name="FieldLoopId"></param>
        /// <param name="FieldForceBcId"></param>
        /// <param name="FieldPortBcIdList"></param>
        /// <param name="VIdRefList"></param>
        /// <param name="Medias"></param>
        /// <param name="LoopDic"></param>
        /// <param name="EdgeDic"></param>
        /// <param name="isCadShow"></param>
        /// <param name="CadDrawerAry"></param>
        /// <param name="Camera"></param>
        /// <returns></returns>
        public static bool SetProblem(
            int probNo,
            ref double WaveguideWidth,
            ref int timeLoopCnt,
            ref double timeDelta,
            ref double gaussianT0,
            ref double gaussianTp,
            ref double NormalizedFreqSrc,
            ref double NormalizedFreq1,
            ref double NormalizedFreq2,
            ref double GraphFreqInterval,
            ref WgUtil.WaveModeDV WaveModeDv,
             ref CFieldWorld World,
            ref uint FieldValId,
            ref uint FieldLoopId,
            ref uint FieldForceBcId,
            ref IList<uint> FieldPortBcIdList,
            ref IList<uint> VIdRefList,
            ref IList<MediaInfo> Medias,
            ref Dictionary<uint, wg2d.World.Loop> LoopDic,
            ref Dictionary<uint, wg2d.World.Edge> EdgeDic,
            ref bool isCadShow,
            ref CDrawerArray CadDrawerAry,
            ref CCamera Camera
            )
        {
            WaveguideWidth = 3.0e-3 * 30 * 4;

            // メッシュの分割長さ
            //double meshL = WaveguideWidth * 1.0 / 60.0;
            double meshL = WaveguideWidth * 1.0 / 65.0;
            double meshLForTimeDelta = meshL;

            // 導波管不連続領域の長さ
            double disconLength = 65.0 / 60.0 * WaveguideWidth;

            // 誘電体スラブ導波路幅
            double slabWidth =WaveguideWidth / 30.0;
            // 誘電体スラブ比誘電率
            double coreEps = 2.402500;
            // グレーティング比誘電率
            double gratingEps = 2.102500;
            // グレーティングの数
            int gratingCnt = 8;  // 偶数とする
            // グレーティング1つの長さ
            double gratingOneLength = slabWidth;
            // グレーティングの全長
            double gratingAllLength = gratingOneLength * ((gratingCnt - 1) * 2 + 1);
            // グレーティング開始位置
            double grating_X1 = 25.0 / 60.0 * WaveguideWidth;
            double grating_X2 = grating_X1 + gratingAllLength;

            // 形状設定で使用する単位長さ
            double unitLen = WaveguideWidth / 60.0;
            // 励振位置
            //double srcPosX = 10 * unitLen;
            double srcPosX = 9 * unitLen;
            // 観測点
            int port1OfsX = 5;
            int port2OfsX = 5;
            double port1PosX = srcPosX + port1OfsX * unitLen;
            double port1PosY = WaveguideWidth * 0.5;
            double port2PosX = disconLength - port2OfsX * unitLen;
            double port2PosY = WaveguideWidth * 0.5;
            System.Diagnostics.Debug.Assert(grating_X1 >= (port1PosX+  5.0 / 60.0 * WaveguideWidth));
            System.Diagnostics.Debug.Assert((grating_X2 + 4.0 / 60.0 * WaveguideWidth) <= port2PosX);

            // 時間領域
            //double courantNumber = 0.5;
            double courantNumber = 0.5;
            //timeLoopCnt = 3000;
            //timeLoopCnt = 1500;
            timeLoopCnt = 1000;

            // 時刻刻み
            //timeDelta = courantNumber * meshL / (c0 * Math.Sqrt(2.0));
            timeDelta = courantNumber * meshLForTimeDelta / (c0 * Math.Sqrt(2.0));

            // モード計算規格化周波数(搬送波規格化周波数)
            NormalizedFreqSrc = 12.0;

            /*
            // ガウシアンパルス
            gaussianT0 = 30 * timeDelta;
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0) * 4.0);
             */

            // 正弦波変調ガウシアンパルス
            // 波数
            double k0Src = NormalizedFreqSrc * pi / WaveguideWidth;
            // 波長
            double waveLengthSrc = 2.0 * pi / k0Src;
            // 周波数
            double freqSrc = c0 / waveLengthSrc;
            // 角周波数
            double omegaSrc = 2.0 * pi * freqSrc;
            // 搬送波の振動回数
            int nCycle = 5;
            //gaussianT0 = (1.0 / freqSrc) * nCycle / 2;
            //gaussianT0 = 0.5 * (1.0 / freqSrc) * nCycle / 2;
            gaussianT0 = 0.48 * (1.0 / freqSrc) * nCycle / 2;
            gaussianTp = gaussianT0 / (2.0 * Math.Sqrt(2.0 * Math.Log(2.0)));

            // 周波数領域
            NormalizedFreq1 = 10.0;
            NormalizedFreq2 = 20.0;
            GraphFreqInterval = 2.0;

            // ポート数
            const int portCnt = 2;

            // 媒質リスト作成
            MediaInfo mediaVacumn = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { 1.0, 0.0, 0.0 },
                   { 0.0, 1.0, 0.0 },
                   { 0.0, 0.0, 1.0 }
                }
            );
            MediaInfo mediaCore = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { coreEps,  0.0,  0.0 },
                   {  0.0, coreEps,  0.0 },
                   {  0.0,  0.0, coreEps }
                }
            );
            MediaInfo mediaGrating = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { gratingEps,  0.0,  0.0 },
                   {  0.0, gratingEps,  0.0 },
                   {  0.0,  0.0, gratingEps }
                }
            );
            Medias.Add(mediaVacumn);
            Medias.Add(mediaCore);
            Medias.Add(mediaGrating);

            // 図面作成、メッシュ生成
            double coreY1 = (WaveguideWidth - slabWidth) * 0.5;
            double coreY2 = coreY1 + slabWidth;
            int loopCnt_cad = 6 + (2 * (gratingCnt - 1) + 1) + 1;
            uint[] slab_loopId_cad_list = new uint[2 + (gratingCnt - 1) + 1];
            slab_loopId_cad_list[0] = 4;
            slab_loopId_cad_list[1] = 6;
            for (int i = 0; i < gratingCnt; i++)
            {
                slab_loopId_cad_list[2 + i] = (uint)(8 + i * 2);
            }
            uint[] grating_loopId_cad_list = new uint[gratingCnt];
            for (int i = 0; i < gratingCnt; i++)
            {
                grating_loopId_cad_list[i] = (uint)(7 + i * 2);
            }

            uint[] port1_eId_list = { 1, 9, 8 };
            uint port1_core_eId = 9;
            uint[] port2_eId_list = { 4, 11, 10 };
            uint port2_core_eId = 11;
            uint[] portSrc_eId_list = { 7, 13, 12 };
            uint portSrc_core_eId = 13;
            uint baseId = 0;
            CIDConvEAMshCad conv = null;
            using (CCadObj2D cad2d = new CCadObj2D())
            {
                //------------------------------------------------------------------
                // 図面作成
                //------------------------------------------------------------------
                {
                    // ループ1
                    IList<CVector2D> pts = new List<CVector2D>();
                    pts.Add(new CVector2D(0.0, WaveguideWidth));  // 頂点1
                    pts.Add(new CVector2D(0.0, 0.0)); // 頂点2
                    pts.Add(new CVector2D(srcPosX, 0.0)); // 頂点3
                    pts.Add(new CVector2D(disconLength, 0.0)); // 頂点4
                    pts.Add(new CVector2D(disconLength, WaveguideWidth)); // 頂点5
                    pts.Add(new CVector2D(srcPosX, WaveguideWidth)); // 頂点6
                    uint lId1 = cad2d.AddPolygon(pts).id_l_add;
                    uint lId2 = cad2d.ConnectVertex_Line(3, 6).id_l_add;
                    System.Diagnostics.Debug.Assert(lId1 == 1);
                    System.Diagnostics.Debug.Assert(lId2 == 2);
                }
                {
                    uint parent_id_l_cad = 2;
                    // 観測点
                    cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port1PosX, port1PosY)); // 頂点7
                    cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port2PosX, port2PosY)); // 頂点8
                }

                // スラブ導波路と境界の交点
                uint[] parent_eId_list = {1, 4, 7};
                double[] portX_list = {0.0, disconLength, srcPosX};
                IList<uint[]> slab_vIds_list = new List<uint[]>();
                for (int portIndex = 0; portIndex < (portCnt + 1); portIndex++)
                {
                    uint parent_eId = parent_eId_list[portIndex];
                    double portX = portX_list[portIndex];

                    double workY1 = 0.0;
                    double workY2 = 0.0;
                    if (portIndex == 0)
                    {
                        workY1 = coreY1;
                        workY2 = coreY2;
                    }
                    else
                    {
                        workY1 = coreY2;
                        workY2 = coreY1;
                    }
                    uint vId1 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(portX, workY1)).id_v_add;
                    uint vId2 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(portX, workY2)).id_v_add;
                    uint[] work_vIds = new uint[2];
                    if (portIndex == 0)
                    {
                        work_vIds[0] = vId1;
                        work_vIds[1] = vId2;
                    }
                    else
                    {
                        work_vIds[0] = vId2;
                        work_vIds[1] = vId1;
                    }
                    slab_vIds_list.Add(work_vIds);
                }
                // スラブ導波路
                {
                    // 励振面の左側領域
                    {
                        uint work_vId1 = slab_vIds_list[0][0];
                        uint work_vId2 = slab_vIds_list[2][0];
                        uint work_eId = cad2d.ConnectVertex_Line(work_vId1, work_vId2).id_e_add;
                    }
                    {
                        uint work_vId1 = slab_vIds_list[0][1];
                        uint work_vId2 = slab_vIds_list[2][1];
                        uint work_eId = cad2d.ConnectVertex_Line(work_vId1, work_vId2).id_e_add;
                    }
                    // 励振面の右側領域
                    {
                        uint work_vId1 = slab_vIds_list[2][0];
                        uint work_vId2 = slab_vIds_list[1][0];
                        uint work_eId = cad2d.ConnectVertex_Line(work_vId1, work_vId2).id_e_add;
                    }
                    {
                        uint work_vId1 = slab_vIds_list[2][1];
                        uint work_vId2 = slab_vIds_list[1][1];
                        uint work_eId = cad2d.ConnectVertex_Line(work_vId1, work_vId2).id_e_add;
                    }
                }
                // グレーティング
                {
                    // 励振面右側の誘電体スラブの上下の辺
                    uint[] slabTopBottom_eIds = {16, 17};
                    double[] work_Ys = {coreY1, coreY2};
                    uint[][] work_vIds_list = new uint[2][];
                    // 上下の辺に頂点を追加
                    for (int edgeIndex = 0; edgeIndex < 2; edgeIndex++) // スラブの上下の辺
                    {
                        uint parent_eId = slabTopBottom_eIds[edgeIndex];
                        double workY = work_Ys[edgeIndex];
                        work_vIds_list[edgeIndex] = new uint[2 * gratingCnt];
                        for (int i = (2 * gratingCnt) - 1; i >= 0; i--)
                        {
                            double workX = grating_X1 + gratingOneLength * i;
                            uint vId = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(workX, workY)).id_v_add;
                            work_vIds_list[edgeIndex][i] = vId;
                        }
                    }
                    // 上下の頂点を結ぶ
                    uint[] grating_eIds = new uint[(2 * gratingCnt)];
                    uint[] grating_lIds = new uint[(2 * gratingCnt)];
                    for (int i = 0; i < (2 * gratingCnt); i++)
                    {
                        uint work_vId1 = work_vIds_list[0][i];
                        uint work_vId2 = work_vIds_list[1][i];
                        CBRepSurface.CResConnectVertex res =cad2d.ConnectVertex_Line(work_vId1, work_vId2);
                        grating_eIds[i] = res.id_e_add;
                        grating_lIds[i] = res.id_l_add;
                    }
                    /*
                    // 分割数調整
                    for (int i = 0; i < (2 * gratingCnt); i++)
                    {
                        double workY = (coreY1 + coreY2) * 0.5;
                        double workX = grating_X1 + gratingOneLength * i;
                        uint parent_eId = grating_eIds[i];
                        uint vId = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(workX, workY)).id_v_add;
                        System.Diagnostics.Debug.Assert(vId != 0);
                    }
                    for (int i = 0; i < (2 * gratingCnt - 1); i++)
                    {
                        double workY = (coreY1 + coreY2) * 0.5;
                        double workX = grating_X1 + gratingOneLength * i + gratingOneLength * 0.5;
                        uint parent_lId = grating_lIds[i];
                        uint vId = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_lId, new CVector2D(workX, workY)).id_v_add;
                        System.Diagnostics.Debug.Assert(vId != 0);
                    }
                     */
                }

                //isCadShow = true;
                // 図面表示
                if (isCadShow)
                {
                    // 誘電体スラブ導波路に色を付ける
                    {
                        uint[] work_lId_list = slab_loopId_cad_list;
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 1.0, 0.0, 1.0 });
                        }
                    }
                    {
                        uint[] work_lId_list = grating_loopId_cad_list;
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 0.0, 0.0, 1.0 });
                        }
                    }
                    // 境界の辺に色を付ける
                    {
                        uint[] work_eId_list = port1_eId_list;
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 0.8, 0.0, 0.0 });
                        }
                    }
                    {
                        uint[] work_eId_list = port2_eId_list;
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 1.0, 1.0, 0.0 });
                        }
                    }
                    {
                        uint[] work_eId_list = portSrc_eId_list;
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 0.0, 1.0, 0.0 });
                        }
                    }
                    // 境界の誘電体スラブの辺
                    cad2d.SetColor_Edge(port1_core_eId, new double[] { 1.0, 0.0, 0.0 });
                    cad2d.SetColor_Edge(port2_core_eId, new double[] { 1.0, 0.0, 0.0 });
                    cad2d.SetColor_Edge(portSrc_core_eId, new double[] { 1.0, 0.0, 0.0 });

                    // DEBUG
                    // 右側領域誘電体スラブ上下の辺
                    cad2d.SetColor_Edge(16, new double[] { 0.0, 0.0, 1.0 });
                    cad2d.SetColor_Edge(17, new double[] { 0.0, 0.0, 1.0 });

                    CadDrawerAry.Clear();
                    CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                    CadDrawerAry.InitTrans(Camera);
                    return true;
                }

                /*
                 // 図面表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                CadDrawerAry.InitTrans(Camera);
                 */

                /*
                // メッシュ表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawerMsh2D(new CMesher2D(cad2d, meshL)));
                CadDrawerAry.InitTrans(Camera);
                */

                //------------------------------------------------------------------
                // メッシュ作成
                //------------------------------------------------------------------
                // メッシュを作成し、ワールド座標系にセットする
                World.Clear();
                using (CMesher2D mesher2d = new CMesher2D(cad2d, meshL))
                {
                    baseId = World.AddMesh(mesher2d);
                    conv = World.GetIDConverter(baseId);
                }
            }
            // 界の値を扱うバッファ?を生成する。
            // フィールド値IDが返却される。
            //    要素の次元: 2次元 界: 複素数スカラー 微分タイプ: 値 要素セグメント: 角節点
            FieldValId = World.MakeField_FieldElemDim(baseId, 2,
                FIELD_TYPE.ZSCALAR, FIELD_DERIVATION_TYPE.VALUE, ELSEG_TYPE.CORNER);

            // 領域
            //   ワールド座標系のループIDを取得
            //   媒質をループ単位で指定する
            FieldLoopId = 0;
            {
                // ワールド座標系のループIDを取得
                uint[] loopId_cad_list  = new uint[loopCnt_cad];
                for (int i = 0; i < loopCnt_cad; i++)
                {
                    loopId_cad_list[i] = (uint)(i + 1);
                }
                int[] mediaIndex_list = new int[loopId_cad_list.Length];
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    int mediaIndex = Medias.IndexOf(mediaVacumn);
                    if (slab_loopId_cad_list.Contains(loopId_cad_list[i]))
                    {
                        mediaIndex = Medias.IndexOf(mediaCore);
                    }
                    else if (grating_loopId_cad_list.Contains(loopId_cad_list[i]))
                    {
                        mediaIndex = Medias.IndexOf(mediaGrating);
                    }
                    mediaIndex_list[i] = mediaIndex;
                }

                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    uint loopId_cad = loopId_cad_list[i];
                    int mediaIndex = mediaIndex_list[i];
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                    {
                        wg2d.World.Loop loop = new wg2d.World.Loop();
                        loop.Set(lId1, mediaIndex);
                        LoopDic.Add(lId1, loop);
                    }
                }
                //System.Diagnostics.Debug.WriteLine("lId:" + lId1);
                FieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
            }

            // 境界条件を設定する
            //   固定境界条件(強制境界)
            //   ワールド座標系の辺IDを取得
            //   媒質は指定しない
            FieldForceBcId = 0;
            {
                uint[] eId_cad_list = {2, 3, 5, 6};
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                }
                // フィールドIDを取得
                FieldForceBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldForceBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
            }
            // 開口条件
            //   ワールド座標系の辺IDを取得
            //   辺単位で媒質を指定する
            FieldPortBcIdList.Clear();
            uint[][] eId_cad_port_list = { port1_eId_list, port2_eId_list, portSrc_eId_list };
            uint[] core_eId_cad_list = { port1_core_eId, port2_core_eId, portSrc_core_eId };
            for (int portIndex = 0; portIndex < (portCnt + 1); portIndex++) // ポート + 励振境界
            {
                uint[] eId_cad_port = eId_cad_port_list[portIndex];
                uint core_eId = core_eId_cad_list[portIndex];
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < eId_cad_port.Length; i++)
                {
                    uint eId_cad = eId_cad_port[i];
                    int mediaIndex = Medias.IndexOf(mediaVacumn);
                    if (eId_cad == core_eId)
                    {
                        mediaIndex = Medias.IndexOf(mediaCore);
                    }
                    else
                    {
                        mediaIndex = Medias.IndexOf(mediaVacumn);
                    }
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                    {
                        wg2d.World.Edge edge = new wg2d.World.Edge();
                        edge.Set(eId, mediaIndex);
                        EdgeDic.Add(eId, edge);
                    }
                }
                uint workFieldPortBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldPortBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
                FieldPortBcIdList.Add(workFieldPortBcId);
            }

            // 観測点
            VIdRefList.Clear();
            uint[] vId_cad_refPort = { 7, 8 };
            foreach (uint vId_cad in vId_cad_refPort)
            {
                uint vId = conv.GetIdEA_fromCad(vId_cad, CAD_ELEM_TYPE.VERTEX);
                VIdRefList.Add(vId);
            }

            return true;
        }
Exemplo n.º 5
0
        /// <summary>
        /// 誘電体スラブ導波路
        /// </summary>
        /// <param name="probNo"></param>
        /// <param name="WaveguideWidth"></param>
        /// <param name="timeLoopCnt"></param>
        /// <param name="timeDelta"></param>
        /// <param name="gaussianT0"></param>
        /// <param name="gaussianTp"></param>
        /// <param name="NormalizedFreqSrc"></param>
        /// <param name="NormalizedFreq1"></param>
        /// <param name="NormalizedFreq2"></param>
        /// <param name="GraphFreqInterval"></param>
        /// <param name="WaveModeDv"></param>
        /// <param name="World"></param>
        /// <param name="FieldValId"></param>
        /// <param name="FieldLoopId"></param>
        /// <param name="FieldForceBcId"></param>
        /// <param name="FieldPmlLoopIdList"></param>
        /// <param name="PmlStPosXList"></param>
        /// <param name="FieldPortSrcBcId"></param>
        /// <param name="VIdRefList"></param>
        /// <param name="Medias"></param>
        /// <param name="LoopDic"></param>
        /// <param name="EdgeDic"></param>
        /// <param name="isCadShow"></param>
        /// <param name="CadDrawerAry"></param>
        /// <param name="Camera"></param>
        /// <returns></returns>
        public static bool SetProblem(
            int probNo,
            ref double WaveguideWidth,
            ref bool isPCWaveguide,
            ref double latticeA,
            ref int timeLoopCnt,
            ref double timeDelta,
            ref double gaussianT0,
            ref double gaussianTp,
            ref double NormalizedFreqSrc,
            ref double NormalizedFreq1,
            ref double NormalizedFreq2,
            ref double GraphFreqInterval,
            ref WgUtil.WaveModeDV WaveModeDv,
             ref CFieldWorld World,
            ref uint FieldValId,
            ref uint FieldLoopId,
            ref uint FieldForceBcId,
            ref IList<uint> FieldPmlLoopIdList,
            ref IList<bool> IsPmlYDirectionList,
            ref IList<double> PmlStPosXList,
            ref IList<double> PmlLengthList,
            ref uint FieldPortSrcBcId,
            ref IList<uint> VIdRefList,
            ref IList<MediaInfo> Medias,
            ref Dictionary<uint, wg2d.World.Loop> LoopDic,
            ref Dictionary<uint, wg2d.World.Edge> EdgeDic,
            ref bool isCadShow,
            ref CDrawerArray CadDrawerAry,
            ref CCamera Camera
            )
        {
            WaveguideWidth = 3.0e-3 * 30 * 4;

            // メッシュの分割長さ
            //double meshL = WaveguideWidth * 1.0 / 60.0;
            //double meshL = WaveguideWidth * 1.0 / 65.0; // メモリ不足
            double meshL = WaveguideWidth * 1.0 / 61.0;
            double meshLForTimeDelta = meshL;

            // 形状設定で使用する単位長さ
            double unitLen = WaveguideWidth / 60.0;
            // PMLの長さ
            double pmlLength = 10 * unitLen;
            //double pmlLength = 12 * unitLen;
            // 導波管不連続領域の長さ
            double disconLength = 25.0 / 60.0 * WaveguideWidth;
            disconLength += 2.0 * pmlLength;

            // 誘電体スラブ導波路幅
            double slabWidth =WaveguideWidth / 30.0;
            // 誘電体スラブ比誘電率
            double coreEps = 2.402500;

            // 励振位置
            //double srcPosX = pmlLength + 10 * unitLen;
            double srcPosX = pmlLength + 9 * unitLen;
            // 観測点
            int port1OfsX = 5;
            int port2OfsX = 5;
            double port1PosX = srcPosX + port1OfsX * unitLen;
            double port1PosY = WaveguideWidth * 0.5;
            double port2PosX = disconLength - pmlLength - port2OfsX * unitLen;
            double port2PosY = WaveguideWidth * 0.5;

            // 時間領域
            //double courantNumber = 0.5;
            double courantNumber = 0.5;
            //timeLoopCnt = 3000;
            timeLoopCnt = 1000;
            // 時刻刻み
            //timeDelta = courantNumber * meshL / (c0 * Math.Sqrt(2.0));
            timeDelta = courantNumber * meshLForTimeDelta / (c0 * Math.Sqrt(2.0));

            // モード計算規格化周波数(搬送波規格化周波数)
            NormalizedFreqSrc = 12.0;

            /*
            // ガウシアンパルス
            gaussianT0 = 30 * timeDelta;
            gaussianTp = gaussianT0 / (Math.Sqrt(2.0) * 4.0);
             */

            // 正弦波変調ガウシアンパルス
            // 波数
            double k0Src = NormalizedFreqSrc * pi / WaveguideWidth;
            // 波長
            double waveLengthSrc = 2.0 * pi / k0Src;
            // 周波数
            double freqSrc = c0 / waveLengthSrc;
            // 角周波数
            double omegaSrc = 2.0 * pi * freqSrc;
            // 搬送波の振動回数
            int nCycle = 5;
            //gaussianT0 = (1.0 / freqSrc) * nCycle / 2;
            //gaussianT0 = 0.5 * (1.0 / freqSrc) * nCycle / 2;
            gaussianT0 = 0.48 * (1.0 / freqSrc) * nCycle / 2;

            gaussianTp = gaussianT0 / (2.0 * Math.Sqrt(2.0 * Math.Log(2.0)));

            // 周波数領域
            NormalizedFreq1 = 10.0;
            NormalizedFreq2 = 20.0;
            GraphFreqInterval = 2.0;

            // ポート数
            const int portCnt = 2;

            // 媒質リスト作成
            MediaInfo mediaVacumn = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { 1.0, 0.0, 0.0 },
                   { 0.0, 1.0, 0.0 },
                   { 0.0, 0.0, 1.0 }
                }
            );
            MediaInfo mediaCore = new MediaInfo
            (
                new double[3, 3]
                {
                   { 1.0/1.0, 0.0,     0.0     },
                   { 0.0,     1.0/1.0, 0.0     },
                   { 0.0,     0.0,     1.0/1.0 }
                },
                new double[3, 3]
                {
                   { coreEps,  0.0,  0.0 },
                   {  0.0, coreEps,  0.0 },
                   {  0.0,  0.0, coreEps }
                }
            );
            Medias.Add(mediaVacumn);
            Medias.Add(mediaCore);

            // 図面作成、メッシュ生成
            double coreY1 = (WaveguideWidth - slabWidth) * 0.5;
            double coreY2 = coreY1 + slabWidth;
            // 全ループ数
            uint loopCnt_cad = 12;
            uint[] slab_loopId_cad_list = {6, 8, 10, 12};
            // ポート1のPML領域ループリスト
            uint[] port1_pml_loopIds_cad = { 1, 5, 6 };
            // ポート2のPML領域ループリスト
            uint[] port2_pml_loopIds_cad = { 4, 11, 12 };
            // PML開始位置X座標
            double[] pmlStPosX_list = { pmlLength, (disconLength - pmlLength) };
            // 観測点頂点ID
            uint[] portRef_vIds_cad = new uint[portCnt];
            // ポート1Pml終端、ポート1、励振面、ポート2、ポート2PML終端
            uint[][] eId_cad_port_list = new uint[5][] {
                new uint[] { 1, 15, 14 },
                new uint[] { 11, 17, 16},
                new uint[] { 12, 19, 18},
                new uint[] { 13, 21, 20},
                new uint[] { 6, 23, 22},
            };
            uint[] eId_cad_core_list = { 15, 17, 19, 21, 23 };
            uint baseId = 0;
            CIDConvEAMshCad conv = null;
            using (CCadObj2D cad2d = new CCadObj2D())
            {
                //------------------------------------------------------------------
                // 図面作成
                //------------------------------------------------------------------
                {
                    // ループ1
                    IList<CVector2D> pts = new List<CVector2D>();
                    pts.Add(new CVector2D(0.0, WaveguideWidth));  // 頂点1
                    pts.Add(new CVector2D(0.0, 0.0)); // 頂点2
                    pts.Add(new CVector2D(pmlLength, 0.0)); // 頂点3
                    pts.Add(new CVector2D(srcPosX, 0.0)); // 頂点4
                    pts.Add(new CVector2D(disconLength - pmlLength, 0.0)); // 頂点5
                    pts.Add(new CVector2D(disconLength, 0.0)); // 頂点6
                    pts.Add(new CVector2D(disconLength, WaveguideWidth)); // 頂点7
                    pts.Add(new CVector2D(disconLength - pmlLength, WaveguideWidth)); // 頂点8
                    pts.Add(new CVector2D(srcPosX, WaveguideWidth)); // 頂点9
                    pts.Add(new CVector2D(pmlLength, WaveguideWidth)); // 頂点10
                    uint lId1 = cad2d.AddPolygon(pts).id_l_add;
                    uint lId2 = cad2d.ConnectVertex_Line(3, 10).id_l_add;
                    uint lId3 = cad2d.ConnectVertex_Line(4, 9).id_l_add;
                    uint lId4 = cad2d.ConnectVertex_Line(5, 8).id_l_add;
                }
                {
                    uint parent_id_l_cad = 3;
                    // 観測点
                    portRef_vIds_cad[0] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port1PosX, port1PosY)).id_v_add; // 頂点11
                    portRef_vIds_cad[1] = cad2d.AddVertex(CAD_ELEM_TYPE.LOOP, parent_id_l_cad, new CVector2D(port2PosX, port2PosY)).id_v_add; // 頂点12
                    // check
                    foreach (uint vId in portRef_vIds_cad)
                    {
                        System.Diagnostics.Debug.Assert(vId != 0);
                    }
                }

                // スラブ導波路と境界の交点
                double[] portX_list = { 0.0, pmlLength, srcPosX, disconLength - pmlLength, disconLength };
                IList<uint[]> slab_vIds_list = new List<uint[]>();
                for (int portIndex = 0; portIndex < 5; portIndex++)
                {
                    uint parent_eId = eId_cad_port_list[portIndex][0];
                    double portX = portX_list[portIndex];

                    double workY1 = 0.0;
                    double workY2 = 0.0;
                    if (portIndex == 0)
                    {
                        workY1 = coreY1;
                        workY2 = coreY2;
                    }
                    else
                    {
                        workY1 = coreY2;
                        workY2 = coreY1;
                    }
                    uint vId1 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(portX, workY1)).id_v_add;
                    uint vId2 = cad2d.AddVertex(CAD_ELEM_TYPE.EDGE, parent_eId, new CVector2D(portX, workY2)).id_v_add;
                    uint[] work_vIds = new uint[2];
                    if (portIndex == 0)
                    {
                        work_vIds[0] = vId1;
                        work_vIds[1] = vId2;
                    }
                    else
                    {
                        work_vIds[0] = vId2;
                        work_vIds[1] = vId1;
                    }
                    slab_vIds_list.Add(work_vIds);
                }
                // スラブ導波路
                for (int portIndex = 0; portIndex < (5 - 1); portIndex++)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        uint work_vId1 = slab_vIds_list[portIndex][i];
                        uint work_vId2 = slab_vIds_list[(portIndex + 1)][i];
                        uint work_eId = cad2d.ConnectVertex_Line(work_vId1, work_vId2).id_e_add;
                    }
                }

                //isCadShow = true;
                // 図面表示
                if (isCadShow)
                {
                    // PML領域に色を付ける
                    uint[][] port_pml_loopIds_cad_list = { port1_pml_loopIds_cad, port2_pml_loopIds_cad };
                    for (int portIndex = 0; portIndex < portCnt; portIndex++)
                    {
                        uint[] work_lId_list = port_pml_loopIds_cad_list[portIndex];
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 0.5, 0.5, 0.5 });
                        }
                    }
                    // 誘電体スラブ導波路に色を付ける
                    {
                        uint[] work_lId_list = slab_loopId_cad_list;
                        foreach (uint lId in work_lId_list)
                        {
                            cad2d.SetColor_Loop(lId, new double[] { 1.0, 0.0, 1.0 });
                        }
                    }
                    // 境界の辺に色を付ける
                    double[][] work_color_B_list = new double[5][] {
                        new double[] { 0.0, 1.0, 0.0 },
                        new double[] { 0.0, 1.0, 0.0 },
                        new double[] { 1.0, 0.0, 0.0 },
                        new double[] { 1.0, 1.0, 0.0 },
                        new double[] { 1.0, 1.0, 0.0 },
                    };
                    for (int portIndex = 0; portIndex < 5; portIndex++)
                    {
                        uint[] work_eId_list = eId_cad_port_list[portIndex];
                        double[] work_color_B = work_color_B_list[portIndex];
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, work_color_B);
                        }
                    }

                    // 境界の誘電体スラブの辺
                    foreach (uint eId in eId_cad_core_list)
                    {
                        cad2d.SetColor_Edge(eId, new double[] { 1.0, 0.0, 0.0 });
                    }

                    // DEBUG
                    {
                        uint[] work_eId_list = { 2, 3, 4, 5, 7, 8, 9, 10 };
                        foreach (uint eId in work_eId_list)
                        {
                            cad2d.SetColor_Edge(eId, new double[] { 1.0, 1.0, 1.0 });
                        }
                    }

                    CadDrawerAry.Clear();
                    CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                    CadDrawerAry.InitTrans(Camera);
                    return true;
                }

                /*
                 // 図面表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawer_Cad2D(cad2d));
                CadDrawerAry.InitTrans(Camera);
                 */

                /*
                // メッシュ表示
                isCadShow = true;
                CadDrawerAry.Clear();
                CadDrawerAry.PushBack(new CDrawerMsh2D(new CMesher2D(cad2d, meshL)));
                CadDrawerAry.InitTrans(Camera);
                */

                //------------------------------------------------------------------
                // メッシュ作成
                //------------------------------------------------------------------
                // メッシュを作成し、ワールド座標系にセットする
                World.Clear();
                using (CMesher2D mesher2d = new CMesher2D(cad2d, meshL))
                {
                    baseId = World.AddMesh(mesher2d);
                    conv = World.GetIDConverter(baseId);
                }
            }
            // 界の値を扱うバッファ?を生成する。
            // フィールド値IDが返却される。
            //    要素の次元: 2次元 界: 複素数スカラー 微分タイプ: 値 要素セグメント: 角節点
            FieldValId = World.MakeField_FieldElemDim(baseId, 2,
                FIELD_TYPE.ZSCALAR, FIELD_DERIVATION_TYPE.VALUE, ELSEG_TYPE.CORNER);

            // 領域
            //   ワールド座標系のループIDを取得
            //   媒質をループ単位で指定する
            FieldLoopId = 0;
            {
                // ワールド座標系のループIDを取得
                uint[] loopId_cad_list  = new uint[loopCnt_cad];
                for (int i = 0; i < loopCnt_cad; i++)
                {
                    loopId_cad_list[i] = (uint)(i + 1);
                }
                int[] mediaIndex_list = new int[loopId_cad_list.Length];
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    int mediaIndex = Medias.IndexOf(mediaVacumn);
                    if (slab_loopId_cad_list.Contains(loopId_cad_list[i]))
                    {
                        mediaIndex = Medias.IndexOf(mediaCore);
                    }
                    mediaIndex_list[i] = mediaIndex;
                }

                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < loopId_cad_list.Length; i++)
                {
                    uint loopId_cad = loopId_cad_list[i];
                    int mediaIndex = mediaIndex_list[i];
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                    {
                        wg2d.World.Loop loop = new wg2d.World.Loop();
                        loop.Set(lId1, mediaIndex);
                        LoopDic.Add(lId1, loop);
                    }
                }
                //System.Diagnostics.Debug.WriteLine("lId:" + lId1);
                FieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
            }
            // PML領域
            FieldPmlLoopIdList.Clear();
            IsPmlYDirectionList.Clear();
            PmlStPosXList.Clear();
            PmlLengthList.Clear();
            uint[][] loopId_cad_list_pml = { port1_pml_loopIds_cad, port2_pml_loopIds_cad };
            for (int portIndex = 0; portIndex < portCnt; portIndex++)
            {
                uint[] loopId_cad_list = loopId_cad_list_pml[portIndex];
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint loopId_cad in loopId_cad_list)
                {
                    uint lId1 = conv.GetIdEA_fromCad(loopId_cad, CAD_ELEM_TYPE.LOOP);
                    aEA.Add(lId1);
                }
                uint workFieldLoopId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldLoopId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0);
                FieldPmlLoopIdList.Add(workFieldLoopId);
                // Y方向PML?
                bool isPmlYDirection = false;
                IsPmlYDirectionList.Add(isPmlYDirection);
                // PML開始位置
                double pmlStPosX = pmlStPosX_list[portIndex];
                PmlStPosXList.Add(pmlStPosX);
                // PML長さ
                PmlLengthList.Add(pmlLength);
            }

            // 境界条件を設定する
            //   固定境界条件(強制境界)
            //   ワールド座標系の辺IDを取得
            //   媒質は指定しない
            FieldForceBcId = 0;
            {
                uint[] eId_cad_list = { 2, 3, 4, 5, 7, 8, 9, 10 }; // PML終端磁気壁
                //uint[] eId_cad_list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // PML終端電気壁
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                foreach (uint eId_cad in eId_cad_list)
                {
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                }
                // フィールドIDを取得
                FieldForceBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(FieldForceBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
            }
            // 開口条件
            //   ワールド座標系の辺IDを取得
            //   辺単位で媒質を指定する
            FieldPortSrcBcId = 0;
            {
                uint portIndex = 2; // 励振面
                uint[] eId_cad_port = eId_cad_port_list[portIndex];
                uint core_eId = eId_cad_core_list[portIndex];
                // 要素アレイのリスト
                IList<uint> aEA = new List<uint>();
                for (int i = 0; i < eId_cad_port.Length; i++)
                {
                    uint eId_cad = eId_cad_port[i];
                    int mediaIndex = Medias.IndexOf(mediaVacumn);
                    if (eId_cad == core_eId)
                    {
                        mediaIndex = Medias.IndexOf(mediaCore);
                    }
                    else
                    {
                        mediaIndex = Medias.IndexOf(mediaVacumn);
                    }
                    uint eId = conv.GetIdEA_fromCad(eId_cad, CAD_ELEM_TYPE.EDGE);
                    aEA.Add(eId);
                    {
                        wg2d.World.Edge edge = new wg2d.World.Edge();
                        edge.Set(eId, mediaIndex);
                        EdgeDic.Add(eId, edge);
                    }
                }
                uint workFieldPortBcId = World.GetPartialField(FieldValId, aEA);
                CFieldValueSetter.SetFieldValue_Constant(workFieldPortBcId, 0, FIELD_DERIVATION_TYPE.VALUE, World, 0); // 境界の界を0で設定
                FieldPortSrcBcId = workFieldPortBcId;
            }

            // 観測点
            VIdRefList.Clear();
            uint[] vId_cad_refPort = portRef_vIds_cad;
            foreach (uint vId_cad in vId_cad_refPort)
            {
                uint vId = conv.GetIdEA_fromCad(vId_cad, CAD_ELEM_TYPE.VERTEX);
                VIdRefList.Add(vId);
            }

            return true;
        }