public int Minimize_ConjugateGradient_v1(int iterInitial, List <ForceField.IForceField> frcflds, double?k, double max_atom_movement, int?max_iteration, double threshold, int randomPurturb, bool[] atomsMovable, IMinimizeLogger logger, InfoPack extra, bool?doSteepDeescent // null or true for default ) { if (doSteepDeescent == null) { doSteepDeescent = true; } if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } // double k = 0.0001; int iter = iterInitial; // 0. Initial configuration of atoms Vectors coords = GetCoords(); if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = GetVectorsZero(); Vectors forces = null; Dictionary <string, object> cache = new Dictionary <string, object>(); double energy = GetPotential(frcflds, coords, out forces, cache); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vectors forces0 = forces; double energy0 = energy; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(this, iter, coords); //if(iter %10 == 0) //{ // System.IO.Directory.CreateDirectory("output"); // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache energy = GetPotential(frcflds, coords, out forces, cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); // This is already checked by "if(forces_NormInf < threshold) stopIteration = true;" //if(forces_NormInf < threshold) ///////////////////////////////////////////////////// { if (iter != 1) { SetCoords((Vector[])coords); } //{ // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} if (extra != null) { extra.SetValue("energy", energy); extra.SetValue("forces", forces); extra.SetValue("forces norm-1", forces_Norm1); extra.SetValue("forces norm-2", forces_Norm2); extra.SetValue("forces norm-inf", forces_NormInf); extra.SetValue("iter", iter); } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if ((randomPurturb > 0) && (iter % randomPurturb == 0)) { Vectors dcoords = GetVectorsRandom(); dcoords *= max_atom_movement; coords = AddConditional(coords, dcoords, atomsMovable); } if (iter > 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h,atomsMovable)); coords_prd = AddConditional(coords, kk * h, atomsMovable); } else { // same to the steepest descent for the first iteration h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); coords_prd = AddConditional(coords, kk * h, atomsMovable); } } // 5. Predict energy or forces on atoms Vectors forces_prd; double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no doSteepDeescent = true; //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0)) if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); coords_prd = AddConditional(coords, kk * h, atomsMovable); //if(randomPurturb) //{ // Vectors dcoords = GetForcesRandom(); // dcoords *= (0.1*max_atom_movement); // coords += dcoords; //} } energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }
public int Minimize_ConjugateGradient_AtomwiseUpdate( List <ForceField.IForceField> frcflds , double threshold = 0.001 // * threshold for forces.NormInf , double?k = null // * step step // 0.0001 , double max_atom_movement = 0.1 // * maximum atom movement , int?max_iteration = null // null for the infinite iteration until converged , bool[] atomsMovable = null // * selection of movable atoms // move all atoms if (atomsMovable == null) or (atomsMovable[all] == true) // move only atom whose (atomsMovable[id] == true) , IMinimizeLogger logger = null // * write log // = new MinimizeLogger_PrintEnergyForceMag() , InfoPack extra = null // get extra information , bool?doSteepDeescent = null // null or true for default , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (doSteepDeescent == null) { doSteepDeescent = true; } if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } int iter = 0; // 0. Initial configuration of atoms Vector[] coords = GetCoords(); if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = GetVectorsZero(); Vectors forces = Vector.NewVectors(size, new double[3]); Vectors moves = Vector.NewVectors(size, new double[3]); Nonbondeds_v1 nonbondeds = null; // Dictionary<string,object> cache = new Dictionary<string, object>(); double energy = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vector[] forces0 = forces; double energy0 = energy; Vectors moves0 = moves; double leastMove = 0.000001; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(this, iter, coords); } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check //cache = new Dictionary<string, object>(); // reset cache //energy = GetPotential(frcflds, coords, out forces, cache); nonbondeds = null; energy = GetPotentialUpdated(frcflds, null, null, null, coords, forces, ref nonbondeds); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { SetCoords(coords); } { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; double kk; { if ((iter > 0) && (iter % 100 == 0)) { //cache = new Dictionary<string, object>(); // reset cache nonbondeds = null; } if (iter > 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } else { // same to the steepest descent for the first iteration h = forces; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } //double kk = (k*h.NormsInf().NormInf() < max_atom_movement) ? k : (max_atom_movement/h.NormsInf().NormInf()); //double kk = (k.Value*NormInf(h,atomsMovable) < max_atom_movement)? k.Value : (max_atom_movement/NormInf(h, atomsMovable)); moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } } // 5. Predict energy or forces on atoms Vectors forces_prd = forces.Clone(); double energy_prd = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds); iter++; //double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no doSteepDeescent = true; //if((doSteepDeescent == false) || ((energy_prd <= energy) && (forces_prd_NormInf < forces_NormInf+1.0)) if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; moves0 = moves; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } moves = moves0.Clone(); coords_prd = AddConditional(coords, atomsMovable, moves, kk * h, leastMove); } //energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); energy_prd = GetPotentialUpdated(frcflds, energy, coords, forces, coords_prd, forces_prd, ref nonbondeds); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; moves0 = moves; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }
public long?Minimize_SteepestDescent(List <ForceField.IForceField> frcflds , double thresholdForMaxNormInf // 0.001 , long maxIter = long.MaxValue , double maxMovePerIter = 0.01 , double?k = 1 , bool[] atomsMovable = null // true for movable atoms, // false for non-movable atoms, // null for all atoms movable , IMinimizeLogger logger = null ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } long iter = 0; // 0. Initial configuration of atoms Vectors coords = GetCoords(); if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vector masses = GetMasses(3); masses = masses / masses.ToArray().Min(); Vectors h = GetVectorsZero(); Vectors forces = null; Dictionary <string, object> cache = new Dictionary <string, object>(); double energy = GetPotential(frcflds, coords, out forces, cache); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vectors forces0 = forces; double energy0 = energy; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); logger.logTrajectory(this, iter, coords); } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < thresholdForMaxNormInf) { stopIteration = true; } if (iter >= maxIter) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache energy = GetPotential(frcflds, coords, out forces, cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < thresholdForMaxNormInf) { if (iter != 1) { SetCoords((Vector[])coords); } //{ // string pdbname = string.Format("mini.conju.{0:D5}.pdb", iter); // pdb.ToFile("output\\"+pdbname, coords.ToArray()); // System.IO.File.AppendAllLines("output\\mini.conju.[animation].pml", new string[] { "load "+pdbname+", 1A6G" }); //} if (lextra != null) { lextra.Add("energy", energy); lextra.Add("forces", forces); lextra.Add("forces norm-1", forces_Norm1); lextra.Add("forces norm-2", forces_Norm2); lextra.Add("forces norm-inf", forces_NormInf); lextra.Add("iter", iter); } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; { if (iter % 100 == 0) { cache = new Dictionary <string, object>(); // reset cache } #region code for purturbation (commented out) //if((randomPurturb > 0) && (iter % randomPurturb == 0)) //{ // Vectors dcoords = GetForcesRandom(); // dcoords *= max_atom_movement; // coords = AddConditional(coords, dcoords, atomsMovable); //} #endregion { // same to the steepest descent for the first iteration h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > maxMovePerIter) { // make the maximum movement as atomsMovable //kk = maxMovePerIter/(hNormInf*kk); kk = maxMovePerIter / hNormInf; } //for(int i=0; i<h.Length; i++) // h[i] = h[i] / masses[i]; coords_prd = AddConditional(coords, kk * h, atomsMovable); } } // 5. Predict energy or forces on atoms Vectors forces_prd; double energy_prd = GetPotential(frcflds, coords_prd, out forces_prd, cache); iter++; double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no //if(energy_prd < energy)// && forces_prd_NormInfinity < forces_NormInfinite) { energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } // 9. goto 1 } }
public int ConjugateGradient(List <ForceField.IForceField> frcflds , double threshold , double?k = null , double max_atom_movement = 0.01 , int?max_iteration = null , IMinimizeLogger logger = null // logger = new MinimizeLogger_PrintEnergyForceMag(logpath); , HPack <double> optOutEnergy = null // optional output for final energy , List <Vector> optOutForces = null // optional output for final force vectors , HPack <double> optOutForcesNorm1 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNorm2 = null // optional output for norm of final force vectors , HPack <double> optOutForcesNormInf = null // optional output for norm of final force vectors ) { if (k == null) { k = double.MaxValue; foreach (ForceField.IForceField frcfld in frcflds) { double?kk = frcfld.GetDefaultMinimizeStep(); if (kk.HasValue) { k = Math.Min(k.Value, kk.Value); } } } Graph <Universe.Atom[], Universe.Bond> univ_flexgraph = univ.BuildFlexibilityGraph(); List <Universe.RotableInfo> univ_rotinfos = univ.GetRotableInfo(univ_flexgraph); // double k = 0.0001; int iter = 0; // 0. Initial configuration of atoms Vector[] coords0 = univ.GetCoords(); Vectors coords = univ.GetCoords(); bool[] atomsMovable = null; if (atomsMovable == null) { atomsMovable = new bool[size]; for (int i = 0; i < size; i++) { atomsMovable[i] = true; } } Vectors h = univ.GetVectorsZero(); Vectors forces = univ.GetVectorsZero(); Dictionary <string, object> cache; double energy; cache = new Dictionary <string, object>(); GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); double forces_NormInf = NormInf(forces, atomsMovable); double forces_Norm1 = Norm(1, forces, atomsMovable); double forces_Norm2 = Norm(2, forces, atomsMovable); Vectors forces0 = forces; double energy0 = energy; while (true) { if (forces.IsComputable == false) { System.Console.Error.WriteLine("non-computable components while doing steepest-descent"); HEnvironment.Exit(0); } if (logger != null) { logger.log(iter, coords, energy, forces, atomsMovable); { // logger.logTrajectory(univ, iter, coords); Vector[] coordsx = coords._vecs.HClone <Vector>(); Trans3 trans = ICP3.OptimalTransform(coordsx, coords0); trans.DoTransform(coordsx); logger.logTrajectory(univ, iter, coordsx); } } // 1. Save the position of atoms // 2. Calculate the potential energy of system and the net forces on atoms // 3. Check if every force reaches to zero, // , and END if yes bool stopIteration = false; if (forces_NormInf < threshold) { stopIteration = true; } if ((max_iteration != null) && (iter >= max_iteration.Value)) { stopIteration = true; } if (stopIteration) { // double check cache = new Dictionary <string, object>(); // reset cache GetPotentialAndTorForce(frcflds, coords , out energy, out forces._vecs , cache); forces_NormInf = NormInf(forces, atomsMovable); forces_Norm1 = Norm(1, forces, atomsMovable); forces_Norm2 = Norm(2, forces, atomsMovable); if (forces_NormInf < threshold) { if (iter != 1) { univ.SetCoords((Vector[])coords); } { if (optOutEnergy != null) { optOutEnergy.value = energy; } if (optOutForces != null) { optOutForces.Clear(); optOutForces.AddRange(forces.ToArray()); } if (optOutForcesNorm1 != null) { optOutForcesNorm1.value = forces_Norm1; } if (optOutForcesNorm2 != null) { optOutForcesNorm2.value = forces_Norm2; } if (optOutForcesNormInf != null) { optOutForcesNormInf.value = forces_NormInf; } } return(iter); } } // 4. Move atoms with conjugated gradient Vectors coords_prd; { if ((iter > 0) && (iter % 100 == 0)) { cache = new Dictionary <string, object>(); // reset cache } if (iter >= 1) { HDebug.Assert(forces0 != null); double r = Vectors.VtV(forces, forces).Sum() / Vectors.VtV(forces0, forces0).Sum(); h = forces + r * h; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } else { // same to the steepest descent for the first iteration h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } } // 5. Predict energy or forces on atoms iter++; double energy_prd; Vectors forces_prd = univ.GetVectorsZero(); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); // double energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); // Vector[] dcoord_prd = univ.GetVectorsZero(); // double[] dangles_prd = TNM.GetRotAngles(univ, coords_prd, forces_prd, 1, dcoordsRotated: dcoord_prd); // dangles_prd = TNM.GetRotAngles(univ, coords_prd, hessian_prd, forces_prd, forceProjectedByTorsional: dcoord_prd); //Vectors coords_prd2 = coords_prd.Clone(); //TNM.RotateTorsionals(coords_prd2, dangles_prd, univ_rotinfos); double forces_prd_NormInf = NormInf(forces_prd, atomsMovable); // NormInf(forces_prd, atomsMovable); double forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); // Norm(1, forces_prd, atomsMovable); double forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); // Norm(2, forces_prd, atomsMovable); // 6. Check if the predicted forces or energy will exceed over the limit // , and goto 1 if no if ((energy_prd < energy + 0.1) && (forces_prd_NormInf < forces_NormInf + 0.0001)) { energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; continue; } if (logger != null) { logger.log(iter, coords_prd, energy_prd, forces_prd, atomsMovable, "will do steepest"); } // 7. Back to saved configuration // 8. Move atoms with simple gradient { // same to the steepest descent h = forces; double kk = k.Value; double hNormInf = NormInf(h, atomsMovable); if (kk * hNormInf > max_atom_movement) { // make the maximum movement as atomsMovable kk = max_atom_movement / (hNormInf); } Vector dangles = Paper.TNM.GetRotAngles(univ, coords, kk * h, 1); //dangles *= -1; coords_prd = Paper.TNM.RotateTorsionals(coords, dangles, univ_rotinfos); } forces_prd = univ.GetVectorsZero(); //energy_prd = univ.GetPotential(frcflds, coords_prd, ref forces_prd._vecs, ref hessian_prd, cache); GetPotentialAndTorForce(frcflds, coords_prd , out energy_prd, out forces_prd._vecs , cache); forces_prd_NormInf = NormInf(forces_prd, atomsMovable); forces_prd_Norm1 = Norm(1, forces_prd, atomsMovable); forces_prd_Norm2 = Norm(2, forces_prd, atomsMovable); energy0 = energy; forces0 = forces; coords = coords_prd; forces = forces_prd; energy = energy_prd; forces_NormInf = forces_prd_NormInf; forces_Norm1 = forces_prd_Norm1; forces_Norm2 = forces_prd_Norm2; // 9. goto 1 } }