public void EnableUVMap(bool isUVMap, FEWorld world) { if ((UVArray != null) == isUVMap) { return; } if (isUVMap) { uint ptCnt = VertexArray.PointCount; UVArray = new double[ptCnt * 2]; if (!world.IsFieldValueId(ValueId)) { return; } FieldValue fv = world.GetFieldValue(ValueId); uint quantityId = fv.QuantityId; uint coCnt = world.GetCoordCount(quantityId); for (int coId = 0; coId < coCnt; coId++) { double[] c = world.GetCoord(quantityId, coId); UVArray[coId * 2 + 0] = c[0] * TexScale; UVArray[coId * 2 + 1] = c[1] * TexScale; } } else { UVArray = null; } }
private void SetTri(FEWorld world, uint valueId) { System.Diagnostics.Debug.Assert(Type == ElementType.Tri); if (Type != ElementType.Tri) { return; } FieldValue fv = world.GetFieldValue(valueId); uint quantityId = fv.QuantityId; int feOrder; { uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, 0); // 先頭の要素 System.Diagnostics.Debug.Assert(feId != 0); TriangleFE triFE = world.GetTriangleFE(quantityId, feId); feOrder = triFE.Order; ElemPtCount = triFE.NodeCount; } Indexs = new uint[ElemPtCount * ElemCount]; for (int iTri = 0; iTri < ElemCount; iTri++) { uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, (uint)iTri); System.Diagnostics.Debug.Assert(feId != 0); TriangleFE triFE = world.GetTriangleFE(quantityId, feId); for (int iPt = 0; iPt < ElemPtCount; iPt++) { Indexs[iTri * ElemPtCount + iPt] = (uint)triFE.NodeCoordIds[iPt]; } } }
// 接触解析の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); } } }
public EMWaveguide1DEigenFEM(FEWorld world, uint quantityId, uint portId) { World = world; QuantityId = quantityId; PortId = portId; CalcMatrixs(); }
public void SetColors(uint bubbleValueId, FieldDerivativeType dt, FEWorld world, IColorMap colorMap) { FieldValue fv = world.GetFieldValue(bubbleValueId); System.Diagnostics.Debug.Assert(fv.IsBubble == true); uint quantityId = fv.QuantityId; var mesh = world.Mesh; MeshType meshType; int[] vertexs; mesh.GetConnectivity(MeshId, out meshType, out vertexs); if (Type == ElementType.Tri) { Colors = new float[ElemCount * 3]; for (int iTri = 0; iTri < ElemCount; iTri++) { // Bubble uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, (uint)iTri); System.Diagnostics.Debug.Assert(feId != 0); double value = fv.GetShowValue((int)(feId - 1), 0, dt); var color = colorMap.GetColor(value); for (int iColor = 0; iColor < 3; iColor++) { Colors[iTri * 3 + iColor] = (float)color[iColor]; } } } else if (Type == ElementType.Quad) { // TRIと同じでよいが要素IDを取得するメソッドが現状ない throw new NotImplementedException(); } }
private void SetLine(FEWorld world, uint valueId) { System.Diagnostics.Debug.Assert(Type == ElementType.Line); if (Type != ElementType.Line) { return; } FieldValue fv = world.GetFieldValue(valueId); uint quantityId = fv.QuantityId; int feOrder; { uint feId = world.GetLineFEIdFromMesh(quantityId, MeshId, 0); // 先頭の要素 System.Diagnostics.Debug.Assert(feId != 0); LineFE lineFE = world.GetLineFE(quantityId, feId); feOrder = lineFE.Order; ElemPtCount = lineFE.NodeCount; } Indexs = new uint[ElemPtCount * ElemCount]; for (int iEdge = 0; iEdge < ElemCount; iEdge++) { uint feId = world.GetLineFEIdFromMesh(quantityId, MeshId, (uint)iEdge); System.Diagnostics.Debug.Assert(feId != 0); LineFE lineFE = world.GetLineFE(quantityId, feId); for (int iPt = 0; iPt < ElemPtCount; iPt++) { Indexs[iEdge * ElemPtCount + iPt] = (uint)lineFE.NodeCoordIds[iPt]; } } }
public EdgeFieldDrawer(uint valueId, FieldDerivativeType valueDt, bool isntDisplacementValue, bool isDrawInnerEdge, FEWorld world) { Set(valueId, valueDt, isntDisplacementValue, isDrawInnerEdge, world); }
public void Update(FEWorld world) { for (int idp = 0; idp < DrawParts.Count; idp++) { VectorFieldDrawPart dp = DrawParts[idp]; dp.Update(ValueId, ValueDt, Type, world); } }
public void Update(FEWorld world) { for (int iDraw = 0; iDraw < Drawers.Count; iDraw++) { IFieldDrawer drawer = Drawers[iDraw] as IFieldDrawer; drawer.Update(world); } }
public FaceFieldDrawer(uint valueId, FieldDerivativeType valueDt, bool isntDisplacementValue, FEWorld world, uint colorValueId, FieldDerivativeType colorValueDt, double min, double max) { ColorMap = new ColorMap(min, max); Set(valueId, valueDt, isntDisplacementValue, world, colorValueId, colorValueDt); }
private void MakeCo2FixedCads(FEWorld world) { Co2FixedCads.Clear(); foreach (var fixedCad in FieldFixedCads) { IList <int> coIds = GetCoordIdsFromCadId(world, fixedCad.CadId, fixedCad.CadElemType); if (fixedCad is DistributedFieldFixedCad) { DistributedFieldFixedCad dist = fixedCad as DistributedFieldFixedCad; dist.InitCoordIds(coIds); } foreach (int coId in coIds) { IList <FieldFixedCad> fixedCads = null; if (!Co2FixedCads.ContainsKey(coId)) { fixedCads = new List <FieldFixedCad>(); Co2FixedCads[coId] = fixedCads; } else { fixedCads = Co2FixedCads[coId]; } if (fixedCads.IndexOf(fixedCad) == -1) { // 同じ変数の拘束条件がすでにあるかチェック { IList <FieldFixedCad> sameFixedCads = new List <FieldFixedCad>(); foreach (FieldFixedCad tmp in fixedCads) { bool isSameTarget = false; foreach (uint iDof in tmp.FixedDofIndexs) { if (fixedCad.FixedDofIndexs.Contains(iDof)) { isSameTarget = true; break; } } if (isSameTarget) { sameFixedCads.Add(tmp); } } if (sameFixedCads.Count > 0) { foreach (FieldFixedCad tmp in sameFixedCads) { fixedCads.Remove(tmp); } } } fixedCads.Add(fixedCad); } } } }
private void SetQuad(FEWorld world) { System.Diagnostics.Debug.Assert(Type == ElementType.Quad); if (Type != ElementType.Quad) { return; } throw new NotImplementedException(); }
public Diffusion2DTDFEM(FEWorld world, double timeStep, double newmarkBeta, double newmarkGamma, uint valueId, uint prevValueId) { World = world; TimeStep = timeStep; NewmarkBeta = newmarkBeta; NewmarkGamma = newmarkGamma; ValueId = valueId; PrevValueId = prevValueId; }
private void SetLine(FEWorld world) { System.Diagnostics.Debug.Assert(Type == ElementType.Line); if (Type != ElementType.Line) { return; } var mesh = world.Mesh; // TODO: あとで //throw new NotImplementedException(); }
public Elastic2DTDFEM(FEWorld world, double timeStep, double newmarkBeta, double newmarkGamma, uint valueId, uint prevValueId) { World = world; TimeStep = timeStep; NewmarkBeta = newmarkBeta; NewmarkGamma = newmarkGamma; ValueId = valueId; PrevValueId = prevValueId; SetupCalcABs(); }
// ポート上の線要素の節点ナンバリング 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++; } } } } } }
public void MakeElements( FEWorld world, IList <double> vertexCoords, Dictionary <uint, uint> cadLoop2Material, Dictionary <uint, uint> cadEdge2Material) { ClearElements(); // 座標、三角形要素と線要素を生成する MakeCoordsAndElements( world, vertexCoords, cadLoop2Material, cadEdge2Material); // 多点拘束の座標生成 MakeCo2MultipointConstraints(world); // Note: 線要素生成後でないと点を特定できない IList <int> zeroCoordIds = GetZeroCoordIds(world); // 多点拘束の対象外の節点を除外する if (Co2MultipointConstraints.Count > 0) { for (int coId = 0; coId < Coords.Count; coId++) { if (!Co2MultipointConstraints.ContainsKey(coId)) { if (zeroCoordIds.IndexOf(coId) == -1) { zeroCoordIds.Add(coId); } } } } // Note: 三角形要素生成後でないと特定できない MakeCo2FixedCads(world); // ポート上の線要素の節点ナンバリング NumberPortNodes(world, zeroCoordIds); // 三角形要素の節点ナンバリング NumberTriangleNodes(world, zeroCoordIds); // 接触解析のMaster/Slave線要素を準備する SetupContactMasterSlaveLineElements(world); // 節点→座標のマップ作成 MakeNode2CoFromCo2Node(); // 頂点→三角形要素のマップと辺→三角形要素のマップ作成 MakeCo2AndEdgeCos2TriangleFE(); }
public FaceFieldDrawPart(uint meshId, FEWorld world, uint valueId) { var mesh = world.Mesh; if (!mesh.IsId(meshId)) { return; } MeshId = meshId; uint cadId; int layer; uint elemCount; MeshType meshType; int loc; mesh.GetInfo(MeshId, out cadId, out layer); mesh.GetMeshInfo(MeshId, out elemCount, out meshType, out loc, out cadId); Layer = layer; ElemCount = elemCount; if (meshType == MeshType.Vertex) { Type = ElementType.Point; Color[0] = 0; Color[1] = 0; Color[2] = 0; } else if (meshType == MeshType.Bar) { Type = ElementType.Line; Color[0] = 0; Color[1] = 0; Color[2] = 0; SetLine(world, valueId); } else if (meshType == MeshType.Tri) { Type = ElementType.Tri; SetTri(world, valueId); } else if (meshType == MeshType.Quad) { Type = ElementType.Quad; SetQuad(world); } else { throw new NotImplementedException(); } }
private IList <int> GetZeroCoordIds(FEWorld world) { IList <int> zeroCoIds = new List <int>(); foreach (var fixedCad in ZeroFieldFixedCads) { IList <int> coIds = GetCoordIdsFromCadId(world, fixedCad.CadId, fixedCad.CadElemType); foreach (int coId in coIds) { zeroCoIds.Add(coId); } } return(zeroCoIds); }
private void UpdateSymmetricTensor2(uint valueId, FieldDerivativeType dt, FEWorld world) { ValueDof = 6; FieldValue fv = world.GetFieldValue(valueId); uint quantityId = fv.QuantityId; uint dof = fv.Dof; System.Diagnostics.Debug.Assert(fv.IsBubble == true); var mesh = world.Mesh; MeshType meshType; int[] vertexs; mesh.GetConnectivity(MeshId, out meshType, out vertexs); if (Type == ElementType.Tri) { Values = new double[ElemCount * ValueDof]; for (int iTri = 0; iTri < ElemCount; iTri++) { // Bubble uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, (uint)iTri); System.Diagnostics.Debug.Assert(feId != 0); double[] sigma = new double[dof]; for (int iDof = 0; iDof < dof; iDof++) { sigma[iDof] = fv.GetShowValue((int)(feId - 1), iDof, dt); } double[] vecs; double ls; double[] vecl; double ll; GetPrincipalStressVectorForSymmetricTensor2(sigma, out vecs, out ls, out vecl, out ll); Values[iTri * ValueDof + 0] = vecs[0]; Values[iTri * ValueDof + 1] = vecs[1]; Values[iTri * ValueDof + 2] = ls; Values[iTri * ValueDof + 3] = vecl[0]; Values[iTri * ValueDof + 4] = vecl[1]; Values[iTri * ValueDof + 5] = ll; } } else if (Type == ElementType.Quad) { // TRIと同じでよいが要素IDを取得するメソッドが現状ない throw new NotImplementedException(); } }
public Hyperelastic2DTDFEM(FEWorld world, double timeStep, double newmarkBeta, double newmarkGamma, uint uValueId, uint prevUValueId, uint lValueId) { World = world; TimeStep = timeStep; NewmarkBeta = newmarkBeta; NewmarkGamma = newmarkGamma; UValueId = uValueId; PrevUValueId = prevUValueId; LValueId = lValueId; SetupCalcABs(); }
public void SetTexScale(double scale, FEWorld world) { TexScale = scale; if (UVArray != null) { if (!world.IsFieldValueId(ValueId)) { return; } FieldValue fv = world.GetFieldValue(ValueId); uint quantityId = fv.QuantityId; uint coCnt = world.GetCoordCount(quantityId); for (int coId = 0; coId < coCnt; coId++) { double[] c = world.GetCoord(quantityId, coId); UVArray[coId * 2 + 0] = c[0] * TexScale; UVArray[coId * 2 + 1] = c[1] * TexScale; } } }
private void Set(uint valueId, FieldDerivativeType valueDt, FEWorld world) { System.Diagnostics.Debug.Assert(world.IsFieldValueId(valueId)); ValueId = valueId; var mesh = world.Mesh; uint dim = world.Dimension; { if (dim == 2) { SutableRotMode = RotMode.RotMode2D; } else if (dim == 3) { SutableRotMode = RotMode.RotMode3D; } } FieldValue fv = world.GetFieldValue(valueId); if (fv.Type == FieldValueType.Vector2 || fv.Type == FieldValueType.Vector3) { Type = VectorFieldDrawerType.Vector; } else if (fv.Type == FieldValueType.SymmetricTensor2) { Type = VectorFieldDrawerType.SymmetricTensor2; } { DrawParts.Clear(); IList <uint> meshIds = mesh.GetIds(); foreach (uint meshId in meshIds) { VectorFieldDrawPart dp = new VectorFieldDrawPart(meshId, world); DrawParts.Add(dp); } } Update(world); }
private void SetTri(FEWorld world) { System.Diagnostics.Debug.Assert(Type == ElementType.Tri); if (Type != ElementType.Tri) { return; } var mesh = world.Mesh; int elemPtCount = 3; MeshType meshType; int[] vertexs; mesh.GetConnectivity(MeshId, out meshType, out vertexs); System.Diagnostics.Debug.Assert(elemPtCount * ElemCount == vertexs.Length); uint dim = Dimension; System.Diagnostics.Debug.Assert(dim == 2); Coords = new double[ElemCount * dim]; for (int iTri = 0; iTri < ElemCount; iTri++) { double[] bubbleCoord = new double[dim]; for (int iPt = 0; iPt < elemPtCount; iPt++) { int coId = vertexs[iTri * elemPtCount + iPt]; double[] coord = world.GetVertexCoord(coId); for (int iDimTmp = 0; iDimTmp < dim; iDimTmp++) { bubbleCoord[iDimTmp] += coord[iDimTmp]; } } for (int iDim = 0; iDim < dim; iDim++) { bubbleCoord[iDim] /= elemPtCount; Coords[iTri * dim + iDim] = bubbleCoord[iDim]; } } }
// 三角形要素の節点ナンバリング 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 UpdateVector(uint valueId, FieldDerivativeType dt, FEWorld world) { ValueDof = 2; FieldValue fv = world.GetFieldValue(valueId); uint quantityId = fv.QuantityId; uint dof = fv.Dof; System.Diagnostics.Debug.Assert(fv.IsBubble == true); var mesh = world.Mesh; MeshType meshType; int[] vertexs; mesh.GetConnectivity(MeshId, out meshType, out vertexs); if (Type == ElementType.Tri) { Values = new double[ElemCount * ValueDof]; for (int iTri = 0; iTri < ElemCount; iTri++) { // Bubble uint feId = world.GetTriangleFEIdFromMesh(quantityId, MeshId, (uint)iTri); System.Diagnostics.Debug.Assert(feId != 0); System.Diagnostics.Debug.Assert(dof >= ValueDof); for (int iDof = 0; iDof < ValueDof; iDof++) { double u = fv.GetShowValue((int)(feId - 1), iDof, dt); Values[iTri * ValueDof + iDof] = u; } } } else if (Type == ElementType.Quad) { // TRIと同じでよいが要素IDを取得するメソッドが現状ない throw new NotImplementedException(); } }
private void MakeCo2MultipointConstraints(FEWorld world) { foreach (MultipointConstraint mpConstraint in MultipointConstraints) { var fixedCads = mpConstraint.FixedCads; foreach (var fixedCad in fixedCads) { IList <int> coIds = GetCoordIdsFromCadId(world, fixedCad.CadId, fixedCad.CadElemType); foreach (int coId in coIds) { IList <MultipointConstraint> mpConstraints = null; if (!Co2MultipointConstraints.ContainsKey(coId)) { Co2MultipointConstraints[coId] = new List <MultipointConstraint>(); } mpConstraints = Co2MultipointConstraints[coId]; if (mpConstraints.IndexOf(mpConstraint) == -1) { mpConstraints.Add(mpConstraint); } } } } }
public IList <LineFE> MakeBoundOfElements(FEWorld world) { IList <LineFE> boundOfTriangelFEs = new List <LineFE>(); HashSet <string> edges = new HashSet <string>(); var feIds = GetTriangleFEIds(); foreach (uint feId in feIds) { TriangleFE triFE = GetTriangleFE(feId); System.Diagnostics.Debug.Assert(triFE.Order == FEOrder); int[][] vertexCoIds = { new int[] { triFE.VertexCoordIds[0], triFE.VertexCoordIds[1] }, new int[] { triFE.VertexCoordIds[1], triFE.VertexCoordIds[2] }, new int[] { triFE.VertexCoordIds[2], triFE.VertexCoordIds[0] } }; int[][] nodeCoIds = null; if (triFE.Order == 1) { int[][] nodeCoIds1 = { new int[] { triFE.NodeCoordIds[0], triFE.NodeCoordIds[1] }, new int[] { triFE.NodeCoordIds[1], triFE.NodeCoordIds[2] }, new int[] { triFE.NodeCoordIds[2], triFE.NodeCoordIds[0] } }; nodeCoIds = nodeCoIds1; } else if (triFE.Order == 2) { int[][] nodeCoIds2 = { new int[] { triFE.NodeCoordIds[0], triFE.NodeCoordIds[1], triFE.NodeCoordIds[3] }, new int[] { triFE.NodeCoordIds[1], triFE.NodeCoordIds[2], triFE.NodeCoordIds[4] }, new int[] { triFE.NodeCoordIds[2], triFE.NodeCoordIds[0], triFE.NodeCoordIds[5] } }; nodeCoIds = nodeCoIds2; } else { System.Diagnostics.Debug.Assert(false); } for (int iEdge = 0; iEdge < 3; iEdge++) { int v1 = vertexCoIds[iEdge][0]; int v2 = vertexCoIds[iEdge][1]; if (v1 > v2) { int tmp = v1; v1 = v2; v2 = tmp; } string edgeKey = v1 + "_" + v2; if (edges.Contains(edgeKey)) { continue; } else { edges.Add(edgeKey); } var lineFE = new LineFE((int)FEOrder); lineFE.World = world; lineFE.SetVertexCoordIds(vertexCoIds[iEdge]); lineFE.SetNodeCoordIds(nodeCoIds[iEdge]); // MeshId等は対応するものがないのでセットしない boundOfTriangelFEs.Add(lineFE); } } return(boundOfTriangelFEs); }
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); }
// 座標、三角形要素と線要素を生成する 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); } } }