コード例 #1
0
        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);
        }
コード例 #2
0
        // 座標、三角形要素と線要素を生成する
        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);
                }
            }
        }
コード例 #3
0
ファイル: EdgeFieldDrawer.cs プロジェクト: lulzzz/IvyFEM
        private void Set(uint valueId, FieldDerivativeType valueDt,
                         bool isntDisplacementValue,
                         bool isDrawInnerEdge,
                         FEWorld world)
        {
            var mesh = world.Mesh;

            if (!world.IsFieldValueId(valueId))
            {
                throw new ArgumentException();
                //return;
            }

            ValueId = valueId;
            ValueDt = valueDt;
            IsntDisplacementValue = isntDisplacementValue;

            var fv = world.GetFieldValue(ValueId);

            // 線要素を生成
            uint quantityId = fv.QuantityId;

            if (isDrawInnerEdge)
            {
                // 内部の全ての辺を描画
                LineFEs = world.MakeBoundOfElements(quantityId);
            }
            else
            {
                // 境界の辺だけ描画
                LineFEs = new List <LineFE>();
                IList <MeshBarArray> barArrays = mesh.GetBarArrays();
                foreach (MeshBarArray barArray in barArrays)
                {
                    uint        eCadId   = barArray.ECadId;
                    IList <int> allCoIds = world.GetCoordIdsFromCadId(quantityId, eCadId, CadElementType.Edge);

                    for (int i = 0; i < (allCoIds.Count - 1); i++)
                    {
                        int    workFEOrder = 1;
                        LineFE lineFE      = new LineFE(workFEOrder);
                        {
                            int[] coIds = { allCoIds[i], allCoIds[i + 1] };
                            lineFE.SetVertexCoordIds(coIds);
                            lineFE.SetNodeCoordIds(coIds);
                        }
                        LineFEs.Add(lineFE);
                    }
                }
            }

            int feOrder;
            {
                LineFE lineFE = LineFEs[0]; // 先頭の要素
                feOrder     = lineFE.Order;
                LinePtCount = lineFE.NodeCount;
            }

            uint ptCnt = LineCount * LinePtCount;
            uint dim   = world.Dimension;

            uint drawDim;

            if (!IsntDisplacementValue &&
                dim == 2 &&
                (fv.Type == FieldValueType.Scalar || fv.Type == FieldValueType.ZScalar))
            {
                drawDim = 3;
            }
            else
            {
                drawDim = dim;
            }
            VertexArray.SetSize(ptCnt, drawDim);

            if (drawDim == 2)
            {
                SutableRotMode = RotMode.RotMode2D;
            }
            else if (dim == 3)
            {
                SutableRotMode = RotMode.RotMode3D;
            }
            else
            {
                SutableRotMode = RotMode.RotMode2DH;
            }


            Update(world);
        }