/// <summary> /// 図面情報を読み込む /// </summary> /// <param name="filename"></param> /// <param name="areaSelection"></param> /// <param name="edgeList"></param> /// <param name="yBoundarySelection">2次的な情報(edgeListから生成される)</param> /// <param name="xBoundarySelection">2次的な情報(edgeListから生成される)</param> /// <param name="incidentPortNo"></param> /// <param name="medias"></param> /// <param name="ndivForOneLattice"></param> /// <param name="rodRadiusRatio"></param> /// <param name="rodCircleDiv"></param> /// <param name="rodRadiusDiv"></param> /// <returns></returns> public static bool LoadFromFile( string filename, ref CadLogic.CellType[,] AreaSelection, ref IList <Edge> EdgeList, ref bool[,] YBoundarySelection, ref bool[,] XBoundarySelection, ref int IncidentPortNo, ref MediaInfo[] Medias, ref int ndivForOneLattice, ref double rodRadiusRatio, ref int rodCircleDiv, ref int rodRadiusDiv ) { bool success = false; Size MaxDiv = Constants.MaxDiv; int MaxMediaCount = Medias.Length; for (int y = 0; y < AreaSelection.GetLength(0); y++) { for (int x = 0; x < AreaSelection.GetLength(1); x++) { AreaSelection[y, x] = CadLogic.CellType.Empty; } } try { using (StreamReader sr = new StreamReader(filename)) { string line; string[] tokens; const char delimiter = ','; int cnt = 0; // 領域選択 line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens[0] != "AreaSelection") { MessageBox.Show("領域選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 3) { MessageBox.Show("領域選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } int x = int.Parse(tokens[0]); int y = int.Parse(tokens[1]); CadLogic.CellType cellType = CadLogic.GetCellTypeFromStr(tokens[2]); if ((x >= 0 && x < MaxDiv.Width) && (y >= 0 && y < MaxDiv.Height)) { AreaSelection[y, x] = cellType; } else { MessageBox.Show("領域選択座標値が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } } // ポート境界 line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens[0] != "EdgeList") { MessageBox.Show("境界選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 5) { MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } int edgeNo = int.Parse(tokens[0]); Point[] p = new Point[2]; for (int k = 0; k < p.Length; k++) { p[k] = new Point(); p[k].X = int.Parse(tokens[1 + k * 2]); p[k].Y = int.Parse(tokens[1 + k * 2 + 1]); } Size delta = new Size(0, 0); if (p[0].X == p[1].X) { // Y方向境界 delta = new Size(0, 1); } else if (p[0].Y == p[1].Y) { // X方向境界 delta = new Size(1, 0); } else { MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } Edge edge = new Edge(delta); edge.No = edgeNo; edge.Set(p[0], p[1]); EdgeList.Add(edge); } foreach (Edge edge in EdgeList) { if (edge.Delta.Width == 0) { // Y方向境界 int x = edge.Points[0].X; int sty = edge.Points[0].Y; int edy = edge.Points[1].Y; for (int y = sty; y < edy; y++) { YBoundarySelection[y, x] = true; } } else if (edge.Delta.Height == 0) { // X方向境界 int y = edge.Points[0].Y; int stx = edge.Points[0].X; int edx = edge.Points[1].X; for (int x = stx; x < edx; x++) { XBoundarySelection[y, x] = true; } } else { MessageBox.Show("Not implemented"); } } line = sr.ReadLine(); if (line.Length == 0) { MessageBox.Show("入射ポート番号がありません"); return(success); } tokens = line.Split(delimiter); if (tokens[0] != "IncidentPortNo") { MessageBox.Show("入射ポート番号がありません"); return(success); } IncidentPortNo = int.Parse(tokens[1]); line = sr.ReadLine(); // 媒質情報? tokens = line.Split(delimiter); if (tokens[0] != "Medias") { MessageBox.Show("媒質情報がありません"); return(success); } cnt = int.Parse(tokens[1]); if (cnt > MaxMediaCount) { MessageBox.Show("媒質情報の個数が不正です"); return(success); } for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); if (line.Length == 0) { MessageBox.Show("媒質情報が不正です"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 1 + 9 + 9) { MessageBox.Show("媒質情報が不正です"); return(success); } int mediaIndex = int.Parse(tokens[0]); System.Diagnostics.Debug.Assert(mediaIndex == i); double[,] p = new double[3, 3]; for (int m = 0; m < p.GetLength(0); m++) { for (int n = 0; n < p.GetLength(1); n++) { p[m, n] = double.Parse(tokens[1 + m * p.GetLength(1) + n]); } } Medias[i].SetP(p); double[,] q = new double[3, 3]; for (int m = 0; m < q.GetLength(0); m++) { for (int n = 0; n < q.GetLength(1); n++) { q[m, n] = double.Parse(tokens[1 + 9 + m * q.GetLength(1) + n]); } } Medias[i].SetQ(q); } line = sr.ReadLine(); if (line == null) { MessageBox.Show("格子1辺の分割数がありません"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "ndivForOneLattice") { MessageBox.Show("格子1辺の分割数がありません"); return(success); } ndivForOneLattice = int.Parse(tokens[1]); line = sr.ReadLine(); if (line == null) { MessageBox.Show("ロッドの半径がありません"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodRadiusRatio") { MessageBox.Show("ロッドの半径がありません"); return(success); } rodRadiusRatio = double.Parse(tokens[1]); line = sr.ReadLine(); if (line == null) { MessageBox.Show("ロッドの円周方向の分割数がありません"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodCircleDiv") { MessageBox.Show("ロッドの円周方向の分割数がありません"); return(success); } rodCircleDiv = int.Parse(tokens[1]); line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodRadiusDiv") { MessageBox.Show("ロッドの半径方向の分割数がありません"); return(success); } rodRadiusDiv = int.Parse(tokens[1]); } success = true; } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); MessageBox.Show(exception.Message); } return(success); }
/// <summary> /// 2次三角形要素メッシュを作成する /// </summary> /// <param name="ndivForOneLattice">格子1辺の分割数</param> /// <param name="rodRadiusRatio">ロッドの半径割合</param> /// <param name="rodCircleDiv">ロッドの円周方向分割数</param> /// <param name="rodRadiusDiv">ロッドの半径方向分割数(1でもメッシュサイズが小さければ複数に分割される)</param> /// <param name="maxDiv">図面の領域サイズ</param> /// <param name="areaSelection">マス目選択フラグ配列</param> /// <param name="edgeList">ポート境界リスト</param> /// <param name="doubleCoords">[OUT]座標リスト(このリストのインデックス+1が節点番号として扱われます)</param> /// <param name="elements">[OUT]要素データリスト 要素データはint[] = { 要素番号, 媒質インデックス, 節点番号1, 節点番号2, ...}</param> /// <param name="portList">[OUT]ポート節点リストのリスト</param> /// <param name="forceBCNodeNumbers">強制境界節点配列</param> /// <param name="elemNoPeriodicList">周期領域の要素番号リスト(ポート - 要素番号)</param> /// <param name="nodePeriodicBList">周期領域境界の節点番号リスト(ポート - 周期領域境界 - 節点番号)</param> /// <param name="defectNodePeriodicList">周期領域の欠陥部の節点番号リスト(ポート- 節点番号)</param> /// <returns></returns> public static bool MkTriMeshSecondOrder( int ndivForOneLattice, double rodRadiusRatio, int rodCircleDiv, int rodRadiusDiv, Size maxDiv, CadLogic.CellType[,] areaSelection, IList<Edge> edgeList, out IList<double[]> doubleCoords, out IList<int[]> elements, out IList<IList<int>> portList, out int[] forceBCNodeNumbers, out IList<IList<uint>> elemNoPeriodicList, out IList<IList<IList<int>>> nodePeriodicBList, out IList<IList<int>> defectNodePeriodicList ) { // セルのメッシュを取得する // 欠陥部セル double[,] ptsInCell_Defect = null; uint[,] nodeBInCell_Defect = null; uint[,] elemNodeInCell_Defect = null; WgMesh.GetCellMesh_Defect_TriSecondOrder( ndivForOneLattice, out ptsInCell_Defect, out nodeBInCell_Defect, out elemNodeInCell_Defect ); // 誘電体ロッドセル double[,] ptsInCell_Rod = null; uint[,] nodeBInCell_Rod = null; uint[] elemLoopIdInCell_Rod = null; uint rodLoopId = 0; uint[,] elemNodeInCell_Rod = null; WgMesh.GetCellMesh_Rod_TriSecondOrder( ndivForOneLattice, rodRadiusRatio, rodCircleDiv, rodRadiusDiv, out ptsInCell_Rod, out nodeBInCell_Rod, out elemLoopIdInCell_Rod, out rodLoopId, out elemNodeInCell_Rod ); elements = new List<int[]>(); // 要素リスト // 座標 - 節点番号対応マップ Dictionary<string, uint> coordToNo = new Dictionary<string, uint>(); // セル→節点番号リストマップ uint[,][] nodeNumbersCellList = new uint[maxDiv.Height, maxDiv.Width][]; // セル→要素番号リストマップ uint[,][] elemNoCellList = new uint[maxDiv.Height, maxDiv.Width][]; // 節点座標 IList<double[]> coords = new List<double[]>(); // 強制境界 Dictionary<int, bool> forceBCNodeNumberDic = new Dictionary<int, bool>(); int nodeCounter = 0; // 節点番号カウンター int elementCounter = 0; // 要素番号カウンター for (int x = 0; x < maxDiv.Width; x++) { for (int y = 0; y < maxDiv.Height; y++) { if (areaSelection[y, x] != CadLogic.CellType.Empty) { CadLogic.CellType workCellType = areaSelection[y, x]; double[,] work_ptsInCell = null; uint[,] work_nodeBInCell = null; uint[] work_elemLoopIdInCell = null; uint work_rodLoopId = 0; uint[,] work_elemNodeInCell = null; if (workCellType == CadLogic.CellType.Rod) { work_ptsInCell = ptsInCell_Rod; work_nodeBInCell = nodeBInCell_Rod; work_elemLoopIdInCell = elemLoopIdInCell_Rod; work_rodLoopId = rodLoopId; work_elemNodeInCell = elemNodeInCell_Rod; } else { System.Diagnostics.Debug.Assert(workCellType == CadLogic.CellType.Defect); work_ptsInCell = ptsInCell_Defect; work_nodeBInCell = nodeBInCell_Defect; work_elemLoopIdInCell = null; work_rodLoopId = 0; work_elemNodeInCell = elemNodeInCell_Defect; } // 全体節点番号 int nodeCntInCell = work_ptsInCell.GetLength(0); // セル内の節点の座標 double[][] pps = new double[nodeCntInCell][]; for (int ino = 0; ino < pps.Length; ino++) { pps[ino] = new double[2]; pps[ino][0] = work_ptsInCell[ino, 0] + x; pps[ino][1] = work_ptsInCell[ino, 1] + y; } // セル内の節点の節点番号 uint[] nodeNumbers = new uint[nodeCntInCell]; for (int ino = 0; ino < nodeCntInCell; ino++) { double[] pp = pps[ino]; double xx = pp[0]; double yy = pp[1]; string coordStr = string.Format("{0:F06}_{1:F06}", xx, yy); uint nodeNumber = 0; if (coordToNo.ContainsKey(coordStr)) { // 追加済み nodeNumber = coordToNo[coordStr]; } else { nodeNumber = (uint)(++nodeCounter); coordToNo.Add(coordStr, nodeNumber); coords.Add(new double[2] { xx, yy }); System.Diagnostics.Debug.Assert(coords.Count == nodeNumber); } System.Diagnostics.Debug.Assert(nodeNumber != 0); // セル内の節点の全体節点番号 nodeNumbers[ino] = nodeNumber; } nodeNumbersCellList[y, x] = nodeNumbers; // 強制境界判定 { int boundaryIndex = -1; if (x == 0 || (x >= 1 && areaSelection[y, x - 1] == CadLogic.CellType.Empty)) { // 左の境界 boundaryIndex = 0; } else if (x == maxDiv.Width - 1 || (x <= maxDiv.Width - 2 && areaSelection[y, x + 1] == CadLogic.CellType.Empty)) { // 右の境界 boundaryIndex = 1; } else if (y == 0 || (y >= 1 && areaSelection[y - 1, x] == CadLogic.CellType.Empty)) { // 下の境界 boundaryIndex = 2; } else if (y == maxDiv.Height - 1 || (y <= maxDiv.Height - 2 && areaSelection[y + 1, x] == CadLogic.CellType.Empty)) { // 上の境界 boundaryIndex = 3; } if (boundaryIndex != -1) { int nodeCntB = work_nodeBInCell.GetLength(1); uint[] work_no_B = new uint[nodeCntB]; for (int ino = 0; ino < nodeCntB; ino++) { work_no_B[ino] = work_nodeBInCell[boundaryIndex, ino]; } for (int ino = 0; ino < nodeCntB; ino++) { uint noCell = work_no_B[ino]; uint nodeNumber = nodeNumbers[noCell]; if (!forceBCNodeNumberDic.ContainsKey((int)nodeNumber)) { forceBCNodeNumberDic.Add((int)nodeNumber, true); double[] coord = coords[(int)nodeNumber - 1]; //System.Diagnostics.Debug.WriteLine("Force: (B{0}) {1} : {2}, {3}", boundaryIndex, nodeNumber, coord[0], coord[1]); } } } } int elemCntInCell = work_elemNodeInCell.GetLength(0); elemNoCellList[y, x] = new uint[elemCntInCell]; for (int ie = 0; ie < elemCntInCell; ie++) { uint[] workNodeElem = new uint[Constants.TriNodeCnt_SecondOrder]; for (int ino = 0; ino < Constants.TriNodeCnt_SecondOrder; ino++) { uint noCell = work_elemNodeInCell[ie, ino]; uint nodeNumber = nodeNumbers[noCell]; workNodeElem[ino] = nodeNumber; } // 媒質 int mediaIndex = 0; if (workCellType == CadLogic.CellType.Rod) { uint workLoopId = work_elemLoopIdInCell[ie]; if (workLoopId == rodLoopId) { mediaIndex = 1; } } // 要素追加 int elemNo = ++elementCounter; elements.Add(new int[] { elemNo, mediaIndex, (int)workNodeElem[0], (int)workNodeElem[1], (int)workNodeElem[2], (int)workNodeElem[3], (int)workNodeElem[4], (int)workNodeElem[5] }); elemNoCellList[y, x][ie] = (uint)elemNo; } } } } // ポート境界 int portCounter = 0; portList = new List<IList<int>>(); elemNoPeriodicList = new List<IList<uint>>(); nodePeriodicBList = new List<IList<IList<int>>>(); defectNodePeriodicList = new List<IList<int>>(); foreach (Edge edge in edgeList) { //System.Diagnostics.Debug.WriteLine("--------------"); portCounter++; System.Diagnostics.Debug.Assert(edge.No == portCounter); // ポート境界 IList<int> portNodes = null; // 周期構造領域 IList<uint> elemNoPeriodic = new List<uint>(); IList<IList<int>> nodePeriodicB = new List<IList<int>>(); IList<int> defectNodePeriodic = new List<int>(); if (edge.Delta.Width == 0) { // 1次線要素 int xx = edge.Points[0].X; int sty = edge.Points[0].Y; int edy = edge.Points[1].Y; int nodeCnt = coords.Count; IList<uint> workPortNodes = new List<uint>(); IList<double> workYs = new List<double>(); for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (Math.Abs(coord[0] - xx) < Constants.PrecisionLowerLimit && coord[1] >= sty - Constants.PrecisionLowerLimit && coord[1] <= edy + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; workPortNodes.Add(nodeNumber); workYs.Add(coord[1]); } } int portNodeCnt = workPortNodes.Count; double[] workYAry = workYs.ToArray(); Array.Sort(workYAry); int[] portNodeAry = new int[portNodeCnt]; for (int i = 0; i < portNodeCnt; i++) { double y = workYAry[i]; int orgIndex = workYs.IndexOf(y); uint nodeNumber = workPortNodes[orgIndex]; portNodeAry[i] = (int)nodeNumber; double[] coord = coords[(int)nodeNumber - 1]; //System.Diagnostics.Debug.WriteLine("portNode: {0}: {1}, {2}", nodeNumber, coord[0], coord[1]); } portNodes = portNodeAry.ToList(); // 周期構造1周期領域 bool isLeftOuterBoundary = true; // 左側が外部境界 int xxPeriodic = xx; // 左境界の場合 if (xx == (maxDiv.Width + 1) || (xx >= 1 && areaSelection[sty, xx - 1] != CadLogic.CellType.Empty)) { // 右側が外部境界の場合 xxPeriodic = xx - 1; isLeftOuterBoundary = false; } // 周期構造領域の要素番号 for (int y = sty; y < edy; y++) { uint[] workElemNoList = elemNoCellList[y, xxPeriodic]; if (workElemNoList == null) { continue; // 全体領域でセルが空の場所 } foreach (uint elemNo in workElemNoList) { elemNoPeriodic.Add(elemNo); } } // 周期構造領域境界の節点番号 // 外部境界 IList<int> workNodesB_Outer = portNodes; // 内部境界 IList<int> workNodesB_Inner = null; { int tagtxx = xx + 1; // 右側境界 if (!isLeftOuterBoundary) { // 右側が外部境界 tagtxx = xx - 1; // 左側境界 } IList<int> workNodesB = null; IList<uint> workPeriodicBNodes = new List<uint>(); IList<double> workPeriodicBYs = new List<double>(); for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (Math.Abs(coord[0] - tagtxx) < Constants.PrecisionLowerLimit && coord[1] >= sty - Constants.PrecisionLowerLimit && coord[1] <= edy + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; workPeriodicBNodes.Add(nodeNumber); workPeriodicBYs.Add(coord[1]); } } int periodicBNodeCnt = workPeriodicBNodes.Count; double[] workPeriodicBYAry = workPeriodicBYs.ToArray(); Array.Sort(workPeriodicBYAry); int[] periodicBNodeAry = new int[periodicBNodeCnt]; for (int i = 0; i < periodicBNodeCnt; i++) { double y = workPeriodicBYAry[i]; int orgIndex = workPeriodicBYs.IndexOf(y); uint nodeNumber = workPeriodicBNodes[orgIndex]; periodicBNodeAry[i] = (int)nodeNumber; int portIndex = portCounter - 1; double[] coord = coords[(int)nodeNumber - 1]; //System.Diagnostics.Debug.WriteLine("nodeB_Inner: {0}: {1}: {2}, {3}", portIndex, nodeNumber, coord[0], coord[1]); } workNodesB = periodicBNodeAry.ToList(); // 格納 workNodesB_Inner = workNodesB; } // 格納 nodePeriodicB.Add(workNodesB_Outer); nodePeriodicB.Add(workNodesB_Inner); // 周期構造領域内欠陥部の節点番号 double periodicDistance = 1.0; for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (coord[0] >= xxPeriodic - Constants.PrecisionLowerLimit && coord[0] <= xxPeriodic + periodicDistance + Constants.PrecisionLowerLimit && coord[1] >= sty - Constants.PrecisionLowerLimit && coord[1] <= edy + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; { // セルのx, yインデックス int work_intX = (int)Math.Round(coord[0]); int work_intY1 = (int)Math.Round(coord[1]); if (work_intX >= maxDiv.Width) { // 解析領域の右境界のとき work_intX--; } if (work_intY1 >= maxDiv.Height) { // 解析領域の上境界のとき work_intY1--; } int work_intY2 = work_intY1 - 1; if (work_intY2 < 0) { work_intY2 = 0; } CadLogic.CellType workCellType1 = areaSelection[work_intY1, work_intX]; if (workCellType1 == CadLogic.CellType.Empty && (work_intX - 1) >= 0 && areaSelection[work_intY1, work_intX - 1] != CadLogic.CellType.Empty) { // 不連続領域の右境界のとき work_intX--; workCellType1 = areaSelection[work_intY1, work_intX]; } CadLogic.CellType workCellType2 = areaSelection[work_intY2, work_intX]; if (workCellType1 == CadLogic.CellType.Defect || workCellType2 == CadLogic.CellType.Defect) { defectNodePeriodic.Add((int)nodeNumber); } } } } } else if (edge.Delta.Height == 0) { // 1次線要素 int yy = edge.Points[0].Y; int stx = edge.Points[0].X; int edx = edge.Points[1].X; int nodeCnt = coords.Count; IList<uint> workPortNodes = new List<uint>(); IList<double> workXs = new List<double>(); for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (Math.Abs(coord[1] - yy) < Constants.PrecisionLowerLimit && coord[0] >= stx - Constants.PrecisionLowerLimit && coord[0] <= edx + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; workPortNodes.Add(nodeNumber); workXs.Add(coord[0]); } } int portNodeCnt = workPortNodes.Count; double[] workXAry = workXs.ToArray(); Array.Sort(workXAry); int[] portNodeAry = new int[portNodeCnt]; for (int i = 0; i < portNodeCnt; i++) { double x = workXAry[i]; int orgIndex = workXs.IndexOf(x); uint nodeNumber = workPortNodes[orgIndex]; portNodeAry[i] = (int)nodeNumber; double[] coord = coords[(int)nodeNumber - 1]; //System.Diagnostics.Debug.WriteLine("portNode: {0}: {1}, {2}", nodeNumber, coord[0], coord[1]); } portNodes = portNodeAry.ToList(); // 周期構造1周期領域 bool isBottomOuterBoundary = true; // 下側が外側境界? int yyPeriodic = yy; // 下境界の場合 if (yy == (maxDiv.Height + 1) || (yy >= 1 && areaSelection[yy - 1, stx] != CadLogic.CellType.Empty)) { // 上境界の場合 yyPeriodic = yy - 1; isBottomOuterBoundary = false; } // 周期構造領域の要素番号 for (int x = stx; x < edx; x++) { uint[] workElemNoList = elemNoCellList[yyPeriodic, x]; if (workElemNoList == null) { continue; // 全体領域でセルが空の場所 } foreach (uint elemNo in workElemNoList) { elemNoPeriodic.Add(elemNo); } } // 周期構造領域境界の節点番号 // 外部境界 IList<int> workNodesB_Outer = portNodes; // 内部境界 IList<int> workNodesB_Inner = null; { int tagtyy = yy + 1; // 上側境界 if (!isBottomOuterBoundary) { // 上側が外部境界のとき tagtyy = yy - 1; // 下側境界 } IList<int> workNodesB = null; IList<uint> workPeriodicBNodes = new List<uint>(); IList<double> workPeriodicBXs = new List<double>(); for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (Math.Abs(coord[1] - tagtyy) < Constants.PrecisionLowerLimit && coord[0] >= stx - Constants.PrecisionLowerLimit && coord[0] <= edx + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; workPeriodicBNodes.Add(nodeNumber); workPeriodicBXs.Add(coord[0]); } } int periodicBNodeCnt = workPeriodicBNodes.Count; double[] workPeriodicBXAry = workPeriodicBXs.ToArray(); Array.Sort(workPeriodicBXAry); int[] periodicBNodeAry = new int[periodicBNodeCnt]; for (int i = 0; i < periodicBNodeCnt; i++) { double x = workPeriodicBXAry[i]; int orgIndex = workPeriodicBXs.IndexOf(x); uint nodeNumber = workPeriodicBNodes[orgIndex]; periodicBNodeAry[i] = (int)nodeNumber; int portIndex = portCounter - 1; double[] coord = coords[(int)nodeNumber - 1]; //System.Diagnostics.Debug.WriteLine("nodeB_Inner: {0}: {1}: {2}, {3}", portIndex, nodeNumber, coord[0], coord[1]); } workNodesB = periodicBNodeAry.ToList(); // 格納 workNodesB_Inner = workNodesB; } // 格納 nodePeriodicB.Add(workNodesB_Outer); nodePeriodicB.Add(workNodesB_Inner); // 周期構造領域内欠陥部の節点番号 double periodicDistance = 1.0; for (int ino = 0; ino < nodeCnt; ino++) { double[] coord = coords[ino]; if (coord[1] >= yyPeriodic - Constants.PrecisionLowerLimit && coord[1] <= yyPeriodic + periodicDistance + Constants.PrecisionLowerLimit && coord[0] >= stx - Constants.PrecisionLowerLimit && coord[0] <= edx + Constants.PrecisionLowerLimit) { uint nodeNumber = (uint)ino + 1; { // セルのx, yインデックス int work_intY = (int)Math.Round(coord[1]); int work_intX1 = (int)Math.Round(coord[0]); if (work_intY >= maxDiv.Height) { // 解析領域の上境界のとき work_intY--; } if (work_intX1 >= maxDiv.Width) { // 解析領域の右境界のとき work_intX1--; } int work_intX2 = work_intX1 - 1; if (work_intX2 < 0) { work_intX2 = 0; } CadLogic.CellType workCellType1 = areaSelection[work_intY, work_intX1]; if (workCellType1 == CadLogic.CellType.Empty && (work_intY - 1) >= 0 && areaSelection[work_intY - 1, work_intX1] != CadLogic.CellType.Empty) { // 不連続領域の上境界のとき work_intY--; workCellType1 = areaSelection[work_intY, work_intX1]; } CadLogic.CellType workCellType2 = areaSelection[work_intY, work_intX2]; if (workCellType1 == CadLogic.CellType.Defect || workCellType2 == CadLogic.CellType.Defect) { defectNodePeriodic.Add((int)nodeNumber); } } } } } else { MessageBox.Show("Not implemented"); } /* // check for (int i = 0; i < portNodes.Count; i++) { System.Diagnostics.Debug.Assert(nodePeriodicB[0].Contains(portNodes[i])); } */ portList.Add(portNodes); elemNoPeriodicList.Add(elemNoPeriodic); nodePeriodicBList.Add(nodePeriodicB); defectNodePeriodicList.Add(defectNodePeriodic); } // 強制境界からポート境界の節点を取り除く // ただし、始点と終点は強制境界なので残す foreach (IList<int> nodes in portList) { for (int i = 0; i < nodes.Count; i++) { if (i != 0 && i != nodes.Count - 1) { int nodeNumber = nodes[i]; if (forceBCNodeNumberDic.ContainsKey(nodeNumber)) { forceBCNodeNumberDic.Remove(nodeNumber); } } } } // 座標値に変換 doubleCoords = new List<double[]>(); for (int i = 0; i < coords.Count; i++) { double[] coord = coords[i]; doubleCoords.Add(coord); } forceBCNodeNumbers = forceBCNodeNumberDic.Keys.ToArray(); return true; }
public bool SortEdgeIds(CCadObj2D cad2d) { bool success = false; if (EdgeIds.Count == 0 || EdgeIds.Count == 1) { // 何もしない success = true; return(success); } //System.Diagnostics.Debug.WriteLine("=========old========"); // チェック用に退避する IList <uint> oldEIdList = new List <uint>(); foreach (uint eId in EdgeIds) { oldEIdList.Add(eId); //System.Diagnostics.Debug.WriteLine("{0}", eId); } //System.Diagnostics.Debug.WriteLine("================="); IList <uint> eIdList = new List <uint>(); eIdList.Add(oldEIdList[0]); oldEIdList.Remove(oldEIdList[0]); while (oldEIdList.Count > 0) { uint workEId = eIdList[eIdList.Count - 1]; // 最後を参照 uint id_v1 = 0; uint id_v2 = 0; CadLogic.getVertexIdsOfEdgeId(cad2d, workEId, out id_v1, out id_v2); uint nextdoor_eId = 0; foreach (uint chkEId in oldEIdList) { uint chk_id_v1 = 0; uint chk_id_v2 = 0; CadLogic.getVertexIdsOfEdgeId(cad2d, chkEId, out chk_id_v1, out chk_id_v2); // 隣の辺かチェック if (id_v1 == chk_id_v1 || id_v1 == chk_id_v2 || id_v2 == chk_id_v1 || id_v2 == chk_id_v2) { nextdoor_eId = chkEId; break; } } if (nextdoor_eId != 0) { eIdList.Add(nextdoor_eId); // 最後に追加 oldEIdList.Remove(nextdoor_eId); } else { break; } } while (oldEIdList.Count > 0) { uint workEId = eIdList[0];// 先頭を参照 uint id_v1 = 0; uint id_v2 = 0; CadLogic.getVertexIdsOfEdgeId(cad2d, workEId, out id_v1, out id_v2); uint nextdoor_eId = 0; foreach (uint chkEId in oldEIdList) { uint chk_id_v1 = 0; uint chk_id_v2 = 0; CadLogic.getVertexIdsOfEdgeId(cad2d, chkEId, out chk_id_v1, out chk_id_v2); // 隣の辺かチェック if (id_v1 == chk_id_v1 || id_v1 == chk_id_v2 || id_v2 == chk_id_v1 || id_v2 == chk_id_v2) { nextdoor_eId = chkEId; break; } } if (nextdoor_eId != 0) { eIdList.Insert(0, nextdoor_eId); // 先頭に追加 oldEIdList.Remove(nextdoor_eId); } else { break; } } //System.Diagnostics.Debug.Assert(oldEIdList.Count == 0); if (oldEIdList.Count != 0) { // ソート失敗 return(success); } // ソート成功 success = true; EdgeIds.Clear(); //System.Diagnostics.Debug.WriteLine("=========new========"); foreach (uint eId in eIdList) { EdgeIds.Add(eId); //System.Diagnostics.Debug.WriteLine("{0}", eId); } //System.Diagnostics.Debug.WriteLine("================="); return(success); }
/// <summary> /// 初期化処理 /// </summary> private void init() { CadModeRadioButtons = new RadioButton[] { radioBtnNone, radioBtnArea, radioBtnMediaFill, radioBtnPort, radioBtnErase, radioBtnIncidentPort, radioBtnPortNumbering }; // Cadモードをラジオボタンに紐づける CadLogic.CadModeType[] cadModeTypeForRadioButtons = new CadLogic.CadModeType[] { CadLogic.CadModeType.None, CadLogic.CadModeType.Area, CadLogic.CadModeType.MediaFill, CadLogic.CadModeType.Port, CadLogic.CadModeType.Erase, CadLogic.CadModeType.IncidentPort, CadLogic.CadModeType.PortNumbering }; System.Diagnostics.Debug.Assert(CadModeRadioButtons.Length == cadModeTypeForRadioButtons.Length); for (int i = 0; i < CadModeRadioButtons.Length; i++) { CadModeRadioButtons[i].Tag = cadModeTypeForRadioButtons[i]; } MediaRadioButtons = new RadioButton[] { radioBtnMedia0, // 導体 radioBtnMedia1, // 真空 radioBtnMedia2, // 誘電体1 radioBtnMedia3 // 誘電体2 }; EpsTextBoxes = new TextBox[] { textBoxEps0, // 導体 textBoxEps1, // 真空 textBoxEps2, // 誘電体1 textBoxEps3 // 誘電体2 }; System.Diagnostics.Debug.Assert(MediaRadioButtons.Length == Constants.MaxMediaCount); System.Diagnostics.Debug.Assert(EpsTextBoxes.Length == Constants.MaxMediaCount); panelMedia.Visible = false; btnLoadCancel.Visible = false; CadLgc = new CadLogic(CadPanel); Solver = new FemSolver(); PostPro = new FemPostProLogic(); // アプリケーションの終了イベントハンドラを設定する AppDomain.CurrentDomain.ProcessExit += (sender, e) => { Console.WriteLine("Process exiting"); System.Diagnostics.Debug.WriteLine("Process exiting"); // フォームの破棄処理を呼び出す this.Dispose(); }; // パネルサイズを記憶する savePanelSize(); //this.DoubleBuffered = true; // ダブルバッファ制御用のプロパティを強制的に取得する System.Reflection.PropertyInfo p; p = typeof(System.Windows.Forms.Control).GetProperty( "DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); // ダブルバッファを有効にする //SimpleOpenGlControlの場合は不要 //p.SetValue(CadPanel, true, null); p.SetValue(FValuePanel, true, null); // フォームのタイトルを退避 TitleBaseName = this.Text + " " + MyUtilLib.MyUtil.getAppVersion(); // ファイル名付きフォームタイトルを設定 setFrmTitle(); // GUI初期化 resetGUI(); }
/// <summary> /// Cadモードをラジオボタンに反映する /// </summary> /// <param name="cadMode"></param> private void setupCadModeRadioButtons(CadLogic.CadModeType cadMode) { foreach (RadioButton rb in CadModeRadioButtons) { if ((CadLogic.CadModeType)rb.Tag == cadMode) { rb.Checked = true; } else { rb.Checked = false; } } }
/// <summary> /// Cadモードをラジオボタンに反映する /// </summary> /// <param name="cadMode"></param> private void setupCadModeRadioButtons(CadLogic.CadModeType cadMode) { // Cadモード(エリア、消しゴム)詳細イメージコンボボックスの選択設定を行う setupDetailCadModeToImgCboxes(cadMode); // ラジオボタンのCadモード(エリア、消しゴム)詳細を更新する setupDetailCadModeToRadioButtons(cadMode); // ラジオボタンのチェック状態を設定する foreach (RadioButton rb in CadModeRadioButtons) { if ((CadLogic.CadModeType)rb.Tag == cadMode) { rb.Checked = true; } else { rb.Checked = false; } } }
/// <summary> /// Cadロジックの変更通知イベントハンドラ /// </summary> /// <param name="sender"></param> private void CadLgc_Change(object sender, CadLogic.CadModeType prevCadMode) { }
/// <summary> /// Cadロジックの変更通知イベントハンドラ /// </summary> /// <param name="sender"></param> private void CadLgc_Change(object sender, CadLogic.CadModeType prevCadMode) { // 自動計算モードの場合、対象周波数の計算を実行する // prevCadModeを参照しているのはUndo/Redoの場合、以前の状態が描画モードであるかどうかで判定する必要があるため if (IsAutoCalc && prevCadMode != CadLogic.CadModeType.None) { runAtOneFreq(); } }
/// <summary> /// 初期化処理 /// </summary> private void init() { CadLgc = new CadLogic(CadPanel); CadLgc.Change += new CadLogic.ChangeDeleagte(CadLgc_Change); Solver = new FemSolver(); PostPro = new FemPostProLogic(); CadModeRadioButtons = new RadioButton[] { radioBtnNone, radioBtnLocation, radioBtnArea, radioBtnPort, radioBtnErase, radioBtnIncidentPort, radioBtnPortNumbering }; // Cadモードをラジオボタンに紐づける CadLogic.CadModeType[] cadModeTypeForRadioButtons = new CadLogic.CadModeType[] { CadLogic.CadModeType.None, CadLogic.CadModeType.Location, CadLogic.CadModeType.Area, CadLogic.CadModeType.Port, CadLogic.CadModeType.Erase, CadLogic.CadModeType.IncidentPort, CadLogic.CadModeType.PortNumbering }; System.Diagnostics.Debug.Assert(CadModeRadioButtons.Length == cadModeTypeForRadioButtons.Length); for (int i = 0; i < CadModeRadioButtons.Length; i++) { CadModeRadioButtons[i].Tag = cadModeTypeForRadioButtons[i]; } // エリア選択描画モードタイプコンボボックスのItemにCadモードを紐づける CellTypeStruct[] cellTypeStructsForImgCBoxCadModeArea = new CellTypeStruct[] { new CellTypeStruct("真空", CadLogic.CellType.Defect), new CellTypeStruct("誘電体ロッド", CadLogic.CellType.Rod), }; // コンボボックスのアイテムをクリア imgcbxCellType.Items.Clear(); foreach (CellTypeStruct cellTypeStruct in cellTypeStructsForImgCBoxCadModeArea) { // コンボボックスにアイテムを追加 imgcbxCellType.Items.Add(cellTypeStruct); if (CadLgc != null) { if (CadLgc.SelectedCellType == cellTypeStruct.CellTypeVal) { imgcbxCellType.SelectedItem = cellTypeStruct; } } } imgcbxCellType.Visible = false; btnLoadCancel.Visible = false; //TEST 4画面表示 FValuePanelIndex = FValuePanelFieldDV_ValueDVPairList.Length; //0; // 等高線図パネルインデックス変更時の処理 changeFValuePanelIndexProc(false); // アプリケーションの終了イベントハンドラを設定する AppDomain.CurrentDomain.ProcessExit += (sender, e) => { System.Diagnostics.Debug.WriteLine("Process exiting"); //System.Diagnostics.Debug.WriteLine("Process exiting"); // フォームの破棄処理を呼び出す this.Dispose(); }; // パネルサイズを記憶する savePanelSize(); //this.DoubleBuffered = true; // ダブルバッファ制御用のプロパティを強制的に取得する System.Reflection.PropertyInfo p; p = typeof(System.Windows.Forms.Control).GetProperty( "DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); // ダブルバッファを有効にする p.SetValue(CadPanel, true, null); p.SetValue(FValuePanel, true, null); // フォームのタイトルを退避 TitleBaseName = this.Text + " " + MyUtilLib.MyUtil.getAppVersion(); // ファイル名付きフォームタイトルを設定 setFrmTitle(); // GUI初期化 resetGUI(); }
///////////////////////////////////////////////////////////////////////////// // 定数 ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // 型 ///////////////////////////////////////////////////////////////////////////// /// <summary> /// 図面情報を保存する /// </summary> /// <param name="filename"></param> /// <param name="AreaSelection"></param> /// <param name="EdgeList"></param> /// <param name="IncidentPortNo"></param> /// <param name="Medias"></param> /// <param name="ndivForOneLattice"></param> /// <param name="rodRadiusRatio"></param> /// <param name="rodCircleDiv"></param> /// <param name="rodRadiusDiv"></param> public static void SaveToFile( string filename, CadLogic.CellType[,] AreaSelection, IList<Edge> EdgeList, int IncidentPortNo, MediaInfo[] Medias, int ndivForOneLattice, double rodRadiusRatio, int rodCircleDiv, int rodRadiusDiv ) { Size MaxDiv = Constants.MaxDiv; try { using (StreamWriter sw = new StreamWriter(filename)) { int counter; string line; // 領域: 書き込む個数の計算 counter = 0; for (int y = 0; y < MaxDiv.Height; y++) { for (int x = 0; x < MaxDiv.Width; x++) { if (AreaSelection[y, x] != CadLogic.CellType.Empty) { counter++; } } } // 領域: 書き込み sw.WriteLine("AreaSelection,{0}", counter); for (int y = 0; y < MaxDiv.Height; y++) { for (int x = 0; x < MaxDiv.Width; x++) { CadLogic.CellType cellType = AreaSelection[y, x]; if (cellType != CadLogic.CellType.Empty) { string cellTypeStr = CadLogic.GetCellTypeStr(cellType); sw.WriteLine("{0},{1},{2}", x, y, cellTypeStr); } } } // ポート境界: 書き込み個数の計算 sw.WriteLine("EdgeList,{0}", EdgeList.Count); // ポート境界: 書き込み foreach (Edge edge in EdgeList) { sw.WriteLine("{0},{1},{2},{3},{4}", edge.No, edge.Points[0].X, edge.Points[0].Y, edge.Points[1].X, edge.Points[1].Y); } // 入射ポート番号 sw.WriteLine("IncidentPortNo,{0}", IncidentPortNo); ////////////////////////////////////////// //// Ver1.1.0.0からの追加情報 ////////////////////////////////////////// // 媒質情報の個数 sw.WriteLine("Medias,{0}", Medias.Length); // 媒質情報の書き込み for(int i = 0; i < Medias.Length; i++) { MediaInfo media = Medias[i]; line = string.Format("{0},", i); double[,] p = media.P; for (int m = 0; m < p.GetLength(0); m++) { for (int n = 0; n < p.GetLength(1); n++) { line += string.Format("{0},", p[m, n]); } } double[,] q = media.Q; for (int m = 0; m < q.GetLength(0); m++) { for (int n = 0; n < q.GetLength(1); n++) { line += string.Format("{0},", q[m, n]); } } line = line.Remove(line.Length - 1); // 最後の,を削除 sw.WriteLine(line); } // 格子1辺の分割数 sw.WriteLine("ndivForOneLattice,{0}", ndivForOneLattice); // ロッドの半径の割合 sw.WriteLine("rodRadiusRatio,{0}", rodRadiusRatio); // ロッドの円周方向分割数 sw.WriteLine("rodCircleDiv,{0}", rodCircleDiv); // ロッドの半径方向分割数 sw.WriteLine("rodRadiusDiv,{0}", rodRadiusDiv); } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); MessageBox.Show(exception.Message); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="text"></param> /// <param name="cadMode"></param> public CadModeTypeStruct(string text, CadLogic.CadModeType cadMode) { Text = text; CadMode = cadMode; }
/// <summary> /// 図面情報を読み込む /// </summary> /// <param name="filename"></param> /// <param name="areaSelection"></param> /// <param name="edgeList"></param> /// <param name="yBoundarySelection">2次的な情報(edgeListから生成される)</param> /// <param name="xBoundarySelection">2次的な情報(edgeListから生成される)</param> /// <param name="incidentPortNo"></param> /// <param name="medias"></param> /// <param name="ndivForOneLattice"></param> /// <param name="rodRadiusRatio"></param> /// <param name="rodCircleDiv"></param> /// <param name="rodRadiusDiv"></param> /// <returns></returns> public static bool LoadFromFile( string filename, ref CadLogic.CellType[,] AreaSelection, ref IList<Edge> EdgeList, ref bool[,] YBoundarySelection, ref bool[,] XBoundarySelection, ref int IncidentPortNo, ref MediaInfo[] Medias, ref int ndivForOneLattice, ref double rodRadiusRatio, ref int rodCircleDiv, ref int rodRadiusDiv ) { bool success = false; Size MaxDiv = Constants.MaxDiv; int MaxMediaCount = Medias.Length; for (int y = 0; y < AreaSelection.GetLength(0); y++) { for (int x = 0; x < AreaSelection.GetLength(1); x++) { AreaSelection[y, x] = CadLogic.CellType.Empty; } } try { using (StreamReader sr = new StreamReader(filename)) { string line; string[] tokens; const char delimiter = ','; int cnt = 0; // 領域選択 line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens[0] != "AreaSelection") { MessageBox.Show("領域選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 3) { MessageBox.Show("領域選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } int x = int.Parse(tokens[0]); int y = int.Parse(tokens[1]); CadLogic.CellType cellType = CadLogic.GetCellTypeFromStr(tokens[2]); if ((x >= 0 && x < MaxDiv.Width) && (y >= 0 && y < MaxDiv.Height)) { AreaSelection[y, x] = cellType; } else { MessageBox.Show("領域選択座標値が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } } // ポート境界 line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens[0] != "EdgeList") { MessageBox.Show("境界選択情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 5) { MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } int edgeNo = int.Parse(tokens[0]); Point[] p = new Point[2]; for (int k = 0; k < p.Length; k++) { p[k] = new Point(); p[k].X = int.Parse(tokens[1 + k * 2]); p[k].Y = int.Parse(tokens[1 + k * 2 + 1]); } Size delta = new Size(0, 0); if (p[0].X == p[1].X) { // Y方向境界 delta = new Size(0, 1); } else if (p[0].Y == p[1].Y) { // X方向境界 delta = new Size(1, 0); } else { MessageBox.Show("境界選択情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return success; } Edge edge = new Edge(delta); edge.No = edgeNo; edge.Set(p[0], p[1]); EdgeList.Add(edge); } foreach (Edge edge in EdgeList) { if (edge.Delta.Width == 0) { // Y方向境界 int x = edge.Points[0].X; int sty = edge.Points[0].Y; int edy = edge.Points[1].Y; for (int y = sty; y < edy; y++) { YBoundarySelection[y, x] = true; } } else if (edge.Delta.Height == 0) { // X方向境界 int y = edge.Points[0].Y; int stx = edge.Points[0].X; int edx = edge.Points[1].X; for (int x = stx; x < edx; x++) { XBoundarySelection[y, x] = true; } } else { MessageBox.Show("Not implemented"); } } line = sr.ReadLine(); if (line.Length == 0) { MessageBox.Show("入射ポート番号がありません"); return success; } tokens = line.Split(delimiter); if (tokens[0] != "IncidentPortNo") { MessageBox.Show("入射ポート番号がありません"); return success; } IncidentPortNo = int.Parse(tokens[1]); line = sr.ReadLine(); // 媒質情報? tokens = line.Split(delimiter); if (tokens[0] != "Medias") { MessageBox.Show("媒質情報がありません"); return success; } cnt = int.Parse(tokens[1]); if (cnt > MaxMediaCount) { MessageBox.Show("媒質情報の個数が不正です"); return success; } for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); if (line.Length == 0) { MessageBox.Show("媒質情報が不正です"); return success; } tokens = line.Split(delimiter); if (tokens.Length != 1 + 9 + 9) { MessageBox.Show("媒質情報が不正です"); return success; } int mediaIndex = int.Parse(tokens[0]); System.Diagnostics.Debug.Assert(mediaIndex == i); double[,] p = new double[3, 3]; for (int m = 0; m < p.GetLength(0); m++) { for (int n = 0; n < p.GetLength(1); n++) { p[m, n] = double.Parse(tokens[1 + m * p.GetLength(1) + n]); } } Medias[i].SetP(p); double[,] q = new double[3, 3]; for (int m = 0; m < q.GetLength(0); m++) { for (int n = 0; n < q.GetLength(1); n++) { q[m, n] = double.Parse(tokens[1 + 9 + m * q.GetLength(1) + n]); } } Medias[i].SetQ(q); } line = sr.ReadLine(); if (line == null) { MessageBox.Show("格子1辺の分割数がありません"); return success; } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "ndivForOneLattice") { MessageBox.Show("格子1辺の分割数がありません"); return success; } ndivForOneLattice = int.Parse(tokens[1]); line = sr.ReadLine(); if (line == null) { MessageBox.Show("ロッドの半径がありません"); return success; } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodRadiusRatio") { MessageBox.Show("ロッドの半径がありません"); return success; } rodRadiusRatio = double.Parse(tokens[1]); line = sr.ReadLine(); if (line == null) { MessageBox.Show("ロッドの円周方向の分割数がありません"); return success; } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodCircleDiv") { MessageBox.Show("ロッドの円周方向の分割数がありません"); return success; } rodCircleDiv = int.Parse(tokens[1]); line = sr.ReadLine(); tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "rodRadiusDiv") { MessageBox.Show("ロッドの半径方向の分割数がありません"); return success; } rodRadiusDiv = int.Parse(tokens[1]); } success = true; } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); MessageBox.Show(exception.Message); } return success; }
/// <summary> /// Cadモード詳細(エリア選択と消しゴムのみ)をイメージコンボボックスに反映する /// </summary> /// <param name="cadMode"></param> private void setupDetailCadModeToRadioButtons(CadLogic.CadModeType cadMode) { // 描画モードがエリア選択の場合は、選択方法コンボボックスのアイテムを選択する if (cadMode == CadLogic.CadModeType.Area || cadMode == CadLogic.CadModeType.AreaFH || cadMode == CadLogic.CadModeType.AreaLine || cadMode == CadLogic.CadModeType.AreaEllipse) { foreach (RadioButton rb in CadModeRadioButtons) { CadLogic.CadModeType workCadMode = (CadLogic.CadModeType)rb.Tag; if (workCadMode == CadLogic.CadModeType.Area || workCadMode == CadLogic.CadModeType.AreaFH || workCadMode == CadLogic.CadModeType.AreaLine || workCadMode == CadLogic.CadModeType.AreaEllipse) { // ラジオボタンのタグを更新する rb.Tag = cadMode; // イメージコンボボックスのイメージをラジオボタンに反映する foreach (CadModeTypeStruct cadModeTypeStruct in imgcbxCadModeArea.Items) { if (cadModeTypeStruct.CadMode == cadMode) { int index = imgcbxCadModeArea.Items.IndexOf(cadModeTypeStruct); rb.Image = imgcbxCadModeArea.ImageList.Images[index]; break; } } break; } } } // 描画モードが消しゴムの場合は、選択方法コンボボックスのアイテムを選択する if (cadMode == CadLogic.CadModeType.Erase || cadMode == CadLogic.CadModeType.EraseFH || cadMode == CadLogic.CadModeType.EraseLine) { foreach (RadioButton rb in CadModeRadioButtons) { CadLogic.CadModeType workCadMode = (CadLogic.CadModeType)rb.Tag; if (workCadMode == CadLogic.CadModeType.Erase || workCadMode == CadLogic.CadModeType.EraseFH || workCadMode == CadLogic.CadModeType.EraseLine) { // ラジオボタンのタグを更新する rb.Tag = cadMode; // イメージコンボボックスのイメージをラジオボタンに反映する foreach (CadModeTypeStruct cadModeTypeStruct in imgcbxCadModeErase.Items) { if (cadModeTypeStruct.CadMode == cadMode) { int index = imgcbxCadModeErase.Items.IndexOf(cadModeTypeStruct); rb.Image = imgcbxCadModeErase.ImageList.Images[index]; break; } } } } } }
/// <summary> /// Cadモード詳細(エリア選択と消しゴムのみ)をイメージコンボボックスに反映する /// </summary> /// <param name="cadMode"></param> private void setupDetailCadModeToImgCboxes(CadLogic.CadModeType cadMode) { // 描画モードがエリア選択の場合は、選択方法コンボボックスのアイテムを選択する if (cadMode == CadLogic.CadModeType.Area || cadMode == CadLogic.CadModeType.AreaFH || cadMode == CadLogic.CadModeType.AreaLine || cadMode == CadLogic.CadModeType.AreaEllipse) { foreach (CadModeTypeStruct cadModeTypeStruct in imgcbxCadModeArea.Items) { if (cadModeTypeStruct.CadMode == cadMode) { imgcbxCadModeArea.SelectedItem = cadModeTypeStruct; break; } } imgcbxCadModeArea.Visible = true; } else { imgcbxCadModeArea.Visible = false; } // 描画モードが消しゴムの場合は、選択方法コンボボックスのアイテムを選択する if (cadMode == CadLogic.CadModeType.Erase || cadMode == CadLogic.CadModeType.EraseFH || cadMode == CadLogic.CadModeType.EraseLine) { foreach (CadModeTypeStruct cadModeTypeStruct in imgcbxCadModeErase.Items) { if (cadModeTypeStruct.CadMode == cadMode) { imgcbxCadModeErase.SelectedItem = cadModeTypeStruct; break; } } imgcbxCadModeErase.Visible = true; } else { imgcbxCadModeErase.Visible = false; } }
///////////////////////////////////////////////////////////////////////////// // 定数 ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // 型 ///////////////////////////////////////////////////////////////////////////// /// <summary> /// 図面情報を保存する /// </summary> /// <param name="filename"></param> /// <param name="AreaSelection"></param> /// <param name="EdgeList"></param> /// <param name="IncidentPortNo"></param> /// <param name="Medias"></param> /// <param name="ndivForOneLattice"></param> /// <param name="rodRadiusRatio"></param> /// <param name="rodCircleDiv"></param> /// <param name="rodRadiusDiv"></param> public static void SaveToFile( string filename, CadLogic.CellType[,] AreaSelection, IList <Edge> EdgeList, int IncidentPortNo, MediaInfo[] Medias, int ndivForOneLattice, double rodRadiusRatio, int rodCircleDiv, int rodRadiusDiv ) { Size MaxDiv = Constants.MaxDiv; try { using (StreamWriter sw = new StreamWriter(filename)) { int counter; string line; // 領域: 書き込む個数の計算 counter = 0; for (int y = 0; y < MaxDiv.Height; y++) { for (int x = 0; x < MaxDiv.Width; x++) { if (AreaSelection[y, x] != CadLogic.CellType.Empty) { counter++; } } } // 領域: 書き込み sw.WriteLine("AreaSelection,{0}", counter); for (int y = 0; y < MaxDiv.Height; y++) { for (int x = 0; x < MaxDiv.Width; x++) { CadLogic.CellType cellType = AreaSelection[y, x]; if (cellType != CadLogic.CellType.Empty) { string cellTypeStr = CadLogic.GetCellTypeStr(cellType); sw.WriteLine("{0},{1},{2}", x, y, cellTypeStr); } } } // ポート境界: 書き込み個数の計算 sw.WriteLine("EdgeList,{0}", EdgeList.Count); // ポート境界: 書き込み foreach (Edge edge in EdgeList) { sw.WriteLine("{0},{1},{2},{3},{4}", edge.No, edge.Points[0].X, edge.Points[0].Y, edge.Points[1].X, edge.Points[1].Y); } // 入射ポート番号 sw.WriteLine("IncidentPortNo,{0}", IncidentPortNo); ////////////////////////////////////////// //// Ver1.1.0.0からの追加情報 ////////////////////////////////////////// // 媒質情報の個数 sw.WriteLine("Medias,{0}", Medias.Length); // 媒質情報の書き込み for (int i = 0; i < Medias.Length; i++) { MediaInfo media = Medias[i]; line = string.Format("{0},", i); double[,] p = media.P; for (int m = 0; m < p.GetLength(0); m++) { for (int n = 0; n < p.GetLength(1); n++) { line += string.Format("{0},", p[m, n]); } } double[,] q = media.Q; for (int m = 0; m < q.GetLength(0); m++) { for (int n = 0; n < q.GetLength(1); n++) { line += string.Format("{0},", q[m, n]); } } line = line.Remove(line.Length - 1); // 最後の,を削除 sw.WriteLine(line); } // 格子1辺の分割数 sw.WriteLine("ndivForOneLattice,{0}", ndivForOneLattice); // ロッドの半径の割合 sw.WriteLine("rodRadiusRatio,{0}", rodRadiusRatio); // ロッドの円周方向分割数 sw.WriteLine("rodCircleDiv,{0}", rodCircleDiv); // ロッドの半径方向分割数 sw.WriteLine("rodRadiusDiv,{0}", rodRadiusDiv); } } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); MessageBox.Show(exception.Message); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="text"></param> /// <param name="cadMode"></param> public CellTypeStruct(string text, CadLogic.CellType cellType) { Text = text; CellTypeVal = cellType; }
/// <summary> /// 図面情報を読み込む /// </summary> /// <returns></returns> public static bool LoadFromFile( string filename, out string appVersion, out string useUtility, ref CCadObj2D editCad2D, ref IList <CadLogic.Loop> loopList, ref IList <EdgeCollection> edgeCollectionList, out int incidentPortNo, ref MediaInfo[] medias ) { bool success = false; //////////////////////////////////////////////////////// // 出力データの初期化 // アプリケーションのバージョン番号 appVersion = ""; // ユーティリティ名 useUtility = ""; // 図面のクリア editCad2D.Clear(); //// ベースループIDを初期化 //baseLoopId = 0; // ループ情報リストの初期化 loopList.Clear(); // 入射ポートの初期化 incidentPortNo = 1; // ポートのエッジコレクションのリストを初期化 edgeCollectionList.Clear(); // 媒質の比誘電率、比透磁率の逆数の初期化 foreach (MediaInfo media in medias) { // 比透磁率の逆数 media.SetP(new double[, ] { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } }); // 比誘電率 media.SetQ(new double[, ] { { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 } }); } try { // Cadオブジェクトデータファイル string basename = Path.GetDirectoryName(filename) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(filename); string cadObjFilename = basename + Constants.CadObjExt; if (File.Exists(cadObjFilename)) { // Cadオブジェクトデータを外部ファイルから読み込む using (CSerializer fin = new CSerializer(cadObjFilename, true)) { editCad2D.Serialize(fin); } } else { MessageBox.Show("CadObjデータファイルがありません"); return(success); } using (StreamReader sr = new StreamReader(filename)) { string line; string[] tokens; const char delimiter = ','; int cnt = 0; // アプリケーションのバージョン番号 line = sr.ReadLine(); if (line == null) { MessageBox.Show("アプリケーションのバージョン情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "AppVersion") { MessageBox.Show("アプリケーションのバージョン情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } appVersion = tokens[1]; // ユーティリティ名 line = sr.ReadLine(); if (line == null) { MessageBox.Show("ユーティリティ情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "UseUtility") { MessageBox.Show("ユーティリティ情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } useUtility = tokens[1]; if (useUtility != CadLogic.UseUtility) { MessageBox.Show("ユーティリティ情報が本アプリケーションのバージョンのものと一致しません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } // ベースループID //line = sr.ReadLine(); //if (line == null) //{ // MessageBox.Show("ベースループIDがありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); // return success; //} //tokens = line.Split(delimiter); //if (tokens.Length != 2 || tokens[0] != "BaseLoopId") //{ // MessageBox.Show("ベースループIDがありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); // return success; //} //baseLoopId = uint.Parse(tokens[1]); // ループのリスト line = sr.ReadLine(); if (line == null) { MessageBox.Show("ループ一覧がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "LoopList") { MessageBox.Show("ループ一覧がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); if (line == null) { MessageBox.Show("ループ情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 4 || tokens[0] != "Loop") { MessageBox.Show("ループ情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } int countNo = int.Parse(tokens[1]); uint loopId = uint.Parse(tokens[2]); int mediaIndex = int.Parse(tokens[3]); System.Diagnostics.Debug.Assert(countNo == i + 1); CadLogic.Loop loop = new CadLogicBase.Loop(loopId, mediaIndex); loopList.Add(loop); } // ポートのエッジコレクションのリスト line = sr.ReadLine(); if (line == null) { MessageBox.Show("ポート一覧がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "EdgeCollectionList") { MessageBox.Show("ポート一覧がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); if (line == null) { MessageBox.Show("ポート情報がありません", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } tokens = line.Split(delimiter); if (tokens.Length < (4 + 1) || tokens[0] != "EdgeCollection") { MessageBox.Show("ポート情報が不正です", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return(success); } int countNo = int.Parse(tokens[1]); int portNo = int.Parse(tokens[2]); int eIdCnt = int.Parse(tokens[3]); System.Diagnostics.Debug.Assert(countNo == i + 1); System.Diagnostics.Debug.Assert(eIdCnt != 0 && eIdCnt == (tokens.Length - 4)); EdgeCollection edgeCollection = new EdgeCollection(); edgeCollection.No = portNo; for (int tokenIndex = 4; tokenIndex < tokens.Length; tokenIndex++) { uint eId = uint.Parse(tokens[tokenIndex]); if (!edgeCollection.ContainsEdgeId(eId)) { bool ret = edgeCollection.AddEdgeId(eId, editCad2D); } } edgeCollectionList.Add(edgeCollection); } // 入射ポート番号 line = sr.ReadLine(); if (line == null) { MessageBox.Show("入射ポート番号がありません"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "IncidentPortNo") { MessageBox.Show("入射ポート番号がありません"); return(success); } incidentPortNo = int.Parse(tokens[1]); // 媒質情報 line = sr.ReadLine(); if (line == null) { MessageBox.Show("媒質情報がありません"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 2 || tokens[0] != "Medias") { MessageBox.Show("媒質情報がありません"); return(success); } cnt = int.Parse(tokens[1]); for (int i = 0; i < cnt; i++) { line = sr.ReadLine(); if (line == null) { MessageBox.Show("媒質情報が不正です"); return(success); } tokens = line.Split(delimiter); if (tokens.Length != 1 + 9 + 9) { MessageBox.Show("媒質情報が不正です"); return(success); } int mediaIndex = int.Parse(tokens[0]); System.Diagnostics.Debug.Assert(mediaIndex == i); if (i >= medias.Length) { //読み飛ばす continue; } double[,] p = new double[3, 3]; for (int m = 0; m < p.GetLength(0); m++) { for (int n = 0; n < p.GetLength(1); n++) { p[m, n] = double.Parse(tokens[1 + m * p.GetLength(1) + n]); } } medias[i].SetP(p); double[,] q = new double[3, 3]; for (int m = 0; m < q.GetLength(0); m++) { for (int n = 0; n < q.GetLength(1); n++) { q[m, n] = double.Parse(tokens[1 + 9 + m * q.GetLength(1) + n]); } } medias[i].SetQ(q); } } // 番号順に並び替え ((List <EdgeCollection>)edgeCollectionList).Sort(); //////////////////////////////////////////////////////////////////////// // Cadオブジェクトの色をセットする // ループとその辺、頂点の色をセット foreach (CadLogic.Loop loop in loopList) { uint id_l = loop.LoopId; int mediaIndex = loop.MediaIndex; MediaInfo media = medias[mediaIndex]; Color backColor = media.BackColor; CadLogic.SetupColorOfCadObjectsForOneLoop(editCad2D, id_l, backColor); } // ポートの色をセットする CadLogic.SetupColorOfPortEdgeCollection(editCad2D, edgeCollectionList, incidentPortNo); success = true; } catch (Exception exception) { System.Diagnostics.Debug.WriteLine(exception.Message + " " + exception.StackTrace); MessageBox.Show(exception.Message); } return(success); }
/// <summary> /// 初期化処理 /// </summary> private void init() { CadModeRadioButtons = new RadioButton[] { radioBtnNone, radioBtnLocation, radioBtnArea, radioBtnPort, radioBtnErase, radioBtnIncidentPort, radioBtnPortNumbering }; // Cadモードをラジオボタンに紐づける CadLogic.CadModeType[] cadModeTypeForRadioButtons = new CadLogic.CadModeType[] { CadLogic.CadModeType.None, CadLogic.CadModeType.Location, CadLogic.CadModeType.Area, CadLogic.CadModeType.Port, CadLogic.CadModeType.Erase, CadLogic.CadModeType.IncidentPort, CadLogic.CadModeType.PortNumbering }; System.Diagnostics.Debug.Assert(CadModeRadioButtons.Length == cadModeTypeForRadioButtons.Length); for (int i = 0; i < CadModeRadioButtons.Length; i++) { CadModeRadioButtons[i].Tag = cadModeTypeForRadioButtons[i]; } // エリア選択描画モードタイプコンボボックスのItemにCadモードを紐づける CadModeTypeStruct[] cadModeTypeStructsForImgCBoxCadModeArea = new CadModeTypeStruct[] { new CadModeTypeStruct("自由描画", CadLogic.CadModeType.AreaFH), new CadModeTypeStruct("長方形描画", CadLogic.CadModeType.Area), new CadModeTypeStruct("直線描画", CadLogic.CadModeType.AreaLine), new CadModeTypeStruct("楕円描画", CadLogic.CadModeType.AreaEllipse) }; // コンボボックスのアイテムをクリア imgcbxCadModeArea.Items.Clear(); foreach (CadModeTypeStruct cadModeTypeStruct in cadModeTypeStructsForImgCBoxCadModeArea) { // コンボボックスにアイテムを追加 imgcbxCadModeArea.Items.Add(cadModeTypeStruct); foreach (CadLogic.CadModeType defCadMode in cadModeTypeForRadioButtons) { if (defCadMode == cadModeTypeStruct.CadMode) { //この時点ではCadLogicがないのでイベントハンドラの実行を抑制する imgcbxCadModeArea.SelectedIndexChanged -= imgcbxCadModeArea_SelectedIndexChanged; // 選択する imgcbxCadModeArea.SelectedItem = cadModeTypeStruct; // イベントハンドラを再設定 imgcbxCadModeArea.SelectedIndexChanged += imgcbxCadModeArea_SelectedIndexChanged; } } } imgcbxCadModeArea.Visible = false; // 消しゴム描画モードタイプコンボボックスのItemにCadモードを紐づける CadModeTypeStruct[] cadModeTypeStructsForImgCBoxCadModeErase = new CadModeTypeStruct[] { new CadModeTypeStruct("自由消去", CadLogic.CadModeType.EraseFH), new CadModeTypeStruct("長方形消去", CadLogic.CadModeType.Erase), new CadModeTypeStruct("直線消去", CadLogic.CadModeType.EraseLine) }; // コンボボックスのアイテムをクリア imgcbxCadModeErase.Items.Clear(); foreach (CadModeTypeStruct cadModeTypeStruct in cadModeTypeStructsForImgCBoxCadModeErase) { // コンボボックスにアイテムを追加 imgcbxCadModeErase.Items.Add(cadModeTypeStruct); foreach (CadLogic.CadModeType defCadMode in cadModeTypeForRadioButtons) { if (defCadMode == cadModeTypeStruct.CadMode) { //この時点ではCadLogicがないのでイベントハンドラの実行を抑制する imgcbxCadModeErase.SelectedIndexChanged -= imgcbxCadModeErase_SelectedIndexChanged; // 選択する imgcbxCadModeErase.SelectedItem = cadModeTypeStruct; // イベントハンドラを再設定 imgcbxCadModeErase.SelectedIndexChanged += imgcbxCadModeErase_SelectedIndexChanged; } } } imgcbxCadModeErase.Visible = false; MediaRadioButtons = new RadioButton[] { radioBtnMedia0, // 真空 radioBtnMedia1, // 誘電体1 radioBtnMedia2 // 誘電体2 }; EpsTextBoxes = new TextBox[] { textBoxEps0, // 真空 textBoxEps1, // 誘電体1 textBoxEps2 // 誘電体2 }; System.Diagnostics.Debug.Assert(MediaRadioButtons.Length == Constants.MaxMediaCount); System.Diagnostics.Debug.Assert(EpsTextBoxes.Length == Constants.MaxMediaCount); panelMedia.Visible = false; btnLoadCancel.Visible = false; CadLgc = new CadLogic(CadPanel); CadLgc.Change += new CadLogic.ChangeDeleagte(CadLgc_Change); Solver = new FemSolver(); PostPro = new FemPostProLogic(); //TEST 4画面表示 FValuePanelIndex = FValuePanelFieldDV_ValueDVPairList.Length; //0; // 等高線図パネルインデックス変更時の処理 changeFValuePanelIndexProc(false); // アプリケーションの終了イベントハンドラを設定する AppDomain.CurrentDomain.ProcessExit += (sender, e) => { System.Diagnostics.Debug.WriteLine("Process exiting"); //System.Diagnostics.Debug.WriteLine("Process exiting"); // フォームの破棄処理を呼び出す this.Dispose(); }; // パネルサイズを記憶する savePanelSize(); //this.DoubleBuffered = true; // ダブルバッファ制御用のプロパティを強制的に取得する System.Reflection.PropertyInfo p; p = typeof(System.Windows.Forms.Control).GetProperty( "DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); // ダブルバッファを有効にする p.SetValue(CadPanel, true, null); p.SetValue(FValuePanel, true, null); // フォームのタイトルを退避 TitleBaseName = this.Text + " " + MyUtilLib.MyUtil.getAppVersion(); // ファイル名付きフォームタイトルを設定 setFrmTitle(); // GUI初期化 resetGUI(); }