public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
            {
                HDebug.Depreciated("check idx1 and idx2");
                int idx1 = 0; // nonbonded.atoms[0].ID;
                int idx2 = 1; // nonbonded.atoms[1].ID;

                Universe.Atom atom1 = info.atoms[0];
                Universe.Atom atom2 = info.atoms[1];

                Vector diff = (coords[idx2] - coords[idx1]);
                double dx   = diff[0];
                double dy   = diff[1];
                double dz   = diff[2];
                double radi = double.NaN;
                double radj = double.NaN;
                double epsi = double.NaN;
                double epsj = double.NaN;

                if (typeof(Universe.Nonbonded14).IsInstanceOfType(info))
                {
                    radi = atom1.Rmin2_14; radi = (double.IsNaN(radi) == false) ? radi : atom1.Rmin2;
                    radj = atom2.Rmin2_14; radj = (double.IsNaN(radj) == false) ? radj : atom2.Rmin2;
                    epsi = atom1.eps_14; epsi = (double.IsNaN(epsi) == false) ? epsi : atom1.epsilon;
                    epsj = atom2.eps_14; epsj = (double.IsNaN(epsj) == false) ? epsj : atom2.epsilon;
                }
                if (typeof(Universe.Nonbonded).IsInstanceOfType(info))
                {
                    radi = atom1.Rmin2;
                    radj = atom2.Rmin2;
                    epsi = atom1.epsilon;
                    epsj = atom2.epsilon;
                }
                HDebug.Assert(double.IsNaN(radi) == false, double.IsNaN(radj) == false, double.IsNaN(epsi) == false, double.IsNaN(epsj) == false);

                // !V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6]
                // !epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j)
                // !Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j
                //
                // V(r) =           epsij * r0^12 * rij^-12  -        2 * epsij * r0^6 * rij^-6
                // F(r) =     -12 * epsij * r0^12 * rij^-13  -     -6*2 * epsij * r0^6 * rij^-7
                // K(r) = -13*-12 * epsij * r0^12 * rij^-14  -  -7*-6*2 * epsij * r0^6 * rij^-8
                double r     = (radi + radj);
                double r6    = Math.Pow(r, 6);
                double r12   = Math.Pow(r, 12);
                double rij2  = (dx * dx + dy * dy + dz * dz);
                double rij   = Math.Sqrt(rij2);
                double rij7  = Math.Pow(rij2, 3) * rij;
                double rij8  = Math.Pow(rij2, 4);
                double rij13 = Math.Pow(rij2, 6) * rij;
                double rij14 = Math.Pow(rij2, 7);
                double epsij = epsi * epsj;
                double fij   = (-12) * epsij * r12 / rij13 - (-6 * 2) * epsij * r6 / rij7;
                double kij   = (-13 * -12) * epsij * r12 / rij14 - (-7 * -6 * 2) * epsij * r6 / rij8;

                pwidxs         = new Pair <int, int> [1];
                pwidxs[0]      = new Pair <int, int>(0, 1);
                pwhessinfos    = new PwIntrActInfo[1];
                pwhessinfos[0] = new PwIntrActInfo(kij, fij);
            }
예제 #2
0
            public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
            {
                Universe.Nonbonded nonbonded = (Universe.Nonbonded)info;

                HDebug.Depreciated("check idx1 and idx2");
                int idx1 = 0; // nonbonded.atoms[0].ID;
                int idx2 = 1; // nonbonded.atoms[1].ID;

                Universe.Atom atom1 = nonbonded.atoms[0];
                Universe.Atom atom2 = nonbonded.atoms[1];
                double        pchij = atom1.Charge * atom2.Charge;

                if (double.IsNaN(pchij))
                {
                    HDebug.Assert(false);
                    pwidxs      = null;
                    pwhessinfos = null;
                    return;
                }

                Vector diff = (coords[idx2] - coords[idx1]);
                double dx   = diff[0];
                double dy   = diff[1];
                double dz   = diff[2];
                double pchi = atom1.Charge;
                double pchj = atom2.Charge;
                double ee   = 80;

                // !V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6]
                // !epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j)
                // !Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j
                //
                // V(rij) =           (332 * pchij / ee) * rij^-1
                // F(rij) = (   -1) * (332 * pchij / ee) * rij^-2
                // K(rij) = (-2*-1) * (332 * pchij / ee) * rij^-3
//                double pchij = pchi * pchj;
                double rij2 = dx * dx + dy * dy + dz * dz;
                double rij  = Math.Sqrt(rij2);
                double rij3 = rij2 * rij;
                double fij  = (-1) * (332 * pchij / ee) / rij2;
                double kij  = (-2 * -1) * (332 * pchij / ee) / rij3;

                pwidxs         = new Pair <int, int> [1];
                pwidxs[0]      = new Pair <int, int>(0, 1);
                pwhessinfos    = new PwIntrActInfo[1];
                pwhessinfos[0] = new PwIntrActInfo(kij, fij);
            }
예제 #3
0
            public virtual void Compute(Universe.AtomPack nonbonded, Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian
                                        , double radi, double radj, double epsi, double epsj, double[,] pwfrc = null, double[,] pwspr = null)
            {
                Universe.Atom atom1 = nonbonded.atoms[0];
                Universe.Atom atom2 = nonbonded.atoms[1];

                Vector pos0 = coords[0];
                Vector pos1 = coords[1];

                double rmin  = (radi + radj);
                double epsij = Math.Sqrt(epsi * epsj);

                double lenergy, forceij, springij;

                Compute(coords, out lenergy, out forceij, out springij, epsij, rmin);
                double abs_forceij = Math.Abs(forceij);

                if (pwfrc != null)
                {
                    pwfrc[0, 1] = pwfrc[1, 0] = forceij;
                }
                if (pwspr != null)
                {
                    pwspr[0, 1] = pwspr[1, 0] = springij;
                }


                ///////////////////////////////////////////////////////////////////////////////
                // energy
                energy += lenergy;
                ///////////////////////////////////////////////////////////////////////////////
                // force
                if (forces != null)
                {
                    Vector frc0, frc1;
                    GetForceVector(pos0, pos1, forceij, out frc0, out frc1);
                    forces[0] += frc0;
                    forces[1] += frc1;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    hessian[0, 1] += GetHessianBlock(coords[0], coords[1], springij, forceij);
                    hessian[1, 0] += GetHessianBlock(coords[1], coords[0], springij, forceij);
                }
            }
예제 #4
0
            public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
            {
                Universe.Bond bond = (Universe.Bond)info;
                double        Kb   = bond.Kb;
                double        b0   = bond.b0;

                HDebug.Assert(coords.Length == 2);
                Vector pos1 = coords[0];
                Vector pos2 = coords[1];
                Vector r12  = pos1 - pos2;
                double r    = r12.Dist;

                double kij = 2 * Kb;
                double fij = (2 * Kb) * (r - b0);

                pwidxs         = new Pair <int, int> [1];
                pwidxs[0]      = new Pair <int, int>(0, 1);
                pwhessinfos    = new PwIntrActInfo[1];
                pwhessinfos[0] = new PwIntrActInfo(kij, fij);
            }
예제 #5
0
 public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
 {
     pwidxs      = null;
     pwhessinfos = null;
     //Universe.Improper improper = (Universe.Improper)info;
     //double Kpsi  = improper.Kpsi;
     ////int    n     = improper.param.n;
     //double psi0 = improper.psi0;
     //Vector a = coords[0];
     //Vector b = coords[1];
     //Vector c = coords[2];
     //Vector d = coords[3];
     //Pair<double, double> fij_kij = GetFijKij(Kpsi, psi0, a, b, c, d);
     //double fij = fij_kij.first;
     //double kij = fij_kij.second;
     //
     //Debug.Assert(coords.Length == 4);
     //pwidxs = new Pair<int, int>[1];
     //pwidxs[0] = new Pair<int, int>(0, 3);
     //pwhessinfos = new PwIntrActInfo[1];
     //pwhessinfos[0] = new PwIntrActInfo(kij, fij);
 }
예제 #6
0
            public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
            {
                Universe.Angle angle  = (Universe.Angle)info;
                double         Ktheta = angle.Ktheta;
                double         Theta0 = angle.Theta0;
                double         Kub    = angle.Kub;
                double         S0     = angle.S0;

                Vector pos1 = coords[0];  // const Vector *pos1 = coords + angle->atom1;
                Vector pos2 = coords[1];  // const Vector *pos2 = coords + angle->atom2;
                Vector pos3 = coords[2];  // const Vector *pos3 = coords + angle->atom3;
                double a    = (pos2 - pos1).Dist;
                double b    = (pos3 - pos2).Dist;
                double c    = (pos3 - pos1).Dist;
                ValueTuple <double, double> fij_kij = GetFijKij(a, b, c, Ktheta, Theta0);
                double fij = fij_kij.Item1;
                double kij = fij_kij.Item2;

                HDebug.Assert(coords.Length == 3);
                pwidxs         = new Pair <int, int> [1];
                pwidxs[0]      = new Pair <int, int>(0, 2);
                pwhessinfos    = new PwIntrActInfo[1];
                pwhessinfos[0] = new PwIntrActInfo(kij, fij);
            }
예제 #7
0
            public void BuildHess4PwIntrAct(Universe.AtomPack info, Vector[] coords, out Pair <int, int>[] pwidxs, out PwIntrActInfo[] pwhessinfos)
            {
                Universe.Improper improper = (Universe.Improper)info;
                double            Kchi     = improper.Kpsi;
                int    n     = improper.n;
                double delta = improper.psi0;

                //Vector pos1 = coords[0];  // const Vector *pos1 = coords + angle->atom1;
                //Vector pos2 = coords[1];  // const Vector *pos2 = coords + angle->atom2;
                //Vector pos3 = coords[2];  // const Vector *pos3 = coords + angle->atom3;
                //double a = (pos2-pos1).Dist;
                //double b = (pos3-pos2).Dist;
                //double c = (pos3-pos1).Dist;
                //Pair<double,double> fij_kij = GetFijKij(a, b, c, Ktheta, Theta0);
                //double fij = fij_kij.first;
                //double kij = fij_kij.second;

                ///           A
                ///          /        B
                ///    a .../. c    /
                ///     \  /  / \ /
                ///      \   /  /\
                ///       \ / /   \
                ///        b ..... d
                ///
                ///   a
                ///   |\                    /
                ///   | \                 /T
                ///   |  \  ----- A ----+----
                ///   |   \           /
                ///   |    \        B
                ///   p     l     /
                ///   | \    \ /
                ///   |T  \   \
                ///   |     \  \
                ///           \ \
                ///             \\
                ///               d
                ///
                /// A = (b-a) x (c-b)
                /// B = (c-b) x (d-c)
                /// (A x B) ⊥ (Δ adp)
                /// p ∈ bc
                /// T + ∠apd = π
                ///
                /// V                   =   K0 (T - T0)^2
                /// F =           dV/dT = 2 K0 (T - T0)
                /// K = (d^2 V)/(d T^2) = 2 K0
                /// return {  dV/dl,  (d^2 V)/(d l^2)  }

                Vector a   = coords[0];
                Vector b   = coords[1];
                Vector c   = coords[2];
                Vector d   = coords[3];
                Vector A   = LinAlg.CrossProd(a - b, b - c);
                Vector B   = LinAlg.CrossProd(b - c, c - d);
                Vector AxB = LinAlg.CrossProd(A, B);
                double ad  = (a - d).Dist;
                Vector p   = Geometry.Point4LinePlaneIntersect(a, d, a + A, b, c);
                double ap  = (a - p).Dist;
                double pd  = (p - d).Dist;

                ValueTuple <double, double> fij_kij = MindyAngle.GetFijKij(ap, pd, ad, Kchi, delta, -1, +1, -1);
                double fij = fij_kij.Item1;
                double kij = fij_kij.Item2;

                HDebug.Assert(coords.Length == 4);
                pwidxs         = new Pair <int, int> [1];
                pwidxs[0]      = new Pair <int, int>(0, 3);
                pwhessinfos    = new PwIntrActInfo[1];
                pwhessinfos[0] = new PwIntrActInfo(kij, fij);
            }
            public virtual void Compute(Universe.AtomPack nonbonded, Vector[] coords, ref double energy, ref Vector[] forces, ref MatrixByArr[,] hessian
                                        , double radi, double radj, double epsi, double epsj, double[,] pwfrc = null, double[,] pwspr = null)
            {
                HDebug.Depreciated("check idx1 and idx2");
                int idx1 = 0; // nonbonded.atoms[0].ID;
                int idx2 = 1; // nonbonded.atoms[1].ID;

                Universe.Atom atom1 = nonbonded.atoms[0];
                Universe.Atom atom2 = nonbonded.atoms[1];

                Vector diff = (coords[idx2] - coords[idx1]);
                double dx   = diff[0];
                double dy   = diff[1];
                double dz   = diff[2];

                //double radi = atom1.Rmin2;
                //double radj = atom2.Rmin2;
                //double epsi = atom1.epsilon;
                //double epsj = atom2.epsilon;

                ///////////////////////////////////////////////////////////////////////////////
                // energy
                energy += EnergyVdw(dx, dy, dz, radi, radj, epsi, epsj);
                ///////////////////////////////////////////////////////////////////////////////
                // force
                if (forces != null)
                {
                    Vector f12 = ForceVdw(dx, dy, dz, radi, radj, epsi, epsj);
                    forces[idx1] += f12;
                    forces[idx2] += -f12;
                }
                ///////////////////////////////////////////////////////////////////////////////
                // hessian
                if (hessian != null)
                {
                    //string option = "Spring+Force";
                    //Vector diff01 = (coords[1] - coords[0]);
                    //Vector diff10 = (coords[0] - coords[1]);
                    //hessian[0, 1] += SprngVdw(diff01, radi, radj, epsi, epsj, option);
                    //hessian[1, 0] += SprngVdw(diff10, radi, radj, epsi, epsj, option);
                    {
                        // !V(Lennard-Jones) = Eps,i,j[(Rmin,i,j/ri,j)**12 - 2(Rmin,i,j/ri,j)**6]
                        // !epsilon: kcal/mole, Eps,i,j = sqrt(eps,i * eps,j)
                        // !Rmin/2: A, Rmin,i,j = Rmin/2,i + Rmin/2,j
                        //
                        // V(r) =           epsij * r0^12 * rij^-12  -        2 * epsij * r0^6 * rij^-6
                        // F(r) =     -12 * epsij * r0^12 * rij^-13  -     -6*2 * epsij * r0^6 * rij^-7
                        // K(r) = -13*-12 * epsij * r0^12 * rij^-14  -  -7*-6*2 * epsij * r0^6 * rij^-8
                        double r     = (radi + radj);
                        double r6    = Math.Pow(r, 6);
                        double r12   = Math.Pow(r, 12);
                        double rij2  = (dx * dx + dy * dy + dz * dz);
                        double rij   = Math.Sqrt(rij2);
                        double rij7  = Math.Pow(rij2, 3) * rij;
                        double rij8  = Math.Pow(rij2, 4);
                        double rij13 = Math.Pow(rij2, 6) * rij;
                        double rij14 = Math.Pow(rij2, 7);
                        double epsij = epsi * epsj;
                        double fij   = (-12) * epsij * r12 / rij13 - (-6 * 2) * epsij * r6 / rij7;
                        double kij   = (-13 * -12) * epsij * r12 / rij14 - (-7 * -6 * 2) * epsij * r6 / rij8;
                        fij *= optHessianForceFactor;
                        //Matrix Hij = ForceField.GetHessianBlock(coords[0], coords[1], kij, fij);
                        hessian[0, 1] += ForceField.GetHessianBlock(coords[0], coords[1], kij, fij);
                        hessian[1, 0] += ForceField.GetHessianBlock(coords[1], coords[0], kij, fij);
                    }
                }
            }