示例#1
0
 public void Print_Matrix(alglib.sparsematrix A, int rows, int col)
 {
     for (int i = 0; i < rows; i++)
     {
         string output = "";
         for (int j = 0; j < col; j++)
         {
             output += alglib.sparseget(A, i, j).ToString("E2") + "  ";
         }
         Console.WriteLine(output);
     }
 }
示例#2
0
 static public void normalize(this alglib.sparsematrix M, IList <int> ids, int k)
 {
     foreach (int id in ids)
     {
         double[] wrow   = new double[k];
         int[]    colids = new int[k];
         int      tmp;
         alglib.sparsegetcompressedrow(M, id, ref colids, ref wrow, out tmp);
         double         sum   = wrow.Sum();
         IList <double> wrowl = wrow.ToList();
         wrowl = wrowl.Divide(sum);
         int i = 0;
         foreach (int id2 in colids)
         {
             try{
                 alglib.sparserewriteexisting(M, id, id2, wrowl [i]);
             }catch (alglib.alglibexception e) {
                 Console.WriteLine(e.msg);
             }
             i++;
         }
     }
 }
示例#3
0
        public double[] LinearSolver_LU(alglib.sparsematrix K, double[] F)
        {
            Stopwatch sw = new Stopwatch(); sw.Start();

            Console.Write("   Solving linear system...   ");

            //  Sparse LU decomposition with column pivoting for sparsity and row pivoting
            //  for stability. Input must be square sparse matrix stored in CRS format.
            //
            //  The algorithm  computes  LU  decomposition  of  a  general  square  matrix
            //  (rectangular ones are not supported). The result  of  an  algorithm  is  a
            //  representation of A as A = P*L*U*Q, where:
            //  * L is lower unitriangular matrix
            //  * U is upper triangular matrix
            //  * P = P0*P1*...*PK, K=N-1, Pi - permutation matrix for I and P[I]
            //  * Q = QK*...*Q1*Q0, K=N-1, Qi - permutation matrix for I and Q[I]
            //
            //  This function pivots columns for higher sparsity, and then pivots rows for
            //  stability (larger element at the diagonal).
            //
            //  INPUT PARAMETERS:
            //      A       -   sparse NxN matrix in CRS format. An exception is generated
            //                  if matrix is non-CRS or non-square.
            //      PivotType-  pivoting strategy:
            //                  * 0 for best pivoting available (2 in current version)
            //                  * 1 for row-only pivoting (NOT RECOMMENDED)
            //                  * 2 for complete pivoting which produces most sparse outputs
            //
            //  OUTPUT PARAMETERS:
            //      A       -   the result of factorization, matrices L and U stored in
            //                  compact form using CRS sparse storage format:
            //                  * lower unitriangular L is stored strictly under main diagonal
            //                  * upper triangilar U is stored ON and ABOVE main diagonal
            //      P       -   row permutation matrix in compact form, array[N]
            //      Q       -   col permutation matrix in compact form, array[N]
            //
            //  This function always succeeds, i.e. it ALWAYS returns valid factorization,
            //  but for your convenience it also returns  boolean  value  which  helps  to
            //  detect symbolically degenerate matrices:
            //  * function returns TRUE, if the matrix was factorized AND symbolically
            //    non-degenerate
            //  * function returns FALSE, if the matrix was factorized but U has strictly
            //    zero elements at the diagonal (the factorization is returned anyway).

            alglib.sparseconverttocrs(K);
            alglib.sparselu(K, 0, out int[] P, out int[] Q);

            // Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
            // matrix A given by its LU factorization, N * 1 vectors x and b.
            //
            //   IMPORTANT: this solver requires input matrix  to  be  in  the  CRS  sparse
            //   storage format. An exception will  be  generated  if  you  pass
            //   matrix in some other format (HASH or SKS).
            //
            // INPUT PARAMETERS
            //    A       -   LU factorization of the sparse matrix, must be NxN exactly
            //                in CRS storage format
            //    P, Q    -   pivot indexes from LU factorization
            //    N       -   size of A, N>0
            //    B       -   array[0..N-1], right part

            alglib.sparselusolve(K, P, Q, alglib.sparsegetnrows(K), F, out double[] U, out alglib.sparsesolverreport report);

            // Termination type (>0 - solution; -3 - error (filled by zeros))
            if (report.terminationtype > 0)
            {
                Console.Write("NORMAL TERMINATION");
            }
            else
            {
                Console.Write("ERROR TERMINATION");
            }
            Console.Write(" (type " + report.terminationtype + ")");
            sw.Stop();
            Console.WriteLine(" in " + sw.Elapsed.TotalSeconds.ToString("F2", CultureInfo.InvariantCulture) + "s");

            return(U);
        }
示例#4
0
        public double[] LinearSolver_Cholesky(alglib.sparsematrix K, double[] F)
        {
            Stopwatch sw = new Stopwatch(); sw.Start();

            //          From ALGLIB manual - sparsecholeskyskyline function
            //
            //  /*************************************************************************
            //  Sparse Cholesky decomposition for skyline matrixm using in-place algorithm
            //  without allocating additional storage.
            //
            //  The algorithm computes Cholesky decomposition  of  a  symmetric  positive-
            //  definite sparse matrix. The result of an algorithm is a representation  of
            //  A as A=U^T*U or A=L*L^T
            //
            //  This  function  is  a  more  efficient alternative to general, but  slower
            //  SparseCholeskyX(), because it does not  create  temporary  copies  of  the
            //  target. It performs factorization in-place, which gives  best  performance
            //  on low-profile matrices. Its drawback, however, is that it can not perform
            //  profile-reducing permutation of input matrix.
            //
            //  INPUT PARAMETERS:
            //      A       -   sparse matrix in skyline storage (SKS) format.
            //      N       -   size of matrix A (can be smaller than actual size of A)
            //      IsUpper -   if IsUpper=True, then factorization is performed on  upper
            //                  triangle. Another triangle is ignored (it may contant some
            //                  data, but it is not changed).
            //
            //
            //  OUTPUT PARAMETERS:
            //      A       -   the result of factorization, stored in SKS. If IsUpper=True,
            //                  then the upper  triangle  contains  matrix  U,  such  that
            //                  A = U^T*U. Lower triangle is not changed.
            //                  Similarly, if IsUpper = False. In this case L is returned,
            //                  and we have A = L*(L^T).
            //                  Note that THIS function does not  perform  permutation  of
            //                  rows to reduce bandwidth.
            //
            //  RESULT:
            //      If  the  matrix  is  positive-definite,  the  function  returns  True.
            //      Otherwise, the function returns False. Contents of A is not determined
            //      in such case.
            //
            //  NOTE: for  performance  reasons  this  function  does NOT check that input
            //        matrix  includes  only  finite  values. It is your responsibility to
            //        make sure that there are no infinite or NAN values in the matrix.
            //
            //    -- ALGLIB routine --
            //       16.01.2014
            //       Bochkanov Sergey
            //  *************************************************************************/

            Console.WriteLine("   Linear system K*U=F:");
            alglib.sparseconverttosks(K);

            Console.Write("    - Cholesky decomposition:");
            bool Result = alglib.sparsecholeskyskyline(K, alglib.sparsegetnrows(K), true);

            if (Result == true)
            {
                Console.WriteLine("   Done");
            }
            else
            {
                Console.WriteLine("   ERROR");
            }


            //          From ALGLIB manual - sparsecholeskysolvesks function
            //
            //   /*************************************************************************
            //   Sparse linear solver for A*x=b with N*N real  symmetric  positive definite
            //   matrix A given by its Cholesky decomposition, and N*1 vectors x and b.
            //
            //   IMPORTANT: this solver requires input matrix to be in  the  SKS  (Skyline)
            //              sparse storage format. An exception will be  generated  if  you
            //              pass matrix in some other format (HASH or CRS).
            //
            //   INPUT PARAMETERS
            //       A       -   sparse NxN matrix stored in SKS format, must be NxN exactly
            //       N       -   size of A, N>0
            //       IsUpper -   which half of A is provided (another half is ignored)
            //       B       -   array[N], right part
            //
            //   OUTPUT PARAMETERS
            //       Rep     -   solver report, following fields are set:
            //                   * rep.terminationtype - solver status; >0 for success,
            //                     set to -3 on failure (degenerate or non-SPD system).
            //       X       -   array[N], it contains:
            //                   * rep.terminationtype>0    =>  solution
            //                   * rep.terminationtype=-3   =>  filled by zeros
            //
            //     -- ALGLIB --
            //        Copyright 26.12.2017 by Bochkanov Sergey
            //   *************************************************************************/

            Console.Write("    - Solving:");
            alglib.sparsecholeskysolvesks(K, alglib.sparsegetnrows(K), true, F, out alglib.sparsesolverreport report, out double[] U);

            // Termination type (>0 - solution; -3 - error (filled by zeros))
            if (report.terminationtype > 0)
            {
                Console.Write("                  NORMAL termination");
            }
            else
            {
                Console.Write("                  ERROR termination");
            }
            Console.WriteLine(" (type " + report.terminationtype + ")");

            sw.Stop();
            Console.WriteLine("    Total time to solve K*U=F:  " + sw.Elapsed.TotalSeconds.ToString("F2", CultureInfo.InvariantCulture) + "s");

            return(U);
        }
示例#5
0
        // Linear system of equation solvers -----------------------------

        public double[] LinearSolver_CG(alglib.sparsematrix K, double[] F, Analysis AnalysisLib)
        {
            Stopwatch sw = new Stopwatch(); sw.Start();

            Console.Write("   Solving linear system...   ");

            alglib.sparseconverttocrs(K);
            alglib.lincgcreate(alglib.sparsegetnrows(K), out alglib.lincgstate s);

            //          From ALGLIB manual - lincgsetcond function
            //
            //  *************************************************************************
            //  This function sets stopping criteria.
            //
            //  INPUT PARAMETERS:
            //      EpsF    -   algorithm will be stopped if norm of residual is less than
            //                  EpsF*||b||.
            //      MaxIts  -   algorithm will be stopped if number of iterations is  more
            //                  than MaxIts.
            //
            //  OUTPUT PARAMETERS:
            //      State   -   structure which stores algorithm state
            //
            //  NOTES:
            //  If  both  EpsF  and  MaxIts  are  zero then small EpsF will be set to small
            //  value.
            //
            //    -- ALGLIB --
            //       Copyright 14.11.2011 by Bochkanov Sergey
            //  *************************************************************************

            double tolerance = AnalysisLib.GetLinSolverTolerance();
            int    IterMax   = AnalysisLib.GetLinSolverMaxIter();

            alglib.lincgsetcond(s, tolerance, IterMax);

            alglib.lincgsolvesparse(s, K, true, F);
            alglib.lincgresults(s, out double[] U, out alglib.lincgreport report);


            // OUTPUT PARAMETERS:
            // X       -   array[N], solution
            // Rep     -   optimization report:
            //             * Rep.TerminationType completetion code:
            //                 * -5    input matrix is either not positive definite,
            //                         too large or too small
            //                 * -4    overflow/underflow during solution
            //                         (ill conditioned problem)
            //                 *  1    ||residual||<=EpsF*||b||
            //                 *  5    MaxIts steps was taken
            //                 *  7    rounding errors prevent further progress,
            //                         best point found is returned
            //             * Rep.IterationsCount contains iterations count
            //             * NMV countains number of matrix-vector calculations

            if (report.terminationtype == 1 || report.terminationtype == 7)
            {
                Console.Write("  NORMAL ");
            }
            else
            {
                Console.Write("  ERROR ");
            }
            Console.Write(" (type " + report.terminationtype + ")");
            sw.Stop();
            Console.WriteLine(" in " + sw.Elapsed.TotalSeconds.ToString("F2", CultureInfo.InvariantCulture) + "s");

            return(U);
        }
示例#6
0
文件: Solver.cs 项目: ovevans/STAN
        private static void SolverNonlinearStatics()
        {
            SolverFunctions Fun = new SolverFunctions();
            Stopwatch       sw  = new Stopwatch(); sw.Start();

            // Analysis settings
            double tolerance = 0.001;

            // Others
            string separator = "  ========================================================== ";


            // Initialize time 0 and time 1
            foreach (Node N in DB.NodeLib.Values)
            {
                N.Initialize_StepZero();
            }
            foreach (Element E in DB.ElemLib.Values)
            {
                E.Initialize_StepZero(DB.FELib);
            }

            // Console paragraph
            Console.WriteLine("\n" + separator);
            if (DB.AnalysisLib.GetAnalysisType().StartsWith("Linear"))
            {
                Console.WriteLine("        LINEAR STATIC ANALYSIS ");
            }
            if (DB.AnalysisLib.GetAnalysisType().StartsWith("Nonlinear"))
            {
                Console.WriteLine("        NONLINEAR STATIC ANALYSIS ");
            }
            Console.WriteLine(separator);

            // *****************************************************************************
            // ========================= MAIN FINITE ELEMENT CODE ==========================
            // *****************************************************************************


            //  ============================ Essential boundary conditions ======================================

            // DoF list with kinematic BC
            List <int> Fix_DOF = new List <int>();

            foreach (BoundaryCondition BC in DB.BCLib.Values.Where(x => x.Type == "SPC"))
            {
                foreach (int NID in BC.NodalValues.Keys)
                {
                    if (BC.NodalValues[NID].Get(0, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[0]);
                    }
                    if (BC.NodalValues[NID].Get(1, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[1]);
                    }
                    if (BC.NodalValues[NID].Get(2, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[2]);
                    }
                }
            }

            // Sort and remove duplicates of kinematic BC
            Fix_DOF = Fix_DOF.Distinct().ToList();
            Fix_DOF.Sort();

            // Define Row index reduction - rows and columns related to Dirichlet BC are removed from K matrix and F vector
            int[] nDOF_reduction = new int[DB.nDOF];
            for (int i = 0; i < Fix_DOF.Count; i++)
            {
                nDOF_reduction[Fix_DOF[i]] = -1;
            }

            int reduc = 0;

            for (int i = 0; i < DB.nDOF; i++)
            {
                if (nDOF_reduction[i] == -1)
                {
                    reduc++;
                }
                else
                {
                    nDOF_reduction[i] = reduc;
                }
            }


            //  >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  INCREMENTAL ANALYSIS   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

            for (int inc = 1; inc <= DB.AnalysisLib.GetIncNumb(); inc++)
            {
                Console.WriteLine("\n" + separator);
                Console.WriteLine("      INCREMENT " + inc);
                Console.WriteLine(separator);

                // Initialize Nodal displacements for new increment
                foreach (Node n in DB.NodeLib.Values)
                {
                    n.Initialize_NewDisp(inc);
                }

                // Initialize Element Strain and Stress for new increment
                foreach (Element Elem in DB.ElemLib.Values)
                {
                    Elem.Initialize_Increment(inc);
                }

                //  ============================ F (Right hand side) Vector =========================================

                double[] F = new double[DB.nDOF - Fix_DOF.Count];

                foreach (BoundaryCondition BC in DB.BCLib.Values.Where(x => x.Type == "PointLoad"))
                {
                    foreach (int NID in BC.NodalValues.Keys)
                    {
                        for (int dir = 0; dir < 3; dir++)
                        {
                            if (nDOF_reduction[DB.NodeLib[NID].DOF[dir]] != -1)
                            {
                                if (inc == 1)
                                {
                                    F[DB.NodeLib[NID].DOF[dir] - nDOF_reduction[DB.NodeLib[NID].DOF[dir]]] +=
                                        BC.NodalValues[NID].Get(dir, 0) * inc / DB.AnalysisLib.GetIncNumb();
                                }
                            }
                        }
                    }
                }

                // ================================    NEWTON-RAPHSON ITERATION   =====================================
                int    iter    = 0;
                double NormF   = Fun.Vector_Norm(F);
                double NormRes = 1;

                // Iteration zero:
                Console.WriteLine("  ITERATION 0: ");
                alglib.sparsematrix K = Fun.ParallelAssembly_K(DB, nDOF_reduction, inc, "Initial");


                // Newton loop
                while (NormRes > tolerance)
                //while (iter<1)
                {
                    if (iter > 0)
                    {
                        Console.WriteLine("  ITERATION " + iter + ": ");
                        K = Fun.ParallelAssembly_K(DB, nDOF_reduction, inc, "Tangent");
                        Fun.Print_Matrix(K, 6, 8);
                    }

                    // ============================== SOLVING LINEAR SYSTEM ===================================

                    double[]            U  = new double[DB.nDOF - Fix_DOF.Count];
                    alglib.sparsematrix K1 = (alglib.sparsematrix)K.make_copy();

                    if (DB.AnalysisLib.GetLinSolver() == "CG")
                    {
                        U = Fun.LinearSolver_CG(K1, F, DB.AnalysisLib);
                    }

                    if (DB.AnalysisLib.GetLinSolver() == "Cholesky")
                    {
                        U = Fun.LinearSolver_Cholesky(K1, F);
                    }

                    if (DB.AnalysisLib.GetLinSolver() == "LU")
                    {
                        U = Fun.LinearSolver_LU(K1, F);
                    }

                    // ================== U (Left hand side) vector reconstruction =====================================

                    double[] U_Full = Fun.Include_BC_DOF(U, nDOF_reduction);

                    // Assign displacements to nodes (replace dU vector and update dU Buffer)
                    foreach (Node n in DB.NodeLib.Values)
                    {
                        n.dU[0] = U_Full[n.DOF[0]];   n.dU_buffer[0] += U_Full[n.DOF[0]];
                        n.dU[1] = U_Full[n.DOF[1]];   n.dU_buffer[1] += U_Full[n.DOF[1]];
                        n.dU[2] = U_Full[n.DOF[2]];   n.dU_buffer[2] += U_Full[n.DOF[2]];

                        //Console.Write("Node " + n.ID + " disp: ");  Fun.Print_Vector(n.dU_buffer, 3);
                    }

                    // Internal Forces vector
                    double[] R = new double[DB.nDOF];

                    Console.Write("   Stress recovery: ");
                    Parallel.ForEach(DB.ElemLib.Values, Elem =>
                    {
                        Elem.Recovery_Stress(DB);
                        Elem.Compute_NodalForces(DB);

                        // Assembly Nodal Forces vector
                        for (int i = 0; i < Elem.NList.Count; i++)
                        {
                            for (int j = 0; j < 3; j++)
                            {
                                R[DB.NodeLib[Elem.NList[i]].DOF[j]] += Elem.NodalForces.GetFast(3 * i + j, 0);
                            }
                        }
                    });
                    R = Fun.Exclude_BC_DOF(R, nDOF_reduction);
                    Console.WriteLine("            Done");

                    Fun.Print_MatrixST(DB.ElemLib[1].dS[0].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[1].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[2].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[3].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[4].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[5].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[6].Transpose(), 1, 6);
                    Fun.Print_MatrixST(DB.ElemLib[1].dS[7].Transpose(), 1, 6);
                    Console.WriteLine("\n Nodal forces:");
                    Fun.Print_Vector(R, R.Length);
                    Console.WriteLine("\n");

                    // Calculate Residual Forces
                    double[] Residual = new double[DB.nDOF - Fix_DOF.Count];

                    for (int i = 0; i < F.Length; i++)
                    {
                        Residual[i] = F[i] - R[i];
                    }

                    // Calculate Residual Forces norm and extreme value
                    NormRes = Fun.Vector_Norm(Residual) / NormF;
                    double ExtremeResidual = Math.Max(Residual.Max(), Math.Abs(Residual.Min()));

                    Console.WriteLine("   Residual norm: " + NormRes.ToString("F4"));
                    Console.WriteLine("   Max residual force: " + ExtremeResidual.ToString("#0.0e+0") + "\n");
                    //Console.WriteLine("\nOut of balance forces:\n" + string.Join("\n", F.Where(x => x != 0)) + "\n");

                    // Next iteration
                    F = Residual;
                    iter++;
                }
                Console.WriteLine("  INCREMENT CONVERGED in " + iter + " iterations\n");

                // Update nodal displacement, element stress and strain
                foreach (Node N in DB.NodeLib.Values)
                {
                    N.Update_Displacement(inc);
                }
                foreach (Element E in DB.ElemLib.Values)
                {
                    E.Update_StrainStress(inc);
                }
            }

            sw.Stop();

            Console.WriteLine("\n" + separator);
            Console.WriteLine("  Total CPU time: " + sw.Elapsed.TotalSeconds.ToString("F2", CultureInfo.InvariantCulture) + " s");
            Console.WriteLine(separator);
        }
示例#7
0
文件: Solver.cs 项目: ovevans/STAN
        private static void SolverLinearStatics()
        {
            SolverFunctions Fun = new SolverFunctions();
            Stopwatch       sw  = new Stopwatch(); sw.Start();

            // Others
            int    inc       = 1;
            string separator = "  ========================================================== ";

            // Initialize time 0 and time 1
            foreach (Node N in DB.NodeLib.Values)
            {
                N.Initialize_StepZero();
                N.Initialize_NewDisp(inc);
            }
            foreach (Element E in DB.ElemLib.Values)
            {
                E.Initialize_StepZero(DB.FELib);
                E.Initialize_Increment(inc);
            }

            // Console paragraph
            Console.WriteLine("\n" + separator);
            Console.WriteLine("        LINEAR STATIC ANALYSIS ");
            Console.WriteLine(separator);

            // *****************************************************************************
            // ========================= MAIN FINITE ELEMENT CODE ==========================
            // *****************************************************************************

            //  ============================ Essential boundary conditions ======================================

            // DoF list with kinematic BC
            List <int> Fix_DOF = new List <int>();

            foreach (BoundaryCondition BC in DB.BCLib.Values.Where(x => x.Type == "SPC"))
            {
                foreach (int NID in BC.NodalValues.Keys)
                {
                    if (BC.NodalValues[NID].Get(0, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[0]);
                    }
                    if (BC.NodalValues[NID].Get(1, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[1]);
                    }
                    if (BC.NodalValues[NID].Get(2, 0) == 1)
                    {
                        Fix_DOF.Add(DB.NodeLib[NID].DOF[2]);
                    }
                }
            }

            // Sort and remove duplicates of kinematic BC
            Fix_DOF = Fix_DOF.Distinct().ToList();
            Fix_DOF.Sort();

            // Define Row index reduction - rows and columns related to Dirichlet BC are removed from K matrix and F vector
            int[] nDOF_reduction = new int[DB.nDOF];
            for (int i = 0; i < Fix_DOF.Count; i++)
            {
                nDOF_reduction[Fix_DOF[i]] = -1;
            }

            int reduc = 0;

            for (int i = 0; i < DB.nDOF; i++)
            {
                if (nDOF_reduction[i] == -1)
                {
                    reduc++;
                }
                else
                {
                    nDOF_reduction[i] = reduc;
                }
            }

            //  ============================ F (Right hand side) Vector =========================================

            double[] F = new double[DB.nDOF - Fix_DOF.Count];

            foreach (BoundaryCondition BC in DB.BCLib.Values.Where(x => x.Type == "PointLoad"))
            {
                foreach (int NID in BC.NodalValues.Keys)
                {
                    for (int dir = 0; dir < 3; dir++)
                    {
                        if (nDOF_reduction[DB.NodeLib[NID].DOF[dir]] != -1)
                        {
                            if (inc == 1)
                            {
                                F[DB.NodeLib[NID].DOF[dir] - nDOF_reduction[DB.NodeLib[NID].DOF[dir]]] +=
                                    BC.NodalValues[NID].Get(dir, 0);
                            }
                        }
                    }
                }
            }

            // ============================== GLOBAL STIFFNESS MATRIX ===================================

            alglib.sparsematrix K = Fun.ParallelAssembly_K(DB, nDOF_reduction, inc, "Initial");

            // ============================== SOLVING LINEAR SYSTEM ===================================

            double[] U = new double[DB.nDOF - Fix_DOF.Count];

            if (DB.AnalysisLib.GetLinSolver() == "CG")
            {
                U = Fun.LinearSolver_CG(K, F, DB.AnalysisLib);
            }
            if (DB.AnalysisLib.GetLinSolver() == "Cholesky")
            {
                U = Fun.LinearSolver_Cholesky(K, F);
            }
            if (DB.AnalysisLib.GetLinSolver() == "LU")
            {
                U = Fun.LinearSolver_LU(K, F);
            }

            // ================== U (Left hand side) vector reconstruction =====================================

            double[] U_Full = Fun.Include_BC_DOF(U, nDOF_reduction);

            // Assign displacements to nodes (replace dU vector and update dU Buffer)
            foreach (Node n in DB.NodeLib.Values)
            {
                n.dU_buffer[0] = U_Full[n.DOF[0]];
                n.dU_buffer[1] = U_Full[n.DOF[1]];
                n.dU_buffer[2] = U_Full[n.DOF[2]];

                //Console.Write("Node " + n.ID + " disp: "); Fun.Print_Vector(n.dU_buffer, 3);
            }

            // Internal Forces vector
            double[] R = new double[DB.nDOF];

            Console.Write("   Stress recovery: ");
            Parallel.ForEach(DB.ElemLib.Values, Elem =>
            {
                Elem.Recovery_Stress(DB);
                Elem.Compute_NodalForces(DB);

                // Assembly Nodal Forces vector
                for (int i = 0; i < Elem.NList.Count; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        R[DB.NodeLib[Elem.NList[i]].DOF[j]] += Elem.NodalForces.GetFast(3 * i + j, 0);
                    }
                }
            });

            R = Fun.Exclude_BC_DOF(R, nDOF_reduction);
            Console.WriteLine("            Done");

            // Update nodal displacement, element stress and strain
            foreach (Node n in DB.NodeLib.Values)
            {
                n.Update_Displacement(inc);
            }
            foreach (Element E in DB.ElemLib.Values)
            {
                E.Update_StrainStress(inc);
            }

            // Print CPU time summary
            sw.Stop();
            Console.WriteLine("\n" + separator);
            Console.WriteLine("  Total CPU time: " + sw.Elapsed.TotalSeconds.ToString("F2", CultureInfo.InvariantCulture) + " s");
            Console.WriteLine(separator);
        }
示例#8
0
    /// <summary>
    /// Call this to build matrices.
    /// </summary>
    public void Initialize(bool clearSources = true)
    {
        float time = Time.realtimeSinceStartup;
        float time0 = time;
        Debug.Log("Initializing matrices...");

        if (clearSources) {
            s = new List<Vertex>();
        }
        bool multiSource = useAccurateMultisource && s.Count > 1;
        int n = g.vertices.Count;

        // Heat matrix (Neumann condition)
        A1 = g.CalculateLcMatrixSparse(- Settings.tFactor * g.h * g.h, false, multiSource ? s : null);
        if (multiSource) {
            modif1 = g.modification;
        }
        for (int i = 0; i < n; i++) {
            alglib.sparseadd(A1, i, i, g.vertices[i].CalculateVertexAreaTri());
        }
        if (useCholesky) {
            alglib.sparseconverttosks(A1);
            alglib.sparsecholeskyskyline(A1, n, true);
        } else {
            alglib.sparseconverttocrs(A1);
        }

        Debug.Log("Heat equation matrix built, time = " + (Time.realtimeSinceStartup - time) * 1000 + "ms");
        time = Time.realtimeSinceStartup;

        if (g.hasBorder && Settings.boundaryCondition > 0) {
            // Dirichlet condition heat matrix
            A1b = g.CalculateLcMatrixSparse(- Settings.tFactor * g.h * g.h, true, multiSource ? s : null);
            if (multiSource) {
                modif1b = g.modification;
            }
            for (int i = 0; i < n; i++) {
                alglib.sparseadd(A1b, i, i, g.vertices[i].CalculateVertexAreaTri());
            }
            if (useCholesky) {
                alglib.sparseconverttosks(A1b);
                alglib.sparsecholeskyskyline(A1b, n, true);
            } else {
                alglib.sparseconverttocrs(A1b);
            }

            Debug.Log("Additional heat equation matrix built (dirichlet), time = " + (Time.realtimeSinceStartup - time) * 1000 + "ms");
            time = Time.realtimeSinceStartup;
        }

        // Laplacien matrix
        A2 = g.CalculateLcMatrixSparse(-1, false, multiSource ? s : null);
        if (multiSource) {
            foreach (Vertex src in s) {
                alglib.sparseadd(A2, src.index, src.index, 1);
            }
        }
        if (useCholesky) {
            for (int i = 0; i < n; i++) {
                alglib.sparseadd(A2, i, i, 0.000000001); // To make it positive definite
            }
            alglib.sparseconverttosks(A2);
            alglib.sparsecholeskyskyline(A2, n, true);
        } else {
            alglib.sparseconverttocrs(A2);
        }

        Debug.Log("Laplacien matrix built, time = " + (Time.realtimeSinceStartup - time) * 1000 + "ms");
        time = Time.realtimeSinceStartup;

        // Tables of Cotangent value * edge vectors
        div = g.CalculateDivData();

        Debug.Log("Cotangent table built, time = " + (Time.realtimeSinceStartup - time) * 1000 + "ms");
        GameObject.Find("Timer2").GetComponent<Text>().text = "Precalculation time = " + (Time.realtimeSinceStartup - time0) * 1000 + "ms";
    }
示例#9
0
        /// <summary>
        /// Generates a list of alglib sparsematrix objects where the first is the diagonal elements and the remaining ones are for D and K for each mode and then the matrices for the cross terms.
        /// </summary>
        /// <param name="basisVectorsByJ">
        /// List of JBasisVectors sorted by J.
        /// </param>
        /// <param name="isQuad">
        /// True means a quadratic basis set is used and quadratic terms will be calculated.
        /// </param>
        /// <param name="input">
        /// FileInfo object containing input information.
        /// </param>
        /// <param name="nColumns">
        /// Integer with order of A.
        /// </param>
        /// <param name="par">
        /// Value indicating max degree of parallelism for matrix generation loop.
        /// </param>
        /// <param name="diagOnly">
        /// Boolean to see if only the diagonal elements should be generated
        /// </param>
        /// <returns>
        /// List of sparsematrix objects corresponding to different parameters.
        /// </returns>
        public static List<alglib.sparsematrix> GenMatrixHash(List<BasisFunction> basisVectorsByJ, bool isQuad, FileInfo input, out int nColumns, int par, bool diagOnly, int position)
        {
            int matSize = basisVectorsByJ.Count;
            nColumns = matSize;
            bool bilinear = false;
            int nModes = input.nModes;

            //Lists to store the positions of the A and E vecs with cross-terms coupling
            List<int> biAVecPos = new List<int>();
            List<int> biEVecPos = new List<int>();
            List<int> eVecPos = new List<int>();
            List<int> aVecPos = new List<int>();
            //List to store the alglib sparse matrices for each variable
            var matList = new List<alglib.sparsematrix>();
            //The Tuple stores the row and column of the matrix element in the two int values and the value at that matrix element as the double
            //order of row and column is unimportant since the matrix is symmetric
            List<ConcurrentBag<Tuple<int, int, double>>> matrixPos = new List<ConcurrentBag<Tuple<int, int, double>>>();

            //this array stores the v and l values for each mode for each basis function as well as Lambda and J
            //all v values are stored in elements 0 through nmodes - 1 and l is in nmodes through 2*nmodes - 1
            //Lambda is stored in element 2*nmodes and J is stored as an int as (J - 0.5) in 2 * nmodes + 1
            //the nested loops initialize the vlLambda arrays for each basis function
            //This is ugly but makes the matrix generation much faster than accessing the objects in the matrix generation and saves me a ton of re-coding
            int[,] vlLambda = new int[matSize, nModes * 2 + 2];
            int[] hashStorage = new int[nModes * 2 + 1];
            //Dictionary<string, int> basisPositions = new Dictionary<string, int>();

            //basisPositions[position] = new Dictionary<string, int>();
            for (int i = 0; i < matSize; i++)
            {
                for (int j = 0; j < nModes; j++)
                {
                    vlLambda[i, j] = hashStorage[j] = basisVectorsByJ[i].modesInVec[j].V;
                    vlLambda[i, j + nModes] = hashStorage[j + nModes] = basisVectorsByJ[i].modesInVec[j].L;
                }
                vlLambda[i, nModes * 2] = hashStorage[nModes * 2] = basisVectorsByJ[i].Lambda;
                vlLambda[i, nModes * 2 + 1] = (int)(basisVectorsByJ[i].J - 0.5M);
                basisPositions[position].Add(BasisFunction.GenerateHashCode(hashStorage, nModes), i);
            }//end loop to make vlLambda

            //generate an array to store omega, omegaExe, D, K and degeneracy of each mode
            //only one copy of this is needed since those values are the same across all basis functions
            var modeVals = new double[nModes, 5];
            for (int i = 0; i < nModes; i++)
            {
                modeVals[i, 0] = basisVectorsByJ[0].modesInVec[i].ModeOmega;
                modeVals[i, 1] = basisVectorsByJ[0].modesInVec[i].Anharmonicity;
                modeVals[i, 2] = basisVectorsByJ[0].modesInVec[i].DBasis;
                modeVals[i, 3] = basisVectorsByJ[0].modesInVec[i].KBasis;
                modeVals[i, 4] = 2.0;//degeneracy = 2 by default
                if (basisVectorsByJ[0].modesInVec[i].SymmetryIsA)
                {
                    modeVals[i, 4] = 1.0;
                    aVecPos.Add(i);
                }
                else
                {
                    modeVals[i, 4] = 2.0;
                    eVecPos.Add(i);
                }
            }//end loop to make modeVals[,] array

            #region HO Terms
            //just the harmonic oscillator terms.  Here only the diagonal elements are generated
            var diag = new alglib.sparsematrix();
            alglib.sparsecreate(matSize, matSize, matSize, out diag);

            //loop through all diagonal elements
            for (int n = 0; n < matSize; n++)
            {
                //one mode harmonic and anharmonic terms
                for (int i = 0; i < input.nModes; i++)
                {
                    double temp = modeVals[i, 0] * ((double)vlLambda[n, i] + (double)modeVals[i, 4] / 2.0) - modeVals[i, 1] * Math.Pow((vlLambda[n, i] + (double)modeVals[i, 4] / 2.0), 2.0);
                    alglib.sparseadd(diag, n, n, temp);
                }//end loop over modes
                continue;
            }//end HO loop
            //add diagonal matrix elements to matList as element [0]
            matList.Add(diag);
            #endregion

            //if this is not the first call to the Hamiltonian generation function then only the diagonal elements are needed
            //therefore, if diagOnly is true, just return matList with only the diagonal portion of the matrix.
            if (diagOnly)
            {
                return matList;
            }

            //loop through each mode to see if a sparse matrix is needed for D and K
            for (int i = 0; i < nModes; i++)
            {
                if (!basisVectorsByJ[0].modesInVec[i].SymmetryIsA || basisVectorsByJ[0].modesInVec[i].DBasis != 0.0)
                {
                    //means this mode is degenerate, add matrices for D and K
                    alglib.sparsematrix tempMat = new alglib.sparsematrix();
                    alglib.sparsecreate(matSize, matSize, matSize * (nModes + 1), out tempMat);
                    matList.Add(tempMat);
                    alglib.sparsematrix tempMat2 = new alglib.sparsematrix();
                    alglib.sparsecreate(matSize, matSize, matSize * (nModes + 1), out tempMat2);
                    matList.Add(tempMat2);
                }
                else
                {
                    //add empty matrices for D and K for non degenerate modes. Probably not a huge deal but saves some memory
                    alglib.sparsematrix tempMat = new alglib.sparsematrix();
                    alglib.sparsecreate(matSize, matSize, 0, out tempMat);
                    matList.Add(tempMat);
                    alglib.sparsematrix tempMat2 = new alglib.sparsematrix();
                    alglib.sparsecreate(matSize, matSize, 0, out tempMat2);
                    matList.Add(tempMat2);
                }
            }

            //initialize cross-terms and generate biAVecPos and biEVecPos lists
            BilinearInitialization(basisVectorsByJ[0].modesInVec, nModes, out bilinear, out biAVecPos, out biEVecPos, input.CrossTermMatrix);
            bool crossQuad = false;
            var crossQuadPos = CrossQuadraticInitialization(eVecPos, out crossQuad, input.CrossTermMatrix);

            //add any matrices needed for cross-terms
            if (input.CrossTermMatrix != null)
            {
                for (int i = 0; i < nModes; i++)
                {
                    for (int j = 0; j < nModes; j++)
                    {
                        //add a new sparsematrix for each nonzero cross-term element
                        if (input.CrossTermMatrix[i, j] != 0.0)
                        {
                            alglib.sparsematrix tempMat = new alglib.sparsematrix();
                            alglib.sparsecreate(matSize, matSize, matSize * (nModes + 1), out tempMat);
                            matList.Add(tempMat);
                        }
                    }
                }
            }//enf if crossTermMatrix == null

            //initialize the concurrentBags for each matrix being generated. -1 in loop bounds because diagonal already done
            for (int n = 0; n < matList.Count - 1; n++)
            {
                matrixPos.Add(new ConcurrentBag<Tuple<int, int, double>>());
            }

            //set up the settings for the parallel foreach loop
            var rangePartitioner = Partitioner.Create(0, matSize);
            ParallelOptions parOp = new ParallelOptions();
            parOp.MaxDegreeOfParallelism = par;
            Parallel.ForEach(rangePartitioner, parOp, (range, loopState) =>
            {
                //indexes n and m are for the rows and columns of the matrix respectively
                for (int n = range.Item1; n < range.Item2; n++)
                {
                    int[] hashInt = new int[nModes * 2 + 1];
                    for (int a = 0; a < hashInt.Length; a++)
                    {
                        hashInt[a] = vlLambda[n, a];
                    }
                    int[] tempInt;
                    int m;
                    double temp;
                    string hashCode;
                    for (int aModes = 0; aModes < aVecPos.Count; aModes++)
                    {
                        #region SymmetricGradient
                        for (int deltaV = -1; deltaV < 2; deltaV += 2)
                        {
                            tempInt = (int[])hashInt.Clone();
                            DeltaVL(ref tempInt, aVecPos[aModes], deltaV, 0, nModes, false);
                            hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                            if (basisPositions[position].TryGetValue(hashCode, out m))
                            {
                                //assign temp here.
                                double oneORnone = 0.0;
                                if (deltaV == 1)
                                {
                                    oneORnone = 1.0;
                                }
                                temp = Math.Sqrt(((double)vlLambda[n, aVecPos[aModes]] + oneORnone));
                                Tuple<int, int, double> ttTemp = new Tuple<int, int, double>(n, m, temp);// basisVectorsByJ[n].modesInVec[mode].v     basisVectorsByJ[n].modesInVec[mode].l
                                matrixPos[2 * aVecPos[aModes]].Add(ttTemp);
                            }
                        }
                        #endregion
                    }
                    for (int eModes = 0; eModes < eVecPos.Count; eModes++)
                    {
                        #region Linear
                        //linear portion
                        //now check each EVecPos mode for a linear element by taking vlLambda[n, ] and changing the values appropriately to find a linear element. Store in tempint
                        //tempInt = (int[])hashInt.Clone();
                        for(int deltal = -1; deltal < 2; deltal += 2)
                        {
                            for (int deltaV = -1; deltaV < 2; deltaV += 2)
                            {
                                tempInt = (int[])hashInt.Clone();
                                DeltaVL(ref tempInt, eVecPos[eModes], deltaV, deltal, nModes);
                                hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                                //if it exists, then assign it to the linear value
                                if (basisPositions[position].TryGetValue(hashCode, out m))
                                {
                                    if (m > n)
                                    {
                                        temp = LinearMatrixElement(vlLambda, n, eVecPos[eModes], nModes, deltal, deltaV);
                                        Tuple<int, int, double> ttTemp = new Tuple<int, int, double>(n, m, temp);// basisVectorsByJ[n].modesInVec[mode].v     basisVectorsByJ[n].modesInVec[mode].l
                                        matrixPos[2 * eVecPos[eModes]].Add(ttTemp);
                                    }
                                }
                            }//end loop over deltaV
                        }//end loop over linear l values
                        #endregion

                        #region Quadratic
                        //check for all quadratic elements
                        //reset tempInt values for Quadratic elements
                        for (int ll = -2; ll < 3; ll += 4)
                        {
                            tempInt = (int[])hashInt.Clone();
                            //for bottom matrix element on page
                            DeltaVL(ref tempInt, eVecPos[eModes], 2, ll, nModes);
                            hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                            if (basisPositions[position].TryGetValue(hashCode, out m))
                            {
                                if (m > n)
                                {
                                    temp = (1 / 4D * Math.Sqrt((vlLambda[n, eVecPos[eModes]] + (ll / 2) * vlLambda[n, nModes + eVecPos[eModes]] + 4D) * (vlLambda[n, eVecPos[eModes]] + (ll / 2) * vlLambda[n, nModes + eVecPos[eModes]] + 2)));
                                    Tuple<int, int, double> tTemp = new Tuple<int, int, double>(n, m, temp);
                                    matrixPos[eVecPos[eModes] * 2 + 1].Add(tTemp);
                                }
                            }

                            //reset tempInt values for Quadratic elements
                            tempInt = (int[])hashInt.Clone();
                            //for middle matrix element on page
                            DeltaVL(ref tempInt, eVecPos[eModes], 0, ll, nModes);
                            hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                            if (basisPositions[position].TryGetValue(hashCode, out m))
                            {
                                if (m > n)
                                {
                                    temp = (1D / 2D * Math.Sqrt((vlLambda[n, eVecPos[eModes]] + (ll / 2) * vlLambda[n, nModes + eVecPos[eModes]] + 2) * (vlLambda[n, eVecPos[eModes]] - (ll / 2) * vlLambda[n, eVecPos[eModes] + nModes])));
                                    Tuple<int, int, double> tTemp = new Tuple<int, int, double>(n, m, temp);
                                    matrixPos[eVecPos[eModes] * 2 + 1].Add(tTemp);
                                }
                            }

                            tempInt = (int[])hashInt.Clone();
                            //for top matrix element on page
                            DeltaVL(ref tempInt, eVecPos[eModes], -2, ll, nModes);
                            hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                            if (basisPositions[position].TryGetValue(hashCode, out m))
                            {
                                if (m > n)
                                {
                                    temp = (1 / 4D * Math.Sqrt((vlLambda[n, eVecPos[eModes]] - (ll / 2) * vlLambda[n, nModes + eVecPos[eModes]]) * (vlLambda[n, eVecPos[eModes]] - (ll / 2) * vlLambda[n, nModes + eVecPos[eModes]] - 2)));
                                    Tuple<int, int, double> tTemp = new Tuple<int, int, double>(n, m, temp);
                                    matrixPos[eVecPos[eModes] * 2 + 1].Add(tTemp);
                                }
                            }
                        }//end quadratic loop over l values
                        #endregion
                    }//end loop over E-modes

                    int crossCount = 0;
                    #region Bilinear
                    if (bilinear)
                    {
                        //loop through A and E vecs with possible coupling
                        for (int a = 0; a < biAVecPos.Count; a++)
                        {
                            for (int e = 0; e < biEVecPos.Count; e++)
                            {
                                //value to keep track of which cross-term matrix we're on.
                                crossCount = a + e;

                                //this is because the cross-term couplings for JT terms are stored in the upper-diagonal of the cross-term matrix
                                int row;
                                int column;
                                if (biAVecPos[a] > biEVecPos[e])
                                {
                                    column = biAVecPos[a];
                                    row = biEVecPos[e];
                                }
                                else
                                {
                                    column = biEVecPos[e];
                                    row = biAVecPos[a];
                                }
                                for (int ll = -1; ll < 2; ll += 2)
                                {
                                    for (int dve = -1; dve < 2; dve += 2)
                                    {
                                        for (int dva = -1; dva < 2; dva += 2)
                                        {
                                            double oneORnone = 0.0;
                                            if (dva == 1)
                                            {
                                                oneORnone = 1.0;
                                            }
                                            double twoORnone = 0.0;
                                            int pre = -1;
                                            if (dve == 1)
                                            {
                                                twoORnone = 2.0;
                                                pre = 1;
                                            }
                                            tempInt = (int[])hashInt.Clone();
                                            //delta vl for e mode
                                            DeltaVL(ref tempInt, biEVecPos[e], dve, ll, nModes);
                                            //delta vl for a mode
                                            DeltaVL(ref tempInt, biAVecPos[a], dva, 0, nModes, false);
                                            hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                                            //formula for bilinear matrix element
                                            if (basisPositions[position].TryGetValue(hashCode, out m))
                                            {
                                                if (m > n)
                                                {
                                                    temp = 0.5 * Math.Sqrt(((double)vlLambda[n, biAVecPos[a]] + oneORnone) * ((double)vlLambda[n, biEVecPos[e]] + ll * pre * vlLambda[n, nModes + biEVecPos[e]] + twoORnone));//ll * (double)vlLambda[n, EVecPos[eModes] + nModes] + 2D))
                                                    Tuple<int, int, double> tTemp = new Tuple<int, int, double>(n, m, temp);
                                                    matrixPos[2 * nModes + crossCount].Add(tTemp);
                                                }
                                            }
                                        }//end loop over delta v values for a mode
                                    }//end loop over delta v values for e mode
                                }//end loop over l values for e mode
                            }//end for loop over evec positions
                        }//end for loop over a vec positions
                    }//end bilinear if
                    #endregion

                    #region Cross-Quadratic
                    if (crossQuad)
                    {
                        for (int crossTerm = 0; crossTerm < crossQuadPos.Count; crossTerm += 2)
                        {
                            crossCount++; // Moved this up since without it, the matrix was adding onto the last one.
                            if (!bilinear && crossTerm == 0) // If bilinear matrices were not generated, then start at 0.
                            {
                                crossCount = 0;
                            }
                            for (int deltal = -1; deltal < 2; deltal += 2)
                            {
                                for (int deltaV = -1; deltaV < 2; deltaV += 2)
                                {
                                    for (int deltal2 = -1; deltal2 < 2; deltal2 += 2)
                                    {
                                        for (int deltaV2 = -1; deltaV2 < 2; deltaV2 += 2)
                                        {
                                            for (int changeLambda = 0; changeLambda < 2; changeLambda++)
                                            {
                                                //tbool makes it so that every other iteration of changeLambda is electronically off-diagonal
                                                bool tbool = false;
                                                if (changeLambda == 0)
                                                {
                                                    tbool = true;
                                                    continue;
                                                }
                                                tempInt = (int[])hashInt.Clone();
                                                //get DeltaVL for the first mode
                                                //DeltaVL(ref tempInt, eVecPos[crossQuadPos[crossTerm]], deltaV, deltal, nModes, tbool);
                                                DeltaVL(ref tempInt, crossQuadPos[crossTerm], deltaV, deltal, nModes, tbool);
                                                //get DeltaVL for the second mode
                                                //DeltaVL(ref tempInt, eVecPos[crossQuadPos[crossTerm + 1]], deltaV2, deltal2, nModes);
                                                DeltaVL(ref tempInt, crossQuadPos[crossTerm + 1], deltaV2, deltal2, nModes);
                                                //generate the hashcode
                                                hashCode = BasisFunction.GenerateHashCode(tempInt, nModes);
                                                //if it exists, then assign it to the linear value
                                                if (basisPositions[position].TryGetValue(hashCode, out m))
                                                {
                                                    if (m > n)
                                                    {
                                                        temp = LinearMatrixElement(vlLambda, n, crossQuadPos[crossTerm], nModes, deltal, deltaV);
                                                        temp *= LinearMatrixElement(vlLambda, n, crossQuadPos[crossTerm + 1], nModes, deltal2, deltaV2);
                                                        temp *= 0.5;
                                                        Tuple<int, int, double> ttTemp = new Tuple<int, int, double>(n, m, temp);// basisVectorsByJ[n].modesInVec[mode].v     basisVectorsByJ[n].modesInVec[mode].l
                                                        matrixPos[2 * nModes + crossCount].Add(ttTemp);
                                                    }
                                                }
                                            }//end loop over change lambda
                                        }//end loop over deltaV
                                    }//end loop over linear l values
                                }//end loop over deltaV
                            }//end loop over linear l values
                            // crossCount++;
                        }//end loop over cross quadratic terms
                    }
                    #endregion
                }//row for loop
            }//end anonymous function in parallel for loop
            );//end parallel for

            //actually add all of the matrix elements to the matrices
            //Start at 0 because matrixPos only has off diagonal elements.  Add elements to matList[i + 1] because matList already has diagonal elements in position 0.
            for (int i = 0; i < matrixPos.Count; i++)
            {
                //add all calculated matrix elements to the appropriate sparsematrices
                foreach (Tuple<int, int, double> spot in matrixPos[i])
                {
                    alglib.sparseadd(matList[i + 1], spot.Item1, spot.Item2, spot.Item3);
                }
            }
            return matList;
        }
示例#10
0
文件: SOCJT.cs 项目: Sekie/SOCJT_2
 /// <summary>
 /// Takes a list of alglib.sparsematrix objects and combines them.
 /// </summary>
 /// <param name="mat">
 /// List of alglib.sparsematrix objects to be combined
 /// </param>
 /// <returns>
 /// alglib.sparsematrix object which contains all elements of all alglib.sparsematrix objects in the List mat.
 /// </returns>
 private static alglib.sparsematrix aggregator(List<alglib.sparsematrix> mat)
 {
     int i;
     int j;
     double oldVal;
     alglib.sparsematrix B = new alglib.sparsematrix();
     alglib.sparsecreate(mat[0].innerobj.m, mat[0].innerobj.n, out B);
     for (int m = 0; m < mat.Count; m++)
     {
         int t0 = 0;
         int t1 = 0;
         while (alglib.sparseenumerate(mat[m], ref t0, ref t1, out i, out j, out oldVal))
         {
             alglib.sparseadd(B, i, j, oldVal);
             //adds lower diagonal matrix elements for all off-diagonal matrices (first element in mat is the diagonal elements so don't do this for it).
             if (m != 0)
             {
                 alglib.sparseadd(B, j, i, oldVal);
             }
         }
     }
     return B;
 }
示例#11
0
文件: SOCJT.cs 项目: Sekie/SOCJT_2
        public List<string> SOCJTroutine(List<ModeInfo> Modes, bool isQuad, string[] inputFile, FileInfo input)
        {
            //Sets minimum and maximum j values.
            Stopwatch measurer = new Stopwatch();
            long howMuchTime;
            decimal jMin;
            decimal jMax;
            //If is quadratic makes sure that the maxJ is at least 7.5
            if (isQuad == true)
            {
                if (input.maxJ < 7.5M)
                {
                    input.maxJ = 7.5M;
                }
            }
            if (isQuad == true)
            {
                jMax = input.maxJ;
                jMin = -input.maxJ;
            }//end if
            else
            {
                jMax = input.maxJ;
                if (input.MinJBool == true)
                {
                    jMin = input.minJ;
                }
                else
                {
                    jMin = 0.5M;
                }
            }//end if

            //Makes a List of Lists of Basis objects with each List of Basis objects being for one mode.
            List<List<BasisByMode>> basisByMode = new List<List<BasisByMode>>();
            for (int i = 0; i < input.nModes; i++)
            {
                basisByMode.Add(new List<BasisByMode>());
                basisByMode[i] = BasisByMode.GenVLCombinations(Modes[i], i);
            }//end for

            //Generates all of the JBasisVectors to be used in calculation.
            List<BasisFunction> hamiltonianVecs = BasisFunction.GenJVecs(basisByMode, input.nModes, jMin, jMax);
            //hamiltonianVecs are the total list of all J vectors in the Hamiltonian

            //Sorts the hamiltonianVecs by J and puts them into a List of Lists of JBasisVectors.
            List<List<BasisFunction>> jBasisVecsByJ = new List<List<BasisFunction>>();
            for (decimal i = jMin; i <= jMax; i++)
            {
                jBasisVecsByJ.Add(GenHamMat.SortByJ(hamiltonianVecs, i));
            }//end for loop

            //Initializes Lists to hold the Hamiltonian matrices, eigenvectors, eigenvalues, basis vectors for the output file and number of columns for each j matrix respectively.
            //Also initializes the Dictionary list for storing the positions of the basis functions
            List<double[,]> zMatrices = new List<double[,]>();
            List<double[]> eigenvalues = new List<double[]>();
            List<List<BasisFunction>> JvecsForOutuput = new List<List<BasisFunction>>();
            List<BasisFunction>[] jbasisoutA = new List<BasisFunction>[0];
            List<int> numColumns = new List<int>();
            GenHamMat.basisPositions = new List<Dictionary<string, int>>();

            #region Hamiltonian
            List<alglib.sparsematrix> sHamMatrix = new List<alglib.sparsematrix>();
            alglib.sparsematrix[] array1;
            int[] numcolumnsA;
            //smallMat = false;
            //Creates the Hamiltonian matrices for linear cases
            int numQuadMatrix = 0;
            List<int> a = new List<int>();

            if (input.M > input.NumberOfIts)
            {
                throw new BasisSetTooSmallException(false);
            }

            if (isQuad == false)
            {
                #region LinearHamiltonian
                measurer.Reset();
                measurer.Start();
                int h = 0;
                array1 = new alglib.sparsematrix[jBasisVecsByJ.Count];
                List<int> basisSize = new List<int>();
                basisSet = jBasisVecsByJ;
                if (!matricesMade)
                {
                    fitHamList = new List<List<alglib.sparsematrix>>();
                    for (int m = 0; m < jBasisVecsByJ.Count; m++)
                    {
                        fitHamList.Add(new List<alglib.sparsematrix>());
                    }
                    //check here to see if matrix file should be used, if so then read from file and make them, set matricesMade to true
                    //matricesMade = matReadFunction(input);
                    basisSize = matReadFunction(input, ref matricesMade);
                }
                numcolumnsA = new int[jBasisVecsByJ.Count];

                //put items up to length in here
                for (int i = (int)(jMin - 0.5M); i < (int)(jMax + 0.5M); i++)
                {
                    GenHamMat.basisPositions.Add(new Dictionary<string, int>());
                }

                ParallelOptions options = new ParallelOptions();
                options.MaxDegreeOfParallelism = input.ParJ;
                try
                {
                    Parallel.For((int)(jMin - 0.5M), (int)(jMax + 0.5M), options, i =>
                    {
                        int nColumns;
                        if (jBasisVecsByJ[i].Count != 0)//changed from h to i
                        {
                            //this checks if the matrix was read from file, and if so if the basis set is the correct size
                            if (basisSize.Count != 0)
                            {
                                if (basisSize[i] != jBasisVecsByJ[i].Count)
                                {
                                    throw new MatrixFileError();
                                }
                            }
                            if (!matricesMade)//if matrices not made then generate all matrices
                            {
                                fitHamList[i] = GenHamMat.GenMatrixHash(jBasisVecsByJ[i], isQuad, input, out nColumns, input.ParMatrix, false, i);
                            }
                            else//this makes sure that the diagonal portion is regenerated on each call.
                            {
                                fitHamList[i][0] = GenHamMat.GenMatrixHash(jBasisVecsByJ[i], isQuad, input, out nColumns, input.ParMatrix, true, i)[0];
                            }
                            numcolumnsA[i] = nColumns;
                            if (numcolumnsA[i] < input.M)
                            {
                                a.Add(0);
                            }
                            h++;
                        }
                        else
                        {
                            a.Add(0);
                        }
                    }//end for loop
                    );
                }
                catch (AggregateException ae)
                {
                    foreach (var e in ae.InnerExceptions)
                    {
                        if (e is MatrixFileError)
                        {
                            throw new MatrixFileError();
                        }
                        else
                        {
                            throw;
                        }
                    }

                }
                measurer.Stop();
                howMuchTime = measurer.ElapsedMilliseconds;
                input.MatrixGenerationTime = (double)howMuchTime / 1000D;
                for (int i = (int)(jMin - 0.5M); i < (int)(jMax + 0.5M); i++)
                {
                    zMatrices.Add(new double[0, 0]);
                    eigenvalues.Add(new double[0]);
                }
                matricesMade = true;
                //handles errors where the basis set is too small
                if (a.Count > 0)
                {
                    throw new BasisSetTooSmallException(true);
                }
                #endregion
            }//end if

            //Creates the Hamiltonian matrices for quadratic cases.
            else
            {
                #region QuadraticHamiltonian
                measurer.Reset();
                measurer.Start();
                int dynVar1 = (int)(jMax - 1.5M);
                int dynVar2 = dynVar1 / 3;
                List<int> basisSize = new List<int>();
                array1 = new alglib.sparsematrix[jBasisVecsByJ.Count - dynVar1 - jBasisVecsByJ.Count / 2];//changed to dynVar1 from 6
                if (!matricesMade)
                {
                    fitHamList = new List<List<alglib.sparsematrix>>();
                    for (int m = 0; m < jBasisVecsByJ.Count - dynVar1 - jBasisVecsByJ.Count / 2; m++)
                    {
                        fitHamList.Add(new List<alglib.sparsematrix>());
                    }
                    //check here to see if matrix file should be used, if so then read from file and make them, set matricesMade to true
                    basisSize = matReadFunction(input, ref matricesMade);
                }
                numcolumnsA = new int[jBasisVecsByJ.Count - dynVar1 - jBasisVecsByJ.Count / 2];//changed to dynVar1 from 6
                jbasisoutA = new List<BasisFunction>[jBasisVecsByJ.Count - dynVar1 - jBasisVecsByJ.Count / 2];//changed to dynVar1 from 6

                for (int i = jBasisVecsByJ.Count / 2; i < jBasisVecsByJ.Count - dynVar1; i++)
                {
                    GenHamMat.basisPositions.Add(new Dictionary<string, int>());
                }

                ParallelOptions options = new ParallelOptions();
                options.MaxDegreeOfParallelism = input.ParJ;
                try
                {
                    Parallel.For(jBasisVecsByJ.Count / 2, jBasisVecsByJ.Count - dynVar1, options, i =>//changed to dynVar1 from 6
                    {
                        List<BasisFunction> quadVecs = new List<BasisFunction>();
                        int nColumns;
                        for (int v = -dynVar2 - 1; v <= dynVar2; v++)
                        {
                            if (i + v * 3 >= 0)
                            {
                                quadVecs.AddRange(jBasisVecsByJ[i + v * 3]);
                            }
                        }
                        //this checks if the matrix was read from file, and if so if the basis set is the correct size
                        if (basisSize.Count != 0)
                        {
                            if (basisSize[i - jBasisVecsByJ.Count / 2] != quadVecs.Count)
                            {
                                throw new MatrixFileError();
                            }
                        }
                        //if matrices aren't made then generate all of them
                        if (!matricesMade)
                        {
                            fitHamList[i - jBasisVecsByJ.Count / 2] = GenHamMat.GenMatrixHash(quadVecs, isQuad, input, out nColumns, input.ParMatrix, false, i - jBasisVecsByJ.Count / 2);
                        }
                        else//If they are made then just generate the diagonal elements.
                        {
                            fitHamList[i - jBasisVecsByJ.Count / 2][0] = GenHamMat.GenMatrixHash(quadVecs, isQuad, input, out nColumns, input.ParMatrix, true, i - jBasisVecsByJ.Count / 2)[0];
                        }

                        jbasisoutA[i - jBasisVecsByJ.Count / 2] = quadVecs;
                        numcolumnsA[i - jBasisVecsByJ.Count / 2] = nColumns;
                        if (numcolumnsA[i - jBasisVecsByJ.Count / 2] < input.M)
                        {
                            a.Add(0);
                        }
                        numQuadMatrix++;
                    }
                    );
                }
                catch (AggregateException ae)
                {
                    foreach (var e in ae.InnerExceptions)
                    {
                        if (e is MatrixFileError)
                        {
                            throw new MatrixFileError();
                        }
                        else
                        {
                            throw;
                        }
                    }

                }
                basisSet = new List<List<BasisFunction>>();
                for (int jj = 0; jj < jbasisoutA.Length; jj++)
                {
                    basisSet.Add(jbasisoutA[jj]);
                }
                matricesMade = true;
                measurer.Stop();
                howMuchTime = measurer.ElapsedMilliseconds;
                input.MatrixGenerationTime = (double)howMuchTime / 1000D;
                if (a.Count > 0)
                {
                    throw new BasisSetTooSmallException(true);
                }
                for (int i = 0; i < 2; i++)
                {
                    zMatrices.Add(new double[0, 0]);
                    eigenvalues.Add(new double[0]);
                }
                #endregion
            }//end else
            #endregion

            //list where each element of mat is a list of alglib.sparsematrix objects.  One for each off-diagonal parameter (D, K, B)
            var mat = new List<List<alglib.sparsematrix>>();
            bool bilinear = false;
            var biAVecPos = new List<int>();
            var biEVecPos = new List<int>();
            GenHamMat.BilinearInitialization(jBasisVecsByJ[0][0].modesInVec, input.nModes, out bilinear, out biAVecPos, out biEVecPos, input.CrossTermMatrix);
            //code here to convert the alglib matrices to matrices for each j block

            for (int i = 0; i < fitHamList.Count; i++)
            {
                int whichCrossMatrix = 0;
                mat.Add(new List<alglib.sparsematrix>());
                int count;
                int DorK;
                double val = 0.0;
                //this adds the diagonal elements to the list
                mat[i].Add(fitHamList[i][0]);
                //go through each member of the list and multiply it by the appropriate value, combine them all
                //skip the first one which is the diagonal elements and isn't multiplied by anything.
                for (int j = 1; j < fitHamList[i].Count; j++)
                {
                    count = (j - 1) / 2;
                    DorK = (j - 1) % 2;
                    if (count < input.nModes)
                    {
                        if (DorK == 0)
                        {
                            if (!Modes[count].IsAType)
                            {
                                val = Math.Sqrt(Modes[count].D) * Modes[count].modeOmega;
                            }
                            else
                            {
                                //val = Math.Sqrt(Modes[count].D);
                                val = Modes[count].D;
                            }
                        }
                        else
                        {
                            val = Modes[count].K * Modes[count].modeOmega;
                        }
                    }
                    else//means it's a cross term. loop over relevant E and A terms in same order as in genFitMatrix function
                    {
                        int crossMatrixCounter = 0;
                        for (int blOrNot = 0; blOrNot < 2; blOrNot++)
                        {
                            for (int row = 0; row < input.CrossTermMatrix.GetLength(0); row++)
                            {
                                for (int column = row + 1; column < input.CrossTermMatrix.GetLength(0); column++)
                                {
                                    if (input.CrossTermMatrix[row, column] != 0.0)
                                    {
                                        //now test to see if this is a bilinear or cross quadratic term. do bilinear first, then cross quadratic.
                                        //then can get the value
                                        //use blOrNot to see if we should be doing bilinear or not
                                        //if this is a bilinear term, only add it if blOrNot == 0
                                        //crossMatrixCounter will keep going
                                        if ((biAVecPos.Exists(x => x == row) || biAVecPos.Exists(x => x == column)) && blOrNot == 0)
                                        {
                                            //means this is a bilinear term
                                            if (crossMatrixCounter == whichCrossMatrix)
                                            {
                                                val = input.CrossTermMatrix[row, column];
                                            }//end conditional to see if this is the cross-term element we want
                                            crossMatrixCounter++;
                                        }
                                        if (!(biAVecPos.Exists(x => x == row) || biAVecPos.Exists(x => x == column)) && blOrNot == 1)
                                        {
                                            //means this is a cross-quadratic term
                                            if (crossMatrixCounter == whichCrossMatrix)
                                            {
                                                val = input.CrossTermMatrix[row, column];
                                            }//end conditional to see if this is the cross-term element we want
                                            crossMatrixCounter++;
                                        }
                                    }//end conditional to see if this matrix element is 0
                                }//end loop over columns of cross-term matrix
                            }//end loop over rows of cross-term matrix
                        }//end loop to go through the cross-term matrix twice
                        whichCrossMatrix++;
                    }//end else for counting if it's D / K or cross-Term
                    mat[i].Add(cTimesSparse(fitHamList[i][j], val));
                }//end loop over fitHamList
            }
            //now need to convert the lists of matrices in each mat element into a single object
            //here convert the alglib matrices to the appropriate things.
            for (int i = 0; i < array1.Length; i++)
            {
                array1[i] = aggregator(mat[i]);//some functio to put in aggregate of mat[i] sparsematrices
            }

            //move this to after genFitMatricss are treated so that SO code does not need to be changed
            #region Spin Orbit
            //add SO stuff here
            if (input.IncludeSO == true)
            {
                //Jvecs for output
                //
                //var tempBasisList = new List<List<BasisFunction>>();
                decimal minS = input.S * -1M;
                List<alglib.sparsematrix> tempMatList = new List<alglib.sparsematrix>();
                List<int> tempNumbColumns = new List<int>();

                for (int i = 0; i < array1.Length; i++)
                {
                    for (decimal j = minS; j <= input.S; j++)
                    {
                        alglib.sparsematrix tempMat = new alglib.sparsematrix();
                        alglib.sparsecopy(array1[i], out tempMat);
                        tempMatList.Add(tempMat);
                        if (isQuad)
                        {
                            JvecsForOutuput.Add(jbasisoutA[i]);
                        }
                        else
                        {
                            JvecsForOutuput.Add(jBasisVecsByJ[i]);
                        }
                        //jbasisoutA for quadratic
                        //jBasisVecsByJ for linear
                        //tempBasisList.Add(JvecsForOutuput[i]);
                        for (int k = 0; k < numcolumnsA[i]; k++)
                        {
                            double temp = input.Azeta * (double)JvecsForOutuput[i][k].Lambda * (double)j;
                            alglib.sparseadd(tempMatList[tempMatList.Count - 1], k, k, temp);
                        }//end loop over diagonal matrix elements
                        tempNumbColumns.Add(numcolumnsA[i]);
                        //means SO only in j = 0.5 block for quadratic cases
                        //if (i > 0 && isQuad)
                        //means SO only in degenerate blocks
                        if ((i - 1) % 3 == 0)
                        {
                            break;
                        }
                    }//end loop over values of S
                }//end loop over all previouly made sparseMatrices

                numcolumnsA = null;
                numcolumnsA = tempNumbColumns.ToArray();
                array1 = null;
                array1 = tempMatList.ToArray();
                //JvecsForOutuput.Clear();
                //JvecsForOutuput = tempBasisList;
                zMatrices.Clear();
                eigenvalues.Clear();
                for (int i = 0; i < array1.Length; i++)
                {
                    zMatrices.Add(new double[0, 0]);
                    eigenvalues.Add(new double[0]);
                }
            }//end if inclSO == true
            #endregion

            for (int i = 0; i < array1.Length; i++)
            {
                alglib.sparseconverttocrs(array1[i]);
            }

            #region Seed
            // Makes an Array of List where the first index is Floor(j) and the second index are all elements in the seed vector to be non zero.
            // The Lanczos routine is parallelized by j, and the routine takes the list at [j] to implement the seed vector. Empty list will indicate that no seed is being used.
            var SeedPositionsByJ = new List<int>[GenHamMat.basisPositions.Count];
            var SeedCoefficientsByJ = new List<double>[GenHamMat.basisPositions.Count];
            var isAbyJ = new List<bool>[GenHamMat.basisPositions.Count]; // Array of Lists where the first index is Floor(j) and the second index are booleans indicating A1 (T) or Not A1 (F)
            for (int i = 0; i < GenHamMat.basisPositions.Count; i++)
            {
                SeedPositionsByJ[i] = new List<int>(); // Initialize seed position list for each j
                SeedCoefficientsByJ[i] = new List<double>();
                isAbyJ[i] = new List<bool>();
            }
            if (input.useSeed)
            {
                SeedPositionsByJ = GenerateSeedPositions(input.SeedFile, input.nModes, isQuad, ref SeedCoefficientsByJ);
            }
            #endregion

            #region Lanczos
            int[] IECODE = new int[array1.Length];
            int[] ITER = new int[array1.Length];
            //actually diagonalizes the Hamiltonian matrix
            measurer.Reset();
            measurer.Start();
            //if the evecs of the lanczos matrices will need to be stored then save the lanczos matrices.
            if (input.PrintVector && !input.BlockLanczos && array1[0].innerobj.m >= Lanczos.basisSetLimit)
            {
                lanczosEVectors = new List<double[,]>();
                for (int i = 0; i < array1.Length; i++)
                {
                    lanczosEVectors.Add(new double[0, 0]);
                }
            }
            ParallelOptions options2 = new ParallelOptions();
            options2.MaxDegreeOfParallelism = input.ParJ;
            try
            {
                Parallel.For(0, array1.Length, options2, i =>//changed to array1.count from sHamMatrix.count
                {
                    double[] evs;
                    double[,] temp;
                    IECODE[i] = -1;

                    //add a parameter to count Lanczos iterations to set possible stopping criteria that way
                    //call MINVAL from here
                    if (!input.BlockLanczos)//means use naiveLanczos routine
                    {
                        ITER[i] = input.NumberOfIts;
                        evs = new double[input.M + 1];
                        temp = new double[numcolumnsA[i], input.M + 1];
                        Lanczos.NaiveLanczos(ref evs, ref temp, ref isAbyJ[i], array1[i], input.NumberOfIts, input.Tolerance, input.PrintVector, SeedPositionsByJ[i], SeedCoefficientsByJ[i], i, input.FilePath);
                    }
                    else//means use block Lanczos from SOCJT
                    {
                        evs = new double[input.M + 1];
                        temp = new double[numcolumnsA[i], input.M + 1];//changed here to numcolumnsA
                        IECODE[i] = -1;
                        ITER[i] = Lanczos.MINVAL(numcolumnsA[i], input.M + 1, input.kFactor, input.M, input.NumberOfIts, input.Tolerance, 0, ref evs, ref temp, ref IECODE[i], array1[i], input.ParVectorMultiplication);
                    }

                    //initialize eigenvalues to have a length.
                    eigenvalues[i] = new double[evs.Length - 1];
                    for (int j = 0; j < evs.Length - 1; j++)
                    {
                        eigenvalues[i][j] = evs[j];
                    }
                    //I think this should be only for if block lanczos or naive lanczos with already calculated eigenvectors
                    if (input.BlockLanczos) // || (!input.BlockLanczos && array1[i].innerobj.m * input.NumberOfIts < Lanczos.basisSetLimit)) // I don't know what this second condition is for.
                    {
                        zMatrices[i] = new double[numcolumnsA[i], evs.Length - 1];//changed input.M to evs.Length - 1
                        for (int j = 0; j < numcolumnsA[i]; j++)
                        {
                            for (int k = 0; k < evs.Length - 1; k++)//changed input.M to evs.Length - 1
                            {
                                zMatrices[i][j, k] = temp[j, k];
                            }
                        }
                    }

                    //here if evectors are needed and hamiltonian is too large assign the lanczosEVectors to the
                    if (!input.BlockLanczos && array1[0].innerobj.m >= Lanczos.basisSetLimit && input.PrintVector)
                    {
                        //assign the evecs of the lanczos matrices to the lanczosEVectors list.
                        lanczosEVectors[i] = new double[temp.GetLength(0), temp.GetLength(1)];
                        for (int j = 0; j < temp.GetLength(0); j++)
                        {
                            for (int k = 0; k < temp.GetLength(1); k++)
                            {
                                lanczosEVectors[i][j, k] = temp[j, k];
                            }
                        }
                    }
                    temp = null;
                    evs = null;
                }//end for
                );
            }//end try
            catch (AggregateException ae)
            {
                foreach (var e in ae.InnerExceptions)
                {
                    if (e is RepeaterError)
                    {
                        throw new RepeaterError();
                    }
                    else
                    {
                        throw;
                    }
                }

            }//end catch

            if (input.CheckEigenvector)
            {
                //LanczosChecker(input, array1, zMatrices, eigenvalues);
                int jBlock = (int)(input.JBlockEigenvector.Item1 - 0.5M);
                CheckJohnEigenvector(input, array1[jBlock], eigenvalues[jBlock][input.JBlockEigenvector.Item2 - 1]);
            }

            if (!input.BlockLanczos && array1[0].innerobj.m * input.NumberOfIts >= Lanczos.basisSetLimit && input.PrintVector)
            {
                //make it so that the output file generator does not try to print the values in the zmatrices which will be the eigenvectors of the lanczos matrix, not the hamiltonian
                input.PrintVector = false;
            }

            measurer.Stop();
            howMuchTime = measurer.ElapsedMilliseconds;
            input.DiagonalizationTime = (double)howMuchTime / 1000D;
            #endregion

            if (input.IncludeSO == false)
            {
                if (isQuad == false)
                {
                    JvecsForOutuput = jBasisVecsByJ;
                }//end if
                else
                {
                    for (int i = 0; i < jbasisoutA.Length; i++)
                    {
                        JvecsForOutuput.Add(jbasisoutA[i]);
                    }
                }//end else
            }

            //writes the eigenvectors to disk if that has been requested
            //if NTooBig == true then the separate eigenvector file will be made after the eigenvectors are calculated
            if (input.EVectorFile && (input.BlockLanczos || input.PrintVector))
            {
                writeVecFile(input, zMatrices, JvecsForOutuput, 0.0);
            }//end if

            //put code here to write eigenvectors to file with entire basis set.
            //do this by writing function to use jbasisvecsbyj which has all basis functions and
            //go through that list, where a basis function is in it and JvecsForOutput, pull the appropriate coefficient
            //from the zmatrices, otherwise just put in a 0.
            if (input.VectorFileComplete)
            {
                writeVecComplete(jBasisVecsByJ, JvecsForOutuput, zMatrices, input, eigenvalues, isQuad);
            }

            //this is where the intensity or overlap will be checked if necessary
            var overlaps = new List<double[]>(eigenvalues.Count);
            for (int count = 0; count < eigenvalues.Count; count++)
            {
                overlaps.Add(new double[eigenvalues[count].Length]);
            }

            if (input.Intensity && input.PrintVector)
            {
                //code here to read vector and take dot product
                double[] vector;
                if (input.JSInten)
                {
                    for (int jIndex = 0; jIndex < eigenvalues.Count(); jIndex++)
                    {
                        vector = EigenvectorReader(input.FilePath + input.VectorName, jIndex);
                        Lanczos.normalize(vector);
                        overlaps[jIndex] = Overlap(zMatrices[jIndex], vector);
                    }
                }
                else
                {
                    vector = ReadSOCJT2Vector(input.VectorName, input.VectorIndex, input.VectorJBlock, input.Special);
                    Lanczos.normalize(vector);
                    for (int jIndex = 0; jIndex < eigenvalues.Count(); jIndex++)
                    {
                        if (jIndex == (int)(input.VectorJBlock - 0.5M))
                        {
                            overlaps[jIndex] = Overlap(zMatrices[jIndex], vector);
                        }
                        else
                        {
                            overlaps[jIndex] = new double[zMatrices[jIndex].GetLength(0)];
                        }
                    }
                }
                foreach (double[] overlap in overlaps)
                {
                    Lanczos.normalize(overlap);
                }
            }

            List<string> linesToWrite = new List<string>();
            finalList = setAndSortEVs(eigenvalues, isAbyJ, input.S, input.IncludeSO, zMatrices, JvecsForOutuput, input, overlaps);//add the eigenvectors so that the symmetry can be included as well
            linesToWrite = OutputFile.makeOutput(input, zMatrices, array1, JvecsForOutuput, eigenvalues, isQuad, finalList, IECODE, ITER);
            outp = linesToWrite;
            return linesToWrite;
        }
示例#12
0
文件: SOCJT.cs 项目: Sekie/SOCJT_2
 /// <summary>
 /// Function that reads a matrix file from file and initializes hamiltonian matrices.
 /// </summary>
 /// <param name="input">
 /// initialized FileInfo object.
 /// </param>
 /// <param name="matricesMade">
 /// Set to true if the matrices are generated after this function call.
 /// </param>
 /// <returns>
 /// Boolean indicating whether or not the fitHamList matrices have been initialized from matFile.
 /// </returns>
 private static List<int> matReadFunction(FileInfo input, ref bool matricesMade)
 {
     matricesMade = false;
     List<int> basisSizeList = new List<int>();
     if (input.UseMatrixFile && input.MatrixMade)
     {
         string[] matFile = { };
         try
         {
             matFile = FileInfo.FileRead(input.MatrixFilePath);
         }
         catch (FileNotFoundException)
         {
             throw new FileNotFoundException("The matrix file does not exist.");
         }
         catch
         {
             throw new Exception("Matrix File Error." + "\r" + "Please check the matrix file and try again.");
         }
         matricesMade = true;
         //read the matrix into memory
         int index = 0, basisSize = 0;
         for (int i = 0; i < matFile.Length; i++)
         {
             if (matFile[i] == "List")
             {
                 index = Convert.ToInt32(matFile[i + 1]);
                 basisSize = Convert.ToInt32(matFile[i + 2]);
                 basisSizeList.Add(basisSize);
                 //this is the matrix for the diagonal elements.  These are added seperately.
                 var B = new alglib.sparsematrix();
                 alglib.sparsecreate(basisSize, basisSize, out B);
                 fitHamList[index].Add(B);
                 continue;
             }//end if matFile[i] == List
             if (matFile[i] == "Matrix")
             {
                 var B = new alglib.sparsematrix();
                 alglib.sparsecreate(basisSize, basisSize, out B);
                 i += 2;
                 while (matFile[i] != "List" && matFile[i] != "Matrix")
                 {
                     alglib.sparseadd(B, Convert.ToInt32(matFile[i]), Convert.ToInt32(matFile[i + 1]), FileInfo.ParseDouble(matFile[i + 2]));
                     i += 3;
                     if (i >= matFile.Length)
                     {
                         break;
                     }
                 }
                 i--;
                 fitHamList[index].Add(B);
             }//end if matFile[i] == Matrix
         }//end for loop over entire matrix file
     }//end if
     //return matricesMade;
     return basisSizeList;
 }
示例#13
0
文件: SOCJT.cs 项目: Sekie/SOCJT_2
 /// <summary>
 /// Used to multiply all elements in a sparse matrix A by the value val
 /// </summary>
 /// <param name="A">
 /// Sparse matrix to be multiplied.
 /// </param>
 /// <param name="val">
 /// Value to be multiplied
 /// </param>
 /// <returns>
 /// Sparesmatrix containing the original matrix A times the double val.
 /// </returns>
 private static alglib.sparsematrix cTimesSparse(alglib.sparsematrix A, double val)
 {
     int i;
     int j;
     double oldVal;
     int t0 = 0;
     int t1 = 0;
     alglib.sparsematrix B = new alglib.sparsematrix();
     alglib.sparsecreate(A.innerobj.m, A.innerobj.n, out B);
     while (alglib.sparseenumerate(A, ref t0, ref t1, out i, out j, out oldVal))
     {
         alglib.sparseadd(B, i, j, oldVal * val);
     }
     return B;
 }
示例#14
0
        /// <summary>
        /// Generates an alglib sparsematrix object to be used in Lanczos diagonalization.
        /// </summary>
        /// <param name="basisVectorsByJ">
        /// List of JBasisVectors sorted by J.
        /// </param>
        /// <param name="isQuad">
        /// True means a quadratic basis set is used and quadratic terms will be calculated.
        /// </param>
        /// <param name="input">
        /// FileInfo object containing input information.
        /// </param>
        /// <param name="nColumns">
        /// Integer with order of A.
        /// </param>
        /// <param name="Large">
        /// boolean value so that genMatrix method could be overloaded.
        /// </param>
        /// <returns></returns>
        public static alglib.sparsematrix genMatrix(List<JBasisVector> basisVectorsByJ, bool isQuad, FileInfo input, out int nColumns, bool Large, int par)
        {
            int matSize = basisVectorsByJ.Count;
            nColumns = matSize;
            int r = 0;
            double temp = 0;

            alglib.sparsematrix A = new alglib.sparsematrix();
            alglib.sparsecreate(matSize, matSize, 10, out A);
            bool containsAVecs = false;
            List<int> AVecPos = new List<int>();
            List<int> EVecPos = new List<int>();
            List<int> biAVecPos = new List<int>();
            List<int> biEVecPos = new List<int>();
            int[] change = new int[3];

            #region CrossTermInitializationStuff
            if (input.includeCrossTerms == true)
            {

                for (int i = 0; i < input.nModes; i++)
                {
                    if (basisVectorsByJ[0].modesInVec[i].symmetryIsA == true)
                    {
                        AVecPos.Add(i);
                        containsAVecs = true;
                        continue;
                    }
                    else
                    {
                        EVecPos.Add(i);
                    }
                }//end for

                //for bilinear coupling
                if (containsAVecs == true)
                {
                    //new lists just for bilinear coupling
                    biAVecPos = AVecPos;
                    biEVecPos = EVecPos;
                    //loop to eliminate any A vectors that have no cross-coupling
                    for (int i = 0; i < biAVecPos.Count; i++)
                    {
                        for (int j = 0; j < biEVecPos.Count; j++)
                        {
                            if (biAVecPos[i] > biEVecPos[j])
                            {
                                if (input.crossTermMatrix[biEVecPos[j], biAVecPos[i]] != 0)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (input.crossTermMatrix[biAVecPos[i], biEVecPos[j]] != 0)
                                {
                                    break;
                                }
                            }
                            if (j == biEVecPos.Count - 1)
                            {
                                biAVecPos.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }

                    //loop to eliminate any E vectors that have no cross-coupling
                    for (int i = 0; i < biEVecPos.Count; i++)
                    {
                        for (int j = 0; j < biAVecPos.Count; j++)
                        {
                            if (biAVecPos[j] > biEVecPos[i])
                            {
                                if (input.crossTermMatrix[biEVecPos[i], biAVecPos[j]] != 0)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                if (input.crossTermMatrix[biAVecPos[j], biEVecPos[i]] != 0)
                                {
                                    break;
                                }
                            }
                            if (j == biAVecPos.Count - 1)
                            {
                                biEVecPos.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }

                //stuff for cross quadratic
                for (int i = 0; i < EVecPos.Count; i++)
                {
                    for (int j = i + 1; j < EVecPos.Count; j++)
                    {
                        if (input.crossTermMatrix[EVecPos[i], EVecPos[j]] != 0)
                        {
                            break;
                        }
                        if (j == EVecPos.Count - 1)
                        {
                            EVecPos.RemoveAt(i);
                            i--;
                            break;
                        }
                    }
                }
            }//end if CrossTerms == true
            #endregion

            //generates the Hamiltonian Matrix

            //this checks to make sure that any cross anharmonic terms are only between two A type modes
            if (input.includeCrossTerms == true)
            {
                for (int i = 1; i < input.nModes; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        if (input.crossTermMatrix[i, j] > 0.0000001 || input.crossTermMatrix[i, j] < -0.0000001)
                        {
                            if (basisVectorsByJ[0].modesInVec[i].symmetryIsA == false || basisVectorsByJ[0].modesInVec[j].symmetryIsA == false)
                            {
                                throw new AEAnharmonicTermException();
                            }
                        }
                    }
                }
            }

            //just the HO terms
            if (input.AT == true)
            {
                for (int n = 0; n < matSize; n++)
                {
                    #region HO Terms + Cross
                    //one mode harmonic and anharmonic terms
                    for (int i = 0; i < input.nModes; i++)
                    {
                        int degeneracy = 2;
                        if (basisVectorsByJ[n].modesInVec[i].symmetryIsA)
                        {
                            degeneracy = 1;
                        }
                        temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].v + (double)degeneracy / 2D) - basisVectorsByJ[n].modesInVec[i].anharmonicity * Math.Pow((basisVectorsByJ[n].modesInVec[i].v + (double)degeneracy / 2), 2);//I deleted the (double) from the degeneracy / 2
                        alglib.sparseadd(A, n, n, temp);//changed from (A, n, m, temp)
                        temp = 0;
                    }

                    //Not wrong, just incomplete.  These are the diagonal terms.  Off diagonal terms are later.

                    //cross anharmonic terms
                    if (input.AT == true)
                    {
                        for (int i = 1; i < input.nModes; i++)
                        {
                            for (int j = 0; j < i; j++)
                            {
                                if (input.crossTermMatrix[i, j] > 0.0000001 || input.crossTermMatrix[j, i] < -0.0000001)
                                {
                                    //added the *4 to this
                                    temp = input.crossTermMatrix[i, j] * 4D * ((double)basisVectorsByJ[n].modesInVec[i].v + (double)1 / 2) * ((double)basisVectorsByJ[n].modesInVec[j].v + (double)1 / 2);//took off the -1
                                    alglib.sparseadd(A, n, n, temp);//changed from (A, n, m, temp)
                                    temp = 0;
                                }//end if
                            }//end j for loop
                        }//end i for loop
                    }//end if AT == true
                    continue;
                    #endregion
                }
            }//end for if AT = true

            else
            {
                for (int n = 0; n < matSize; n++)
                {
                    #region HO Terms
                    //one mode harmonic and anharmonic terms
                    for (int i = 0; i < input.nModes; i++)
                    {
                        int degeneracy = 2;
                        if (basisVectorsByJ[n].modesInVec[i].symmetryIsA)
                        {
                            degeneracy = 1;
                        }
                        temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].v + (double)degeneracy / 2D) - basisVectorsByJ[n].modesInVec[i].anharmonicity * Math.Pow((basisVectorsByJ[n].modesInVec[i].v + (double)degeneracy / 2), 2);//I deleted the (double) from the degeneracy / 2
                        alglib.sparseadd(A, n, n, temp);//changed from (A, n, m, temp)
                        temp = 0;
                    }//end if AT == true
                    continue;
                    #endregion
                }
            }

            //now the JT terms

            //Parallel.For(0, par, hh =>
                //{
                    //for (int n = hh * (matSize / par); n < ((hh + 1) * matSize) / par; n++)
                    for(int n = 0; n < matSize; n++)
                    {
                        for (int m = n + 1; m < matSize; m++)//changed from r + 1
                        {
                            //double temp;
                            int numberOfChanges = modeChangeCounter(basisVectorsByJ, input.nModes, n, m);

                            //makes it skip any places where matrix elements are 0.
                            if (numberOfChanges > 2)
                            {
                                continue;
                            }

                            //indexes n and m are for the rows and columns of the matrix respectively
                            if (basisVectorsByJ[n].Lambda == basisVectorsByJ[m].Lambda && input.Special == false && input.AT == false)//checks to see if it can have an off diagonal term
                            {
                                continue;
                            }

                            if (input.Special == true && numberOfChanges <= 2 && basisVectorsByJ[n].Lambda == basisVectorsByJ[m].Lambda)
                            {
                                #region Special
                                if (numberOfChanges == 1)
                                {
                                    if (basisVectorsByJ[n].modesInVec[0].v + 1 == basisVectorsByJ[m].modesInVec[0].v)
                                    {
                                        temp = input.crossTermMatrix[0, 0] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[0].v + 1D) * (2D * (double)basisVectorsByJ[n].modesInVec[1].v + 1D);//mode two stuff
                                        alglib.sparseadd(A, n, m, temp);
                                        alglib.sparseadd(A, m, n, temp);
                                        temp = 0;
                                        continue;
                                    }
                                    /*
                                    if (basisVectorsByJ[n].modesInVec[0].v - 1 == basisVectorsByJ[m].modesInVec[0].v)
                                    {
                                        temp = input.crossTermMatrix[0, 0] * Math.Sqrt(basisVectorsByJ[n].modesInVec[0].modeOmega * (double)basisVectorsByJ[n].modesInVec[0].v) * basisVectorsByJ[n].modesInVec[1].modeOmega * (2D * (double)basisVectorsByJ[n].modesInVec[1].v + 1D);//mode two stuff
                                        alglib.sparseadd(A, n, m, temp);
                                        temp = 0;
                                        continue;
                                    }
                                    */
                                }
                                if (numberOfChanges == 2)
                                {
                                    if (basisVectorsByJ[n].modesInVec[0].v + 1 == basisVectorsByJ[m].modesInVec[0].v)
                                    {
                                        /*
                                        if (basisVectorsByJ[n].modesInVec[1].v - 2 == basisVectorsByJ[m].modesInVec[1].v)
                                        {
                                            temp = input.crossTermMatrix[0, 0] * Math.Sqrt(basisVectorsByJ[n].modesInVec[0].modeOmega * (double)basisVectorsByJ[n].modesInVec[0].v + 1D) * basisVectorsByJ[n].modesInVec[1].modeOmega * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[1].v - 1D) * (double)basisVectorsByJ[n].modesInVec[1].v);
                                            alglib.sparseadd(A, n, m, temp);
                                            temp = 0;
                                            continue;
                                        }
                                        */
                                        if (basisVectorsByJ[n].modesInVec[1].v + 2 == basisVectorsByJ[m].modesInVec[1].v)
                                        {
                                            temp = input.crossTermMatrix[0, 0] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[0].v + 1D) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[1].v + 2D) * ((double)basisVectorsByJ[n].modesInVec[1].v + 1D));
                                            alglib.sparseadd(A, n, m, temp);
                                            alglib.sparseadd(A, m, n, temp);
                                            temp = 0;
                                            continue;
                                        }
                                    }
                                    if (basisVectorsByJ[n].modesInVec[0].v - 1 == basisVectorsByJ[m].modesInVec[0].v)
                                    {
                                        if (basisVectorsByJ[n].modesInVec[1].v + 2 == basisVectorsByJ[m].modesInVec[1].v)
                                        {
                                            temp = input.crossTermMatrix[0, 0] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[0].v) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[1].v + 2D) * ((double)basisVectorsByJ[n].modesInVec[1].v + 1D));
                                            alglib.sparseadd(A, n, m, temp);
                                            alglib.sparseadd(A, m, n, temp);
                                            temp = 0;
                                            continue;
                                        }
                                        /*
                                        if (basisVectorsByJ[n].modesInVec[1].v - 2 == basisVectorsByJ[m].modesInVec[1].v)
                                        {
                                            temp = input.crossTermMatrix[0, 0] * Math.Sqrt(basisVectorsByJ[n].modesInVec[0].modeOmega * (double)basisVectorsByJ[n].modesInVec[0].v) * basisVectorsByJ[n].modesInVec[1].modeOmega * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[1].v - 1D) * (double)basisVectorsByJ[n].modesInVec[1].v);
                                            alglib.sparseadd(A, n, m, temp);
                                            temp = 0;
                                            continue;
                                        }
                                        */
                                    }

                                    continue;
                                }
                                #endregion
                            }

                            if (input.AT == true && basisVectorsByJ[n].Lambda == basisVectorsByJ[m].Lambda && numberOfChanges <= 2)
                            {
                                #region Cross-AT
                                //also, add an exception so that if one of these modes is an e type mode it throws an error
                                for (int i = 1; i < input.nModes; i++)//rows
                                {
                                    for (int j = 0; j < i; j++)//columns
                                    {
                                        if (input.crossTermMatrix[i, j] > 0.0000001 || input.crossTermMatrix[i, j] < -0.00000001)
                                        {
                                            if (basisVectorsByJ[n].modesInVec[i].v + 2 == basisVectorsByJ[m].modesInVec[i].v)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[j].v + 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v + 3D * (double)basisVectorsByJ[n].modesInVec[i].v + 2D) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v + 3D * (double)basisVectorsByJ[n].modesInVec[j].v + 2D);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                                if (basisVectorsByJ[n].modesInVec[j].v == basisVectorsByJ[m].modesInVec[j].v && numberOfChanges == 1)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v + 3D * (double)basisVectorsByJ[n].modesInVec[i].v + 2D) * 2D * ((double)basisVectorsByJ[n].modesInVec[j].v + 0.5);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                                if (basisVectorsByJ[n].modesInVec[j].v - 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v + 3D * (double)basisVectorsByJ[n].modesInVec[i].v + 2D) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v - (double)basisVectorsByJ[n].modesInVec[j].v);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                            }
                                            if (basisVectorsByJ[n].modesInVec[i].v == basisVectorsByJ[m].modesInVec[i].v && numberOfChanges == 1)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[j].v + 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * 2D * ((double)basisVectorsByJ[n].modesInVec[i].v + 0.5) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v + 3D * (double)basisVectorsByJ[n].modesInVec[j].v + 2D);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                                /*
                                                if (basisVectorsByJ[n].modesInVec[j].v == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * 4D * ((double)basisVectorsByJ[n].modesInVec[i].v + 0.5) * ((double)basisVectorsByJ[n].modesInVec[j].v + 0.5);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    temp = 0;
                                                }
                                                */
                                                if (basisVectorsByJ[n].modesInVec[j].v - 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * 2D * ((double)basisVectorsByJ[n].modesInVec[i].v + 0.5) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v - (double)basisVectorsByJ[n].modesInVec[j].v);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                            }
                                            if (basisVectorsByJ[n].modesInVec[i].v - 2 == basisVectorsByJ[m].modesInVec[i].v)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[j].v + 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v - (double)basisVectorsByJ[n].modesInVec[i].v) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v + 3D * (double)basisVectorsByJ[n].modesInVec[j].v + 2D);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                                if (basisVectorsByJ[n].modesInVec[j].v == basisVectorsByJ[m].modesInVec[j].v && numberOfChanges == 1)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v - (double)basisVectorsByJ[n].modesInVec[i].v) * 2D * ((double)basisVectorsByJ[n].modesInVec[j].v + 0.5);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                                if (basisVectorsByJ[n].modesInVec[j].v - 2 == basisVectorsByJ[m].modesInVec[j].v)
                                                {
                                                    temp = input.crossTermMatrix[i, j] * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[i].v * (double)basisVectorsByJ[n].modesInVec[i].v - (double)basisVectorsByJ[n].modesInVec[i].v) * Math.Sqrt((double)basisVectorsByJ[n].modesInVec[j].v * (double)basisVectorsByJ[n].modesInVec[j].v - (double)basisVectorsByJ[n].modesInVec[j].v);
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }
                                            }
                                            //go through possible nonzero terms
                                        }
                                    }
                                }
                                #endregion
                            }

                            //calculate JT terms
                            if (numberOfChanges == 1)//changed this to one from zero
                            {
                                for (int i = 0; i < input.nModes; i++)
                                {
                                    if (basisVectorsByJ[n].modesInVec[i].v == basisVectorsByJ[m].modesInVec[i].v && basisVectorsByJ[n].modesInVec[i].l == basisVectorsByJ[m].modesInVec[i].l)
                                    {
                                        continue;
                                    }//this just makes it skip the extra conditionals if it's not the mode with the potential JT term
                                    #region linear terms
                                    if (basisVectorsByJ[n].modesInVec[i].v + 1 == basisVectorsByJ[m].modesInVec[i].v && basisVectorsByJ[n].modesInVec[i].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[i].l)
                                    {
                                        temp = basisVectorsByJ[n].modesInVec[i].modeOmega * Math.Sqrt(basisVectorsByJ[n].modesInVec[i].DBasis * ((double)basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[i].l + 2D));
                                        alglib.sparseadd(A, n, m, temp);
                                        alglib.sparseadd(A, m, n, temp);
                                        temp = 0;
                                        break;//I think I can do this
                                    }//end first if
                                    if (basisVectorsByJ[n].modesInVec[i].v + 1 == basisVectorsByJ[m].modesInVec[i].v && basisVectorsByJ[n].modesInVec[i].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[i].l)
                                    {
                                        temp = basisVectorsByJ[n].modesInVec[i].modeOmega * Math.Sqrt(basisVectorsByJ[n].modesInVec[i].DBasis * ((double)basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[i].l + 2D));
                                        alglib.sparseadd(A, n, m, temp);
                                        alglib.sparseadd(A, m, n, temp);
                                        temp = 0;
                                        break;
                                    }//end second if

                                    //I don't think this code is ever used since I only have the upper triangle of the matrix being used
                                    /*
                                    if (basisVectorsByJ[n].modesInVec[i].v - 1 == basisVectorsByJ[m].modesInVec[i].v && basisVectorsByJ[n].modesInVec[i].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[i].l)
                                    {
                                        matrix[n, m] += basisVectorsByJ[n].modesInVec[i].modeOmega * Math.Sqrt(basisVectorsByJ[n].modesInVec[i].DBasis * ((double)basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[i].l));//don't think this 2 should be here
                                        break;
                                    }//end third if
                                    if (basisVectorsByJ[n].modesInVec[i].v - 1 == basisVectorsByJ[m].modesInVec[i].v && basisVectorsByJ[n].modesInVec[i].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[i].l)
                                    {
                                        matrix[n, m] += basisVectorsByJ[n].modesInVec[i].modeOmega * Math.Sqrt(basisVectorsByJ[n].modesInVec[i].DBasis * ((double)basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[i].l));//don't think this 2 should be here
                                        break;
                                    }//end fourth if
                                    */
                                    #endregion
                                    if (isQuad == true)
                                    {
                                        #region quadratic terms
                                        if (basisVectorsByJ[n].modesInVec[i].v - 2 == basisVectorsByJ[m].modesInVec[i].v)
                                        {

                                            if (basisVectorsByJ[n].modesInVec[i].l + 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 4D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l) * (basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l - 2)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for top terms in +/-
                                            if (basisVectorsByJ[n].modesInVec[i].l - 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 4D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l) * (basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l - 2)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for bottom terms in +/-
                                            break;
                                        }//end if for top quadratic term (1 of 3)

                                        if (basisVectorsByJ[n].modesInVec[i].v == basisVectorsByJ[m].modesInVec[i].v)
                                        {
                                            if (basisVectorsByJ[n].modesInVec[i].l + 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 2D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 2) * (basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for top terms in +/-
                                            if (basisVectorsByJ[n].modesInVec[i].l - 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 2D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 2) * (basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for bottom terms in +/-
                                            break;
                                        }//end if for top quadratic term (2 of 3)

                                        if (basisVectorsByJ[n].modesInVec[i].v + 2 == basisVectorsByJ[m].modesInVec[i].v)
                                        {

                                            if (basisVectorsByJ[n].modesInVec[i].l + 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 4D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 4D) * (basisVectorsByJ[n].modesInVec[i].v + Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 2)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for top terms in +/-
                                            if (basisVectorsByJ[n].modesInVec[i].l - 2 * Math.Pow(-1D, input.S2) == basisVectorsByJ[m].modesInVec[i].l)
                                            {
                                                temp = basisVectorsByJ[n].modesInVec[i].modeOmega * (basisVectorsByJ[n].modesInVec[i].KBasis / 4D * Math.Sqrt((basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 4D) * (basisVectorsByJ[n].modesInVec[i].v - Math.Pow(-1, input.S2) * basisVectorsByJ[n].modesInVec[i].l + 2)));
                                                alglib.sparseadd(A, n, m, temp);
                                                alglib.sparseadd(A, m, n, temp);
                                                temp = 0;
                                            }//end if for bottom terms in +/-
                                            break;
                                        }//end if for top quadratic term (3 of 3)
                                        #endregion
                                    }//end if
                                }//end for loop
                            }//end of JT terms part

                            #region Cross Terms
                            if (input.includeCrossTerms == true && numberOfChanges == 2)
                            {
                                //bilinear stuff
                                if (containsAVecs == true)
                                {
                                    #region Bilinear
                                    for (int a = 0; a < biAVecPos.Count; a++)
                                    {
                                        for (int e = 0; e < biEVecPos.Count; e++)
                                        {
                                            int row;
                                            int column;
                                            if (biAVecPos[a] > biEVecPos[e])
                                            {
                                                column = biAVecPos[a];
                                                row = biEVecPos[e];
                                            }
                                            else
                                            {
                                                column = biEVecPos[e];
                                                row = biAVecPos[a];
                                            }
                                            if (basisVectorsByJ[n].modesInVec[biAVecPos[a]].v + 1 == basisVectorsByJ[m].modesInVec[biAVecPos[a]].v)
                                            {
                                                ////*
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v + 1D) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;//I think I can do this
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v + 1D) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                //*/
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v + 1D) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v + 1D) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                            }
                                            if (basisVectorsByJ[n].modesInVec[biAVecPos[a]].v - 1 == basisVectorsByJ[m].modesInVec[biAVecPos[a]].v)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;//I think I can do this
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                ////*
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l - (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v + Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - 1 == basisVectorsByJ[m].modesInVec[biEVecPos[e]].v && basisVectorsByJ[n].modesInVec[biEVecPos[e]].l + (int)Math.Pow(-1D, (double)input.S1) == basisVectorsByJ[m].modesInVec[biEVecPos[e]].l)
                                                {
                                                    temp = input.crossTermMatrix[row, column] * Math.Sqrt(basisVectorsByJ[n].modesInVec[biAVecPos[a]].modeOmega * basisVectorsByJ[n].modesInVec[biEVecPos[e]].modeOmega) * Math.Sqrt(((double)basisVectorsByJ[n].modesInVec[biAVecPos[a]].v) * ((double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].v - Math.Pow(-1D, (double)input.S1) * (double)basisVectorsByJ[n].modesInVec[biEVecPos[e]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                                //*/
                                            }
                                            //if statements for A mode with if statements for e mode within

                                            //here is where to put the if conditions for the matrix
                                        }
                                    }
                                    #endregion
                                }//end bilinear stuff

                                if (EVecPos.Count > 1)
                                {
                                    #region Cross-Quadratic
                                    int ps = -1;
                                    if (input.S1 == 0)
                                    {
                                        ps = 1;
                                    }
                                    for (int i = 0; i < EVecPos.Count; i++)
                                    {
                                        for (int j = i + 1; j < EVecPos.Count; j++)
                                        {
                                            if (basisVectorsByJ[n].modesInVec[EVecPos[i]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[i]].v && basisVectorsByJ[n].modesInVec[EVecPos[i]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[i]].l)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                            }//end first if
                                            if (basisVectorsByJ[n].modesInVec[EVecPos[i]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[i]].v && basisVectorsByJ[n].modesInVec[EVecPos[i]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[i]].l)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l + 2D)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                            }//end second if
                                            if (basisVectorsByJ[n].modesInVec[EVecPos[i]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[i]].v && basisVectorsByJ[n].modesInVec[EVecPos[i]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[i]].l)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                            }//end third if
                                            if (basisVectorsByJ[n].modesInVec[EVecPos[i]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[i]].v && basisVectorsByJ[n].modesInVec[EVecPos[i]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[i]].l)
                                            {
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end first if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v + 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l + 2D));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end second if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l - ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v + (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end third if
                                                if (basisVectorsByJ[n].modesInVec[EVecPos[j]].v - 1 == basisVectorsByJ[m].modesInVec[EVecPos[j]].v && basisVectorsByJ[n].modesInVec[EVecPos[j]].l + ps == basisVectorsByJ[m].modesInVec[EVecPos[j]].l)
                                                {
                                                    temp = input.crossTermMatrix[EVecPos[i], EVecPos[j]] * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[i]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[i]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[i]].l)) * Math.Sqrt(basisVectorsByJ[n].modesInVec[EVecPos[j]].modeOmega * ((double)basisVectorsByJ[n].modesInVec[EVecPos[j]].v - (double)ps * (double)basisVectorsByJ[n].modesInVec[EVecPos[j]].l));
                                                    alglib.sparseadd(A, n, m, temp);
                                                    alglib.sparseadd(A, m, n, temp);
                                                    temp = 0;
                                                    continue;
                                                }//end fourth if
                                            }//end fourth if
                                        }
                                    }
                                    #endregion
                                }//end Cross-quadratic

                            }//end if CrossTerms = true
                            #endregion

                        }//column for loop
                        r++;
                    }//row for loop
                //}
            //);//end parallel for

            //end the parallel loop here

            alglib.sparseconverttocrs(A);
            return A;
        }