/// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 12/25/2012
        ///
        /// Purpose: Root class for static sparse N-D solvers (KU=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   = new Vector(NDF);                               //Make global load vector
            MatrixSparseLinkedList K = new MatrixSparseLinkedList(NDF); // Make global stiffness matrix

            Timer_Assemble = new StopWatchTimer();
            Timer_Assemble.StartTimer();
            //Assemble F and K
            int NE = Elements.Length; //Get the number of elements

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

            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustFAndK(ref F, ref K);
            }
            Timer_Assemble.StopTimer();

            Timer_Solve = new StopWatchTimer();
            Timer_Solve.StartTimer();
            //Solve system
            U = K.SolveLinearSystem(F);
            Timer_Solve.StopTimer();
        }
Beispiel #2
0
        public override void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke)
        {
            int Ip, Iq;
            int NNPE = ElementNodes.Length;

            for (int p = 0; p < NNPE; p++)
            {
                Node_ND_Unknowns_VectorField Unknown_p = (Node_ND_Unknowns_VectorField)ElementNodes[p].Unknowns;
                int NDFp = Unknown_p.UnknownDoFs.Length;
                for (int i = 0; i < NDFp; i++)
                {
                    Ip = Unknown_p.UnknownDoFs[i];
                    for (int q = 0; q < NNPE; q++)
                    {
                        Node_ND_Unknowns_VectorField Unknown_q = (Node_ND_Unknowns_VectorField)ElementNodes[q].Unknowns;
                        int NDFq = Unknown_q.UnknownDoFs.Length;
                        for (int j = 0; j < NDFq; j++)
                        {
                            Iq = Unknown_q.UnknownDoFs[j];
                            K.AddToMatrixElement(Ip, Iq, Ke.Values[NNPE * p + i][NNPE * q + j]);
                        }
                    }
                }
            }
        }
        public override void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke)
        {
            int Ip, Iq;
            int NNPE = ElementNodes.Length;

            for (int p = 0; p < NNPE; p++)
            {
                Node_ND_Unknowns_ScalarField TheUnknowns_p = (Node_ND_Unknowns_ScalarField)ElementNodes[p].Unknowns;
                Ip = TheUnknowns_p.UnknownDoF;
                for (int q = 0; q < NNPE; q++)
                {
                    Node_ND_Unknowns_ScalarField TheUnknowns_q = (Node_ND_Unknowns_ScalarField)ElementNodes[q].Unknowns;
                    Iq = TheUnknowns_q.UnknownDoF;
                    K.AddToMatrixElement(Ip, Iq, Ke.Values[p][q]);
                }
            }
        }
        public override void SolveFEMSystem_Parallel()
        {
            //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
            MatrixSparseLinkedList K = new MatrixSparseLinkedList(NDF); // Make global stiffness matrix

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

            ParallelOptions op = new ParallelOptions();

            op.MaxDegreeOfParallelism = Environment.ProcessorCount;

            Timer_Assemble = new StopWatchTimer();
            Timer_Assemble.StartTimer();
            Parallel.For(0, NE, op, i =>
            {
                Vector Fe        = Elements[i].Calculate_Fe();
                Matrix_Jagged Ke = Elements[i].Calculate_Ke();
                lock (K_Lock) { Elements[i].Assemble(ref K, Ke); }
                lock (F_Lock) { Elements[i].Assemble(ref F, Fe); }
            });

            //Adjust for boundary conditions
            int NBE = BoundaryElements.Length;

            for (int i = 0; i < NBE; i++)
            {
                BoundaryElements[i].AdjustFAndK(ref F, ref K);
            }
            Timer_Assemble.StopTimer();

            Timer_Solve = new StopWatchTimer();
            Timer_Solve.StartTimer();
            //Solve system
            U        = new Vector();
            U.Values = K.SolveLinearSystem_Parallel(F.Values);
            Timer_Solve.StopTimer();
        }
        public override void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke)
        {
            int Ip, Iq, I1p, I1pi, I1, I2q, I2qk, I2;
            int NNPE = ElementNodes.Length;

            int NumberOFPhysics, TotalDoFPerNode;

            int[] DofPerPhysics;
            int[] StartIndexPerPhysics = Get_StartIndexForEachPhysics(out NumberOFPhysics, out TotalDoFPerNode, out DofPerPhysics);

            for (int p = 0; p < NNPE; p++)
            {
                Node_ND_Unknowns_MultiPhysics Unknowns_p = (Node_ND_Unknowns_MultiPhysics)ElementNodes[p].Unknowns;
                I1p = TotalDoFPerNode * p;
                for (int i = 0; i < NumberOFPhysics; i++)
                {
                    I1pi = I1p + StartIndexPerPhysics[i];
                    for (int j = 0; j < DofPerPhysics[i]; j++)
                    {
                        I1 = I1pi + j;
                        Ip = Unknowns_p.UnknownDoFs[PhysicsUsed[i]][j];
                        for (int q = 0; q < NNPE; q++)
                        {
                            Node_ND_Unknowns_MultiPhysics Unknowns_q = (Node_ND_Unknowns_MultiPhysics)ElementNodes[q].Unknowns;
                            I2q = TotalDoFPerNode * q;
                            for (int k = 0; k < NumberOFPhysics; k++)
                            {
                                I2qk = I2q + StartIndexPerPhysics[k];
                                for (int l = 0; l < DofPerPhysics[k]; l++)
                                {
                                    I2 = I2qk + l;
                                    Iq = Unknowns_q.UnknownDoFs[PhysicsUsed[k]][l];
                                    K.AddToMatrixElement(Ip, Iq, Ke.Values[I1][I2]);
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <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);
            }
        }
Beispiel #7
0
 public virtual void AdjustM(double Time, ref MatrixSparseLinkedList M)
 {
 }
 public virtual void AdjustFAndK(ref Vector F, ref MatrixSparseLinkedList K)
 {
 }
Beispiel #9
0
 public void CalculateAndAssemble_FeAndKe(ref Vector F, ref MatrixSparseLinkedList K)
 {
     CalculateAndAssemble_Fe(ref F);
     CalculateAndAssemble_Ke(ref K);
 }
Beispiel #10
0
 public void CalculateAndAssemble_FeAndKeAndCeAndMe(ref Vector F, ref MatrixSparseLinkedList K, ref MatrixSparseLinkedList C, ref MatrixSparseLinkedList M)
 {
     CalculateAndAssemble_FeAndKeAndCe(ref F, ref K, ref C);
     CalculateAndAssemble_Me(ref M);
 }
Beispiel #11
0
 public virtual void Assemble(ref MatrixSparseLinkedList K, Matrix_Jagged Ke)
 {
     //Need to implement
 }
Beispiel #12
0
        public void CalculateAndAssemble_Me(ref MatrixSparseLinkedList M)
        {
            Matrix_Jagged Me = Calculate_Me();

            Assemble(ref M, Me);
        }
Beispiel #13
0
        public void CalculateAndAssemble_Ce(ref MatrixSparseLinkedList C)
        {
            Matrix_Jagged Ce = Calculate_Ce();

            Assemble(ref C, Ce);
        }
Beispiel #14
0
        public void CalculateAndAssemble_Ke(ref MatrixSparseLinkedList K)
        {
            Matrix_Jagged Ke = Calculate_Ke();

            Assemble(ref K, Ke);
        }
        /// <summary>
        /// Developed by: Mehrdad Negahban
        /// Date: 12/27/2012
        ///
        /// Purpose: Newmark method to solve second order transient N-D problem using sparse matrix model (M d^2U/dt^2  + K U = F)
        /// Comments:   May add artificial damping (+ C dU/dt)
        ///
        /// Date modified:
        /// Modified by:
        /// Comments:
        /// </summary>
        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)
            MatrixSparseLinkedList K = new MatrixSparseLinkedList(NDF); // Make global stiffness matrix
            MatrixSparseLinkedList M = 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_FeAndKeAndMe(ref F, ref K, ref M);
            }

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

            Mhat.LUDecomposition_Parallel();
            //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.Values = Mhat.SolveLinearSystemForwardEliminationAndBackSubstitution((F_new - CDamping * v_old - K * u_old).Values);

                    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);
            }
        }