// 接触解析のMaster/Slave線要素を準備する private void SetupContactMasterSlaveLineElements(FEWorld world) { Mesher2D mesh = world.Mesh; IList <uint> feIds = LineFEArray.GetObjectIds(); foreach (var feId in feIds) { LineFE lineFE = LineFEArray.GetObject(feId); uint cadId; { uint meshId = lineFE.MeshId; uint elemCnt; MeshType meshType; int loc; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId); System.Diagnostics.Debug.Assert(meshType == MeshType.Bar); } if (ContactSlaveEIds.Contains(cadId)) { // Slave上の線要素 ContactSlaveLineFEIds.Add(feId); } if (ContactMasterEIds.Contains(cadId)) { // Master上の線要素 ContactMasterLineFEIds.Add(feId); } } }
// ポート上の線要素の節点ナンバリング private void NumberPortNodes(FEWorld world, IList <int> zeroCoordIds) { Mesher2D mesh = world.Mesh; // ポート上の線要素の抽出と節点ナンバリング uint portCnt = GetPortCount(); for (int portId = 0; portId < portCnt; portId++) { PortCondition portCondition = PortConditions[portId]; IList <uint> portEIds = portCondition.EIds; var lineFEIds = new List <uint>(); PortLineFEIdss.Add(lineFEIds); var portCo2Node = new Dictionary <int, int>(); PortCo2Nodes.Add(portCo2Node); int portNodeId = 0; IList <uint> feIds = LineFEArray.GetObjectIds(); foreach (var feId in feIds) { LineFE lineFE = LineFEArray.GetObject(feId); uint cadId; { uint meshId = lineFE.MeshId; uint elemCnt; MeshType meshType; int loc; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId); System.Diagnostics.Debug.Assert(meshType == MeshType.Bar); } if (portEIds.Contains(cadId)) { // ポート上の線要素 lineFEIds.Add(feId); int[] coIds = lineFE.NodeCoordIds; foreach (int coId in coIds) { if (!portCo2Node.ContainsKey(coId) && zeroCoordIds.IndexOf(coId) == -1) { portCo2Node[coId] = portNodeId; portNodeId++; } } } } } }
// 三角形要素の節点ナンバリング private void NumberTriangleNodes(FEWorld world, IList <int> zeroCoordIds) { Mesher2D mesh = world.Mesh; // ナンバリング int nodeId = 0; IList <uint> feIds = TriangleFEArray.GetObjectIds(); foreach (uint feId in feIds) { TriangleFE fe = TriangleFEArray.GetObject(feId); int elemPtCnt = fe.NodeCoordIds.Length; int[] coIds = fe.NodeCoordIds; for (int iPt = 0; iPt < elemPtCnt; iPt++) { int coId = coIds[iPt]; if (!Co2Node.ContainsKey(coId) && zeroCoordIds.IndexOf(coId) == -1) { Co2Node[coId] = nodeId; nodeId++; } } uint meshId = fe.MeshId; int iElem = fe.MeshElemId; uint elemCnt; MeshType meshType; int loc; uint cadId; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId); System.Diagnostics.Debug.Assert(meshType == MeshType.Tri); var triArray = mesh.GetTriArrays(); var tri = triArray[loc].Tris[iElem]; tri.FEId = (int)feId; string key = string.Format(meshId + "_" + iElem); Mesh2TriangleFE.Add(key, feId); } }
// 座標、三角形要素と線要素を生成する private void MakeCoordsAndElements( FEWorld world, IList <double> vertexCoords, Dictionary <uint, uint> cadLoop2Material, Dictionary <uint, uint> cadEdge2Material) { Mesher2D mesh = world.Mesh; System.Diagnostics.Debug.Assert(mesh != null); if (FEOrder == 1) { Coords = new List <double>(vertexCoords); } else if (FEOrder == 2) { Coords = new List <double>(vertexCoords); } else { System.Diagnostics.Debug.Assert(false); } IList <uint> meshIds = mesh.GetIds(); ////////////////////////////////////////////////// // 領域の三角形要素 // まず要素を作る // この順番で生成した要素は隣接していない Dictionary <string, IList <int> > edge2MidPt = new Dictionary <string, IList <int> >(); foreach (uint meshId in meshIds) { uint elemCnt; MeshType meshType; int loc; uint cadId; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId); if (meshType != MeshType.Tri) { continue; } if (!cadLoop2Material.ContainsKey(cadId)) { throw new IndexOutOfRangeException(); } uint maId = cadLoop2Material[cadId]; int elemVertexCnt = 3; int elemNodeCnt = 0; if (FEOrder == 1) { elemNodeCnt = 3; } else if (FEOrder == 2) { elemNodeCnt = 6; } else { System.Diagnostics.Debug.Assert(false); } MeshType dummyMeshType; int[] vertexs; mesh.GetConnectivity(meshId, out dummyMeshType, out vertexs); System.Diagnostics.Debug.Assert(meshType == dummyMeshType); System.Diagnostics.Debug.Assert(elemVertexCnt * elemCnt == vertexs.Length); for (int iElem = 0; iElem < elemCnt; iElem++) { int[] vertexCoIds = new int[elemVertexCnt]; for (int iPt = 0; iPt < elemVertexCnt; iPt++) { int coId = vertexs[iElem * elemVertexCnt + iPt]; vertexCoIds[iPt] = coId; } int[] nodeCoIds = new int[elemNodeCnt]; if (FEOrder == 1) { System.Diagnostics.Debug.Assert(nodeCoIds.Length == vertexCoIds.Length); vertexCoIds.CopyTo(nodeCoIds, 0); } else if (FEOrder == 2) { for (int i = 0; i < elemVertexCnt; i++) { nodeCoIds[i] = vertexCoIds[i]; { int v1 = vertexCoIds[i]; int v2 = vertexCoIds[(i + 1) % elemVertexCnt]; if (v1 > v2) { int tmp = v1; v1 = v2; v2 = tmp; } string edgeKey = v1 + "_" + v2; int midPtCoId = -1; if (edge2MidPt.ContainsKey(edgeKey)) { midPtCoId = edge2MidPt[edgeKey][0]; } else { double[] vPt1 = world.GetVertexCoord(v1); double[] vPt2 = world.GetVertexCoord(v2); double[] midPt = { (vPt1[0] + vPt2[0]) / 2.0, (vPt1[1] + vPt2[1]) / 2.0 }; midPtCoId = (int)(Coords.Count / Dimension); Coords.Add(midPt[0]); Coords.Add(midPt[1]); var list = new List <int>(); list.Add(midPtCoId); edge2MidPt[edgeKey] = list; } nodeCoIds[i + elemVertexCnt] = midPtCoId; } } } else { System.Diagnostics.Debug.Assert(false); } TriangleFE fe = new TriangleFE((int)FEOrder); fe.World = world; fe.SetVertexCoordIds(vertexCoIds); fe.SetNodeCoordIds(nodeCoIds); fe.MaterialId = maId; fe.MeshId = meshId; fe.MeshElemId = iElem; // 仮登録 uint freeId = TriangleFEArray.GetFreeObjectId(); uint feId = TriangleFEArray.AddObject(freeId, fe); System.Diagnostics.Debug.Assert(feId == freeId); } } ////////////////////////////////////////////////// // 境界の線要素 foreach (uint meshId in meshIds) { uint elemCnt; MeshType meshType; int loc; uint cadId; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId); if (meshType != MeshType.Bar) { continue; } int elemVertexCnt = 2; int elemNodeCnt = 0; if (FEOrder == 1) { elemNodeCnt = 2; } else if (FEOrder == 2) { elemNodeCnt = 3; } else { System.Diagnostics.Debug.Assert(false); } MeshType dummyMeshType; int[] vertexs; mesh.GetConnectivity(meshId, out dummyMeshType, out vertexs); System.Diagnostics.Debug.Assert(meshType == dummyMeshType); System.Diagnostics.Debug.Assert(elemVertexCnt * elemCnt == vertexs.Length); //System.Diagnostics.Debug.Assert(CadEdge2Material.ContainsKey(cadId)); //if (!CadEdge2Material.ContainsKey(cadId)) //{ // throw new IndexOutOfRangeException(); //} // 未指定のマテリアルも許容する uint maId = cadEdge2Material.ContainsKey(cadId) ? cadEdge2Material[cadId] : 0; for (int iElem = 0; iElem < elemCnt; iElem++) { int[] vertexCoIds = new int[elemVertexCnt]; for (int iPt = 0; iPt < elemVertexCnt; iPt++) { int coId = vertexs[iElem * elemVertexCnt + iPt]; vertexCoIds[iPt] = coId; } int[] nodeCoIds = new int[elemNodeCnt]; if (FEOrder == 1) { System.Diagnostics.Debug.Assert(nodeCoIds.Length == vertexCoIds.Length); vertexCoIds.CopyTo(nodeCoIds, 0); } else if (FEOrder == 2) { for (int i = 0; i < 2; i++) { nodeCoIds[i] = vertexCoIds[i]; } // 線要素上の中点 int v1 = vertexCoIds[0]; int v2 = vertexCoIds[1]; if (v1 > v2) { int tmp = v1; v1 = v2; v2 = tmp; } string edgeKey = v1 + "_" + v2; if (!edge2MidPt.ContainsKey(edgeKey)) { System.Diagnostics.Debug.Assert(false); } int midPtCoId = edge2MidPt[edgeKey][0]; nodeCoIds[2] = midPtCoId; } else { System.Diagnostics.Debug.Assert(false); } LineFE fe = new LineFE((int)FEOrder); fe.World = world; fe.SetVertexCoordIds(vertexCoIds); fe.SetNodeCoordIds(nodeCoIds); fe.MaterialId = maId; fe.MeshId = meshId; fe.MeshElemId = iElem; uint freeId = LineFEArray.GetFreeObjectId(); uint feId = LineFEArray.AddObject(freeId, fe); System.Diagnostics.Debug.Assert(feId == freeId); string key = string.Format(meshId + "_" + iElem); Mesh2LineFE.Add(key, feId); } } }
public IList <int> GetCoordIdsFromCadId(FEWorld world, uint cadId, CadElementType cadElemType) { Mesher2D mesh = world.Mesh; IList <int> coIds = null; if (cadElemType == CadElementType.Vertex) { uint meshId = mesh.GetIdFromCadId(cadId, cadElemType); uint elemCnt; MeshType meshType; int loc; uint cadIdTmp; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadIdTmp); MeshType dummyMeshType; int[] vertexs; mesh.GetConnectivity(meshId, out dummyMeshType, out vertexs); System.Diagnostics.Debug.Assert(meshType == dummyMeshType); coIds = vertexs.ToList(); } else if (cadElemType == CadElementType.Edge) { coIds = new List <int>(); IList <uint> feIds = LineFEArray.GetObjectIds(); foreach (uint feId in feIds) { LineFE lineFE = LineFEArray.GetObject(feId); uint cadIdTmp; { uint meshId = lineFE.MeshId; uint elemCnt; MeshType meshType; int loc; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadIdTmp); System.Diagnostics.Debug.Assert(meshType == MeshType.Bar); } if (cadIdTmp == cadId) { foreach (int coId in lineFE.NodeCoordIds) { if (coIds.IndexOf(coId) == -1) { coIds.Add(coId); } } } } } else if (cadElemType == CadElementType.Loop) { coIds = new List <int>(); IList <uint> feIds = TriangleFEArray.GetObjectIds(); foreach (uint feId in feIds) { TriangleFE triFE = TriangleFEArray.GetObject(feId); uint cadIdTmp; { uint meshId = triFE.MeshId; uint elemCnt; MeshType meshType; int loc; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadIdTmp); System.Diagnostics.Debug.Assert(meshType == MeshType.Tri); } if (cadIdTmp == cadId) { foreach (int coId in triFE.NodeCoordIds) { if (coIds.IndexOf(coId) == -1) { coIds.Add(coId); } } } } } else { throw new InvalidOperationException(); } return(coIds); }
public void UpdateCadGeometry(CadObject2D cad2D) { Mesher2D mesh = new Mesher2D(cad2D); for (int idp = 0; idp < DrawParts.Count; idp++) { CadObject2DDrawPart dp = DrawParts[idp]; dp.Clear(); uint cadId = dp.CadId; CadElementType cadType = dp.Type; if (!cad2D.IsElementId(cadType, cadId)) { continue; } uint meshId = mesh.GetIdFromCadId(cadId, cadType); if (meshId == 0) { continue; } MeshType meshType; uint elemCnt; int loc; uint cadId0; mesh.GetMeshInfo(meshId, out elemCnt, out meshType, out loc, out cadId0); System.Diagnostics.Debug.Assert(cadId0 == cadId); if (meshType == MeshType.Tri) { dp.SetTriArray(mesh.GetTriArrays()[loc]); double[] color = cad2D.GetLoopColor(cadId0); for (int iTmp = 0; iTmp < 3; iTmp++) { dp.Color[iTmp] = (float)color[iTmp]; } } else if (meshType == MeshType.Bar) { dp.SetBarArray(mesh.GetBarArrays()[loc]); System.Diagnostics.Debug.Assert(cadType == CadElementType.Edge); Edge2D edge = cad2D.GetEdge(cadId); dp.CurveType = edge.CurveType; dp.CtrlPoints.Clear(); // 2019-03-11 エッジの色 FIX double[] color = edge.Color; for (int iTmp = 0; iTmp < 3; iTmp++) { dp.Color[iTmp] = (float)color[iTmp]; } if (edge.CurveType == CurveType.CurveArc) { OpenTK.Vector2d cPt; double radius; edge.GetCenterRadius(out cPt, out radius); dp.CtrlPoints.Add(cPt); } else if (edge.CurveType == CurveType.CurveBezier) { IList <OpenTK.Vector2d> cos = edge.GetCurvePoint(); dp.CtrlPoints.Add(cos[0]); dp.CtrlPoints.Add(cos[1]); } } else if (meshType == MeshType.Vertex) { dp.SetVertex(mesh.GetVertexs()[loc]); } } { // 座標をセット IList <OpenTK.Vector2d> vec2Ds = mesh.GetVectors(); uint ptCnt = (uint)vec2Ds.Count; uint ndim = 2; VertexArray.SetSize(ptCnt, ndim); for (int iPt = 0; iPt < ptCnt; iPt++) { VertexArray.VertexCoordArray[iPt * ndim] = vec2Ds[iPt].X; VertexArray.VertexCoordArray[iPt * ndim + 1] = vec2Ds[iPt].Y; } if (VertexArray.UVCoordArray != null) { for (int iPt = 0; iPt < ptCnt; iPt++) { VertexArray.UVCoordArray[iPt * ndim] = vec2Ds[iPt].X * TexScale; VertexArray.UVCoordArray[iPt * ndim + 1] = vec2Ds[iPt].Y * TexScale; } } } }