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