// 接触解析の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); } }
public void UpdateCoord(Mesher2D mesher) { { // 座標をセット IList <OpenTK.Vector2d> vecs = mesher.GetVectors(); uint nDim = 2; uint nVec = (uint)vecs.Count; if (VertexArray.Dimension != nDim) { return; } if (VertexArray.PointCount != nVec) { return; } for (int ivec = 0; ivec < nVec; ivec++) { VertexArray.VertexCoordArray[ivec * nDim] = vecs[ivec].X; VertexArray.VertexCoordArray[ivec * nDim + 1] = vecs[ivec].Y; } } }
// 座標、三角形要素と線要素を生成する 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; } } } }
private bool Set(Mesher2D mesher) { SutableRotMode = RotMode.RotMode2D; // DrawMode 1 : 2D int layerMin = 0; int layerMax = 0; { bool isInited = false; IList <MeshTriArray2D> triArrays = mesher.GetTriArrays(); for (int itri = 0; itri < triArrays.Count; itri++) { int layer = triArrays[itri].Layer; if (isInited) { layerMin = (layer < layerMin) ? layer : layerMin; layerMax = (layer > layerMax) ? layer : layerMax; } else { layerMin = layer; layerMax = layer; isInited = true; } } IList <MeshQuadArray2D> quadArrays = mesher.GetQuadArrays(); for (int iquad = 0; iquad < quadArrays.Count; iquad++) { int layer = quadArrays[iquad].Layer; if (isInited) { layerMin = (layer < layerMin) ? layer : layerMin; layerMax = (layer > layerMax) ? layer : layerMax; } else { layerMin = layer; layerMax = layer; isInited = true; } } } double layerHeight = 1.0 / (layerMax - layerMin + 1); { // 三角形要素をセット IList <MeshTriArray2D> triArrays = mesher.GetTriArrays(); for (int itri = 0; itri < triArrays.Count; itri++) { Mesher2DDrawPart dp = new Mesher2DDrawPart(triArrays[itri]); int layer = triArrays[itri].Layer; dp.Height = (layer - layerMin) * layerHeight; DrawParts.Add(dp); } } { // 四角形要素をセット IList <MeshQuadArray2D> quadArrays = mesher.GetQuadArrays(); for (int iquad = 0; iquad < quadArrays.Count; iquad++) { Mesher2DDrawPart dp = new Mesher2DDrawPart(quadArrays[iquad]); int layer = quadArrays[iquad].Layer; dp.Height = (layer - layerMin) * layerHeight; DrawParts.Add(dp); } } { // 線要素をセット IList <MeshBarArray> barArrays = mesher.GetBarArrays(); for (int ibar = 0; ibar < barArrays.Count; ibar++) { double height = 0; { int layer = barArrays[ibar].Layer; height += (layer - layerMin + 0.01) * layerHeight; } Mesher2DDrawPart dp = new Mesher2DDrawPart(barArrays[ibar]); dp.Height = height; DrawParts.Add(dp); } } { // 頂点をセット IList <MeshVertex> vertexs = mesher.GetVertexs(); for (int iver = 0; iver < vertexs.Count; iver++) { double height = 0; /* * { * int layer = vertexs[iver].Layer; * height += (layer - layerMin + 0.1) * layerHeight; * } */ height = 0.2; Mesher2DDrawPart dp = new Mesher2DDrawPart(vertexs[iver]); dp.Height = height; DrawParts.Add(dp); } } { // 座標をセット IList <OpenTK.Vector2d> vec2Ds = mesher.GetVectors(); uint nDim = 2; uint nVec = (uint)vec2Ds.Count; VertexArray.SetSize(nVec, nDim); for (int ivec = 0; ivec < nVec; ivec++) { VertexArray.VertexCoordArray[ivec * nDim] = vec2Ds[ivec].X; VertexArray.VertexCoordArray[ivec * nDim + 1] = vec2Ds[ivec].Y; } } return(true); }
public Mesher2DDrawer(Mesher2D mesher, bool isDrawFace = true) { IsDrawFace = isDrawFace; Set(mesher); }