public void GetPotentialBuildHessian(Vector[] coords, MatrixByArr[,] hess, ref MatrixByArr hessian) { int size = coords.GetLength(0); for (int c = 0; c < size * 3; c++) { for (int r = 0; r < size * 3; r++) { hessian[c, r] = hess[c / 3, r / 3][c % 3, r % 3]; } } hessian = (hessian + hessian.Tr()) / 2; for (int i = 0; i < size; i++) { hessian[i * 3 + 0, i *3 + 0] = 0; hessian[i * 3 + 0, i *3 + 1] = 0; hessian[i * 3 + 0, i *3 + 2] = 0; hessian[i * 3 + 1, i *3 + 0] = 0; hessian[i * 3 + 1, i *3 + 1] = 0; hessian[i * 3 + 1, i *3 + 2] = 0; hessian[i * 3 + 2, i *3 + 0] = 0; hessian[i * 3 + 2, i *3 + 1] = 0; hessian[i * 3 + 2, i *3 + 2] = 0; int c = i; for (int r = 0; r < size; r++) { hessian[i * 3 + 0, i *3 + 0] -= hessian[c * 3 + 0, r *3 + 0]; hessian[i * 3 + 0, i *3 + 1] -= hessian[c * 3 + 0, r *3 + 1]; hessian[i * 3 + 0, i *3 + 2] -= hessian[c * 3 + 0, r *3 + 2]; hessian[i * 3 + 1, i *3 + 0] -= hessian[c * 3 + 1, r *3 + 0]; hessian[i * 3 + 1, i *3 + 1] -= hessian[c * 3 + 1, r *3 + 1]; hessian[i * 3 + 1, i *3 + 2] -= hessian[c * 3 + 1, r *3 + 2]; hessian[i * 3 + 2, i *3 + 0] -= hessian[c * 3 + 2, r *3 + 0]; hessian[i * 3 + 2, i *3 + 1] -= hessian[c * 3 + 2, r *3 + 1]; hessian[i * 3 + 2, i *3 + 2] -= hessian[c * 3 + 2, r *3 + 2]; } } }
public static double[] GetRotAngles(Universe univ , Vector[] coords , Vector[] dcoords , Func <Vector, MatrixByArr> Diag , Func <MatrixByArr, MatrixByArr> InvSymm , Func <MatrixByArr, MatrixByArr, MatrixByArr, MatrixByArr> Mul , MatrixByArr J = null , Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = null , List <Universe.RotableInfo> univ_rotinfos = null , Vector[] dcoordsRotated = null ) { if (J == null) { if (univ_rotinfos == null) { if (univ_flexgraph == null) { univ_flexgraph = univ.BuildFlexibilityGraph(); } univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); } J = TNM.GetJ(univ, coords, univ_rotinfos); } Vector dangles; { Vector R = Vector.FromBlockvector(dcoords); MatrixByArr M = Diag(univ.GetMasses(3)); MatrixByArr Jt = J.Tr(); MatrixByArr invJMJ = InvSymm(Mul(Jt, M, J)); Vector A = LinAlg.MV(Mul(invJMJ, Jt, M), R); // (6) of TNM paper dangles = A; if (dcoordsRotated != null) { HDebug.Assert(dcoordsRotated.Length == dcoords.Length); Vector dR = LinAlg.MV(J, A); Vector ldcoordsRotated = dR; HDebug.Assert(ldcoordsRotated.Size == dcoordsRotated.Length * 3); for (int i = 0; i < dcoordsRotated.Length; i++) { int i3 = i * 3; dcoordsRotated[i] = new double[] { ldcoordsRotated[i3 + 0], ldcoordsRotated[i3 + 1], ldcoordsRotated[i3 + 2] }; } } } if (HDebug.IsDebuggerAttached) { Vector tdangles = GetRotAngles(univ, coords, dcoords, J, univ_flexgraph, univ_rotinfos); HDebug.Assert(0.9999 < (tdangles.Dist / dangles.Dist), (tdangles.Dist / dangles.Dist) < 1.0001); HDebug.Assert(LinAlg.DotProd(tdangles, dangles) / (tdangles.Dist * dangles.Dist) > 0.9999); HDebug.Assert((tdangles - dangles).Dist / tdangles.Dist < 0.0001); } return(dangles); }
public static MatrixByArr[,] GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos, Func <MatrixByArr, MatrixByArr> fnInv3x3 = null) { if (fnInv3x3 == null) { fnInv3x3 = delegate(MatrixByArr A) { using (new Matlab.NamedLock("GetJ")) { return(LinAlg.Inv3x3(A)); } } } ; MatrixByArr I = GetITa(univ.atoms.ToArray(), coords); MatrixByArr invI = fnInv3x3(I); Vector R = GetRa(univ.atoms.ToArray(), coords); double M = GetMa(univ.atoms.ToArray()); Vector MR = GetMaRa(univ.atoms.ToArray(), coords); MatrixByArr MRx = GetSSMatrix(MR); MatrixByArr MRxt = MRx.Tr(); MatrixByArr III = I - (1.0 / M) * MRx * MRxt; // { MI - 1/M * [MR]x * [MR]x^t } MatrixByArr invIII = fnInv3x3(III); //Vector MMR = GetMaMaRa(univ.atoms.ToArray()); int n = univ.atoms.Count; int m = rotInfos.Count; MatrixByArr[,] J = new MatrixByArr[n, m]; for (int a = 0; a < m; a++) { RotableInfo rotInfo = rotInfos[a]; Vector Ra = GetRa(rotInfo.rotAtoms, coords); double Ma = GetMa(rotInfo.rotAtoms); Vector MaRa = GetMaRa(rotInfo.rotAtoms, coords); MatrixByArr Ia = GetITa(rotInfo.rotAtoms, coords); HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom)); Vector sa = coords[rotInfo.bondedAtom.ID]; //Vector Sa = sa * rotInfos[a].rotAtoms.Length; Vector ea; { HashSet <Atom> bondatoms = new HashSet <Atom>(rotInfo.bond.atoms); bondatoms.Remove(rotInfo.bondedAtom); HDebug.Assert(bondatoms.Count == 1); HDebug.Assert(rotInfo.rotAtoms.Contains(bondatoms.First()) == false); ea = (sa - coords[bondatoms.First().ID]).UnitVector(); } Vector Aa; { Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa); Vector IAa = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa); Aa = LinAlg.MV(invI, IAa); } { //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa); //Vector ea_sa = Vector.CrossProd3(ea, sa); Vector IAa = new double[3]; IAa += -LinAlg.MV(Ia, ea); IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa)); IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M; Aa = LinAlg.MV(invIII, IAa); } Vector ta = new double[3]; { //Aa = new double[3]; // check "translational Eckart condition" only //ta += (-1/M) * Vector.CrossProd3(Aa, MMR); ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR); ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa); } for (int i = 0; i < n; i++) { double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = new double[3]; //Jia += Vector.CrossProd3(Aa, ri*mi); Jia += LinAlg.CrossProd3(Aa, ri); Jia += ta; J[i, a] = Jia.ToColMatrix(); } foreach (Atom ira in rotInfo.rotAtoms) { int i = ira.ID; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = LinAlg.CrossProd3(ea, ri - sa); J[i, a] += Jia.ToColMatrix(); } //if(Debug.IsDebuggerAttached) //{ // // check Eckart condition // // http://en.wikipedia.org/wiki/Eckart_conditions // ////////////////////////////////////////////////////////////////////// // // 1. translational Eckart condition // // sum{i=1..n}{mi * Jia} = 0 // Vector mJ = EckartConditionTrans(univ, J, a); // Debug.AssertTolerance(0.00000001, mJ); // // 2. rotational Eckart condition // // sum{i=1..n}{mi * r0i x Jia} = 0, // // where 'x' is the cross product // Vector mrJ = EckartConditionRotat(univ, coords, J, a); // Debug.AssertTolerance(0.00000001, mrJ); //} } return(J); }
public unsafe static MatrixByArr GetJ(Universe univ, Vector[] coords, List <RotableInfo> rotInfos) { HDebug.Assert(rotInfos.ListMolecule().HUnion().Length == 1); Dictionary <Universe.Molecule, Dictionary <string, object> > moleMRI = new Dictionary <Universe.Molecule, Dictionary <string, object> >(); int n = univ.atoms.Count; int m = rotInfos.Count; MatrixByArr J = new double[3 * n, m]; double[] _Ja = new double[3 * n]; for (int a = 0; a < m; a++) { var mole = rotInfos[a].mole; if (moleMRI.ContainsKey(rotInfos[a].mole) == false) { double _M = 0; Vector _R = new double[3]; Vector _MR = new double[3]; MatrixByArr _I = new double[3, 3]; GetMaRaMaraITa(mole.atoms.ToArray(), coords, ref _M, ref _R, ref _MR, ref _I); MatrixByArr _invI = LinAlg.Inv3x3(_I); MatrixByArr _MRx = GetSSMatrix(_MR); MatrixByArr _MRxt = _MRx.Tr(); MatrixByArr _III = _I - (1.0 / _M) * _MRx * _MRxt; // { MI - 1/M * [MR]x * [MR]x^t } MatrixByArr _invIII = LinAlg.Inv3x3(_III); moleMRI.Add(mole, new Dictionary <string, object>()); moleMRI[mole].Add("invI", _invI); moleMRI[mole].Add("invIII", _invIII); moleMRI[mole].Add("MR", _MR); moleMRI[mole].Add("R", _R); moleMRI[mole].Add("M", _M); } MatrixByArr invI = moleMRI[mole]["invI"] as MatrixByArr; MatrixByArr invIII = moleMRI[mole]["invIII"] as MatrixByArr; Vector MR = moleMRI[mole]["MR"] as Vector; Vector R = moleMRI[mole]["R"] as Vector; double M = (double)(moleMRI[mole]["M"]); RotableInfo rotInfo = rotInfos[a]; double Ma = 0; Vector Ra = new double[3]; Vector MaRa = new double[3]; MatrixByArr Ia = new double[3, 3]; GetMaRaMaraITa(rotInfo.rotAtoms, coords, ref Ma, ref Ra, ref MaRa, ref Ia); HDebug.Assert(rotInfo.rotAtoms.Contains(rotInfo.bondedAtom)); Vector sa = coords[rotInfo.bondedAtom.ID]; Vector ea; { Atom bondatom = null; HDebug.Assert(rotInfo.bond.atoms.Length == 2); if (rotInfo.bond.atoms[0] == rotInfo.bondedAtom) { bondatom = rotInfo.bond.atoms[1]; } else { bondatom = rotInfo.bond.atoms[0]; } HDebug.Assert(rotInfo.rotAtoms.Contains(bondatom) == false); ea = (sa - coords[bondatom.ID]).UnitVector(); } Vector Aa; { Vector ea_Rasa = LinAlg.CrossProd3(ea, Ra - sa); Vector IAa = -LinAlg.MV(Ia, ea) + LinAlg.CrossProd3(Ma * R - MaRa, ea_Rasa); Aa = LinAlg.MV(invI, IAa); } { //Vector ea_MaRa_Masa = Vector.CrossProd3(ea, MaRa-Ma*sa); //Vector ea_sa = Vector.CrossProd3(ea, sa); Vector IAa = new double[3]; IAa += -LinAlg.MV(Ia, ea); IAa += LinAlg.CrossProd3(MaRa, LinAlg.CrossProd3(ea, sa)); IAa += LinAlg.CrossProd3(MR, LinAlg.CrossProd3(ea, MaRa - Ma * sa)) / M; Aa = LinAlg.MV(invIII, IAa); } Vector ta = new double[3]; { //Aa = new double[3]; // check "translational Eckart condition" only //ta += (-1/M) * Vector.CrossProd3(Aa, MMR); ta += (-1 / M) * LinAlg.CrossProd3(Aa, MR); ta += (-1 / M) * LinAlg.CrossProd3(ea, MaRa - Ma * sa); } fixed(double *Ja = _Ja) { //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = new double[3]; //Jia += Vector.CrossProd3(Aa, ri*mi); Jia += LinAlg.CrossProd3(Aa, ri); Jia += ta; //J[i, a] = Jia.ToColMatrix(); Ja[i * 3 + 0] = Jia[0]; Ja[i * 3 + 2] = Jia[2]; Ja[i * 3 + 1] = Jia[1]; } foreach (Atom ira in rotInfo.rotAtoms) { int i = ira.ID; Vector ri = coords[univ.atoms[i].ID]; Vector Jia = LinAlg.CrossProd3(ea, ri - sa); //J[i, a] += Jia.ToColMatrix(); Ja[i * 3 + 0] += Jia[0]; Ja[i * 3 + 1] += Jia[1]; Ja[i * 3 + 2] += Jia[2]; } //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; J[i * 3 + 0, a] = Ja[i * 3 + 0]; J[i * 3 + 1, a] = Ja[i * 3 + 1]; J[i * 3 + 2, a] = Ja[i * 3 + 2]; } } if (HDebug.IsDebuggerAttached) { // check Eckart condition // http://en.wikipedia.org/wiki/Eckart_conditions ////////////////////////////////////////////////////////////////////// // 1. translational Eckart condition // sum{i=1..n}{mi * Jia} = 0 Vector mJ = new double[3]; //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; //Vector Jia = J[i, a].ToVector(); Vector Jia = new double[3] { J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a] }; mJ += mi * Jia; } HDebug.AssertTolerance(0.00000001, mJ); ////////////////////////////////////////////////////////////////////// // 1. rotational Eckart condition // sum{i=1..n}{mi * r0i x Jia} = 0, // where 'x' is the cross product Vector mrJ = new double[3]; //for(int i=0; i<n; i++) foreach (Atom iaa in mole.atoms) { int i = iaa.ID; double mi = univ.atoms[i].Mass; Vector ri = coords[univ.atoms[i].ID]; //Vector Jia = J[i, a].ToVector(); Vector Jia = new double[3] { J[i * 3 + 0, a], J[i * 3 + 1, a], J[i * 3 + 2, a] }; mrJ += mi * LinAlg.CrossProd3(ri, Jia); } HDebug.AssertTolerance(0.0000001, mrJ); } } return(J); }