Ejemplo n.º 1
0
        // ポート上の線要素の節点ナンバリング
        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++;
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
 public void Copy(PortCondition src)
 {
     EIds           = new List <uint>(src.EIds);
     ValueType      = src.ValueType;
     Dof            = src.Dof;
     FixedDofIndexs = new List <uint>(src.FixedDofIndexs);
     DoubleValues   = null;
     if (src.DoubleValues != null)
     {
         DoubleValues = new double[src.DoubleValues.Length];
         src.DoubleValues.CopyTo(DoubleValues, 0);
     }
     ComplexValues = null;
     if (src.ComplexValues != null)
     {
         ComplexValues = new System.Numerics.Complex[src.ComplexValues.Length];
         src.ComplexValues.CopyTo(ComplexValues, 0);
     }
     IntAdditionalParameters     = new List <int>(src.IntAdditionalParameters);
     DoubleAdditionalParameters  = new List <double>(src.DoubleAdditionalParameters);
     ComplexAdditionalParameters = new List <System.Numerics.Complex>(src.ComplexAdditionalParameters);
 }
Ejemplo n.º 3
0
        // 境界が流線方向と同じとき
        // ψの法線成分(速度の接線成分に比例)がある
        // ψ = const or 0
        // Taylor級数展開 2次までの項を考慮
        protected void SetVorticityDirichletBCOfVorticityForTangentFlow(IvyFEM.Linear.DoubleSparseMatrix A, double[] B)
        {
            uint wQuantityId = 0;
            uint pQuantityId = 1;
            int  wNodeCnt    = (int)World.GetNodeCount(wQuantityId);
            int  pNodeCnt    = (int)World.GetNodeCount(pQuantityId);
            int  offset      = wNodeCnt;

            if (World.GetPortCount(wQuantityId) == 0)
            {
                return;
            }
            uint portCnt = World.GetPortCount(wQuantityId);
            IList <PortCondition> portConditions = World.GetPortConditions(wQuantityId);
            IList <uint>          feIds          = World.GetLineFEIds(wQuantityId);

            for (int portId = 0; portId < portCnt; portId++)
            {
                PortCondition portCondition = portConditions[portId];
                //IList<int> intParam = portCondition.IntAdditionalParameters;
                //System.Diagnostics.Debug.Assert(intParam.Count == 0);
                IList <uint>   bcEIds = portCondition.EIds;
                IList <double> param  = portCondition.DoubleAdditionalParameters;
                System.Diagnostics.Debug.Assert(param.Count == 2); // 0: dψ/dx 1: dψ/dy
                double pxValue = param[0];
                double pyValue = param[1];

                foreach (uint feId in feIds)
                {
                    LineFE lineFE = World.GetLineFE(wQuantityId, feId);
                    uint   meshId = lineFE.MeshId;
                    //int meshElemId = lineFE.MeshElemId;
                    uint eId;
                    {
                        uint     elemCount;
                        MeshType meshType;
                        int      loc;
                        uint     cadId;
                        World.Mesh.GetMeshInfo(meshId, out elemCount, out meshType, out loc, out cadId);
                        System.Diagnostics.Debug.Assert(meshType == MeshType.Bar);
                        eId = cadId;
                    }
                    if (bcEIds.Contains(eId))
                    {
                        // BCを適用する辺
                    }
                    else
                    {
                        continue;
                    }

                    // BC
                    uint  elemNodeCnt = lineFE.NodeCount;
                    int[] wCoIds      = lineFE.NodeCoordIds;
                    int[] wNodes      = new int[elemNodeCnt];
                    int[] pNodes      = new int[elemNodeCnt];
                    for (int iNode = 0; iNode < elemNodeCnt; iNode++)
                    {
                        int coId = wCoIds[iNode];
                        wNodes[iNode] = World.Coord2Node(wQuantityId, coId);
                        pNodes[iNode] = World.Coord2Node(pQuantityId, coId);
                    }

                    Material ma0 = World.GetMaterial(lineFE.MaterialId);
                    System.Diagnostics.Debug.Assert(ma0 is NewtonFluidMaterial);
                    var      ma  = ma0 as NewtonFluidMaterial;
                    double   rho = ma.MassDensity;
                    double   mu  = ma.Mu;
                    double[] g   = { ma.GravityX, ma.GravityY };

                    double[] normal = lineFE.GetNormal();

                    int coId1   = wCoIds[0];
                    int coId2   = wCoIds[1];
                    int adjCoId = -1; // adjacent
                    {
                        IList <uint> triFEIds   = World.GetTriangleFEIdsFromEdgeCoord(wQuantityId, coId1, coId2);
                        uint         triFEId    = triFEIds[0];
                        TriangleFE   triFE      = World.GetTriangleFE(wQuantityId, triFEId);
                        int[]        triFECoIds = triFE.NodeCoordIds;
                        foreach (int coId in triFECoIds)
                        {
                            if (coId != coId1 && coId != coId2)
                            {
                                adjCoId = coId;
                                break;
                            }
                        }
                        System.Diagnostics.Debug.Assert(adjCoId != -1);
                    }
                    //int wAdjNodeId = -1;
                    //wAdjNodeId = World.Coord2Node(wQuantityId, adjCoId); // 特殊な場合-1はありえる
                    int pAdjNodeId = -1;
                    pAdjNodeId = World.Coord2Node(pQuantityId, adjCoId); // 特殊な場合-1はありえる
                    double[] pt1   = World.GetCoord(wQuantityId, coId1);
                    double[] pt2   = World.GetCoord(wQuantityId, coId2);
                    double[] adjPt = World.GetCoord(wQuantityId, adjCoId);
                    double   hn    = IvyFEM.CadUtils.TriHeight(
                        new OpenTK.Vector2d(adjPt[0], adjPt[1]), // 点
                        new OpenTK.Vector2d(pt1[0], pt1[1]),     // 辺の点1
                        new OpenTK.Vector2d(pt2[0], pt2[1])      // 辺の点2
                        );

                    for (int row = 0; row < elemNodeCnt; row++)
                    {
                        int rowCoId   = wCoIds[row];
                        int rowNodeId = wNodes[row];
                        if (rowNodeId == -1)
                        {
                            continue;
                        }
                        for (int colNodeId = 0; colNodeId < wNodeCnt; colNodeId++)
                        {
                            int colCoId = World.Node2Coord(wQuantityId, colNodeId);
                            if (colCoId == rowCoId)
                            {
                                A[rowNodeId, colNodeId] = 1.0;
                            }
                            else
                            {
                                A[rowNodeId, colNodeId] = 0;
                            }
                        }
                        for (int colNodeId = 0; colNodeId < pNodeCnt; colNodeId++)
                        {
                            int colCoId = World.Node2Coord(pQuantityId, colNodeId);
                            if (colCoId == rowCoId)
                            {
                                A[rowNodeId, offset + colNodeId] = -2.0 / (hn * hn);
                            }
                            else if (pAdjNodeId != -1 && colNodeId == pAdjNodeId)
                            {
                                A[rowNodeId, offset + colNodeId] = 2.0 / (hn * hn);
                            }
                            else
                            {
                                A[rowNodeId, offset + colNodeId] = 0;
                            }
                        }
                        B[rowNodeId] = -(normal[0] * pxValue + normal[1] * pyValue) * (2.0 / hn);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        private void SetABC(IvyFEM.Linear.ComplexSparseMatrix A, System.Numerics.Complex[] B)
        {
            uint quantityId = 0;

            if (World.GetPortCount(quantityId) == 0)
            {
                return;
            }
            System.Diagnostics.Debug.Assert(World.GetPortCount(quantityId) == 1);
            IList <PortCondition> portConditions = World.GetPortConditions(quantityId);
            PortCondition         portCondition  = portConditions[0];
            IList <uint>          abcEIds        = portCondition.EIds;
            IList <uint>          feIds          = World.GetLineFEIds(quantityId);

            foreach (uint feId in feIds)
            {
                LineFE lineFE = World.GetLineFE(quantityId, feId);
                uint   meshId = lineFE.MeshId;
                //int meshElemId = lineFE.MeshElemId;
                uint eId;
                {
                    uint     elemCount;
                    MeshType meshType;
                    int      loc;
                    uint     cadId;
                    World.Mesh.GetMeshInfo(meshId, out elemCount, out meshType, out loc, out cadId);
                    System.Diagnostics.Debug.Assert(meshType == MeshType.Bar);
                    eId = cadId;
                }
                if (abcEIds.Contains(eId))
                {
                    // ABCを適用する辺
                }
                else
                {
                    continue;
                }

                // ABC
                uint  elemNodeCnt = lineFE.NodeCount;
                int[] coIds       = lineFE.NodeCoordIds;
                int[] nodes       = new int[elemNodeCnt];
                for (int iNode = 0; iNode < elemNodeCnt; iNode++)
                {
                    int coId = coIds[iNode];
                    nodes[iNode] = World.Coord2Node(quantityId, coId);
                }
                Material ma0 = World.GetMaterial(lineFE.MaterialId);
                System.Diagnostics.Debug.Assert(ma0 is HelmholtzMaterial);
                var    ma = ma0 as HelmholtzMaterial;
                double v  = ma.Velocity;
                //System.Numerics.Complex f = ma.F;
                double omega = 2.0 * Math.PI * Frequency;
                double k     = omega / v;

                double[,] sNN   = lineFE.CalcSNN();
                double[,] sNxNx = lineFE.CalcSNxNx();
                for (int row = 0; row < elemNodeCnt; row++)
                {
                    int rowNodeId = nodes[row];
                    if (rowNodeId == -1)
                    {
                        continue;
                    }
                    for (int col = 0; col < elemNodeCnt; col++)
                    {
                        int colNodeId = nodes[col];
                        if (colNodeId == -1)
                        {
                            continue;
                        }

                        System.Numerics.Complex a =
                            System.Numerics.Complex.ImaginaryOne * k * sNN[row, col] -
                            System.Numerics.Complex.ImaginaryOne / (2.0 * k) * sNxNx[row, col];
                        A[rowNodeId, colNodeId] += a;
                    }
                }
            }
        }
Ejemplo n.º 5
0
 public PortCondition(PortCondition src)
 {
     Copy(src);
 }