Пример #1
0
        public static double GetSprTensor(Vector[] coords, HessMatrix hess, int atm1, int atm2, IList <int> atms, ILinAlg ila)
        {
            HDebug.Assert(atms.Count == atms.HUnion().Length);

            int[] idxs = atms.HUnion();
            idxs = idxs.HRemoveAll(atm1);
            idxs = idxs.HRemoveAll(atm2);
            idxs = idxs.HInsert(0, atm2);
            idxs = idxs.HInsert(0, atm1);
            HDebug.Assert(idxs.HExcept(atms).HExcept(atm1, atm2).Length == 0);
            HDebug.Assert(idxs[0] == atm1);
            HDebug.Assert(idxs[1] == atm2);

            HessMatrix H = hess.ReshapeByAtom(idxs);

            H = Hess.GetHessFixDiag(H);
            HDebug.Assert(H.ColSize == H.RowSize, H.RowSize == idxs.Length * 3);
            // H should have 6 zero eigenvalues !!
            // since it is the original hessian matrix.

            Vector u12 = (coords[atm2] - coords[atm1]).UnitVector();
            Matrix S12 = Matrix.Zeros(idxs.Length * 3, 6);

            for (int i = 0; i < 6; i++)
            {
                S12[i, i] = 1;
            }

            Matrix invkij = GetInvSprTensorSymm(H, S12, ila);

            HDebug.Assert(invkij.ColSize == 1, invkij.RowSize == 1);
            HDebug.Assert(invkij[0, 0] > 0);

            double kij = 1 / invkij[0, 0];

            return(kij);
        }
Пример #2
0
        public static double GetSprScalar(Vector[] coords, HessMatrix hess, int atm1, int atm2, IList <int> atms, ILinAlg ila)
        {
            HDebug.Assert(atms.Count == atms.HUnion().Length);

            int[] idxs = atms.HUnion();
            idxs = idxs.HRemoveAll(atm1);
            idxs = idxs.HRemoveAll(atm2);
            idxs = idxs.HInsert(0, atm2);
            idxs = idxs.HInsert(0, atm1);
            HDebug.Assert(idxs.HExcept(atms).HExcept(atm1, atm2).Length == 0);
            HDebug.Assert(idxs[0] == atm1);
            HDebug.Assert(idxs[1] == atm2);

            HessMatrix H = hess.ReshapeByAtom(idxs);

            H = Hess.GetHessFixDiag(H);
            HDebug.Assert(H.ColSize == H.RowSize, H.RowSize == idxs.Length * 3);
            // H should have 6 zero eigenvalues !!
            // since it is the original hessian matrix.

            // return "0" spring if there is no connect between atm1 and atm2
            {
                Graph <int, object> g = new Graph <int, object>();
                for (int i = 0; i < H.ColBlockSize; i++)
                {
                    g.AddNode(i);
                }
                foreach (var bc_br_bval in H.EnumBlocks())
                {
                    int bc = bc_br_bval.Item1;
                    int br = bc_br_bval.Item2;
                    if (bc > br)
                    {
                        continue;
                    }
                    g.AddEdge(bc, br, new object());
                    //g.AddEdge(br, bc, new object()); // g is bi-directional graph
                }
                var paths = g.FindPathShortest(g.GetNode(0), new Graph <int, object> .Node[] { g.GetNode(1) });
                if (paths == null)
                {
                    // if there is no path between 0 <-> 1, then there is no spring
                    return(0);
                }
            }

            Vector u12 = (coords[atm2] - coords[atm1]).UnitVector();
            Matrix S12 = new double[idxs.Length * 3, 1];

            S12[0, 0] = u12[0];    S12[1, 0] = u12[1];    S12[2, 0] = u12[2];
            S12[3, 0] = -u12[0];    S12[4, 0] = -u12[1];    S12[5, 0] = -u12[2];

            Matrix invkij = GetInvSprTensorSymm(H, S12, ila);

            HDebug.Assert(invkij.ColSize == 1, invkij.RowSize == 1);
            HDebug.Assert(invkij[0, 0] > 0);

            double kij = 1 / invkij[0, 0];

            return(kij);
        }