private void Get_Side_Nodes(Node_ND[] ElementNodes, out int[][] NNPE_Side, out Node_ND[][] Side_Nodes)
        {
            NNPE_Side       = new int[3][];
            NNPE_Side[0]    = new int[2];
            NNPE_Side[0][0] = NNPE_l;
            NNPE_Side[0][1] = NNPE_m;
            NNPE_Side[1]    = new int[2];
            NNPE_Side[1][0] = NNPE_m;
            NNPE_Side[1][1] = NNPE_n;
            NNPE_Side[2]    = new int[2];
            NNPE_Side[2][0] = NNPE_l;
            NNPE_Side[2][1] = NNPE_n;
            int[] NNPS = new int[3];
            NNPS[0]    = NNPE_l * NNPE_m;
            NNPS[1]    = NNPE_m * NNPE_n;
            NNPS[2]    = NNPE_n * NNPE_l;
            Side_Nodes = new Node_ND[6][];
            for (int i = 0; i < 3; i++)
            {
                Side_Nodes[i]     = new Node_ND[NNPS[i]];
                Side_Nodes[i + 3] = new Node_ND[NNPS[i]];
            }
            int index = 0;

            for (int j = 0; j < NNPE_m; j++)
            {
                for (int i = 0; i < NNPE_l; i++)
                {
                    Side_Nodes[0][index] = ElementNodes[index];
                    Side_Nodes[3][index] = ElementNodes[NNPS[0] * (NNPE_n - 1) + index];
                    index++;
                }
            }
            index = 0;
            for (int j = 0; j < NNPE_n; j++)
            {
                for (int i = 0; i < NNPE_m; i++)
                {
                    Side_Nodes[1][index] = ElementNodes[j * NNPS[0] + NNPE_l * i];
                    Side_Nodes[4][index] = ElementNodes[j * NNPS[0] + (NNPE_l - 1) * i];
                    index++;;
                }
            }
            index = 0;
            for (int j = 0; j < NNPE_n; j++)
            {
                for (int i = 0; i < NNPE_l; i++)
                {
                    Side_Nodes[2][index] = ElementNodes[j * NNPS[0] + i];
                    Side_Nodes[5][index] = ElementNodes[j * NNPS[0] + (NNPE_l - 1) + NNPE_l * (NNPE_m - 1) + i];
                    index++;;
                }
            }
        }
Exemplo n.º 2
0
 public Element_ND_VectorField(int NNPE)
 {
     ElementNodes = new Node_ND[NNPE];
 }
        /// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 12/26/2012
        ///
        /// Purpose: CrankNicholson solver using sparse matrix for first order transient problem (C dU/dt + K U = F)
        /// Comments:
        ///
        /// Date modified:
        /// Modified by:
        /// Comments:
        /// </summary>
        public override void SolveFEMSystem()
        {
            //Set up the load vector and stiffness matrix
            int    NDF               = Unknowns_NDoF;                   //Get the size of the unknowns temperature (one per node)
            Vector F_old             = new Vector(NDF);                 //Make global load vector (old)
            Vector F_new             = new Vector(NDF);                 //Make global load vector (new)
            MatrixSparseLinkedList K = new MatrixSparseLinkedList(NDF); // Make global stiffness matrix
            MatrixSparseLinkedList C = new MatrixSparseLinkedList(NDF); // Make global thermal mass matrix

            //Assemble F, K, C
            int NE = Elements.Length; //Get the number of elements

            for (int i = 0; i < NE; i++)
            {
                Elements[i].CalculateAndAssemble_FeAndKeAndCe(ref F_old, ref K, ref C);
            }
            //Adjust for boundary conditions
            int NBE = BoundaryElements.Length;

            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustK(Times.Values[StartIndex], ref K);
            }
            K = 0.5 * K;

            C = C / DTime;
            MatrixSparseLinkedList C1 = C - K;

            C = C + K; // Calculate Chat and store in C
            //Adjust C for boundary condition
            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustChat(Times.Values[StartIndex], ref C);
            }
            C.LUDecomposition_Parallel();//Run LU decomposition on C

            //Adjust F for BC
            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustF(Times.Values[StartIndex], ref F_old);
            }
            F_old = 0.5D * F_old;

            //Store initial time and temperature
            Vector U_old = new Vector(Ut[StartIndex]);

            Node_ND.Set_UnknownForNode(Nodes, U_old);
            StoreSensors(StartIndex);
            Vector Fhat;
            double RTime = Times.Values[StartIndex];

            for (int i = StartIndex; i < NumberOfStepsToStore; i++)
            {
                for (int j = 0; j < NumberOfStepsToSkipOutput; j++)
                {
                    RTime          += DTime; //Increment to new time
                    Element_ND.Time = RTime; //Give new time to all elements
                    F_new           = new Vector(NDF);
                    for (int k = 0; k < NE; k++)
                    {
                        Elements[k].CalculateAndAssemble_Fe(ref F_new); //Calculate new F
                    }
                    //Adjust new F for BC
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustF(RTime, ref F_new);
                    }
                    F_new = 0.5 * F_new;

                    Fhat = F_old + F_new + C1 * U_old; //Get Fhat
                    //Adust Fhat for BC
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustFhat(RTime, ref F_new);
                    }

                    U_old.Values = C.SolveLinearSystemForwardEliminationAndBackSubstitution(Fhat.Values); //Solve for new temperatures
                    F_old        = F_new;                                                                 //Move new F to old F for next step
                }
                Times.Values[i + 1] = RTime;                                                              //Store time
                Ut[i + 1]           = new Vector(U_old);                                                  //Store vector of node temperatures
                Solver_Output_Info.StoreAStep(i + 1, Times.Values[i + 1], Ut[i + 1], DTime, NumberOfStepsToSkipOutput);
                Solver_Output_Info.SaveToFile(Solver_Output_Info.Make_OuptutAddress());

                Node_ND.Set_UnknownForNode(Nodes, U_old);
                StoreSensors(i + 1);
            }
        }
        public override void SolveFEMSystem()
        {
            double beta  = Newmark_beta;
            double gamma = Newmark_gamma;
            //Set up the load vector and stiffness matrix
            int           NDF   = Unknowns_NDoF;               //Get the size of the unknowns temperature (one per node)
            Vector        F     = new Vector(NDF);             //Make global load vector (old)
            Vector        F_new = new Vector(NDF);             //Make global load vector (new)
            Matrix_Jagged K     = new Matrix_Jagged(NDF, NDF); // Make global stiffness matrix
            Matrix_Jagged M     = new Matrix_Jagged(NDF, NDF); // Make global thermal mass matrix

            //Assemble F, K, C
            int NE = Elements.Length; //Get the number of elements

            for (int i = 0; i < NE; i++)
            {
                Elements[i].CalculateAndAssemble_FeAndKeAndMe(ref F, ref K, ref M);
            }

            Matrix_Jagged CDamping = ArtificialDamping_Factor_M * M + ArtificialDamping_Factor_K * K;
            Matrix_Jagged Mhat     = M + (gamma * DTime) * CDamping + (beta * DTime * DTime) * K;

            Mhat.SolveLinearSystem_LUDecomp();
            //Adjust for boundary conditions
            int NBE = BoundaryElements.Length;

            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustF(Times.Values[StartIndex], ref F);
                BoundaryElements[i].AdjustK(Times.Values[StartIndex], ref K);
            }
            //Initial conditions
            Vector u_old = new Vector(Ut[StartIndex]);
            Vector v_old = new Vector(Vt[StartIndex]);
            //Initial acceleration
            Vector a_old = M.SolveLinearSystem(F - K * u_old);

            Node_ND.Set_UnknownForNode(Nodes, u_old);
            StoreSensors(StartIndex);

            double RTime = 0.0D;

            for (int i = StartIndex; i < NumberOfStepsToStore; i++)
            {
                for (int j = 0; j < NumberOfStepsToSkipOutput; j++)
                {
                    RTime          += DTime; //Increment to new time
                    Element_ND.Time = RTime; //Give new time to all elements

                    F_new = new Vector(NDF);
                    for (int k = 0; k < NE; k++)
                    {
                        Elements[k].CalculateAndAssemble_Fe(ref F_new); //Calculate new F
                    }
                    //Adjust new F for BC
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustF(RTime, ref F_new);
                    }

                    //solve for new values
                    u_old += DTime * v_old + (0.5D * DTime * DTime * (1.0D - 2.0D * beta)) * a_old;
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustU(RTime, ref u_old);
                    }

                    v_old += ((1.0D - gamma) * DTime) * a_old;
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustV(RTime, ref v_old);
                    }

                    a_old = Mhat.SolveLinearSystem_BackSub(F_new - CDamping * v_old - K * u_old);

                    u_old += (beta * DTime * DTime) * a_old;
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustU(RTime, ref u_old);
                    }

                    v_old += (gamma * DTime) * a_old;
                    for (int k = 0; k < NBE; k++)
                    {
                        BoundaryElements[k].AdjustV(RTime, ref v_old);
                    }
                }
                Times.Values[i + 1] = RTime;             //Store time
                Ut[i + 1]           = new Vector(u_old); //Store vector of node displacements
                Vt[i + 1]           = new Vector(v_old); //Store vector of node velocity

                Solver_Output_Info.StoreAStep(i + 1, Times.Values[i + 1], Ut[i + 1], Vt[i + 1], DTime, NumberOfStepsToSkipOutput);
                Solver_Output_Info.SaveToFile(Solver_Output_Info.Make_OuptutAddress());

                Node_ND.Set_UnknownForNode(Nodes, u_old);
                StoreSensors(i + 1);
            }
        }
Exemplo n.º 5
0
 public Element_ND_ScalarField(int NNPE)
 {
     ElementNodes = new Node_ND[NNPE];
 }
 public Element_ND_MultiPhysics(int NNPE, int[] physicsUsed)
 {
     ElementNodes = new Node_ND[NNPE];
     PhysicsUsed  = physicsUsed;
 }
        private void Get_Side_NodesAndNodeLocations(Node_ND[] ElementNodes, out Node_ND[][] Side_Nodes, out Vector[][] Side_NodeLocations_X, out Vector[][] Side_NodeLocations_Xi)
        {
            int NNPS = NNPE_m * (NNPE_m - 1) / 2 + NNPE_m;

            Side_Nodes            = new Node_ND[4][];
            Side_NodeLocations_X  = new Vector[4][];
            Side_NodeLocations_Xi = new Vector[4][];
            for (int i = 0; i < 4; i++)
            {
                Side_Nodes[i]            = new Node_ND[NNPS];
                Side_NodeLocations_X[i]  = new Vector[NNPS];
                Side_NodeLocations_Xi[i] = new Vector[NNPS];
            }
            int index = 0;

            for (int j = 0; j < NNPE_m; j++)
            {
                for (int i = 0; i < NNPE_m - j; i++)
                {
                    Side_Nodes[0][index]            = ElementNodes[index];
                    Side_NodeLocations_X[0][index]  = ElementNodes[index].X;
                    Side_NodeLocations_Xi[0][index] = NodeXi[index];
                    index++;
                }
            }
            index = 0;
            for (int j = 0; j < NNPE_m; j++)
            {
                for (int i = 0; i < NNPE_m - j; i++)
                {
                    Side_Nodes[1][index]            = ElementNodes[index];
                    Side_NodeLocations_X[1][index]  = ElementNodes[index].X;
                    Side_NodeLocations_Xi[1][index] = NodeXi[index];
                    index += NNPE_m - j - i;
                }
            }
            index = 0;
            int index_2 = 0;

            for (int j = 0; j < NNPE_m; j++)
            {
                index = index_2;
                for (int i = 0; i < NNPE_m - j; i++)
                {
                    Side_Nodes[2][index]            = ElementNodes[index];
                    Side_NodeLocations_X[2][index]  = ElementNodes[index].X;
                    Side_NodeLocations_Xi[2][index] = NodeXi[index];
                    index++;
                }
                index_2 += (NNPE_m - j) * (NNPE_m - j - 1) / 2 + NNPE_m - j;
            }
            index   = 0;
            index_2 = 0;
            for (int j = 0; j < NNPE_m; j++)
            {
                index = index_2;
                for (int i = 0; i < NNPE_m - j; i++)
                {
                    index += NNPE_m - j - i;
                    Side_Nodes[3][index]            = ElementNodes[index];
                    Side_NodeLocations_X[3][index]  = ElementNodes[index].X;
                    Side_NodeLocations_Xi[3][index] = NodeXi[index];
                }
                index_2 += (NNPE_m - j) * (NNPE_m - j - 1) / 2 + NNPE_m - j;
            }
        }