public double[] SolveLinearSystem_Parallel_LU(double[] RightHandSide)
        {
            StopWatch_Solver_LU_Total                = new StopWatchTimer();
            StopWatch_Solver_LU_Decomposition        = new StopWatchTimer();
            StopWatch_Solver_LU_ForwardElimination   = new StopWatchTimer();
            StopWatch_Solver_LU_BackSubstitution     = new StopWatchTimer();
            StopWatch_Solver_LU_CalculateDeterminant = new StopWatchTimer();

            StopWatch_Solver_LU_Total.StartTimer();

            // PLU decomposition
            StopWatch_Solver_LU_Decomposition.StartTimer();
            this.LUDecomposition_Parallel();
            StopWatch_Solver_LU_Decomposition.StopTimer();

            // Forward elimination
            StopWatch_Solver_LU_ForwardElimination.StartTimer();
            this.ForwardElimination(RightHandSide);
            StopWatch_Solver_LU_ForwardElimination.StopTimer();

            //Backward elimination
            StopWatch_Solver_LU_BackSubstitution.StartTimer();
            this.BackSubstitution();
            StopWatch_Solver_LU_BackSubstitution.StopTimer();

            // Determinant
            StopWatch_Solver_LU_CalculateDeterminant.StartTimer();
            this.CalculateDeterminant();
            StopWatch_Solver_LU_CalculateDeterminant.StopTimer();

            StopWatch_Solver_LU_Total.StopTimer();

            return(rightHandSide);
        }
        /// <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();
        }
        public double[] SolveLinearSystemForwardEliminationAndBackSubstitution(double[] RightHandSide)
        {
            WriteToDisplay.WriteInfo("\n  Solving linear system using link-list storage method and PLU decomposition\n\n");
            WriteToDisplay.WriteInfo("   Number of equations = " + n.ToString() + "\n");

            StopWatchTimer Totaltime = new StopWatchTimer();

            Totaltime.StartTimer();

            StopWatchTimer timer = new StopWatchTimer();

            //rightHandSide = RightHandSide;
            //ScaleAllRowsAndRightHandSideAndRemoveZeros();
            //this.RemoveAllZeros();

            // PLU decomposition
            timer.StartTimer();
            //this.LUDecomposition();
            timer.StopTimer();
            WriteToDisplay.WriteInfo("   PLU decomposition time = " + timer.TimeElapsedInSeconds().ToString() + "\n");

            // Forward elimination
            timer.StartTimer();
            this.ForwardElimination(RightHandSide);
            timer.StopTimer();
            WriteToDisplay.WriteInfo("   Forward elimination time = " + timer.TimeElapsedInSeconds().ToString() + "\n");

            //Backward elimination
            timer.StartTimer();
            this.BackSubstitution();
            timer.StopTimer();
            WriteToDisplay.WriteInfo("   Backward elimination time = " + timer.TimeElapsedInSeconds().ToString() + "\n");

            // Determinant
            timer.StartTimer();
            this.CalculateDeterminant();
            timer.StopTimer();
            WriteToDisplay.WriteInfo("   Determinant time = " + timer.TimeElapsedInSeconds().ToString() + "\n");

            Totaltime.StopTimer();
            WriteToDisplay.WriteInfo("\n  Total time to solve = " + Totaltime.TimeElapsedInSeconds().ToString() + "\n\n");

            return(rightHandSide);
        }
        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();
        }