Example #1
0
        private double radius; // 外接円半径

        #endregion Fields

        #region Constructors

        /// <summary>
        /// DelaunayElement2Dクラスの新規インスタンスを初期化し,各頂点情報(座標,ID)をセットする.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        public DelaunayElement2D(Node a, Node b, Node c)
        {
            Elementcode = ElementCode.Tria03;
            Nodes = new List<Node>() { a, b, c };
            Edges = new List<Edge>() { new Edge(a.ID, b.ID), new Edge(b.ID, c.ID), new Edge(c.ID, a.ID) };

            center = new Node(-256, false, 0.0, 0.0);
            radius = 0;
            SetSideLength();
            Area = CalcArea();
            SetCircumscribedCircle();
            DeleteFlag = false;
        }
Example #2
0
 /// <summary>
 /// コピーコンストラクタ
 /// </summary>
 /// <param name="source">コピーされるobject</param>
 public DelaunayElement2D(DelaunayElement2D source)
 {
     Elementcode = source.Elementcode;
     Nodes = new List<Node>() { source.Nodes[0], source.Nodes[1], source.Nodes[2] };
     Edges = new List<Edge>() { source.Edges[0], source.Edges[1], source.Edges[2] };
     Area = source.Area;
     center = new Node(source.center);
     radius = source.radius;
     DeleteFlag = source.DeleteFlag;
 }
Example #3
0
 /// <summary>
 /// (要素が四面体の場合のみ)与えられた点の座標が外接球の内部に含まれるかどうか判定する.
 /// </summary>
 /// <param name="p">点</param>
 /// <returns>判定結果</returns>
 public bool IsInside(Node p)
 {
     if (Nodes.Count == 4)
     {
         double distance_sq = ((p.X - center.X) * (p.X - center.X) + (p.Y - center.Y) * (p.Y - center.Y) + (p.Z - center.Z) * (p.Z - center.Z));
         if (distance_sq < radius * radius)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
     else
     {
         return false;
     }
 }
Example #4
0
        public Element3D(Node a, Node b, Node c, Node d)
        {
            Nodes = new List<Node>() { a, b, c, d };
            Edges = new List<Edge>();
            Surfaces = new List<Surface3D>() { new Surface3D(a.ID, b.ID, c.ID), new Surface3D(a.ID, d.ID, b.ID), new Surface3D(b.ID, d.ID, c.ID), new Surface3D(a.ID, c.ID, d.ID) };

            center = new Node(0, false, 0.0, 0.0, 0.0);
            SetCircumscribedSphere();
            DeleteFlag = false;
        }
Example #5
0
 /// <summary>
 /// コピーコンストラクタ
 /// </summary>
 /// <param name="source"></param>
 public Element3D(Element3D source)
 {
     elementcode = source.elementcode;
     material = source.material;
     Nodes = new List<Node>();
     for (int i = 0; i < source.Nodes.Count; ++i)
     {
         Nodes.Add(new Node(source.Nodes[i]));
     }
     Edges = new List<Edge>();
     for (int i = 0; i < source.Edges.Count; ++i)
     {
         Edges.Add(new Edge(source.Edges[i]));
     }
     Surfaces = new List<Surface3D>();
     for (int i = 0; i < source.Surfaces.Count; ++i)
     {
         Surfaces.Add(new Surface3D(source.Surfaces[i]));
     }
     center = new Node(source.center);
     radius = source.radius;
     DeleteFlag = source.DeleteFlag;
 }
Example #6
0
 /// <summary>
 /// 追加ノードに対して,そのノードを外接球内部に含むような要素をすべて探索し,該当領域のメッシュ・サーフェスを抽出する.
 /// </summary>
 /// <param name="adding_node">追加ノード</param>
 /// <param name="rediv_surface">再分割要素を囲むサーフェスを返す</param>
 private void SearchRedivisionMesh(Node adding_node, out List<Surface3D> rediv_surface)
 {
     rediv_surface = new List<Surface3D>();
     for (int j = 0; j < delaunay_elements.Count; j++)
     {
         if (delaunay_elements[j].IsInside(adding_node))	//ノードを外接球内部に含むような要素であれば
         {
             for (int k = 0; k < 4; k++)
             {
                 var find_surface = delaunay_elements[j].GetSurface(k);
                 if (rediv_surface.Exists(ls => ls == find_surface))
                 {
                     rediv_surface.RemoveAll(ls => ls == find_surface);	//サーフェスの重複は必ず2回なので重複が検知された場合除去
                 }
                 else
                 {
                     rediv_surface.Add(find_surface);	//重複のない場合は取り合えず追加
                 }
             }
             delaunay_elements[j].DeleteFlag = true;		//削除用フラグのセット
         }
     }
 }
Example #7
0
        /// <summary>
        /// 与えられている全てのノード座標を読み取り,これらすべてを囲むようなブラケット三角形要素を生成し,elemに追加する.また,最大値最小値をセットする.
        /// </summary>
        private void SetBracketTriangle()
        {
            var min_x = givennode_min_x = given_node.Min(ls => ls.X);
            var max_x = givennode_max_x = given_node.Max(ls => ls.X);
            var min_y = givennode_min_y = given_node.Min(ls => ls.Y);
            var max_y = givennode_max_y = given_node.Max(ls => ls.Y);
            var min_z = givennode_min_z = given_node.Min(ls => ls.Z);
            var max_z = givennode_max_z = given_node.Max(ls => ls.Z);
            var cubecenter = new Node(0, false, (min_x + max_x) / 2, (min_y + max_y) / 2, (min_z + max_z) / 2);
            var cubulength = Math.Max(Math.Max((max_x - min_x), (max_y - min_y)), (max_z - min_z));	//与えられた全てのノードを内部に含み,各辺が座標軸に平行な最小の立方体の辺の長さ

            // cubelength = a とおく.一辺aの立方体の外接円の半径rはr=\sqrt{3}/2*a
            // 半径rの球の外接正四面体の一辺の長さLはL=3\sqrt{2}a
            // 球の中心から正四面体の頂点までの距離は3r = 3*\sqrt{3}/2*a <= 3a
            // 球の中心から正四面体の面までの距離はr = \sqrt{3}/2*a <= a
            bracket_node.Add(new Node(-4, false, cubecenter.X, cubecenter.Y + 2.5 * cubulength, cubecenter.Z - cubulength));		//上から見て底面上
            bracket_node.Add(new Node(-3, false, cubecenter.X - 2.2 * cubulength, cubecenter.Y - 1.3 * cubulength, cubecenter.Z - cubulength));		//上から見て底面左下
            bracket_node.Add(new Node(-2, false, cubecenter.X + 2.2 * cubulength, cubecenter.Y - 1.3 * cubulength, cubecenter.Z - cubulength));		//上から見て底面右下
            bracket_node.Add(new Node(-1, false, cubecenter.X, cubecenter.Y, cubecenter.Z + 3 * cubulength));		//真上

            delaunay_elements.Add(new Element3D(bracket_node[0], bracket_node[1], bracket_node[2], bracket_node[3]));
        }
Example #8
0
        /// <summary>
        /// 再分割領域を分割しメッシュを追加する.
        /// </summary>
        /// <param name="adding_node"></param>
        /// <param name="rediv_surface"></param>
        private void Redivision(Node adding_node, List<Surface3D> rediv_surface)
        {
            for (int i = 0; i < rediv_surface.Count; i++)
            {
                double[,] coordi = new double[3, 3];

                for (int j = 0; j < 3; j++)
                {
                    if (rediv_surface[i].GetNodeID(j) < 0)		//ノードインデックス負数(ブラケット節点)の場合
                    {
                        coordi[j, 0] = bracket_node[4 + rediv_surface[i].GetNodeID(j)].X;
                        coordi[j, 1] = bracket_node[4 + rediv_surface[i].GetNodeID(j)].Y;
                        coordi[j, 2] = bracket_node[4 + rediv_surface[i].GetNodeID(j)].Z;
                    }
                    else
                    {
                        coordi[j, 0] = given_node[rediv_surface[i].GetNodeID(j)].X;
                        coordi[j, 1] = given_node[rediv_surface[i].GetNodeID(j)].Y;
                        coordi[j, 2] = given_node[rediv_surface[i].GetNodeID(j)].Z;
                    }
                }

                delaunay_elements.Add(new Element3D(new Node(rediv_surface[i].GetNodeID(0), false, coordi[0, 0], coordi[0, 1], coordi[0, 2]),
                                                    new Node(rediv_surface[i].GetNodeID(1), false, coordi[1, 0], coordi[1, 1], coordi[1, 2]),
                                                    new Node(rediv_surface[i].GetNodeID(2), false, coordi[2, 0], coordi[2, 1], coordi[2, 2]),
                                                    adding_node
                                                    )
                                        );
            }
        }
Example #9
0
 /// <summary>
 /// 追加ノードに対して,そのノードを外接円内部に含むような要素をすべて探索し,該当領域のメッシュ・エッジ・ノードを抽出する.
 /// </summary>
 /// <param name="add_node">追加ノード</param>
 /// <param name="rediv_edge">再分割要素を囲むエッジを返す</param>
 private void SearchRedivisionMesh(Node add_node, out List<Edge> rediv_edge)
 {
     rediv_edge = new List<Edge>();
     for (int i = 0; i < delaunay_elements.Count; i++)
     {
         if (delaunay_elements[i].IsInside(add_node))		//ノードを外接円内部に含むような要素の探索
         {
             for (int j = 0; j < 3; j++)
             {
                 var find_edge = delaunay_elements[i].GetEdge(j);
                 if (rediv_edge.Exists(ls => ls == find_edge))
                 {
                     rediv_edge.RemoveAll(ls => ls == find_edge);	//エッジの重複は必ず2回なので重複が検地された場合除去
                 }
                 else
                 {
                     rediv_edge.Add(find_edge);	//重複のない場合は追加
                 }
             }
             delaunay_elements[i].DeleteFlag = true;		//削除用フラグのセット
         }
     }
 }
Example #10
0
 /// <summary>
 /// 再分割領域を分割しメッシュを追加する.
 /// </summary>
 /// <param name="adding_node">追加ノード</param>
 /// <param name="rediv_edge">再分割領域を囲むエッジ</param>
 private void Redivision(Node adding_node, List<Edge> rediv_edge)
 {
     for (int j = 0; j < rediv_edge.Count; j++)
     {
         double start_coordi_x = 0;
         double start_coordi_y = 0;
         double end_coordi_x = 0;
         double end_coordi_y = 0;
         bool start_onboundary = false;
         bool end_onboundary = false;
         if (rediv_edge[j].StartNodeId < 0)		//ノードインデックス負数(ブラケット節点)の場合
         {
             //
             start_coordi_x = bracket_node[bracket_node.Count + rediv_edge[j].StartNodeId].X;
             start_coordi_y = bracket_node[bracket_node.Count + rediv_edge[j].StartNodeId].Y;
             start_onboundary = bracket_node[bracket_node.Count + rediv_edge[j].StartNodeId].OnBoundary;
         }
         else
         {
             start_coordi_x = given_node[rediv_edge[j].StartNodeId].X;
             start_coordi_y = given_node[rediv_edge[j].StartNodeId].Y;
             start_onboundary = given_node[rediv_edge[j].StartNodeId].OnBoundary;
         }
         if (rediv_edge[j].EndNodeId < 0)		//ノードインデックス負数(ブラケット節点)の場合
         {
             end_coordi_x = bracket_node[bracket_node.Count + rediv_edge[j].EndNodeId].X;
             end_coordi_y = bracket_node[bracket_node.Count + rediv_edge[j].EndNodeId].Y;
             end_onboundary = bracket_node[bracket_node.Count + rediv_edge[j].EndNodeId].OnBoundary;
         }
         else
         {
             end_coordi_x = given_node[rediv_edge[j].EndNodeId].X;
             end_coordi_y = given_node[rediv_edge[j].EndNodeId].Y;
             end_onboundary = given_node[rediv_edge[j].EndNodeId].OnBoundary;
         }
         delaunay_elements.Add(new DelaunayElement2D(adding_node,
                                             new Node(rediv_edge[j].StartNodeId, start_onboundary, start_coordi_x, start_coordi_y),
                                             new Node(rediv_edge[j].EndNodeId, end_onboundary, end_coordi_x, end_coordi_y)
                                             )
                                 );
     }
 }
Example #11
0
 /// <summary>
 /// コピーコンストラクタ
 /// </summary>
 /// <param name="source"></param>
 public Node(Node source)
 {
     Dimension = source.Dimension;
     ID = source.ID;
     OnBoundary = source.OnBoundary;
     ConnectedNodeID = new List<int>();
     for (int i = 0; i < source.ConnectedNodeID.Count; ++i)
     {
         ConnectedNodeID.Add(source.ConnectedNodeID[i]);
     }
     coordinates = new double[Dimension];
     rest = new bool[Dimension];
     point_force = new double[Dimension];
     point_force_exist = new bool[Dimension];
     for (int i = 0; i < Dimension; ++i)
     {
         coordinates[i] = source.coordinates[i];
         rest[i] = source.rest[i];
         point_force[i] = source.point_force[i];
         point_force_exist[i] = source.point_force_exist[i];
     }
 }
Example #12
0
 public bool PositiveSide(Node p)
 {
     return true;
 }