示例#1
0
        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];
                }
            }
        }
示例#2
0
            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);
            }
示例#3
0
                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);
                }
示例#4
0
                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);
                }