From dfc96470c32b0f6805d4f732cc935a95fd0c58b8 Mon Sep 17 00:00:00 2001 From: leothan Date: Thu, 17 Apr 2025 14:45:53 -0500 Subject: [PATCH 01/23] FIRE and NSTOVSUT optimization methods added --- .../structurefinder/FIRE_BE/__init__.py | 81 ++++++++++ .../structurefinder/FIRE_BE/be2_DC_NVT.py | 116 ++++++++++++++ .../structurefinder/FIRE_BE/be2_DC_VarT.py | 123 +++++++++++++++ .../structurefinder/FIRE_BE/be2_FIRE.py | 144 ++++++++++++++++++ .../structurefinder/FIRE_NSTOVSUT/__init__.py | 81 ++++++++++ .../FIRE_NSTOVSUT/nesterov_FIRE.py | 143 +++++++++++++++++ .../FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py | 116 ++++++++++++++ .../FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py | 126 +++++++++++++++ .../FIRE_NSTOVSUT/nesterov_SUT_NDC.py | 106 +++++++++++++ .../structurefinder/FIRE_VV/__init__.py | 81 ++++++++++ .../structurefinder/FIRE_VV/vv_DC_NVT.py | 118 ++++++++++++++ .../structurefinder/FIRE_VV/vv_DC_VarT.py | 125 +++++++++++++++ src/python/structurefinder/FIRE_VV/vv_FIRE.py | 139 +++++++++++++++++ .../structurefinder/NSTOVSUT/__init__.py | 81 ++++++++++ .../NSTOVSUT/nesterov_SUT_NDC.py | 106 +++++++++++++ .../structurefinder/pyberny/__init__.py | 26 ++-- 16 files changed, 1696 insertions(+), 16 deletions(-) create mode 100644 src/python/structurefinder/FIRE_BE/__init__.py create mode 100644 src/python/structurefinder/FIRE_BE/be2_DC_NVT.py create mode 100644 src/python/structurefinder/FIRE_BE/be2_DC_VarT.py create mode 100644 src/python/structurefinder/FIRE_BE/be2_FIRE.py create mode 100644 src/python/structurefinder/FIRE_NSTOVSUT/__init__.py create mode 100644 src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py create mode 100644 src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py create mode 100644 src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py create mode 100644 src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py create mode 100644 src/python/structurefinder/FIRE_VV/__init__.py create mode 100644 src/python/structurefinder/FIRE_VV/vv_DC_NVT.py create mode 100644 src/python/structurefinder/FIRE_VV/vv_DC_VarT.py create mode 100644 src/python/structurefinder/FIRE_VV/vv_FIRE.py create mode 100644 src/python/structurefinder/NSTOVSUT/__init__.py create mode 100644 src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py diff --git a/src/python/structurefinder/FIRE_BE/__init__.py b/src/python/structurefinder/FIRE_BE/__init__.py new file mode 100644 index 0000000..2979804 --- /dev/null +++ b/src/python/structurefinder/FIRE_BE/__init__.py @@ -0,0 +1,81 @@ +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pluginplay as pp +from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString +from berny import Berny, geomlib +import chemist +import numpy as np +import tensorwrapper as tw + + +class GeomoptViaPyberny(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergy()) + self.description("Performs PyBerny optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergy() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Convert Chemist Chemical System to XYZ + xyz = "" + xyz += (str(molecule.size()) + "\n\n") + for i in range(molecule.size()): + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + + # Loads the geometry string into the Berny optimizer + # object. + optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) + + for geom in optimizer: + + # Converts the "Berny" geometry object to Chemical System + geom2xyz = geom.dumps('xyz') + print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') + lines = geom2xyz.split('\n') + print('Lines of geom2xyz: \n' + str(lines) + '\n') + mol_string = '\n'.join(lines[2:]) + print('Lines to string: \n' + mol_string + '\n') + xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + geom = chemist.ChemicalSystem(xyz2chem_mol) + print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + geom_nuclei = geom.molecule.nuclei.as_nuclei() + geom_points = geom_nuclei.charges.point_set + + # Main optimizer operation + energy = submods["Energy"].run_as(TotalEnergy(), geom) + print('Interim energy: \n' + str(energy) + '\n') + gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + print('Interim gradient: \n' + str(gradients) + '\n') + optimizer.send((energy, gradients)) + + opt_geom = geom.molecule.nuclei + print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + # Optimized energy is of type "float" + e = tw.Tensor(energy) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_pyberny_modules(mm): + mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/FIRE_BE/be2_DC_NVT.py b/src/python/structurefinder/FIRE_BE/be2_DC_NVT.py new file mode 100644 index 0000000..25b1eb0 --- /dev/null +++ b/src/python/structurefinder/FIRE_BE/be2_DC_NVT.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 16:34:02 2024 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + + +class BE2_DC_NVT(): + + def __init__(self,r0,h): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + k=0 + i=0 + #--------------------------------------------------------------------- + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + Np = 0 + Nreset = Nreset + 1 + #------------------------------------------------------------------ + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- BACKWARD EULER(2)--------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + F[i+1]*h + #-- ENERGY ------------------------------------------------------- + E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_BE/be2_DC_VarT.py b/src/python/structurefinder/FIRE_BE/be2_DC_VarT.py new file mode 100644 index 0000000..eae6725 --- /dev/null +++ b/src/python/structurefinder/FIRE_BE/be2_DC_VarT.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 16:34:02 2024 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class BE2_DC_VarT(): + + def __init__(self,r0,h0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + h = h0 #<-- time steps + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + t_max = 0.3 #<-- Maximum time step + #-------------------------------------------------------------------- + k=0 + i=0 + #--------------------------------------------------------------------- + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + h = h0 + Np = 0 + Nreset = Nreset + 1 + #------ TIME STEP UPDATE ----------------------------------------- + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + h = h = min(1.1*h,t_max) + #------------------------------------------------------------------ + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- BACKWARD EULER(2)--------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + F[i+1]*h + #-- ENERGY ------------------------------------------------------- + E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_BE/be2_FIRE.py b/src/python/structurefinder/FIRE_BE/be2_FIRE.py new file mode 100644 index 0000000..2772131 --- /dev/null +++ b/src/python/structurefinder/FIRE_BE/be2_FIRE.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 16:13:47 2024 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class BE2_FIRE(): + + def __init__(self,r0,h0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) #<-- Position minimum + h = h0 #<-- Time step + #--------------------------------------------------------------------- + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + alpha = 0.1 + t_max = 0.3 + #--------------------------------------------------------------------- + + k=0 + i=0 + Nreset = 0 + #---------------------------------------------------------------------- + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- FIRE ------------------------------------------------------ + #---- alpha RESET and Half time step setting --------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + h = 0.5*h + alpha = 0.1 + Np = 0 + Nreset = Nreset + 1 + + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + + #----- FORCE UNITE VECTOR ------------------------------------ + + fh = F[i]/np.linalg.norm(F[i]) + + #---- FIRE VELOCITY CORRECTION ------------------------------- + VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + #------------------------------------------------------------- + + #----- alpha, time step UPGRADE ------------------------------ + if Np>5: + + h = min(1.1*h,t_max) + + + alpha = 0.99*alpha + + + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- BACKWARD EULER(2)--------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + F[i+1]*h + #-- ENERGY ------------------------------------------------------- + E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.alpha = alpha + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/__init__.py b/src/python/structurefinder/FIRE_NSTOVSUT/__init__.py new file mode 100644 index 0000000..2979804 --- /dev/null +++ b/src/python/structurefinder/FIRE_NSTOVSUT/__init__.py @@ -0,0 +1,81 @@ +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pluginplay as pp +from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString +from berny import Berny, geomlib +import chemist +import numpy as np +import tensorwrapper as tw + + +class GeomoptViaPyberny(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergy()) + self.description("Performs PyBerny optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergy() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Convert Chemist Chemical System to XYZ + xyz = "" + xyz += (str(molecule.size()) + "\n\n") + for i in range(molecule.size()): + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + + # Loads the geometry string into the Berny optimizer + # object. + optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) + + for geom in optimizer: + + # Converts the "Berny" geometry object to Chemical System + geom2xyz = geom.dumps('xyz') + print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') + lines = geom2xyz.split('\n') + print('Lines of geom2xyz: \n' + str(lines) + '\n') + mol_string = '\n'.join(lines[2:]) + print('Lines to string: \n' + mol_string + '\n') + xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + geom = chemist.ChemicalSystem(xyz2chem_mol) + print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + geom_nuclei = geom.molecule.nuclei.as_nuclei() + geom_points = geom_nuclei.charges.point_set + + # Main optimizer operation + energy = submods["Energy"].run_as(TotalEnergy(), geom) + print('Interim energy: \n' + str(energy) + '\n') + gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + print('Interim gradient: \n' + str(gradients) + '\n') + optimizer.send((energy, gradients)) + + opt_geom = geom.molecule.nuclei + print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + # Optimized energy is of type "float" + e = tw.Tensor(energy) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_pyberny_modules(mm): + mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py new file mode 100644 index 0000000..27928b6 --- /dev/null +++ b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Apr 30 04:13:14 2024 + +@author: Felix Rojas +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class NAG_FIRE(): + + def __init__(self,r0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] + #--------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + alpha = 0.001 + mu = 0.9 + theta = 0.1 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- FIRE ------------------------------------------------------- + #---- TIME STEPS and Theta Reset ---------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = VEL[0] + alpha = 0.001 + mu = 0.9 + theta = 0.1 + Np = 0 + Nreset = Nreset + 1 + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + + #----- FORCE UNITE VECTOR ------------------------------------ + + fh = F[i]/np.linalg.norm(F[i]) + + #---- FIRE VELOCITY CORRECTION --------------------- + VEL[i] = (1-theta)*VEL[i] + theta*np.linalg.norm(VEL[i])*fh + #------------------------------------------------------------ + + #----- TIME STEP and THETA UPGRADE --------------------------- + if Np>5: + + alpha = 1.1*alpha + + mu = 1.1*mu + + theta = 0.99*theta + + + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + VEL.append(0) + F.append(0) + norm_force.append(0) + E.append(0) + #--------------- NAG-SUTSKEVER-- --------------------------------- + + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = mu*VEL[i] + alpha*F[i] + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i+1] + #-- FORCE --------------------------------------------------------- + F[i+1] =Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.alpha = alpha + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py new file mode 100644 index 0000000..7255af4 --- /dev/null +++ b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 12:30:09 2024 + +@author: Felix Rojas +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class NAG_SUT_DCNVT(): + + def __init__(self,r0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + v0 = np.array(0) + VEL = [v0] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + alpha = 0.001 + mu = 0.9 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + Nreset = Nreset + 1 + #------------------------------------------------------------------ + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + VEL.append(0) + F.append(0) + norm_force.append(0) + E.append(0) + #--------------- NAG-SUTSKEVER-- --------------------------------- + + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = mu*VEL[i] + alpha*F[i] + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i+1] + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py new file mode 100644 index 0000000..845007d --- /dev/null +++ b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 12:30:09 2024 + +@author: Felix Rojas +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class NAG_SUT_DC_VarT(): + + def __init__(self,r0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + v0 = np.array(0) + VEL = [v0] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + alpha = 0.001 + mu = 0.9 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + alpha = 0.001 + mu = 0.9 + Nreset = Nreset + 1 + #------ TIME STEP UPDATE ----------------------------------------- + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + #--- TIME STEP UPGRADE -------------------------------------- + alpha = 1.1*alpha + mu = 1.1*mu + #------------------------------------------------------------------ + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + VEL.append(0) + F.append(0) + norm_force.append(0) + E.append(0) + #--------------- NAG-SUTSKEVER-- --------------------------------- + + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = mu*VEL[i] + alpha*F[i] + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i+1] + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.alpha = alpha + self.mu = mu + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py new file mode 100644 index 0000000..caabce8 --- /dev/null +++ b/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 12:30:09 2024 + +@author: Felix Rojas +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class NAG_SUT_NDC(): + + def __init__(self,r0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + VEL = [np.array(0)] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + Ncycle = 1000 + #--------------------------------------------------------------------- + alpha = 0.001 + mu = 0.9 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + VEL.append(0) + F.append(0) + norm_force.append(0) + E.append(0) + #--------------- NAG-SUTSKEVER-- --------------------------------- + + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = mu*VEL[i] + alpha*F[i] + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i+1] + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/FIRE_VV/__init__.py b/src/python/structurefinder/FIRE_VV/__init__.py new file mode 100644 index 0000000..2979804 --- /dev/null +++ b/src/python/structurefinder/FIRE_VV/__init__.py @@ -0,0 +1,81 @@ +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pluginplay as pp +from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString +from berny import Berny, geomlib +import chemist +import numpy as np +import tensorwrapper as tw + + +class GeomoptViaPyberny(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergy()) + self.description("Performs PyBerny optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergy() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Convert Chemist Chemical System to XYZ + xyz = "" + xyz += (str(molecule.size()) + "\n\n") + for i in range(molecule.size()): + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + + # Loads the geometry string into the Berny optimizer + # object. + optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) + + for geom in optimizer: + + # Converts the "Berny" geometry object to Chemical System + geom2xyz = geom.dumps('xyz') + print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') + lines = geom2xyz.split('\n') + print('Lines of geom2xyz: \n' + str(lines) + '\n') + mol_string = '\n'.join(lines[2:]) + print('Lines to string: \n' + mol_string + '\n') + xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + geom = chemist.ChemicalSystem(xyz2chem_mol) + print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + geom_nuclei = geom.molecule.nuclei.as_nuclei() + geom_points = geom_nuclei.charges.point_set + + # Main optimizer operation + energy = submods["Energy"].run_as(TotalEnergy(), geom) + print('Interim energy: \n' + str(energy) + '\n') + gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + print('Interim gradient: \n' + str(gradients) + '\n') + optimizer.send((energy, gradients)) + + opt_geom = geom.molecule.nuclei + print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + # Optimized energy is of type "float" + e = tw.Tensor(energy) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_pyberny_modules(mm): + mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/FIRE_VV/vv_DC_NVT.py b/src/python/structurefinder/FIRE_VV/vv_DC_NVT.py new file mode 100644 index 0000000..22a071a --- /dev/null +++ b/src/python/structurefinder/FIRE_VV/vv_DC_NVT.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Aug 11 11:26:48 2023 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class VV_DC_NVT(): + + def __init__(self,r0,h0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + h = h0 + #--------------------------------------------------------------------- + E0= Lennard_Jones_Potential(r0).LJ_energy + #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + Np = 0 + Nreset = Nreset + 1 + #------------------------------------------------------------------ + + + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- VELOCITY VERLET ---------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + #-- FORCE --------------------------------------------------------- + F[i+1]= Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + #-- ENERGY ------------------------------------------------------- + E[i+1]= Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + #--- LIST position update------------------------------------------ + i = i + 1 + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- + diff --git a/src/python/structurefinder/FIRE_VV/vv_DC_VarT.py b/src/python/structurefinder/FIRE_VV/vv_DC_VarT.py new file mode 100644 index 0000000..8a9b15d --- /dev/null +++ b/src/python/structurefinder/FIRE_VV/vv_DC_VarT.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Aug 11 11:26:48 2023 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + + +class VV_DC_VarT(): + + def __init__(self,r0,h0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + h = h0 #<-- time step + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0 = Lennard_Jones_Potential(r0).LJ_energy + #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + t_max = 0.3 #<-- Maximum time step + #-------------------------------------------------------------------- + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- Direction Correction --------------------------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + h = h0 + Np = 0 + Nreset = Nreset + 1 + #------ TIME STEP UPDATE ------------------------------------------ + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + h = h = min(1.1*h,t_max) + #------------------------------------------------------------------ + + + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- VELOCITY VERLET ---------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + #-- FORCE --------------------------------------------------------- + F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + #--- LIST position update------------------------------------------ + i = i + 1 + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- + diff --git a/src/python/structurefinder/FIRE_VV/vv_FIRE.py b/src/python/structurefinder/FIRE_VV/vv_FIRE.py new file mode 100644 index 0000000..3442532 --- /dev/null +++ b/src/python/structurefinder/FIRE_VV/vv_FIRE.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Fri Aug 11 11:26:48 2023 + +@author: leothan +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class VV_FIRE(): + + def __init__(self,r0,h0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) #<-- Position minimum + h = h0 #<-- Time step + #--------------------------------------------------------------------- + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [ np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list + #---------------------------------------------------------------------- + Ncycle = 1000 + Np = 0 + Nreset = 0 + #--------------------------------------------------------------------- + alpha = 0.1 + t_max = 0.3 #<-- Max time step + #--------------------------------------------------------------------- + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- FIRE ------------------------------------------------------- + #---- alpha RESET and Half time step setting -------------------- + if np.dot(VEL[i],F[i])<=0: + VEL[i] = v0 + h = 0.5*h + alpha = 0.1 + Np = 0 + Nreset = Nreset + 1 + elif np.dot(VEL[i],F[i])>0: + Np = Np + 1 + + #----- FORCE UNITE VECTOR ------------------------------------ + + fh = F[i]/np.linalg.norm(F[i]) + + #---- FIRE VELOCITY CORRECTION --------------------- + VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + #------------------------------------------------------------ + + #----- alpha, time step UPGRADE ------------------------------ + if Np>5: + + h = min(1.1*h,t_max) + + + alpha = 0.99*alpha + + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + F.append(0) + norm_force.append(0) + VEL.append(0) + E.append(0) + #--------------- VELOCITY VERLET ---------------------------------- + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + #-- FORCE --------------------------------------------------------- + F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.Np = Np + self.alpha = alpha + self.Nreset = Nreset + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/NSTOVSUT/__init__.py b/src/python/structurefinder/NSTOVSUT/__init__.py new file mode 100644 index 0000000..2979804 --- /dev/null +++ b/src/python/structurefinder/NSTOVSUT/__init__.py @@ -0,0 +1,81 @@ +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pluginplay as pp +from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString +from berny import Berny, geomlib +import chemist +import numpy as np +import tensorwrapper as tw + + +class GeomoptViaPyberny(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergy()) + self.description("Performs PyBerny optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergy() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Convert Chemist Chemical System to XYZ + xyz = "" + xyz += (str(molecule.size()) + "\n\n") + for i in range(molecule.size()): + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + + # Loads the geometry string into the Berny optimizer + # object. + optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) + + for geom in optimizer: + + # Converts the "Berny" geometry object to Chemical System + geom2xyz = geom.dumps('xyz') + print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') + lines = geom2xyz.split('\n') + print('Lines of geom2xyz: \n' + str(lines) + '\n') + mol_string = '\n'.join(lines[2:]) + print('Lines to string: \n' + mol_string + '\n') + xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + geom = chemist.ChemicalSystem(xyz2chem_mol) + print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + geom_nuclei = geom.molecule.nuclei.as_nuclei() + geom_points = geom_nuclei.charges.point_set + + # Main optimizer operation + energy = submods["Energy"].run_as(TotalEnergy(), geom) + print('Interim energy: \n' + str(energy) + '\n') + gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + print('Interim gradient: \n' + str(gradients) + '\n') + optimizer.send((energy, gradients)) + + opt_geom = geom.molecule.nuclei + print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + # Optimized energy is of type "float" + e = tw.Tensor(energy) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_pyberny_modules(mm): + mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py new file mode 100644 index 0000000..caabce8 --- /dev/null +++ b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 29 12:30:09 2024 + +@author: Felix Rojas +""" + +# Imported modules +import numpy as np +from LJ_potential import Lennard_Jones_Potential + +class NAG_SUT_NDC(): + + def __init__(self,r0): + + #---- DATA INITIALIZAION --------------------------------------------- + r0 = np.array([r0]) + POS = [r0] #<-- Position list + VEL = [np.array(0)] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1/6) + #--------------------------------------------------------------------- + E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E = [E0] + #--------------------------------------------------------------------- + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] + #---------------------------------------------------------------------- + Ncycle = 1000 + #--------------------------------------------------------------------- + alpha = 0.001 + mu = 0.9 + #--------------------------------------------------------------------- + + k=0 + i=0 + while k < (Ncycle): + k = k + 1 + #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + #------------------------------------------------------------------ + if pos_norm_error < 10**(-8): + break + #----- NEW ELEMENT in the lists ----------------------------------- + POS.append(0) + VEL.append(0) + F.append(0) + norm_force.append(0) + E.append(0) + #--------------- NAG-SUTSKEVER-- --------------------------------- + + #-- VELOCITY ------------------------------------------------------ + VEL[i+1] = mu*VEL[i] + alpha*F[i] + #-- POSITION ------------------------------------------------------ + POS[i+1] = POS[i] + VEL[i+1] + #-- FORCE --------------------------------------------------------- + F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart + norm_force[i+1] = np.linalg.norm(F[i+1]) + #-- ENERGY ------------------------------------------------------- + E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + + break + #------------------------------------------------------------------ + + #------------- NORM OF FORCE CONVERGENCE -------------------------- + if np.linalg.norm(F[i+1])<10**(-8): + + break + #------------------------------------------------------------------ + + + #--- LIST position update------------------------------------------ + i = i + 1 + + #--------- END OF OPTIMIZTION PROCESS --------------------------------- + #--- COLLECTED DATA ANALYSIS ------------------------------------------ + #---------------------------------------------------------------------- + POS = np.array(POS) #<--- To calculate the position errors + ini_dist = np.linalg.norm(r0 - pos_minima) + #---- position error calculation ------------------------------------- + position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + #--------------------------------------------------------------------- + + #----------------- Energy Error calculations ------------------------- + E = np.array(E)#<---- To calculate Energy errors + #--------------------------------------------------------------------- + energy_errors = abs((E - MIN)/(E[0]-MIN)) + #------- ATRIBUTES ---------------------------------------------------- + self.steps = len(E) + self.positions = POS + self.minima_error = position_errors + self.forces = F + self.norm_forces = np.array(norm_force) + self.velocity = VEL + self.energy = E + self.energy_errors = energy_errors + self.min_force =min(norm_force) + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/pyberny/__init__.py b/src/python/structurefinder/pyberny/__init__.py index 886f192..2979804 100644 --- a/src/python/structurefinder/pyberny/__init__.py +++ b/src/python/structurefinder/pyberny/__init__.py @@ -16,6 +16,8 @@ from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString from berny import Berny, geomlib import chemist +import numpy as np +import tensorwrapper as tw class GeomoptViaPyberny(pp.ModuleBase): @@ -37,8 +39,7 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + - str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -53,31 +54,24 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as( - MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + - str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + - str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as( - EnergyNuclearGradientStdVectorD(), geom, - geom_points.as_point_set()) + gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print( - 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + - str(opt_geom)) + print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) # Optimized energy is of type "float" - e = energy + e = tw.Tensor(energy) print(e) rv = self.results() return pt.wrap_results(rv, e) From 50a4e1a918afe17f0e089299fff3dcc48ef3f8f9 Mon Sep 17 00:00:00 2001 From: leothan Date: Mon, 21 Apr 2025 09:13:09 -0500 Subject: [PATCH 02/23] FIRE optimizers added --- .../structurefinder/FIRE_BE/be2_FIRE.py | 112 ++++++++++++------ .../test_optimizers/test_pybernyop.py | 78 ++++++------ 2 files changed, 119 insertions(+), 71 deletions(-) diff --git a/src/python/structurefinder/FIRE_BE/be2_FIRE.py b/src/python/structurefinder/FIRE_BE/be2_FIRE.py index 2772131..0d94987 100644 --- a/src/python/structurefinder/FIRE_BE/be2_FIRE.py +++ b/src/python/structurefinder/FIRE_BE/be2_FIRE.py @@ -1,47 +1,93 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Mon Apr 29 16:13:47 2024 +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. -@author: leothan -""" - -# Imported modules +import pluginplay as pp +from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString +from berny import Berny, geomlib +import chemist import numpy as np -from LJ_potential import Lennard_Jones_Potential +import tensorwrapper as tw + +class GeomoptViaBackwardEulerFIRE(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergy()) + self.description("Performs Backware Euler-FIRE optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergy() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Convert Chemist Chemical System to XYZ + xyz = "" + xyz += (str(molecule.size()) + "\n\n") + for i in range(molecule.size()): + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + + # def e_func(geom): + # return submods["Energy"].run_as(TotalEnergy(), geom) + + # def grad_func(geom): + # return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + + # Loads the geometry string into the Berny optimizer + # object. + # optimizer = BE2_FIRE(settings) + # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) + # print(optimized_geom) + + # Optimized energy is of type "float" + e = tw.Tensor(np.array(optimized_energy)) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_backwardeulerfire_modules(mm): + mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) + + + + + +#----------------------------------------------------------------------------------------------------------------- class BE2_FIRE(): - def __init__(self,r0,h0): + def __init__(self,v0,h0,numbcycles): - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) #<-- Position minimum - h = h0 #<-- Time step - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v_initial = np.array(v0) #<-- Initial Velocity + VEL = [v_initial] #<-- Velocity list #---------------------------------------------------------------------- - Ncycle = 1000 + h = h0 #<-- Time step + #---------------------------------------------------------------------- + #----- Optimization cycle parameters ---------------------------------- + Ncycle = numbcycles Np = 0 Nreset = 0 - #--------------------------------------------------------------------- + #------FIRE parameters ----------------------------------------------- alpha = 0.1 t_max = 0.3 - #--------------------------------------------------------------------- - - k=0 - i=0 - Nreset = 0 + #------Counters ------------------------------------------------------ + k=0 #<-- Convergence cycles + i=0 #<-- numpy array counter #---------------------------------------------------------------------- while k < (Ncycle): k = k + 1 @@ -55,7 +101,7 @@ def __init__(self,r0,h0): #----- FIRE ------------------------------------------------------ #---- alpha RESET and Half time step setting --------------------- if np.dot(VEL[i],F[i])<=0: - VEL[i] = v0 + VEL[i] = v_initial h = 0.5*h alpha = 0.1 Np = 0 diff --git a/tests/python/unit_tests/test_optimizers/test_pybernyop.py b/tests/python/unit_tests/test_optimizers/test_pybernyop.py index 26611e6..d718f3a 100644 --- a/tests/python/unit_tests/test_optimizers/test_pybernyop.py +++ b/tests/python/unit_tests/test_optimizers/test_pybernyop.py @@ -1,43 +1,45 @@ -# Copyright 2024 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# # Copyright 2024 NWChemEx Community +# # +# # Licensed under the Apache License, Version 2.0 (the "License"); +# # you may not use this file except in compliance with the License. +# # You may obtain a copy of the License at +# # +# # http://www.apache.org/licenses/LICENSE-2.0 +# # +# # Unless required by applicable law or agreed to in writing, software +# # distributed under the License is distributed on an "AS IS" BASIS, +# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# # See the License for the specific language governing permissions and +# # limitations under the License. -import structurefinder -import nwchemex -import pluginplay as pp -import chemist -import unittest -from simde import TotalEnergy +# import structurefinder +# import nwchemex +# import pluginplay as pp +# import chemist +# import unittest +# from simde import TotalEnergy +# import numpy as np +# import tensorwrapper as tw -class Test_optimize_pyberny(unittest.TestCase): +# class Test_optimize_pyberny(unittest.TestCase): - def test_optimize_pyberny(self): - mm = pp.ModuleManager() - nwchemex.load_modules(mm) - structurefinder.load_modules(mm) - mm.change_input("NWChem : SCF", "basis set", "sto-3g") - mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") - mm.change_submod("PyBerny", "Gradient", "NWChem : SCF Gradient") - mm.change_submod("PyBerny", "Energy", "NWChem : SCF") - mm.change_submod("Pyberny", "StringConv", - "ChemicalSystem via QCElemental") - egy = mm.run_as(TotalEnergy(), "PyBerny", - chemist.ChemicalSystem(self.mol)) - print("Energy = " + str(egy)) - self.assertAlmostEqual(egy, -1.117505879316, 10) +# def test_optimize_pyberny(self): +# mm = pp.ModuleManager() +# nwchemex.load_modules(mm) +# structurefinder.load_modules(mm) +# mm.change_input("NWChem : SCF", "basis set", "sto-3g") +# mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") +# mm.change_submod("PyBerny", "Gradient", "NWChem : SCF Gradient") +# mm.change_submod("PyBerny", "Energy", "NWChem : SCF") +# mm.change_submod("Pyberny", "StringConv", +# "ChemicalSystem via QCElemental") +# egy = mm.run_as(TotalEnergy(), "PyBerny", +# chemist.ChemicalSystem(self.mol)) +# print("Energy = " + str(egy)) +# self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) - def setUp(self): - self.mol = chemist.Molecule() - self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) - self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) +# def setUp(self): +# self.mol = chemist.Molecule() +# self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) +# self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) From 26d9a5d045d6a4a02e603678f3474dc2ee015761 Mon Sep 17 00:00:00 2001 From: leothan Date: Mon, 21 Apr 2025 09:30:00 -0500 Subject: [PATCH 03/23] First changes to be2_FIRE.py --- .../structurefinder/FIRE_BE/be2_FIRE.py | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/python/structurefinder/FIRE_BE/be2_FIRE.py b/src/python/structurefinder/FIRE_BE/be2_FIRE.py index 0d94987..d74d1fb 100644 --- a/src/python/structurefinder/FIRE_BE/be2_FIRE.py +++ b/src/python/structurefinder/FIRE_BE/be2_FIRE.py @@ -53,24 +53,9 @@ def run_(self, inputs, submods): # print(optimized_geom) # Optimized energy is of type "float" - e = tw.Tensor(np.array(optimized_energy)) - print(e) - rv = self.results() - return pt.wrap_results(rv, e) - - -def load_backwardeulerfire_modules(mm): - mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) - - - - #----------------------------------------------------------------------------------------------------------------- - -class BE2_FIRE(): - - def __init__(self,v0,h0,numbcycles): + def BE2_FIRE(self,v0,h0,numbcycles): #---------------------------------------------------------------------- v_initial = np.array(v0) #<-- Initial Velocity @@ -187,4 +172,19 @@ def __init__(self,v0,h0,numbcycles): self.Nreset = Nreset self.min_force =min(norm_force) #---------------------------------------------------------------------- - # END of code -------------------------------------------------------- + + + e = tw.Tensor(np.array(optimized_energy)) + print(e) + rv = self.results() + return pt.wrap_results(rv, e) + + +def load_backwardeulerfire_modules(mm): + mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) + + + + + + From 5a24d1752e7b4e9acbf64dc155058afce37f8cb0 Mon Sep 17 00:00:00 2001 From: leothan Date: Mon, 21 Apr 2025 10:30:26 -0500 Subject: [PATCH 04/23] getting coordinates of molecule line 37 --- .../structurefinder/FIRE_BE/be2_FIRE.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/python/structurefinder/FIRE_BE/be2_FIRE.py b/src/python/structurefinder/FIRE_BE/be2_FIRE.py index d74d1fb..204d381 100644 --- a/src/python/structurefinder/FIRE_BE/be2_FIRE.py +++ b/src/python/structurefinder/FIRE_BE/be2_FIRE.py @@ -34,11 +34,15 @@ def run_(self, inputs, submods): mol, = pt.unwrap_inputs(inputs) molecule = mol.molecule - # Convert Chemist Chemical System to XYZ - xyz = "" - xyz += (str(molecule.size()) + "\n\n") + # Construction of the coordinate vecotr + numb_atoms = molecule.size() #<-- Number of atoms + numb_coord = 3*numb_atoms #<-- Number of coordinates + R_xyz = np.zeros(numb_atoms) #<-- Initializing the coordiantes vector for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + for j in range(numb_coord): + R_xyz[j] = molecule.at(i).x + R_xyz[j+1] = molecule.at(i).y + R_xyz[j+2] = molecule.at(i).z # def e_func(geom): # return submods["Energy"].run_as(TotalEnergy(), geom) @@ -55,7 +59,7 @@ def run_(self, inputs, submods): # Optimized energy is of type "float" #----------------------------------------------------------------------------------------------------------------- - def BE2_FIRE(self,v0,h0,numbcycles): + def BE2_FIRE(self,v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=1000, error = 10**(-8)): #---------------------------------------------------------------------- v_initial = np.array(v0) #<-- Initial Velocity @@ -68,8 +72,9 @@ def BE2_FIRE(self,v0,h0,numbcycles): Np = 0 Nreset = 0 #------FIRE parameters ----------------------------------------------- - alpha = 0.1 - t_max = 0.3 + alpha = alpha + t_max = t_max + error = error #------Counters ------------------------------------------------------ k=0 #<-- Convergence cycles i=0 #<-- numpy array counter @@ -81,7 +86,7 @@ def BE2_FIRE(self,v0,h0,numbcycles): down_pos_norm_error = np.linalg.norm(POS[0]-MIN) pos_norm_error = (up_pos_norm_error/down_pos_norm_error) #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): + if pos_norm_error < error: break #----- FIRE ------------------------------------------------------ #---- alpha RESET and Half time step setting --------------------- @@ -130,13 +135,13 @@ def BE2_FIRE(self,v0,h0,numbcycles): E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): + if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: break #------------------------------------------------------------------ #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): + if np.linalg.norm(F[i+1])< error: break #------------------------------------------------------------------ From 125c87fd63c5c47ac9e50797559eba9b44d94962 Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 6 May 2025 15:47:29 -0500 Subject: [PATCH 05/23] adding fire folder and testing backward_euler.py --- .../structurefinder/FIRE_BE/be2_FIRE.py | 195 ----------------- src/python/structurefinder/__init__.py | 3 +- src/python/structurefinder/fire/__init__.py | 0 .../backward_euler}/__init__.py | 0 .../fire/backward_euler/backward_euler.py | 196 ++++++++++++++++++ .../backward_euler}/be2_DC_NVT.py | 0 .../backward_euler}/be2_DC_VarT.py | 0 .../nesterov_sutskever}/__init__.py | 0 .../nesterov_SUT_DC_NVT.py | 0 .../nesterov_SUT_DC_VarT.py | 0 .../nesterov_sutskever}/nesterov_SUT_NDC.py | 0 .../nesterov_sutskever/nesterov_sutskever.py} | 0 .../velocity_verlet}/__init__.py | 0 .../velocity_verlet/velocity_verlet.py} | 0 .../velocity_verlet}/vv_DC_NVT.py | 0 .../velocity_verlet}/vv_DC_VarT.py | 0 .../test_backward_euler_fire.py | 49 +++++ 17 files changed, 247 insertions(+), 196 deletions(-) delete mode 100644 src/python/structurefinder/FIRE_BE/be2_FIRE.py create mode 100644 src/python/structurefinder/fire/__init__.py rename src/python/structurefinder/{FIRE_BE => fire/backward_euler}/__init__.py (100%) create mode 100644 src/python/structurefinder/fire/backward_euler/backward_euler.py rename src/python/structurefinder/{FIRE_BE => fire/backward_euler}/be2_DC_NVT.py (100%) rename src/python/structurefinder/{FIRE_BE => fire/backward_euler}/be2_DC_VarT.py (100%) rename src/python/structurefinder/{FIRE_NSTOVSUT => fire/nesterov_sutskever}/__init__.py (100%) rename src/python/structurefinder/{FIRE_NSTOVSUT => fire/nesterov_sutskever}/nesterov_SUT_DC_NVT.py (100%) rename src/python/structurefinder/{FIRE_NSTOVSUT => fire/nesterov_sutskever}/nesterov_SUT_DC_VarT.py (100%) rename src/python/structurefinder/{FIRE_NSTOVSUT => fire/nesterov_sutskever}/nesterov_SUT_NDC.py (100%) rename src/python/structurefinder/{FIRE_NSTOVSUT/nesterov_FIRE.py => fire/nesterov_sutskever/nesterov_sutskever.py} (100%) rename src/python/structurefinder/{FIRE_VV => fire/velocity_verlet}/__init__.py (100%) rename src/python/structurefinder/{FIRE_VV/vv_FIRE.py => fire/velocity_verlet/velocity_verlet.py} (100%) rename src/python/structurefinder/{FIRE_VV => fire/velocity_verlet}/vv_DC_NVT.py (100%) rename src/python/structurefinder/{FIRE_VV => fire/velocity_verlet}/vv_DC_VarT.py (100%) create mode 100644 tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py diff --git a/src/python/structurefinder/FIRE_BE/be2_FIRE.py b/src/python/structurefinder/FIRE_BE/be2_FIRE.py deleted file mode 100644 index 204d381..0000000 --- a/src/python/structurefinder/FIRE_BE/be2_FIRE.py +++ /dev/null @@ -1,195 +0,0 @@ -# Copyright 2023 NWChemEx-Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pluginplay as pp -from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString -from berny import Berny, geomlib -import chemist -import numpy as np -import tensorwrapper as tw - -class GeomoptViaBackwardEulerFIRE(pp.ModuleBase): - - def __init__(self): - pp.ModuleBase.__init__(self) - self.satisfies_property_type(TotalEnergy()) - self.description("Performs Backware Euler-FIRE optimization") - self.add_submodule(TotalEnergy(), "Energy") - self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") - self.add_submodule(MoleculeFromString(), "StringConv") - - def run_(self, inputs, submods): - pt = TotalEnergy() - mol, = pt.unwrap_inputs(inputs) - molecule = mol.molecule - - # Construction of the coordinate vecotr - numb_atoms = molecule.size() #<-- Number of atoms - numb_coord = 3*numb_atoms #<-- Number of coordinates - R_xyz = np.zeros(numb_atoms) #<-- Initializing the coordiantes vector - for i in range(molecule.size()): - for j in range(numb_coord): - R_xyz[j] = molecule.at(i).x - R_xyz[j+1] = molecule.at(i).y - R_xyz[j+2] = molecule.at(i).z - - # def e_func(geom): - # return submods["Energy"].run_as(TotalEnergy(), geom) - - # def grad_func(geom): - # return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) - - # Loads the geometry string into the Berny optimizer - # object. - # optimizer = BE2_FIRE(settings) - # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) - # print(optimized_geom) - - # Optimized energy is of type "float" - -#----------------------------------------------------------------------------------------------------------------- - def BE2_FIRE(self,v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=1000, error = 10**(-8)): - - #---------------------------------------------------------------------- - v_initial = np.array(v0) #<-- Initial Velocity - VEL = [v_initial] #<-- Velocity list - #---------------------------------------------------------------------- - h = h0 #<-- Time step - #---------------------------------------------------------------------- - #----- Optimization cycle parameters ---------------------------------- - Ncycle = numbcycles - Np = 0 - Nreset = 0 - #------FIRE parameters ----------------------------------------------- - alpha = alpha - t_max = t_max - error = error - #------Counters ------------------------------------------------------ - k=0 #<-- Convergence cycles - i=0 #<-- numpy array counter - #---------------------------------------------------------------------- - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < error: - break - #----- FIRE ------------------------------------------------------ - #---- alpha RESET and Half time step setting --------------------- - if np.dot(VEL[i],F[i])<=0: - VEL[i] = v_initial - h = 0.5*h - alpha = 0.1 - Np = 0 - Nreset = Nreset + 1 - - elif np.dot(VEL[i],F[i])>0: - Np = Np + 1 - - #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i]/np.linalg.norm(F[i]) - - #---- FIRE VELOCITY CORRECTION ------------------------------- - VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh - #------------------------------------------------------------- - - #----- alpha, time step UPGRADE ------------------------------ - if Np>5: - - h = min(1.1*h,t_max) - - - alpha = 0.99*alpha - - - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - F.append(0) - norm_force.append(0) - VEL.append(0) - E.append(0) - #--------------- BACKWARD EULER(2)--------------------------------- - #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h - #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) - #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + F[i+1]*h - #-- ENERGY ------------------------------------------------------- - E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])< error: - - break - #------------------------------------------------------------------ - - - #--- LIST position update------------------------------------------ - i = i + 1 - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.alpha = alpha - self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - - - e = tw.Tensor(np.array(optimized_energy)) - print(e) - rv = self.results() - return pt.wrap_results(rv, e) - - -def load_backwardeulerfire_modules(mm): - mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) - - - - - - diff --git a/src/python/structurefinder/__init__.py b/src/python/structurefinder/__init__.py index 4de7eee..531a387 100644 --- a/src/python/structurefinder/__init__.py +++ b/src/python/structurefinder/__init__.py @@ -14,7 +14,7 @@ from .pyberny import load_pyberny_modules from .lj_potential.lennard_jones_potential_module import load_lennard_jones_potential - +from .fire.backward_euler import load_backwardeulerfire_modules def load_modules(mm): """ @@ -22,3 +22,4 @@ def load_modules(mm): """ load_pyberny_modules(mm) load_lennard_jones_potential(mm) + load_backwardeulerfire_modules(mm) diff --git a/src/python/structurefinder/fire/__init__.py b/src/python/structurefinder/fire/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/python/structurefinder/FIRE_BE/__init__.py b/src/python/structurefinder/fire/backward_euler/__init__.py similarity index 100% rename from src/python/structurefinder/FIRE_BE/__init__.py rename to src/python/structurefinder/fire/backward_euler/__init__.py diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py new file mode 100644 index 0000000..8d72dee --- /dev/null +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -0,0 +1,196 @@ +# Copyright 2023 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pluginplay as pp +from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy,TotalEnergyNuclearOptimization, MoleculeFromString) +from berny import Berny, geomlib +import chemist +import numpy as np +import tensorwrapper as tw + +class GeomoptViaBackwardEulerFIRE(pp.ModuleBase): + + def __init__(self): + pp.ModuleBase.__init__(self) + self.satisfies_property_type(TotalEnergyNuclearOptimization()) + self.description("Performs Backward Euler-FIRE optimization") + self.add_submodule(TotalEnergy(), "Energy") + self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") + self.add_submodule(MoleculeFromString(), "StringConv") + + def run_(self, inputs, submods): + pt = TotalEnergyNuclearOptimization() + mol, = pt.unwrap_inputs(inputs) + molecule = mol.molecule + + # Construction of the coordinate vecotr + # numb_atoms = molecule.size() #<-- Number of atoms + # numb_coord = 3*numb_atoms #<-- Number of coordinates + # R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector + # for i in range(molecule.size()): + # for j in range(3): + # R_xyz[j] = molecule.at(i).x + # R_xyz[j+1] = molecule.at(i).y + # R_xyz[j+2] = molecule.at(i).z + # return R_xyz + # def e_func(geom): + # return submods["Energy"].run_as(TotalEnergy(), geom) + + # def grad_func(geom): + # return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + + # Loads the geometry string into the Berny optimizer + # object. + # optimizer = BE2_FIRE(settings) + # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) + # print(optimized_geom) + + # Optimized energy is of type "float" + +#----------------------------------------------------------------------------------------------------------------- +# def BE2_FIRE(self,v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=1000, error = 10**(-8)): + +# #---------------------------------------------------------------------- +# v_initial = np.array(v0) #<-- Initial Velocity +# VEL = [v_initial] #<-- Velocity list +# #---------------------------------------------------------------------- +# h = h0 #<-- Time step +# #---------------------------------------------------------------------- +# #----- Optimization cycle parameters ---------------------------------- +# Ncycle = numbcycles +# Np = 0 +# Nreset = 0 +# #------FIRE parameters ----------------------------------------------- +# alpha = alpha +# t_max = t_max +# error = error +# #------Counters ------------------------------------------------------ +# k=0 #<-- Convergence cycles +# i=0 #<-- numpy array counter +# #---------------------------------------------------------------------- +# while k < (Ncycle): +# k = k + 1 +# #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- +# up_pos_norm_error = np.linalg.norm(POS[i] - MIN) +# down_pos_norm_error = np.linalg.norm(POS[0]-MIN) +# pos_norm_error = (up_pos_norm_error/down_pos_norm_error) +# #------------------------------------------------------------------ +# if pos_norm_error < error: +# break +# #----- FIRE ------------------------------------------------------ +# #---- alpha RESET and Half time step setting --------------------- +# if np.dot(VEL[i],F[i])<=0: +# VEL[i] = v_initial +# h = 0.5*h +# alpha = 0.1 +# Np = 0 +# Nreset = Nreset + 1 + +# elif np.dot(VEL[i],F[i])>0: +# Np = Np + 1 + +# #----- FORCE UNITE VECTOR ------------------------------------ + +# fh = F[i]/np.linalg.norm(F[i]) + +# #---- FIRE VELOCITY CORRECTION ------------------------------- +# VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh +# #------------------------------------------------------------- + +# #----- alpha, time step UPGRADE ------------------------------ +# if Np>5: + +# h = min(1.1*h,t_max) + + +# alpha = 0.99*alpha + + +# #----- NEW ELEMENT in the lists ----------------------------------- +# POS.append(0) +# F.append(0) +# norm_force.append(0) +# VEL.append(0) +# E.append(0) +# #--------------- BACKWARD EULER(2)--------------------------------- +# #-- POSITION ------------------------------------------------------ +# POS[i+1] = POS[i] + VEL[i]*h +# #-- FORCE --------------------------------------------------------- +# F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart +# norm_force[i+1] = np.linalg.norm(F[i+1]) +# #-- VELOCITY ------------------------------------------------------ +# VEL[i+1] = VEL[i] + F[i+1]*h +# #-- ENERGY ------------------------------------------------------- +# E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + +# #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- +# if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: + +# break +# #------------------------------------------------------------------ + +# #------------- NORM OF FORCE CONVERGENCE -------------------------- +# if np.linalg.norm(F[i+1])< error: + +# break +# #------------------------------------------------------------------ + + +# #--- LIST position update------------------------------------------ +# i = i + 1 +# #--------- END OF OPTIMIZTION PROCESS --------------------------------- + +# #--- COLLECTED DATA ANALYSIS ------------------------------------------ +# #---------------------------------------------------------------------- +# POS = np.array(POS) #<--- To calculate the position errors +# ini_dist = np.linalg.norm(r0 - pos_minima) +# #---- position error calculation ------------------------------------- +# position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist +# #--------------------------------------------------------------------- + +# #----------------- Energy Error calculations ------------------------- +# E = np.array(E)#<---- To calculate Energy errors +# #--------------------------------------------------------------------- +# energy_errors = abs((E - MIN)/(E[0]-MIN)) +# #------- ATRIBUTES ---------------------------------------------------- +# self.steps = len(E) +# self.positions = POS +# self.minima_error = position_errors +# self.forces = F +# self.norm_forces = np.array(norm_force) +# self.velocity = VEL +# self.energy = E +# self.energy_errors = energy_errors +# self.Np = Np +# self.alpha = alpha +# self.Nreset = Nreset +# self.min_force =min(norm_force) +# #---------------------------------------------------------------------- + + + e = tw.Tensor(np.array(0)) + ps = chemist.PointSetD() + ps.push_back(chemist.PointD(1.0,2.0,3.0)) + # print(e) + rv = self.results() + return pt.wrap_results(rv, e, ps) + +def load_backwardeulerfire_modules(mm): + mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) + + + + + + diff --git a/src/python/structurefinder/FIRE_BE/be2_DC_NVT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py similarity index 100% rename from src/python/structurefinder/FIRE_BE/be2_DC_NVT.py rename to src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py diff --git a/src/python/structurefinder/FIRE_BE/be2_DC_VarT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py similarity index 100% rename from src/python/structurefinder/FIRE_BE/be2_DC_VarT.py rename to src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/__init__.py b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py similarity index 100% rename from src/python/structurefinder/FIRE_NSTOVSUT/__init__.py rename to src/python/structurefinder/fire/nesterov_sutskever/__init__.py diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py similarity index 100% rename from src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_NVT.py rename to src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py similarity index 100% rename from src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_DC_VarT.py rename to src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py similarity index 100% rename from src/python/structurefinder/FIRE_NSTOVSUT/nesterov_SUT_NDC.py rename to src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py diff --git a/src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py similarity index 100% rename from src/python/structurefinder/FIRE_NSTOVSUT/nesterov_FIRE.py rename to src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py diff --git a/src/python/structurefinder/FIRE_VV/__init__.py b/src/python/structurefinder/fire/velocity_verlet/__init__.py similarity index 100% rename from src/python/structurefinder/FIRE_VV/__init__.py rename to src/python/structurefinder/fire/velocity_verlet/__init__.py diff --git a/src/python/structurefinder/FIRE_VV/vv_FIRE.py b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py similarity index 100% rename from src/python/structurefinder/FIRE_VV/vv_FIRE.py rename to src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py diff --git a/src/python/structurefinder/FIRE_VV/vv_DC_NVT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py similarity index 100% rename from src/python/structurefinder/FIRE_VV/vv_DC_NVT.py rename to src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py diff --git a/src/python/structurefinder/FIRE_VV/vv_DC_VarT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py similarity index 100% rename from src/python/structurefinder/FIRE_VV/vv_DC_VarT.py rename to src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py new file mode 100644 index 0000000..5a5c846 --- /dev/null +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -0,0 +1,49 @@ +# # Copyright 2024 NWChemEx Community +# # +# # Licensed under the Apache License, Version 2.0 (the "License"); +# # you may not use this file except in compliance with the License. +# # You may obtain a copy of the License at +# # +# # http://www.apache.org/licenses/LICENSE-2.0 +# # +# # Unless required by applicable law or agreed to in writing, software +# # distributed under the License is distributed on an "AS IS" BASIS, +# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# # See the License for the specific language governing permissions and +# # limitations under the License. + +import structurefinder +import nwchemex +import pluginplay as pp +import chemist +import unittest +from simde import TotalEnergyNuclearOptimization +import numpy as np +import tensorwrapper as tw + + +class Test_TotalEnergyNuclearOptimization(unittest.TestCase): + + def test_optimize_BEfire(self): + mm = pp.ModuleManager() + nwchemex.load_modules(mm) + structurefinder.load_modules(mm) + mm.change_input("NWChem : SCF", "basis set", "sto-3g") + mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") + mm.change_submod("BackwardEulerFire", "Gradient", "NWChem : SCF Gradient") + mm.change_submod("BackwardEulerFire", "Energy", "NWChem : SCF") + mm.change_submod("BackwardEulerFire", "StringConv", + "ChemicalSystem via QCElemental") + egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), "BackwardEulerFire", + self.sys, self.pointset) + print("Energy = " + str(egy)) + print(pts) + #self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) + + def setUp(self): + self.mol = chemist.Molecule() + self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) + self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) + self.sys = chemist.ChemicalSystem(self.mol) + self.nuclei = self.mol.nuclei.as_nuclei() + self.pointset = self.nuclei.charges.point_set.as_point_set() From 46c5e06a6204b8736ae75d13e88fb7c534441936 Mon Sep 17 00:00:00 2001 From: leothan Date: Sun, 1 Jun 2025 15:44:18 -0500 Subject: [PATCH 06/23] last changes not final June 1st --- src/python/structurefinder/__init__.py | 2 +- .../fire/backward_euler/backward_euler.py | 24 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/python/structurefinder/__init__.py b/src/python/structurefinder/__init__.py index 531a387..cbe9a96 100644 --- a/src/python/structurefinder/__init__.py +++ b/src/python/structurefinder/__init__.py @@ -14,7 +14,7 @@ from .pyberny import load_pyberny_modules from .lj_potential.lennard_jones_potential_module import load_lennard_jones_potential -from .fire.backward_euler import load_backwardeulerfire_modules +from .fire.backward_euler.backward_euler import load_backwardeulerfire_modules def load_modules(mm): """ diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index 8d72dee..a92b6bc 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -14,7 +14,6 @@ import pluginplay as pp from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy,TotalEnergyNuclearOptimization, MoleculeFromString) -from berny import Berny, geomlib import chemist import numpy as np import tensorwrapper as tw @@ -31,19 +30,20 @@ def __init__(self): def run_(self, inputs, submods): pt = TotalEnergyNuclearOptimization() - mol, = pt.unwrap_inputs(inputs) + mol, points = pt.unwrap_inputs(inputs) molecule = mol.molecule # Construction of the coordinate vecotr - # numb_atoms = molecule.size() #<-- Number of atoms - # numb_coord = 3*numb_atoms #<-- Number of coordinates - # R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector - # for i in range(molecule.size()): - # for j in range(3): - # R_xyz[j] = molecule.at(i).x - # R_xyz[j+1] = molecule.at(i).y - # R_xyz[j+2] = molecule.at(i).z - # return R_xyz + numb_atoms = molecule.size() #<-- Number of atoms + numb_coord = 3*numb_atoms #<-- Number of coordinates + R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector + for i in range(molecule.size()): + for j in range(3): + R_xyz[j] = molecule.at(i).x + R_xyz[j+1] = molecule.at(i).y + R_xyz[j+2] = molecule.at(i).z + print(R_xyz) + # def e_func(geom): # return submods["Energy"].run_as(TotalEnergy(), geom) @@ -179,7 +179,7 @@ def run_(self, inputs, submods): # #---------------------------------------------------------------------- - e = tw.Tensor(np.array(0)) + e = tw.Tensor(np.array([0.0],[0.0])) ps = chemist.PointSetD() ps.push_back(chemist.PointD(1.0,2.0,3.0)) # print(e) From f66687ef472f489401fa6e356c35c3d4d5a6a0a8 Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 17 Jun 2025 11:31:04 -0500 Subject: [PATCH 07/23] gitignore and change to backward_euler.py --- .gitignore | 1 + .../structurefinder/fire/backward_euler/backward_euler.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ebb5abb..7317922 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ __pycache__/ build/ venv/ install/ +toolchain.cmake diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index a92b6bc..ec19139 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -179,7 +179,7 @@ def run_(self, inputs, submods): # #---------------------------------------------------------------------- - e = tw.Tensor(np.array([0.0],[0.0])) + e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() ps.push_back(chemist.PointD(1.0,2.0,3.0)) # print(e) From c94930272451ee7761c4b51ce0ad875e7daada97 Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 17 Jun 2025 13:57:51 -0500 Subject: [PATCH 08/23] updates to backward_euler.py and test_backward_eluer.py --- .../fire/backward_euler/backward_euler.py | 36 +++++++++---------- .../test_backward_euler_fire.py | 14 +++++++- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index ec19139..f07d9ad 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -37,26 +37,24 @@ def run_(self, inputs, submods): numb_atoms = molecule.size() #<-- Number of atoms numb_coord = 3*numb_atoms #<-- Number of coordinates R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector - for i in range(molecule.size()): - for j in range(3): - R_xyz[j] = molecule.at(i).x - R_xyz[j+1] = molecule.at(i).y - R_xyz[j+2] = molecule.at(i).z - print(R_xyz) + for i_atom in range(molecule.size()): + R_xyz[3*i_atom] = molecule.at(i_atom).x + R_xyz[3*i_atom + 1] = molecule.at(i_atom).y + R_xyz[3*i_atom + 2] = molecule.at(i_atom).z + print(list(R_xyz)) - # def e_func(geom): - # return submods["Energy"].run_as(TotalEnergy(), geom) - - # def grad_func(geom): - # return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + def e_func(geom): + return submods["Energy"].run_as(TotalEnergy(), geom) + + def grad_func(geom): + return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) - # Loads the geometry string into the Berny optimizer - # object. - # optimizer = BE2_FIRE(settings) - # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) - # print(optimized_geom) + #Loads the geometry string into the Berny optimizer object. + optimizer = BE2_FIRE(settings) + optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) + #print(optimized_geom) - # Optimized energy is of type "float" + # Optimized energy is of type "float" #----------------------------------------------------------------------------------------------------------------- # def BE2_FIRE(self,v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=1000, error = 10**(-8)): @@ -181,8 +179,8 @@ def run_(self, inputs, submods): e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() - ps.push_back(chemist.PointD(1.0,2.0,3.0)) - # print(e) + for i in range(numb_atoms): + ps.push_back(chemist.PointD(R_xyz[3*i],R_xyz[3*i + 1], R_xyz[3*i + 2])) rv = self.results() return pt.wrap_results(rv, e, ps) diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index 5a5c846..31bd8a9 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -21,6 +21,17 @@ import numpy as np import tensorwrapper as tw +def print_pointset(pointset): + printout = ' ' + for i in range(pointset.size()): + printout+= '[' + for j in range(3): + printout+= str(pointset.at(i).coord(j)) + ' ' + printout+= ']' + print(printout) + + + class Test_TotalEnergyNuclearOptimization(unittest.TestCase): @@ -37,7 +48,8 @@ def test_optimize_BEfire(self): egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), "BackwardEulerFire", self.sys, self.pointset) print("Energy = " + str(egy)) - print(pts) + print_pointset(pts) + # print(pts) <-- chemist types missing python string representation #self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) def setUp(self): From b63221c25b14def605abf9a31bf09d4fd670512b Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 17 Jun 2025 14:37:37 -0500 Subject: [PATCH 09/23] update of backward_euler.py --- .../fire/backward_euler/backward_euler.py | 25 ++++++++++++++----- .../test_backward_euler_fire.py | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index f07d9ad..5ed2e10 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -41,17 +41,30 @@ def run_(self, inputs, submods): R_xyz[3*i_atom] = molecule.at(i_atom).x R_xyz[3*i_atom + 1] = molecule.at(i_atom).y R_xyz[3*i_atom + 2] = molecule.at(i_atom).z - print(list(R_xyz)) + # print(list(R_xyz)) + # molecule.at(0).x = 110 + # print(molecule) + + def nwchemex_molecule(R_xyz): + for i_atom in range(R_xyz): + molecule.at(i_atom).x = R_xyz[3*i_atom] + molecule.at(i_atom).y = R_xyz[3*i_atom + 1] + molecule.at(i_atom).z = R_xyz[3*i_atom + 2] + return molecule def e_func(geom): - return submods["Energy"].run_as(TotalEnergy(), geom) + current_molecule = nwchemex_molecule(geom) + return submods["Energy"].run_as(TotalEnergy(), current_molecule) def grad_func(geom): - return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + current_molecule = nwchemex_molecule(geom) + current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() + return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), current_molecule, current_points) - #Loads the geometry string into the Berny optimizer object. - optimizer = BE2_FIRE(settings) - optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) + + # #Loads the geometry string into the Berny optimizer object. + # optimizer = BE2_FIRE(settings) + # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) #print(optimized_geom) # Optimized energy is of type "float" diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index 31bd8a9..4739bb5 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -49,6 +49,7 @@ def test_optimize_BEfire(self): self.sys, self.pointset) print("Energy = " + str(egy)) print_pointset(pts) + print(self.sys.molecule) # print(pts) <-- chemist types missing python string representation #self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) From 7d590c46bf3159b1c1b6ef34db1dff3f6eab16a8 Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 18 Jun 2025 12:05:39 -0500 Subject: [PATCH 10/23] getting ready for master merge --- .vscode/settings.json | 4 + Testing/Temporary/CTestCostData.txt | 1 + Testing/Temporary/LastTest.log | 3 + .../fire/backward_euler/backward_euler.py | 83 ++++++++++++------- .../structurefinder/pyberny/__init__.py | 2 +- .../test_backward_euler_fire.py | 2 +- .../test_optimizers/test_pybernyop.py | 54 ++++++------ 7 files changed, 88 insertions(+), 61 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 Testing/Temporary/CTestCostData.txt create mode 100644 Testing/Temporary/LastTest.log diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..44ac2e6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "cmake.configureOnOpen": false, + "cmake.buildDirectory": "${workspaceFolder}/build", +} \ No newline at end of file diff --git a/Testing/Temporary/CTestCostData.txt b/Testing/Temporary/CTestCostData.txt new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/Testing/Temporary/CTestCostData.txt @@ -0,0 +1 @@ +--- diff --git a/Testing/Temporary/LastTest.log b/Testing/Temporary/LastTest.log new file mode 100644 index 0000000..fbcc7b8 --- /dev/null +++ b/Testing/Temporary/LastTest.log @@ -0,0 +1,3 @@ +Start testing: Jun 18 10:09 CDT +---------------------------------------------------------- +End testing: Jun 18 10:09 CDT diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index 5ed2e10..c32764b 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -45,22 +45,31 @@ def run_(self, inputs, submods): # molecule.at(0).x = 110 # print(molecule) - def nwchemex_molecule(R_xyz): - for i_atom in range(R_xyz): - molecule.at(i_atom).x = R_xyz[3*i_atom] - molecule.at(i_atom).y = R_xyz[3*i_atom + 1] - molecule.at(i_atom).z = R_xyz[3*i_atom + 2] + def updated_molecule_coord(coordinates,molecule): + numb_atoms = molecule.size() + for i_atom in range(numb_atoms): + molecule.at(i_atom).x = coordinates[3*i_atom] + molecule.at(i_atom).y = coordinates[3*i_atom + 1] + molecule.at(i_atom).z = coordinates[3*i_atom + 2] return molecule - def e_func(geom): - current_molecule = nwchemex_molecule(geom) - return submods["Energy"].run_as(TotalEnergy(), current_molecule) + def e_func(new_coord,molecule): + current_molecule = updated_molecule_coord(new_coord,molecule) + return submods["Energy"].run_as(TotalEnergy(), chemist.ChemicalSystem(current_molecule)) - def grad_func(geom): - current_molecule = nwchemex_molecule(geom) + def grad_func(new_coord, molecule): + current_molecule = updated_molecule_coord(new_coord, molecule) current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() - return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), current_molecule, current_points) - + return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), chemist.ChemicalSystem(current_molecule), current_points) + + def print_pointset(pointset): + printout = ' ' + for i in range(pointset.size()): + printout+= '[' + for j in range(3): + printout+= str(round(pointset.at(i).coord(j),10)) + ' ' + printout+= ']' + print(printout) # #Loads the geometry string into the Berny optimizer object. # optimizer = BE2_FIRE(settings) @@ -70,26 +79,36 @@ def grad_func(geom): # Optimized energy is of type "float" #----------------------------------------------------------------------------------------------------------------- -# def BE2_FIRE(self,v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=1000, error = 10**(-8)): - -# #---------------------------------------------------------------------- -# v_initial = np.array(v0) #<-- Initial Velocity -# VEL = [v_initial] #<-- Velocity list -# #---------------------------------------------------------------------- -# h = h0 #<-- Time step -# #---------------------------------------------------------------------- -# #----- Optimization cycle parameters ---------------------------------- -# Ncycle = numbcycles -# Np = 0 -# Nreset = 0 -# #------FIRE parameters ----------------------------------------------- -# alpha = alpha -# t_max = t_max -# error = error -# #------Counters ------------------------------------------------------ -# k=0 #<-- Convergence cycles -# i=0 #<-- numpy array counter -# #---------------------------------------------------------------------- + def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=100, error_power = -8, time_step_update = 5): + mol = molecule + mol_coord = R_xyz + #---------------------------------------------------------------------- + error = 10^(error_power) + v_0 = np.full(numb_coord,v0) #<-- Initial Velocity + VEL = [v_0] #<-- Velocity vector + + E_0 = e_func(mol_coord,mol) #<-- Initial Energy + Energy = [E_0] #<-- Energy list + G_0 = grad_func(mol_coord,mol) #<-- Initial Gradient + Gradient = [G_0] #<-- Gradient list + R_0 = R_xyz #<-- Initial Coordinate Vector + coord_vector = np.array(R_0) #<-- Coordinate Vector + #---------------------------------------------------------------------- + h = h0 #<-- Time step + #---------------------------------------------------------------------- + #----- Optimization cycle parameters ---------------------------------- + Ncycle = numbcycles + Np = time_step_update + Nreset = 0 + #------FIRE parameters ----------------------------------------------- + alpha = alpha + t_max = t_max + error = error + #------Counters ------------------------------------------------------ + k=0 #<-- Convergence cycles + i=0 #<-- numpy array counter + #---------------------------------------------------------------------- + backwardeuler_FIRE(molecule,numb_coord, R_xyz) # while k < (Ncycle): # k = k + 1 # #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- diff --git a/src/python/structurefinder/pyberny/__init__.py b/src/python/structurefinder/pyberny/__init__.py index 2979804..2cee774 100644 --- a/src/python/structurefinder/pyberny/__init__.py +++ b/src/python/structurefinder/pyberny/__init__.py @@ -71,7 +71,7 @@ def run_(self, inputs, submods): opt_geom = geom.molecule.nuclei print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) # Optimized energy is of type "float" - e = tw.Tensor(energy) + e = tw.Tensor(energy) print(e) rv = self.results() return pt.wrap_results(rv, e) diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index 4739bb5..cd60bb8 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -51,7 +51,7 @@ def test_optimize_BEfire(self): print_pointset(pts) print(self.sys.molecule) # print(pts) <-- chemist types missing python string representation - #self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) + #self.assertAlmostEqual(np.array(egy).item(), -1.117505879316, 10) def setUp(self): self.mol = chemist.Molecule() diff --git a/tests/python/unit_tests/test_optimizers/test_pybernyop.py b/tests/python/unit_tests/test_optimizers/test_pybernyop.py index d718f3a..305e85a 100644 --- a/tests/python/unit_tests/test_optimizers/test_pybernyop.py +++ b/tests/python/unit_tests/test_optimizers/test_pybernyop.py @@ -12,34 +12,34 @@ # # See the License for the specific language governing permissions and # # limitations under the License. -# import structurefinder -# import nwchemex -# import pluginplay as pp -# import chemist -# import unittest -# from simde import TotalEnergy -# import numpy as np -# import tensorwrapper as tw +import structurefinder +import nwchemex +import pluginplay as pp +import chemist +import unittest +from simde import TotalEnergy +import numpy as np +import tensorwrapper as tw -# class Test_optimize_pyberny(unittest.TestCase): +class Test_optimize_pyberny(unittest.TestCase): -# def test_optimize_pyberny(self): -# mm = pp.ModuleManager() -# nwchemex.load_modules(mm) -# structurefinder.load_modules(mm) -# mm.change_input("NWChem : SCF", "basis set", "sto-3g") -# mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") -# mm.change_submod("PyBerny", "Gradient", "NWChem : SCF Gradient") -# mm.change_submod("PyBerny", "Energy", "NWChem : SCF") -# mm.change_submod("Pyberny", "StringConv", -# "ChemicalSystem via QCElemental") -# egy = mm.run_as(TotalEnergy(), "PyBerny", -# chemist.ChemicalSystem(self.mol)) -# print("Energy = " + str(egy)) -# self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) + def test_optimize_pyberny(self): + mm = pp.ModuleManager() + nwchemex.load_modules(mm) + structurefinder.load_modules(mm) + mm.change_input("NWChem : SCF", "basis set", "sto-3g") + mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") + mm.change_submod("PyBerny", "Gradient", "NWChem : SCF Gradient") + mm.change_submod("PyBerny", "Energy", "NWChem : SCF") + mm.change_submod("Pyberny", "StringConv", + "ChemicalSystem via QCElemental") + egy = mm.run_as(TotalEnergy(), "PyBerny", + chemist.ChemicalSystem(self.mol)) + print("Energy = " + str(egy)) + self.assertAlmostEqual(np.array(egy), -1.117505879316, 10) -# def setUp(self): -# self.mol = chemist.Molecule() -# self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) -# self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) + def setUp(self): + self.mol = chemist.Molecule() + self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) + self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) From ca17edc7239f14723ce41c113c24cbfdeb6c533c Mon Sep 17 00:00:00 2001 From: Jacob Heflin Date: Wed, 18 Jun 2025 12:25:44 -0500 Subject: [PATCH 11/23] ignored editor files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7317922..deb0c24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ build/ venv/ install/ toolchain.cmake +.vscode/ From c444367920b78ff46609bdd7e4530bcedb8bf5d8 Mon Sep 17 00:00:00 2001 From: Jacob Heflin Date: Wed, 18 Jun 2025 12:26:08 -0500 Subject: [PATCH 12/23] removed editor files --- .vscode/settings.json | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 44ac2e6..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "cmake.configureOnOpen": false, - "cmake.buildDirectory": "${workspaceFolder}/build", -} \ No newline at end of file From 20719c0425ed94bd3ab235920699bc760eb0b0b4 Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 18 Jun 2025 12:52:04 -0500 Subject: [PATCH 13/23] remove Testing folder and cleaned pyberny test file --- Testing/Temporary/CTestCostData.txt | 1 - Testing/Temporary/LastTest.log | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 Testing/Temporary/CTestCostData.txt delete mode 100644 Testing/Temporary/LastTest.log diff --git a/Testing/Temporary/CTestCostData.txt b/Testing/Temporary/CTestCostData.txt deleted file mode 100644 index ed97d53..0000000 --- a/Testing/Temporary/CTestCostData.txt +++ /dev/null @@ -1 +0,0 @@ ---- diff --git a/Testing/Temporary/LastTest.log b/Testing/Temporary/LastTest.log deleted file mode 100644 index fbcc7b8..0000000 --- a/Testing/Temporary/LastTest.log +++ /dev/null @@ -1,3 +0,0 @@ -Start testing: Jun 18 10:09 CDT ----------------------------------------------------------- -End testing: Jun 18 10:09 CDT From ae22916d6b21d38563fe38b621303a0267e8e5b1 Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 18 Jun 2025 12:52:34 -0500 Subject: [PATCH 14/23] changed pyberny test --- .../test_optimizers/test_pybernyop.py | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/python/unit_tests/test_optimizers/test_pybernyop.py b/tests/python/unit_tests/test_optimizers/test_pybernyop.py index 1d8403e..22da6c0 100644 --- a/tests/python/unit_tests/test_optimizers/test_pybernyop.py +++ b/tests/python/unit_tests/test_optimizers/test_pybernyop.py @@ -1,16 +1,16 @@ -# # Copyright 2024 NWChemEx Community -# # -# # Licensed under the Apache License, Version 2.0 (the "License"); -# # you may not use this file except in compliance with the License. -# # You may obtain a copy of the License at -# # -# # http://www.apache.org/licenses/LICENSE-2.0 -# # -# # Unless required by applicable law or agreed to in writing, software -# # distributed under the License is distributed on an "AS IS" BASIS, -# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# # See the License for the specific language governing permissions and -# # limitations under the License. +# Copyright 2024 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import structurefinder import nwchemex From 374fc9a4af1109da12cbb3ab7c9bebf45f1eac4a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 18 Jun 2025 17:53:24 +0000 Subject: [PATCH 15/23] Committing clang-format changes --- .../structurefinder/NSTOVSUT/__init__.py | 22 +- .../NSTOVSUT/nesterov_SUT_NDC.py | 97 +++--- src/python/structurefinder/__init__.py | 1 + src/python/structurefinder/fire/__init__.py | 13 + .../fire/backward_euler/__init__.py | 22 +- .../fire/backward_euler/backward_euler.py | 297 +++++++++--------- .../fire/backward_euler/be2_DC_NVT.py | 97 +++--- .../fire/backward_euler/be2_DC_VarT.py | 106 ++++--- .../fire/nesterov_sutskever/__init__.py | 22 +- .../nesterov_sutskever/nesterov_SUT_DC_NVT.py | 99 +++--- .../nesterov_SUT_DC_VarT.py | 111 ++++--- .../nesterov_sutskever/nesterov_SUT_NDC.py | 97 +++--- .../nesterov_sutskever/nesterov_sutskever.py | 128 ++++---- .../fire/velocity_verlet/__init__.py | 22 +- .../fire/velocity_verlet/velocity_verlet.py | 127 ++++---- .../fire/velocity_verlet/vv_DC_NVT.py | 96 +++--- .../fire/velocity_verlet/vv_DC_VarT.py | 99 +++--- .../test_backward_euler_fire.py | 30 +- 18 files changed, 847 insertions(+), 639 deletions(-) diff --git a/src/python/structurefinder/NSTOVSUT/__init__.py b/src/python/structurefinder/NSTOVSUT/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/NSTOVSUT/__init__.py +++ b/src/python/structurefinder/NSTOVSUT/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py index caabce8..b4a7503 100644 --- a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py +++ b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,88 +23,89 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_NDC(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list + POS = [r0] #<-- Position list VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- + break + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -101,6 +115,7 @@ def __init__(self,r0): self.velocity = VEL self.energy = E self.energy_errors = energy_errors - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/__init__.py b/src/python/structurefinder/__init__.py index cbe9a96..672de3f 100644 --- a/src/python/structurefinder/__init__.py +++ b/src/python/structurefinder/__init__.py @@ -16,6 +16,7 @@ from .lj_potential.lennard_jones_potential_module import load_lennard_jones_potential from .fire.backward_euler.backward_euler import load_backwardeulerfire_modules + def load_modules(mm): """ Loads the collection of all modules provided by StructureFinder. diff --git a/src/python/structurefinder/fire/__init__.py b/src/python/structurefinder/fire/__init__.py index e69de29..a8d4745 100644 --- a/src/python/structurefinder/fire/__init__.py +++ b/src/python/structurefinder/fire/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/python/structurefinder/fire/backward_euler/__init__.py b/src/python/structurefinder/fire/backward_euler/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/backward_euler/__init__.py +++ b/src/python/structurefinder/fire/backward_euler/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index c32764b..f745012 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -13,11 +13,13 @@ # limitations under the License. import pluginplay as pp -from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy,TotalEnergyNuclearOptimization, MoleculeFromString) +from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy, + TotalEnergyNuclearOptimization, MoleculeFromString) import chemist import numpy as np import tensorwrapper as tw + class GeomoptViaBackwardEulerFIRE(pp.ModuleBase): def __init__(self): @@ -35,42 +37,46 @@ def run_(self, inputs, submods): # Construction of the coordinate vecotr numb_atoms = molecule.size() #<-- Number of atoms - numb_coord = 3*numb_atoms #<-- Number of coordinates + numb_coord = 3 * numb_atoms #<-- Number of coordinates R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector for i_atom in range(molecule.size()): - R_xyz[3*i_atom] = molecule.at(i_atom).x - R_xyz[3*i_atom + 1] = molecule.at(i_atom).y - R_xyz[3*i_atom + 2] = molecule.at(i_atom).z + R_xyz[3 * i_atom] = molecule.at(i_atom).x + R_xyz[3 * i_atom + 1] = molecule.at(i_atom).y + R_xyz[3 * i_atom + 2] = molecule.at(i_atom).z # print(list(R_xyz)) # molecule.at(0).x = 110 # print(molecule) - def updated_molecule_coord(coordinates,molecule): - numb_atoms = molecule.size() + def updated_molecule_coord(coordinates, molecule): + numb_atoms = molecule.size() for i_atom in range(numb_atoms): - molecule.at(i_atom).x = coordinates[3*i_atom] - molecule.at(i_atom).y = coordinates[3*i_atom + 1] - molecule.at(i_atom).z = coordinates[3*i_atom + 2] + molecule.at(i_atom).x = coordinates[3 * i_atom] + molecule.at(i_atom).y = coordinates[3 * i_atom + 1] + molecule.at(i_atom).z = coordinates[3 * i_atom + 2] return molecule - - def e_func(new_coord,molecule): - current_molecule = updated_molecule_coord(new_coord,molecule) - return submods["Energy"].run_as(TotalEnergy(), chemist.ChemicalSystem(current_molecule)) - + + def e_func(new_coord, molecule): + current_molecule = updated_molecule_coord(new_coord, molecule) + return submods["Energy"].run_as( + TotalEnergy(), chemist.ChemicalSystem(current_molecule)) + def grad_func(new_coord, molecule): current_molecule = updated_molecule_coord(new_coord, molecule) - current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() - return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), chemist.ChemicalSystem(current_molecule), current_points) + current_points = current_molecule.nuclei.as_nuclei( + ).charges.point_set.as_point_set() + return submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), + chemist.ChemicalSystem(current_molecule), current_points) def print_pointset(pointset): printout = ' ' for i in range(pointset.size()): - printout+= '[' + printout += '[' for j in range(3): - printout+= str(round(pointset.at(i).coord(j),10)) + ' ' - printout+= ']' + printout += str(round(pointset.at(i).coord(j), 10)) + ' ' + printout += ']' print(printout) - + # #Loads the geometry string into the Berny optimizer object. # optimizer = BE2_FIRE(settings) # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) @@ -78,23 +84,34 @@ def print_pointset(pointset): # Optimized energy is of type "float" + #----------------------------------------------------------------------------------------------------------------- - def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=100, error_power = -8, time_step_update = 5): + + def backwardeuler_FIRE(molecule, + numb_coord, + R_xyz, + v0=0, + h0=0.03, + alpha=0.1, + t_max=0.3, + numbcycles=100, + error_power=-8, + time_step_update=5): mol = molecule mol_coord = R_xyz #---------------------------------------------------------------------- - error = 10^(error_power) - v_0 = np.full(numb_coord,v0) #<-- Initial Velocity - VEL = [v_0] #<-- Velocity vector - - E_0 = e_func(mol_coord,mol) #<-- Initial Energy - Energy = [E_0] #<-- Energy list - G_0 = grad_func(mol_coord,mol) #<-- Initial Gradient - Gradient = [G_0] #<-- Gradient list - R_0 = R_xyz #<-- Initial Coordinate Vector - coord_vector = np.array(R_0) #<-- Coordinate Vector + error = 10 ^ (error_power) + v_0 = np.full(numb_coord, v0) #<-- Initial Velocity + VEL = [v_0] #<-- Velocity vector + + E_0 = e_func(mol_coord, mol) #<-- Initial Energy + Energy = [E_0] #<-- Energy list + G_0 = grad_func(mol_coord, mol) #<-- Initial Gradient + Gradient = [G_0] #<-- Gradient list + R_0 = R_xyz #<-- Initial Coordinate Vector + coord_vector = np.array(R_0) #<-- Coordinate Vector #---------------------------------------------------------------------- - h = h0 #<-- Time step + h = h0 #<-- Time step #---------------------------------------------------------------------- #----- Optimization cycle parameters ---------------------------------- Ncycle = numbcycles @@ -105,122 +122,116 @@ def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1 t_max = t_max error = error #------Counters ------------------------------------------------------ - k=0 #<-- Convergence cycles - i=0 #<-- numpy array counter + k = 0 #<-- Convergence cycles + i = 0 #<-- numpy array counter #---------------------------------------------------------------------- - backwardeuler_FIRE(molecule,numb_coord, R_xyz) -# while k < (Ncycle): -# k = k + 1 -# #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- -# up_pos_norm_error = np.linalg.norm(POS[i] - MIN) -# down_pos_norm_error = np.linalg.norm(POS[0]-MIN) -# pos_norm_error = (up_pos_norm_error/down_pos_norm_error) -# #------------------------------------------------------------------ -# if pos_norm_error < error: -# break -# #----- FIRE ------------------------------------------------------ -# #---- alpha RESET and Half time step setting --------------------- -# if np.dot(VEL[i],F[i])<=0: -# VEL[i] = v_initial -# h = 0.5*h -# alpha = 0.1 -# Np = 0 -# Nreset = Nreset + 1 - -# elif np.dot(VEL[i],F[i])>0: -# Np = Np + 1 - -# #----- FORCE UNITE VECTOR ------------------------------------ - -# fh = F[i]/np.linalg.norm(F[i]) - -# #---- FIRE VELOCITY CORRECTION ------------------------------- -# VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh -# #------------------------------------------------------------- - -# #----- alpha, time step UPGRADE ------------------------------ -# if Np>5: - -# h = min(1.1*h,t_max) - - -# alpha = 0.99*alpha - - -# #----- NEW ELEMENT in the lists ----------------------------------- -# POS.append(0) -# F.append(0) -# norm_force.append(0) -# VEL.append(0) -# E.append(0) -# #--------------- BACKWARD EULER(2)--------------------------------- -# #-- POSITION ------------------------------------------------------ -# POS[i+1] = POS[i] + VEL[i]*h -# #-- FORCE --------------------------------------------------------- -# F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart -# norm_force[i+1] = np.linalg.norm(F[i+1]) -# #-- VELOCITY ------------------------------------------------------ -# VEL[i+1] = VEL[i] + F[i+1]*h -# #-- ENERGY ------------------------------------------------------- -# E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - -# #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- -# if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: - -# break -# #------------------------------------------------------------------ - -# #------------- NORM OF FORCE CONVERGENCE -------------------------- -# if np.linalg.norm(F[i+1])< error: - -# break -# #------------------------------------------------------------------ - - -# #--- LIST position update------------------------------------------ -# i = i + 1 -# #--------- END OF OPTIMIZTION PROCESS --------------------------------- - -# #--- COLLECTED DATA ANALYSIS ------------------------------------------ -# #---------------------------------------------------------------------- -# POS = np.array(POS) #<--- To calculate the position errors -# ini_dist = np.linalg.norm(r0 - pos_minima) -# #---- position error calculation ------------------------------------- -# position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist -# #--------------------------------------------------------------------- - -# #----------------- Energy Error calculations ------------------------- -# E = np.array(E)#<---- To calculate Energy errors -# #--------------------------------------------------------------------- -# energy_errors = abs((E - MIN)/(E[0]-MIN)) -# #------- ATRIBUTES ---------------------------------------------------- -# self.steps = len(E) -# self.positions = POS -# self.minima_error = position_errors -# self.forces = F -# self.norm_forces = np.array(norm_force) -# self.velocity = VEL -# self.energy = E -# self.energy_errors = energy_errors -# self.Np = Np -# self.alpha = alpha -# self.Nreset = Nreset -# self.min_force =min(norm_force) -# #---------------------------------------------------------------------- - + + backwardeuler_FIRE(molecule, numb_coord, R_xyz) + # while k < (Ncycle): + # k = k + 1 + # #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + # up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + # down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + # pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + # #------------------------------------------------------------------ + # if pos_norm_error < error: + # break + # #----- FIRE ------------------------------------------------------ + # #---- alpha RESET and Half time step setting --------------------- + # if np.dot(VEL[i],F[i])<=0: + # VEL[i] = v_initial + # h = 0.5*h + # alpha = 0.1 + # Np = 0 + # Nreset = Nreset + 1 + + # elif np.dot(VEL[i],F[i])>0: + # Np = Np + 1 + + # #----- FORCE UNITE VECTOR ------------------------------------ + + # fh = F[i]/np.linalg.norm(F[i]) + + # #---- FIRE VELOCITY CORRECTION ------------------------------- + # VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + # #------------------------------------------------------------- + + # #----- alpha, time step UPGRADE ------------------------------ + # if Np>5: + + # h = min(1.1*h,t_max) + + # alpha = 0.99*alpha + + # #----- NEW ELEMENT in the lists ----------------------------------- + # POS.append(0) + # F.append(0) + # norm_force.append(0) + # VEL.append(0) + # E.append(0) + # #--------------- BACKWARD EULER(2)--------------------------------- + # #-- POSITION ------------------------------------------------------ + # POS[i+1] = POS[i] + VEL[i]*h + # #-- FORCE --------------------------------------------------------- + # F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart + # norm_force[i+1] = np.linalg.norm(F[i+1]) + # #-- VELOCITY ------------------------------------------------------ + # VEL[i+1] = VEL[i] + F[i+1]*h + # #-- ENERGY ------------------------------------------------------- + # E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + + # #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + # if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: + + # break + # #------------------------------------------------------------------ + + # #------------- NORM OF FORCE CONVERGENCE -------------------------- + # if np.linalg.norm(F[i+1])< error: + + # break + # #------------------------------------------------------------------ + + # #--- LIST position update------------------------------------------ + # i = i + 1 + # #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + # #--- COLLECTED DATA ANALYSIS ------------------------------------------ + # #---------------------------------------------------------------------- + # POS = np.array(POS) #<--- To calculate the position errors + # ini_dist = np.linalg.norm(r0 - pos_minima) + # #---- position error calculation ------------------------------------- + # position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + # #--------------------------------------------------------------------- + + # #----------------- Energy Error calculations ------------------------- + # E = np.array(E)#<---- To calculate Energy errors + # #--------------------------------------------------------------------- + # energy_errors = abs((E - MIN)/(E[0]-MIN)) + # #------- ATRIBUTES ---------------------------------------------------- + # self.steps = len(E) + # self.positions = POS + # self.minima_error = position_errors + # self.forces = F + # self.norm_forces = np.array(norm_force) + # self.velocity = VEL + # self.energy = E + # self.energy_errors = energy_errors + # self.Np = Np + # self.alpha = alpha + # self.Nreset = Nreset + # self.min_force =min(norm_force) + # #---------------------------------------------------------------------- e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() for i in range(numb_atoms): - ps.push_back(chemist.PointD(R_xyz[3*i],R_xyz[3*i + 1], R_xyz[3*i + 2])) + ps.push_back( + chemist.PointD(R_xyz[3 * i], R_xyz[3 * i + 1], + R_xyz[3 * i + 2])) rv = self.results() return pt.wrap_results(rv, e, ps) -def load_backwardeulerfire_modules(mm): - mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) - - - - - +def load_backwardeulerfire_modules(mm): + mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) diff --git a/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py index 25b1eb0..2bb69f7 100644 --- a/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py +++ b/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 16:34:02 2024 @@ -12,48 +25,48 @@ class BE2_DC_NVT(): - - def __init__(self,r0,h): - + + def __init__(self, r0, h): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 #--------------------------------------------------------------------- while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Np = 0 Nreset = Nreset + 1 #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -61,45 +74,44 @@ def __init__(self,r0,h): E.append(0) #--------------- BACKWARD EULER(2)--------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + POS[i + 1] = POS[i] + VEL[i] * h #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + F[i+1]*h + VEL[i + 1] = VEL[i] + F[i + 1] * h #-- ENERGY ------------------------------------------------------- - E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -111,6 +123,7 @@ def __init__(self,r0,h): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py index eae6725..615e4e5 100644 --- a/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py +++ b/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 16:34:02 2024 @@ -10,57 +23,58 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class BE2_DC_VarT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - h = h0 #<-- time steps - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + h = h0 #<-- time steps + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - t_max = 0.3 #<-- Maximum time step + t_max = 0.3 #<-- Maximum time step #-------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 #--------------------------------------------------------------------- while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 h = h0 Np = 0 Nreset = Nreset + 1 #------ TIME STEP UPDATE ----------------------------------------- - elif np.dot(VEL[i],F[i])>0: - Np = Np + 1 - h = h = min(1.1*h,t_max) + elif np.dot(VEL[i], F[i]) > 0: + Np = Np + 1 + h = h = min(1.1 * h, t_max) #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -68,45 +82,44 @@ def __init__(self,r0,h0): E.append(0) #--------------- BACKWARD EULER(2)--------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + POS[i + 1] = POS[i] + VEL[i] * h #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + F[i+1]*h + VEL[i + 1] = VEL[i] + F[i + 1] * h #-- ENERGY ------------------------------------------------------- - E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -118,6 +131,7 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py index 7255af4..4167c01 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,96 +23,97 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_DCNVT(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) + POS = [r0] #<-- Position list + v0 = np.array(0) VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Nreset = Nreset + 1 #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -111,6 +125,7 @@ def __init__(self,r0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py index 845007d..31e9a4d 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,104 +23,105 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_DC_VarT(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) + POS = [r0] #<-- Position list + v0 = np.array(0) VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 - alpha = 0.001 + alpha = 0.001 mu = 0.9 Nreset = Nreset + 1 #------ TIME STEP UPDATE ----------------------------------------- - elif np.dot(VEL[i],F[i])>0: - Np = Np + 1 - #--- TIME STEP UPGRADE -------------------------------------- - alpha = 1.1*alpha - mu = 1.1*mu + elif np.dot(VEL[i], F[i]) > 0: + Np = Np + 1 + #--- TIME STEP UPGRADE -------------------------------------- + alpha = 1.1 * alpha + mu = 1.1 * mu #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -121,6 +135,7 @@ def __init__(self,r0): self.Nreset = Nreset self.alpha = alpha self.mu = mu - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py index caabce8..b4a7503 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,88 +23,89 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_NDC(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list + POS = [r0] #<-- Position list VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- + break + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -101,6 +115,7 @@ def __init__(self,r0): self.velocity = VEL self.energy = E self.energy_errors = energy_errors - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py index 27928b6..dba0e2a 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Tue Apr 30 04:13:14 2024 @@ -10,122 +23,123 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_FIRE(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #--------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 theta = 0.1 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- FIRE ------------------------------------------------------- #---- TIME STEPS and Theta Reset ---------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = VEL[0] alpha = 0.001 mu = 0.9 theta = 0.1 Np = 0 Nreset = Nreset + 1 - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - + #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i]/np.linalg.norm(F[i]) - + + fh = F[i] / np.linalg.norm(F[i]) + #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1-theta)*VEL[i] + theta*np.linalg.norm(VEL[i])*fh + VEL[i] = (1 - theta) * VEL[i] + theta * np.linalg.norm( + VEL[i]) * fh #------------------------------------------------------------ - + #----- TIME STEP and THETA UPGRADE --------------------------- - if Np>5: - - alpha = 1.1*alpha - - mu = 1.1*mu - - theta = 0.99*theta - - - #----- NEW ELEMENT in the lists ----------------------------------- + if Np > 5: + + alpha = 1.1 * alpha + + mu = 1.1 * mu + + theta = 0.99 * theta + + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] =Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break - #------------------------------------------------------------------ + #------------------------------------------------------------------ - #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -138,6 +152,6 @@ def __init__(self,r0): self.Np = Np self.alpha = alpha self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/__init__.py b/src/python/structurefinder/fire/velocity_verlet/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/velocity_verlet/__init__.py +++ b/src/python/structurefinder/fire/velocity_verlet/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py index 3442532..b2cc0ca 100644 --- a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py +++ b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -10,73 +23,74 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class VV_FIRE(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) #<-- Position minimum - h = h0 #<-- Time step + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #<-- Position minimum + h = h0 #<-- Time step #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.1 - t_max = 0.3 #<-- Max time step + alpha = 0.1 + t_max = 0.3 #<-- Max time step #--------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- FIRE ------------------------------------------------------- #---- alpha RESET and Half time step setting -------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 - h = 0.5*h + h = 0.5 * h alpha = 0.1 Np = 0 Nreset = Nreset + 1 - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - + #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i]/np.linalg.norm(F[i]) - + + fh = F[i] / np.linalg.norm(F[i]) + #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + VEL[i] = (1 - alpha) * VEL[i] + alpha * np.linalg.norm( + VEL[i]) * fh #------------------------------------------------------------ - + #----- alpha, time step UPGRADE ------------------------------ - if Np>5: - - h = min(1.1*h,t_max) - - - alpha = 0.99*alpha - - #----- NEW ELEMENT in the lists ----------------------------------- + if Np > 5: + + h = min(1.1 * h, t_max) + + alpha = 0.99 * alpha + + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -84,44 +98,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break - #------------------------------------------------------------------ + #------------------------------------------------------------------ - #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -134,6 +147,6 @@ def __init__(self,r0,h0): self.Np = Np self.alpha = alpha self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py index 22a071a..44826db 100644 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py +++ b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -10,53 +23,53 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class VV_DC_NVT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) h = h0 #--------------------------------------------------------------------- - E0= Lennard_Jones_Potential(r0).LJ_energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Np = 0 Nreset = Nreset + 1 - #------------------------------------------------------------------ + #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -64,43 +77,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]= Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]= Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - + #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -112,7 +125,6 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code --------------------------------------------------------- - diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py index 8a9b15d..f5ed759 100644 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py +++ b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -12,58 +25,57 @@ class VV_DC_VarT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - h = h0 #<-- time step - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + h = h0 #<-- time step + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - t_max = 0.3 #<-- Maximum time step + t_max = 0.3 #<-- Maximum time step #-------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 h = h0 Np = 0 Nreset = Nreset + 1 #------ TIME STEP UPDATE ------------------------------------------ - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - h = h = min(1.1*h,t_max) - #------------------------------------------------------------------ + h = h = min(1.1 * h, t_max) + #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -71,43 +83,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - + #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -119,7 +131,6 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code --------------------------------------------------------- - diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index cd60bb8..cb0d9f8 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -1,3 +1,17 @@ +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # # Copyright 2024 NWChemEx Community # # # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,18 +35,17 @@ import numpy as np import tensorwrapper as tw + def print_pointset(pointset): printout = ' ' for i in range(pointset.size()): - printout+= '[' + printout += '[' for j in range(3): - printout+= str(pointset.at(i).coord(j)) + ' ' - printout+= ']' + printout += str(pointset.at(i).coord(j)) + ' ' + printout += ']' print(printout) - - class Test_TotalEnergyNuclearOptimization(unittest.TestCase): def test_optimize_BEfire(self): @@ -41,12 +54,13 @@ def test_optimize_BEfire(self): structurefinder.load_modules(mm) mm.change_input("NWChem : SCF", "basis set", "sto-3g") mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") - mm.change_submod("BackwardEulerFire", "Gradient", "NWChem : SCF Gradient") + mm.change_submod("BackwardEulerFire", "Gradient", + "NWChem : SCF Gradient") mm.change_submod("BackwardEulerFire", "Energy", "NWChem : SCF") mm.change_submod("BackwardEulerFire", "StringConv", "ChemicalSystem via QCElemental") - egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), "BackwardEulerFire", - self.sys, self.pointset) + egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), + "BackwardEulerFire", self.sys, self.pointset) print("Energy = " + str(egy)) print_pointset(pts) print(self.sys.molecule) From 78ca58515a772845fd268d9fca7777fd76d1e363 Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 18 Jun 2025 13:24:10 -0500 Subject: [PATCH 16/23] Track VSCode settings to prevent automatic rebuilds --- .vscode/settings.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9ef1d57 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "cmake.configureOnOpen": false, + "cmake.buildDirectory": "${workspaceFolder}/build", + "cmake.sourceDirectory": "${workspaceFolder}", + "cmake.generator": "Ninja", + "cmake.buildOnSave": false, + "cmake.configureOnEdit": false +} \ No newline at end of file From 8ced491c7385e98e2e1547d54e71dbeb12020f01 Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 1 Jul 2025 21:21:49 -0500 Subject: [PATCH 17/23] backward euler and fire completed --- .gitignore | 7 +- .../fire/backward_euler/backward_euler.py | 188 +++++++++++++++--- .../test_backward_euler_fire.py | 4 +- 3 files changed, 163 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index deb0c24..22bb655 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,10 @@ __pycache__/ build/ -venv/ +.venv/ install/ toolchain.cmake -.vscode/ +.vscode/* +!.vscode/settings.json +StructureFinder.code-workspace + diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index c32764b..f9027ad 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -41,35 +41,42 @@ def run_(self, inputs, submods): R_xyz[3*i_atom] = molecule.at(i_atom).x R_xyz[3*i_atom + 1] = molecule.at(i_atom).y R_xyz[3*i_atom + 2] = molecule.at(i_atom).z - # print(list(R_xyz)) + #print(list(R_xyz)) # molecule.at(0).x = 110 - # print(molecule) + #print(molecule) def updated_molecule_coord(coordinates,molecule): numb_atoms = molecule.size() for i_atom in range(numb_atoms): molecule.at(i_atom).x = coordinates[3*i_atom] - molecule.at(i_atom).y = coordinates[3*i_atom + 1] + molecule.at(i_atom).y = coordinates[3*i_atom + 1] molecule.at(i_atom).z = coordinates[3*i_atom + 2] return molecule def e_func(new_coord,molecule): current_molecule = updated_molecule_coord(new_coord,molecule) return submods["Energy"].run_as(TotalEnergy(), chemist.ChemicalSystem(current_molecule)) - + def grad_func(new_coord, molecule): current_molecule = updated_molecule_coord(new_coord, molecule) - current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() + current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() # The problem is here when using 0.0 coordinates return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), chemist.ChemicalSystem(current_molecule), current_points) - def print_pointset(pointset): - printout = ' ' - for i in range(pointset.size()): - printout+= '[' - for j in range(3): - printout+= str(round(pointset.at(i).coord(j),10)) + ' ' - printout+= ']' - print(printout) + def create_coord_string(molecule): + mol_string = "" + mol_string += f"{molecule.size()}\n\n" + for atom in range(molecule.size()): + mol_string += f"{molecule.at(atom).name} {molecule.at(atom).x} {molecule.at(atom).y} {molecule.at(atom).z}\n" + return mol_string + + # def print_pointset(pointset): + # printout = ' ' + # for i in range(pointset.size()): + # printout+= '[' + # for j in range(3): + # printout+= str(pointset.at(i).coord(j)) + ' ' + # printout+= ']' + # print(printout) # #Loads the geometry string into the Berny optimizer object. # optimizer = BE2_FIRE(settings) @@ -79,38 +86,137 @@ def print_pointset(pointset): # Optimized energy is of type "float" #----------------------------------------------------------------------------------------------------------------- - def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=100, error_power = -8, time_step_update = 5): - mol = molecule + def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=150, error_power = -8, time_step_update = 5): mol_coord = R_xyz + Molecule = [molecule] #---------------------------------------------------------------------- - error = 10^(error_power) - v_0 = np.full(numb_coord,v0) #<-- Initial Velocity - VEL = [v_0] #<-- Velocity vector - - E_0 = e_func(mol_coord,mol) #<-- Initial Energy - Energy = [E_0] #<-- Energy list - G_0 = grad_func(mol_coord,mol) #<-- Initial Gradient - Gradient = [G_0] #<-- Gradient list - R_0 = R_xyz #<-- Initial Coordinate Vector - coord_vector = np.array(R_0) #<-- Coordinate Vector + error = 10**(error_power) + #----VELOCITY --------------------------------------------------------- + v_initial = -np.array(grad_func(mol_coord, molecule))*h0 + v_0 = np.array(grad_func(mol_coord, molecule))*0 + VEL = [v_initial] #<-- Velocity list + #----ENERGY ------------------------------------------------------------ + E_0 = e_func(mol_coord,molecule) #<-- Initial Energy + Energy = [np.array(E_0)] #<-- Energy list + #----FORCE----------------------------------------------------------- + F_0 = -np.array(grad_func(mol_coord, molecule)) #<-- Initial Gradient + # input('Press enter to continue\n') + # print(type(G_0)) + FORCE = [F_0] #<-- Gradient list + # print('This is the gradient') + # test = [Gradient] + # print(test) + # input('press enter to continue') + #-----COORDINATE VECTOR ----------------------------------------------- + R_0 = R_xyz #<-- Initial Coordinate Vector + coord_vector = [np.array(R_0)] #<-- Coordinate Vector + #---------------------------------------------------------------------- h = h0 #<-- Time step #---------------------------------------------------------------------- #----- Optimization cycle parameters ---------------------------------- Ncycle = numbcycles - Np = time_step_update + Np = 0 Nreset = 0 #------FIRE parameters ----------------------------------------------- alpha = alpha t_max = t_max - error = error #------Counters ------------------------------------------------------ - k=0 #<-- Convergence cycles - i=0 #<-- numpy array counter + k=0 #<-- Convergence cycles conter + i=0 #<-- counter #---------------------------------------------------------------------- - backwardeuler_FIRE(molecule,numb_coord, R_xyz) -# while k < (Ncycle): -# k = k + 1 + Rxyz_error_list = [] + egy_error_list = [] + force_error_list = [] + coord_list = [] + mol_string = create_coord_string(molecule) + while k < (Ncycle): + k += 1 + print(f"Starting step: {k}") + #----- FIRE ------------------------------------------------------ + #---- alpha RESET and Half time step setting --------------------- + if (np.dot(VEL[i],FORCE[i])<=0) and Np>0: + VEL[i] = v_0 + h = 0.5*h + alpha = 0.1 + Np = 0 + Nreset = Nreset + 1 + + elif np.dot(VEL[i],FORCE[i])>0: + Np = Np + 1 + + #----- FORCE UNITE VECTOR ------------------------------------ + + force_unit = FORCE[i]/np.linalg.norm(FORCE[i]) + + #---- FIRE VELOCITY CORRECTION ------------------------------- + VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*force_unit + #------------------------------------------------------------- + + #----- alpha, time step UPGRADE ------------------------------ + if Np>time_step_update: + + h = min(1.1*h,t_max) + + + alpha = 0.99*alpha + #--------------- BACKWARD EULER(2)--------------------------------- + #-- COORD_VECTOR ------------------------------------------------------ + x_j = coord_vector[i] + #-- + x_newj = x_j + VEL[i]*h + coord_vector.append(x_newj) + #-- NEW GRAD --------------------------------------------------------- + force_newj = -np.array(grad_func(x_newj, molecule)) + FORCE.append(force_newj) + #-- VELOCITY ------------------------------------------------------ + vel_newj = VEL[i] + FORCE[i+1]*h + VEL.append(vel_newj) + + + + #-- NEW ENEGY + egy_newj = e_func(x_newj,molecule) + Energy.append(np.array(egy_newj)) + #-- + + #--- ERRORS ---------------------------------------------------------- + Rxyz_error = np.linalg.norm(coord_vector[i] - coord_vector[i+1]) + Rxyz_error_list.append(Rxyz_error) + + egy_error = np.abs(Energy[i] - Energy[i+1]) + egy_error_list.append(egy_error) + + force_error = np.linalg.norm(FORCE[i]-FORCE[i+1]) + force_error_list.append(force_error) + + #--- LIST OF COORDINATES + mol_string = create_coord_string(molecule) + coord_list.append(mol_string) + + + if (Rxyz_error < error) and (egy_error < error) and (force_error < error): + break + + + + + if k == Ncycle: + print(f"Maximum number of optimization steps achieved: {Ncycle}") + break + i+=1 + print(f"values of i: {i}") + return { + 'Energy':Energy, + 'Energy Error':egy_error_list, + 'FORCE': FORCE, + 'FORCE Error': force_error_list, + 'Coordinates': coord_vector, + 'Coordinates error':Rxyz_error_list, + 'Coordinate Strings': coord_list, + 'Molecule':Molecule, + } + # #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- # up_pos_norm_error = np.linalg.norm(POS[i] - MIN) # down_pos_norm_error = np.linalg.norm(POS[0]-MIN) @@ -208,6 +314,24 @@ def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1 # self.min_force =min(norm_force) # #---------------------------------------------------------------------- + test = backwardeuler_FIRE(molecule, R_xyz) + egy_error = test['Energy Error'] + print(egy_error) + force_error = test['FORCE Error'] + print(force_error) + Rxyz_error = test['Coordinates error'] + print(Rxyz_error) + + input('Press enter to continue') + mol = test['Molecule'] + print(len(mol)) + for i in mol: + print(i) + input('Press enter to continue') + final_coords_string = "".join(test['Coordinate Strings']) + + with open('test.xyz', "w") as file: + file.write(final_coords_string) e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index cd60bb8..7ef8dae 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -49,14 +49,14 @@ def test_optimize_BEfire(self): self.sys, self.pointset) print("Energy = " + str(egy)) print_pointset(pts) - print(self.sys.molecule) + #print(self.sys.molecule) # print(pts) <-- chemist types missing python string representation #self.assertAlmostEqual(np.array(egy).item(), -1.117505879316, 10) def setUp(self): self.mol = chemist.Molecule() self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0)) - self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0)) + self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.4)) self.sys = chemist.ChemicalSystem(self.mol) self.nuclei = self.mol.nuclei.as_nuclei() self.pointset = self.nuclei.charges.point_set.as_point_set() From bba231db96e3a3cc4d151d53c2faf4b6b4ac82f9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 2 Jul 2025 02:26:38 +0000 Subject: [PATCH 18/23] Committing clang-format changes --- .../fire/backward_euler/backward_euler.py | 271 +++++++++--------- 1 file changed, 141 insertions(+), 130 deletions(-) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index 0e83280..d8dc084 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -40,9 +40,9 @@ def run_(self, inputs, submods): numb_coord = 3 * numb_atoms #<-- Number of coordinates R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector for i_atom in range(molecule.size()): - R_xyz[3*i_atom] = molecule.at(i_atom).x - R_xyz[3*i_atom + 1] = molecule.at(i_atom).y - R_xyz[3*i_atom + 2] = molecule.at(i_atom).z + R_xyz[3 * i_atom] = molecule.at(i_atom).x + R_xyz[3 * i_atom + 1] = molecule.at(i_atom).y + R_xyz[3 * i_atom + 2] = molecule.at(i_atom).z # print(list(R_xyz)) # molecule.at(0).x = 110 #print(molecule) @@ -50,29 +50,33 @@ def run_(self, inputs, submods): def updated_molecule_coord(coordinates, molecule): numb_atoms = molecule.size() for i_atom in range(numb_atoms): - molecule.at(i_atom).x = coordinates[3*i_atom] - molecule.at(i_atom).y = coordinates[3*i_atom + 1] - molecule.at(i_atom).z = coordinates[3*i_atom + 2] + molecule.at(i_atom).x = coordinates[3 * i_atom] + molecule.at(i_atom).y = coordinates[3 * i_atom + 1] + molecule.at(i_atom).z = coordinates[3 * i_atom + 2] return molecule - - def e_func(new_coord,molecule): - current_molecule = updated_molecule_coord(new_coord,molecule) - return submods["Energy"].run_as(TotalEnergy(), chemist.ChemicalSystem(current_molecule)) - + + def e_func(new_coord, molecule): + current_molecule = updated_molecule_coord(new_coord, molecule) + return submods["Energy"].run_as( + TotalEnergy(), chemist.ChemicalSystem(current_molecule)) + def grad_func(new_coord, molecule): current_molecule = updated_molecule_coord(new_coord, molecule) - current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() - return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), chemist.ChemicalSystem(current_molecule), current_points) + current_points = current_molecule.nuclei.as_nuclei( + ).charges.point_set.as_point_set() + return submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), + chemist.ChemicalSystem(current_molecule), current_points) def print_pointset(pointset): printout = ' ' for i in range(pointset.size()): - printout+= '[' + printout += '[' for j in range(3): - printout+= str(round(pointset.at(i).coord(j),10)) + ' ' - printout+= ']' + printout += str(round(pointset.at(i).coord(j), 10)) + ' ' + printout += ']' print(printout) - + # #Loads the geometry string into the Berny optimizer object. # optimizer = BE2_FIRE(settings) # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) @@ -82,21 +86,31 @@ def print_pointset(pointset): #----------------------------------------------------------------------------------------------------------------- - def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=100, error_power = -8, time_step_update = 5): + + def backwardeuler_FIRE(molecule, + numb_coord, + R_xyz, + v0=0, + h0=0.03, + alpha=0.1, + t_max=0.3, + numbcycles=100, + error_power=-8, + time_step_update=5): mol = molecule mol_coord = R_xyz Molecule = [molecule] #---------------------------------------------------------------------- - error = 10^(error_power) - v_0 = np.full(numb_coord,v0) #<-- Initial Velocity - VEL = [v_0] #<-- Velocity vector - - E_0 = e_func(mol_coord,mol) #<-- Initial Energy - Energy = [E_0] #<-- Energy list - G_0 = grad_func(mol_coord,mol) #<-- Initial Gradient - Gradient = [G_0] #<-- Gradient list - R_0 = R_xyz #<-- Initial Coordinate Vector - coord_vector = np.array(R_0) #<-- Coordinate Vector + error = 10 ^ (error_power) + v_0 = np.full(numb_coord, v0) #<-- Initial Velocity + VEL = [v_0] #<-- Velocity vector + + E_0 = e_func(mol_coord, mol) #<-- Initial Energy + Energy = [E_0] #<-- Energy list + G_0 = grad_func(mol_coord, mol) #<-- Initial Gradient + Gradient = [G_0] #<-- Gradient list + R_0 = R_xyz #<-- Initial Coordinate Vector + coord_vector = np.array(R_0) #<-- Coordinate Vector #---------------------------------------------------------------------- h = h0 #<-- Time step #---------------------------------------------------------------------- @@ -108,109 +122,106 @@ def backwardeuler_FIRE(molecule,numb_coord, R_xyz, v0 = 0,h0 = 0.03, alpha = 0.1 alpha = alpha t_max = t_max #------Counters ------------------------------------------------------ - k=0 #<-- Convergence cycles - i=0 #<-- numpy array counter + k = 0 #<-- Convergence cycles + i = 0 #<-- numpy array counter #---------------------------------------------------------------------- - backwardeuler_FIRE(molecule,numb_coord, R_xyz) -# while k < (Ncycle): -# k = k + 1 -# #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- -# up_pos_norm_error = np.linalg.norm(POS[i] - MIN) -# down_pos_norm_error = np.linalg.norm(POS[0]-MIN) -# pos_norm_error = (up_pos_norm_error/down_pos_norm_error) -# #------------------------------------------------------------------ -# if pos_norm_error < error: -# break -# #----- FIRE ------------------------------------------------------ -# #---- alpha RESET and Half time step setting --------------------- -# if np.dot(VEL[i],F[i])<=0: -# VEL[i] = v_initial -# h = 0.5*h -# alpha = 0.1 -# Np = 0 -# Nreset = Nreset + 1 - -# elif np.dot(VEL[i],F[i])>0: -# Np = Np + 1 - -# #----- FORCE UNITE VECTOR ------------------------------------ - -# fh = F[i]/np.linalg.norm(F[i]) - -# #---- FIRE VELOCITY CORRECTION ------------------------------- -# VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh -# #------------------------------------------------------------- - -# #----- alpha, time step UPGRADE ------------------------------ -# if Np>5: - -# h = min(1.1*h,t_max) - - -# alpha = 0.99*alpha - - -# #----- NEW ELEMENT in the lists ----------------------------------- -# POS.append(0) -# F.append(0) -# norm_force.append(0) -# VEL.append(0) -# E.append(0) -# #--------------- BACKWARD EULER(2)--------------------------------- -# #-- POSITION ------------------------------------------------------ -# POS[i+1] = POS[i] + VEL[i]*h -# #-- FORCE --------------------------------------------------------- -# F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart -# norm_force[i+1] = np.linalg.norm(F[i+1]) -# #-- VELOCITY ------------------------------------------------------ -# VEL[i+1] = VEL[i] + F[i+1]*h -# #-- ENERGY ------------------------------------------------------- -# E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - -# #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- -# if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: - -# break -# #------------------------------------------------------------------ - -# #------------- NORM OF FORCE CONVERGENCE -------------------------- -# if np.linalg.norm(F[i+1])< error: - -# break -# #------------------------------------------------------------------ - - -# #--- LIST position update------------------------------------------ -# i = i + 1 -# #--------- END OF OPTIMIZTION PROCESS --------------------------------- - -# #--- COLLECTED DATA ANALYSIS ------------------------------------------ -# #---------------------------------------------------------------------- -# POS = np.array(POS) #<--- To calculate the position errors -# ini_dist = np.linalg.norm(r0 - pos_minima) -# #---- position error calculation ------------------------------------- -# position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist -# #--------------------------------------------------------------------- - -# #----------------- Energy Error calculations ------------------------- -# E = np.array(E)#<---- To calculate Energy errors -# #--------------------------------------------------------------------- -# energy_errors = abs((E - MIN)/(E[0]-MIN)) -# #------- ATRIBUTES ---------------------------------------------------- -# self.steps = len(E) -# self.positions = POS -# self.minima_error = position_errors -# self.forces = F -# self.norm_forces = np.array(norm_force) -# self.velocity = VEL -# self.energy = E -# self.energy_errors = energy_errors -# self.Np = Np -# self.alpha = alpha -# self.Nreset = Nreset -# self.min_force =min(norm_force) -# #---------------------------------------------------------------------- - + + backwardeuler_FIRE(molecule, numb_coord, R_xyz) + # while k < (Ncycle): + # k = k + 1 + # #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- + # up_pos_norm_error = np.linalg.norm(POS[i] - MIN) + # down_pos_norm_error = np.linalg.norm(POS[0]-MIN) + # pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + # #------------------------------------------------------------------ + # if pos_norm_error < error: + # break + # #----- FIRE ------------------------------------------------------ + # #---- alpha RESET and Half time step setting --------------------- + # if np.dot(VEL[i],F[i])<=0: + # VEL[i] = v_initial + # h = 0.5*h + # alpha = 0.1 + # Np = 0 + # Nreset = Nreset + 1 + + # elif np.dot(VEL[i],F[i])>0: + # Np = Np + 1 + + # #----- FORCE UNITE VECTOR ------------------------------------ + + # fh = F[i]/np.linalg.norm(F[i]) + + # #---- FIRE VELOCITY CORRECTION ------------------------------- + # VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + # #------------------------------------------------------------- + + # #----- alpha, time step UPGRADE ------------------------------ + # if Np>5: + + # h = min(1.1*h,t_max) + + # alpha = 0.99*alpha + + # #----- NEW ELEMENT in the lists ----------------------------------- + # POS.append(0) + # F.append(0) + # norm_force.append(0) + # VEL.append(0) + # E.append(0) + # #--------------- BACKWARD EULER(2)--------------------------------- + # #-- POSITION ------------------------------------------------------ + # POS[i+1] = POS[i] + VEL[i]*h + # #-- FORCE --------------------------------------------------------- + # F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart + # norm_force[i+1] = np.linalg.norm(F[i+1]) + # #-- VELOCITY ------------------------------------------------------ + # VEL[i+1] = VEL[i] + F[i+1]*h + # #-- ENERGY ------------------------------------------------------- + # E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy + + # #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + # if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: + + # break + # #------------------------------------------------------------------ + + # #------------- NORM OF FORCE CONVERGENCE -------------------------- + # if np.linalg.norm(F[i+1])< error: + + # break + # #------------------------------------------------------------------ + + # #--- LIST position update------------------------------------------ + # i = i + 1 + # #--------- END OF OPTIMIZTION PROCESS --------------------------------- + + # #--- COLLECTED DATA ANALYSIS ------------------------------------------ + # #---------------------------------------------------------------------- + # POS = np.array(POS) #<--- To calculate the position errors + # ini_dist = np.linalg.norm(r0 - pos_minima) + # #---- position error calculation ------------------------------------- + # position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + # #--------------------------------------------------------------------- + + # #----------------- Energy Error calculations ------------------------- + # E = np.array(E)#<---- To calculate Energy errors + # #--------------------------------------------------------------------- + # energy_errors = abs((E - MIN)/(E[0]-MIN)) + # #------- ATRIBUTES ---------------------------------------------------- + # self.steps = len(E) + # self.positions = POS + # self.minima_error = position_errors + # self.forces = F + # self.norm_forces = np.array(norm_force) + # self.velocity = VEL + # self.energy = E + # self.energy_errors = energy_errors + # self.Np = Np + # self.alpha = alpha + # self.Nreset = Nreset + # self.min_force =min(norm_force) + # #---------------------------------------------------------------------- e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() From 64796184ac18bd8e5ee2718ae73064dcdb1e12d8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 2 Jul 2025 03:21:35 +0000 Subject: [PATCH 19/23] Committing clang-format changes --- .../structurefinder/NSTOVSUT/__init__.py | 22 +- .../NSTOVSUT/nesterov_SUT_NDC.py | 97 ++++---- src/python/structurefinder/__init__.py | 1 + src/python/structurefinder/fire/__init__.py | 13 + .../fire/backward_euler/__init__.py | 22 +- .../fire/backward_euler/backward_euler.py | 232 +++++++++--------- .../fire/backward_euler/be2_DC_NVT.py | 97 ++++---- .../fire/backward_euler/be2_DC_VarT.py | 106 ++++---- .../fire/nesterov_sutskever/__init__.py | 22 +- .../nesterov_sutskever/nesterov_SUT_DC_NVT.py | 99 ++++---- .../nesterov_SUT_DC_VarT.py | 111 +++++---- .../nesterov_sutskever/nesterov_SUT_NDC.py | 97 ++++---- .../nesterov_sutskever/nesterov_sutskever.py | 128 +++++----- .../fire/velocity_verlet/__init__.py | 22 +- .../fire/velocity_verlet/velocity_verlet.py | 127 +++++----- .../fire/velocity_verlet/vv_DC_NVT.py | 96 ++++---- .../fire/velocity_verlet/vv_DC_VarT.py | 99 ++++---- .../test_backward_euler_fire.py | 30 ++- 18 files changed, 814 insertions(+), 607 deletions(-) diff --git a/src/python/structurefinder/NSTOVSUT/__init__.py b/src/python/structurefinder/NSTOVSUT/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/NSTOVSUT/__init__.py +++ b/src/python/structurefinder/NSTOVSUT/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py index caabce8..b4a7503 100644 --- a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py +++ b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,88 +23,89 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_NDC(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list + POS = [r0] #<-- Position list VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- + break + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -101,6 +115,7 @@ def __init__(self,r0): self.velocity = VEL self.energy = E self.energy_errors = energy_errors - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/__init__.py b/src/python/structurefinder/__init__.py index cbe9a96..672de3f 100644 --- a/src/python/structurefinder/__init__.py +++ b/src/python/structurefinder/__init__.py @@ -16,6 +16,7 @@ from .lj_potential.lennard_jones_potential_module import load_lennard_jones_potential from .fire.backward_euler.backward_euler import load_backwardeulerfire_modules + def load_modules(mm): """ Loads the collection of all modules provided by StructureFinder. diff --git a/src/python/structurefinder/fire/__init__.py b/src/python/structurefinder/fire/__init__.py index e69de29..a8d4745 100644 --- a/src/python/structurefinder/fire/__init__.py +++ b/src/python/structurefinder/fire/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/src/python/structurefinder/fire/backward_euler/__init__.py b/src/python/structurefinder/fire/backward_euler/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/backward_euler/__init__.py +++ b/src/python/structurefinder/fire/backward_euler/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index f9027ad..2d8cbff 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -13,11 +13,13 @@ # limitations under the License. import pluginplay as pp -from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy,TotalEnergyNuclearOptimization, MoleculeFromString) +from simde import (EnergyNuclearGradientStdVectorD, TotalEnergy, + TotalEnergyNuclearOptimization, MoleculeFromString) import chemist import numpy as np import tensorwrapper as tw + class GeomoptViaBackwardEulerFIRE(pp.ModuleBase): def __init__(self): @@ -35,32 +37,37 @@ def run_(self, inputs, submods): # Construction of the coordinate vecotr numb_atoms = molecule.size() #<-- Number of atoms - numb_coord = 3*numb_atoms #<-- Number of coordinates + numb_coord = 3 * numb_atoms #<-- Number of coordinates R_xyz = np.zeros(numb_coord) #<-- Initializing the coordiantes vector for i_atom in range(molecule.size()): - R_xyz[3*i_atom] = molecule.at(i_atom).x - R_xyz[3*i_atom + 1] = molecule.at(i_atom).y - R_xyz[3*i_atom + 2] = molecule.at(i_atom).z + R_xyz[3 * i_atom] = molecule.at(i_atom).x + R_xyz[3 * i_atom + 1] = molecule.at(i_atom).y + R_xyz[3 * i_atom + 2] = molecule.at(i_atom).z #print(list(R_xyz)) # molecule.at(0).x = 110 #print(molecule) - def updated_molecule_coord(coordinates,molecule): - numb_atoms = molecule.size() + def updated_molecule_coord(coordinates, molecule): + numb_atoms = molecule.size() for i_atom in range(numb_atoms): - molecule.at(i_atom).x = coordinates[3*i_atom] - molecule.at(i_atom).y = coordinates[3*i_atom + 1] - molecule.at(i_atom).z = coordinates[3*i_atom + 2] + molecule.at(i_atom).x = coordinates[3 * i_atom] + molecule.at(i_atom).y = coordinates[3 * i_atom + 1] + molecule.at(i_atom).z = coordinates[3 * i_atom + 2] return molecule - - def e_func(new_coord,molecule): - current_molecule = updated_molecule_coord(new_coord,molecule) - return submods["Energy"].run_as(TotalEnergy(), chemist.ChemicalSystem(current_molecule)) - + + def e_func(new_coord, molecule): + current_molecule = updated_molecule_coord(new_coord, molecule) + return submods["Energy"].run_as( + TotalEnergy(), chemist.ChemicalSystem(current_molecule)) + def grad_func(new_coord, molecule): current_molecule = updated_molecule_coord(new_coord, molecule) - current_points = current_molecule.nuclei.as_nuclei().charges.point_set.as_point_set() # The problem is here when using 0.0 coordinates - return submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), chemist.ChemicalSystem(current_molecule), current_points) + current_points = current_molecule.nuclei.as_nuclei( + ).charges.point_set.as_point_set( + ) # The problem is here when using 0.0 coordinates + return submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), + chemist.ChemicalSystem(current_molecule), current_points) def create_coord_string(molecule): mol_string = "" @@ -68,7 +75,7 @@ def create_coord_string(molecule): for atom in range(molecule.size()): mol_string += f"{molecule.at(atom).name} {molecule.at(atom).x} {molecule.at(atom).y} {molecule.at(atom).z}\n" return mol_string - + # def print_pointset(pointset): # printout = ' ' # for i in range(pointset.size()): @@ -77,7 +84,7 @@ def create_coord_string(molecule): # printout+= str(pointset.at(i).coord(j)) + ' ' # printout+= ']' # print(printout) - + # #Loads the geometry string into the Berny optimizer object. # optimizer = BE2_FIRE(settings) # optimized_energy, optimized_geom = optimizer.optimize(xyz, e_func, grad_func) @@ -86,33 +93,42 @@ def create_coord_string(molecule): # Optimized energy is of type "float" #----------------------------------------------------------------------------------------------------------------- - def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbcycles=150, error_power = -8, time_step_update = 5): + + def backwardeuler_FIRE(molecule, + R_xyz, + h0=0.03, + alpha=0.1, + t_max=0.3, + numbcycles=150, + error_power=-8, + time_step_update=5): mol_coord = R_xyz Molecule = [molecule] #---------------------------------------------------------------------- error = 10**(error_power) #----VELOCITY --------------------------------------------------------- - v_initial = -np.array(grad_func(mol_coord, molecule))*h0 - v_0 = np.array(grad_func(mol_coord, molecule))*0 - VEL = [v_initial] #<-- Velocity list + v_initial = -np.array(grad_func(mol_coord, molecule)) * h0 + v_0 = np.array(grad_func(mol_coord, molecule)) * 0 + VEL = [v_initial] #<-- Velocity list #----ENERGY ------------------------------------------------------------ - E_0 = e_func(mol_coord,molecule) #<-- Initial Energy - Energy = [np.array(E_0)] #<-- Energy list + E_0 = e_func(mol_coord, molecule) #<-- Initial Energy + Energy = [np.array(E_0)] #<-- Energy list #----FORCE----------------------------------------------------------- - F_0 = -np.array(grad_func(mol_coord, molecule)) #<-- Initial Gradient + F_0 = -np.array(grad_func(mol_coord, + molecule)) #<-- Initial Gradient # input('Press enter to continue\n') # print(type(G_0)) - FORCE = [F_0] #<-- Gradient list + FORCE = [F_0] #<-- Gradient list # print('This is the gradient') # test = [Gradient] # print(test) # input('press enter to continue') #-----COORDINATE VECTOR ----------------------------------------------- - R_0 = R_xyz #<-- Initial Coordinate Vector - coord_vector = [np.array(R_0)] #<-- Coordinate Vector - + R_0 = R_xyz #<-- Initial Coordinate Vector + coord_vector = [np.array(R_0)] #<-- Coordinate Vector + #---------------------------------------------------------------------- - h = h0 #<-- Time step + h = h0 #<-- Time step #---------------------------------------------------------------------- #----- Optimization cycle parameters ---------------------------------- Ncycle = numbcycles @@ -122,8 +138,8 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc alpha = alpha t_max = t_max #------Counters ------------------------------------------------------ - k=0 #<-- Convergence cycles conter - i=0 #<-- counter + k = 0 #<-- Convergence cycles conter + i = 0 #<-- counter #---------------------------------------------------------------------- Rxyz_error_list = [] egy_error_list = [] @@ -135,88 +151,88 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc print(f"Starting step: {k}") #----- FIRE ------------------------------------------------------ #---- alpha RESET and Half time step setting --------------------- - if (np.dot(VEL[i],FORCE[i])<=0) and Np>0: + if (np.dot(VEL[i], FORCE[i]) <= 0) and Np > 0: VEL[i] = v_0 - h = 0.5*h + h = 0.5 * h alpha = 0.1 Np = 0 Nreset = Nreset + 1 - - elif np.dot(VEL[i],FORCE[i])>0: + + elif np.dot(VEL[i], FORCE[i]) > 0: Np = Np + 1 - + #----- FORCE UNITE VECTOR ------------------------------------ - - force_unit = FORCE[i]/np.linalg.norm(FORCE[i]) - - #---- FIRE VELOCITY CORRECTION ------------------------------- - VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*force_unit - #------------------------------------------------------------- - - #----- alpha, time step UPGRADE ------------------------------ - if Np>time_step_update: - - h = min(1.1*h,t_max) - - - alpha = 0.99*alpha + + force_unit = FORCE[i] / np.linalg.norm(FORCE[i]) + + #---- FIRE VELOCITY CORRECTION ------------------------------- + VEL[i] = (1 - alpha) * VEL[i] + alpha * np.linalg.norm( + VEL[i]) * force_unit + #------------------------------------------------------------- + + #----- alpha, time step UPGRADE ------------------------------ + if Np > time_step_update: + + h = min(1.1 * h, t_max) + + alpha = 0.99 * alpha #--------------- BACKWARD EULER(2)--------------------------------- #-- COORD_VECTOR ------------------------------------------------------ x_j = coord_vector[i] #-- - x_newj = x_j + VEL[i]*h + x_newj = x_j + VEL[i] * h coord_vector.append(x_newj) #-- NEW GRAD --------------------------------------------------------- - force_newj = -np.array(grad_func(x_newj, molecule)) + force_newj = -np.array(grad_func(x_newj, molecule)) FORCE.append(force_newj) #-- VELOCITY ------------------------------------------------------ - vel_newj = VEL[i] + FORCE[i+1]*h + vel_newj = VEL[i] + FORCE[i + 1] * h VEL.append(vel_newj) - - - + #-- NEW ENEGY - egy_newj = e_func(x_newj,molecule) + egy_newj = e_func(x_newj, molecule) Energy.append(np.array(egy_newj)) #-- - + #--- ERRORS ---------------------------------------------------------- - Rxyz_error = np.linalg.norm(coord_vector[i] - coord_vector[i+1]) + Rxyz_error = np.linalg.norm(coord_vector[i] - + coord_vector[i + 1]) Rxyz_error_list.append(Rxyz_error) - - egy_error = np.abs(Energy[i] - Energy[i+1]) + + egy_error = np.abs(Energy[i] - Energy[i + 1]) egy_error_list.append(egy_error) - - force_error = np.linalg.norm(FORCE[i]-FORCE[i+1]) + + force_error = np.linalg.norm(FORCE[i] - FORCE[i + 1]) force_error_list.append(force_error) #--- LIST OF COORDINATES mol_string = create_coord_string(molecule) coord_list.append(mol_string) - - if (Rxyz_error < error) and (egy_error < error) and (force_error < error): + if (Rxyz_error < error) and (egy_error + < error) and (force_error + < error): break - - - if k == Ncycle: - print(f"Maximum number of optimization steps achieved: {Ncycle}") + print( + f"Maximum number of optimization steps achieved: {Ncycle}" + ) break - i+=1 + i += 1 print(f"values of i: {i}") return { - 'Energy':Energy, - 'Energy Error':egy_error_list, + 'Energy': Energy, + 'Energy Error': egy_error_list, 'FORCE': FORCE, 'FORCE Error': force_error_list, 'Coordinates': coord_vector, - 'Coordinates error':Rxyz_error_list, + 'Coordinates error': Rxyz_error_list, 'Coordinate Strings': coord_list, - 'Molecule':Molecule, - } - + 'Molecule': Molecule, + } + + # #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- # up_pos_norm_error = np.linalg.norm(POS[i] - MIN) # down_pos_norm_error = np.linalg.norm(POS[0]-MIN) @@ -232,28 +248,26 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc # alpha = 0.1 # Np = 0 # Nreset = Nreset + 1 - + # elif np.dot(VEL[i],F[i])>0: # Np = Np + 1 - + # #----- FORCE UNITE VECTOR ------------------------------------ - + # fh = F[i]/np.linalg.norm(F[i]) - + # #---- FIRE VELOCITY CORRECTION ------------------------------- # VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh # #------------------------------------------------------------- - + # #----- alpha, time step UPGRADE ------------------------------ # if Np>5: - + # h = min(1.1*h,t_max) - - + # alpha = 0.99*alpha - - -# #----- NEW ELEMENT in the lists ----------------------------------- + +# #----- NEW ELEMENT in the lists ----------------------------------- # POS.append(0) # F.append(0) # norm_force.append(0) @@ -261,7 +275,7 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc # E.append(0) # #--------------- BACKWARD EULER(2)--------------------------------- # #-- POSITION ------------------------------------------------------ -# POS[i+1] = POS[i] + VEL[i]*h +# POS[i+1] = POS[i] + VEL[i]*h # #-- FORCE --------------------------------------------------------- # F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart # norm_force[i+1] = np.linalg.norm(F[i+1]) @@ -269,36 +283,35 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc # VEL[i+1] = VEL[i] + F[i+1]*h # #-- ENERGY ------------------------------------------------------- # E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - -# #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + +# #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- # if abs(E[i+1]-MIN)/abs(E[0]-MIN) < error: - + # break # #------------------------------------------------------------------ - + # #------------- NORM OF FORCE CONVERGENCE -------------------------- # if np.linalg.norm(F[i+1])< error: - + # break -# #------------------------------------------------------------------ +# #------------------------------------------------------------------ - # #--- LIST position update------------------------------------------ # i = i + 1 # #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + # #--- COLLECTED DATA ANALYSIS ------------------------------------------ # #---------------------------------------------------------------------- # POS = np.array(POS) #<--- To calculate the position errors # ini_dist = np.linalg.norm(r0 - pos_minima) # #---- position error calculation ------------------------------------- -# position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist +# position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist # #--------------------------------------------------------------------- - + # #----------------- Energy Error calculations ------------------------- # E = np.array(E)#<---- To calculate Energy errors # #--------------------------------------------------------------------- -# energy_errors = abs((E - MIN)/(E[0]-MIN)) +# energy_errors = abs((E - MIN)/(E[0]-MIN)) # #------- ATRIBUTES ---------------------------------------------------- # self.steps = len(E) # self.positions = POS @@ -313,7 +326,7 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc # self.Nreset = Nreset # self.min_force =min(norm_force) # #---------------------------------------------------------------------- - + test = backwardeuler_FIRE(molecule, R_xyz) egy_error = test['Energy Error'] print(egy_error) @@ -329,22 +342,19 @@ def backwardeuler_FIRE(molecule, R_xyz, h0 = 0.03, alpha = 0.1, t_max=0.3, numbc print(i) input('Press enter to continue') final_coords_string = "".join(test['Coordinate Strings']) - + with open('test.xyz', "w") as file: file.write(final_coords_string) e = tw.Tensor(np.array([0.0])) ps = chemist.PointSetD() for i in range(numb_atoms): - ps.push_back(chemist.PointD(R_xyz[3*i],R_xyz[3*i + 1], R_xyz[3*i + 2])) + ps.push_back( + chemist.PointD(R_xyz[3 * i], R_xyz[3 * i + 1], + R_xyz[3 * i + 2])) rv = self.results() return pt.wrap_results(rv, e, ps) -def load_backwardeulerfire_modules(mm): - mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) - - - - - +def load_backwardeulerfire_modules(mm): + mm.add_module("BackwardEulerFire", GeomoptViaBackwardEulerFIRE()) diff --git a/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py index 25b1eb0..2bb69f7 100644 --- a/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py +++ b/src/python/structurefinder/fire/backward_euler/be2_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 16:34:02 2024 @@ -12,48 +25,48 @@ class BE2_DC_NVT(): - - def __init__(self,r0,h): - + + def __init__(self, r0, h): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 #--------------------------------------------------------------------- while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Np = 0 Nreset = Nreset + 1 #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -61,45 +74,44 @@ def __init__(self,r0,h): E.append(0) #--------------- BACKWARD EULER(2)--------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + POS[i + 1] = POS[i] + VEL[i] * h #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + F[i+1]*h + VEL[i + 1] = VEL[i] + F[i + 1] * h #-- ENERGY ------------------------------------------------------- - E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -111,6 +123,7 @@ def __init__(self,r0,h): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py b/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py index eae6725..615e4e5 100644 --- a/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py +++ b/src/python/structurefinder/fire/backward_euler/be2_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 16:34:02 2024 @@ -10,57 +23,58 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class BE2_DC_VarT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - h = h0 #<-- time steps - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + h = h0 #<-- time steps + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- E0 = Lennard_Jones_Potential(r0).LJ_energy #<-- Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - t_max = 0.3 #<-- Maximum time step + t_max = 0.3 #<-- Maximum time step #-------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 #--------------------------------------------------------------------- while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 h = h0 Np = 0 Nreset = Nreset + 1 #------ TIME STEP UPDATE ----------------------------------------- - elif np.dot(VEL[i],F[i])>0: - Np = Np + 1 - h = h = min(1.1*h,t_max) + elif np.dot(VEL[i], F[i]) > 0: + Np = Np + 1 + h = h = min(1.1 * h, t_max) #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -68,45 +82,44 @@ def __init__(self,r0,h0): E.append(0) #--------------- BACKWARD EULER(2)--------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + POS[i + 1] = POS[i] + VEL[i] * h #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + F[i+1]*h + VEL[i + 1] = VEL[i] + F[i + 1] * h #-- ENERGY ------------------------------------------------------- - E[i+1] = Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -118,6 +131,7 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py index 7255af4..4167c01 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,96 +23,97 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_DCNVT(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) + POS = [r0] #<-- Position list + v0 = np.array(0) VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Nreset = Nreset + 1 #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -111,6 +125,7 @@ def __init__(self,r0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py index 845007d..31e9a4d 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,104 +23,105 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_DC_VarT(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) + POS = [r0] #<-- Position list + v0 = np.array(0) VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 - alpha = 0.001 + alpha = 0.001 mu = 0.9 Nreset = Nreset + 1 #------ TIME STEP UPDATE ----------------------------------------- - elif np.dot(VEL[i],F[i])>0: - Np = Np + 1 - #--- TIME STEP UPGRADE -------------------------------------- - alpha = 1.1*alpha - mu = 1.1*mu + elif np.dot(VEL[i], F[i]) > 0: + Np = Np + 1 + #--- TIME STEP UPGRADE -------------------------------------- + alpha = 1.1 * alpha + mu = 1.1 * mu #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -121,6 +135,7 @@ def __init__(self,r0): self.Nreset = Nreset self.alpha = alpha self.mu = mu - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py index caabce8..b4a7503 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Mon Apr 29 12:30:09 2024 @@ -10,88 +23,89 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_SUT_NDC(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list + POS = [r0] #<-- Position list VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- Ncycle = 1000 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- + break + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] = Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - - + #--- LIST position update------------------------------------------ i = i + 1 - + #--------- END OF OPTIMIZTION PROCESS --------------------------------- #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -101,6 +115,7 @@ def __init__(self,r0): self.velocity = VEL self.energy = E self.energy_errors = energy_errors - self.min_force =min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- + self.min_force = min(norm_force) + + #---------------------------------------------------------------------- + # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py index 27928b6..dba0e2a 100644 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py +++ b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Tue Apr 30 04:13:14 2024 @@ -10,122 +23,123 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class NAG_FIRE(): - - def __init__(self,r0): - + + def __init__(self, r0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- - E0=Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List norm_force = [np.linalg.norm(F[0])] #--------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.001 + alpha = 0.001 mu = 0.9 theta = 0.1 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- FIRE ------------------------------------------------------- #---- TIME STEPS and Theta Reset ---------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = VEL[0] alpha = 0.001 mu = 0.9 theta = 0.1 Np = 0 Nreset = Nreset + 1 - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - + #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i]/np.linalg.norm(F[i]) - + + fh = F[i] / np.linalg.norm(F[i]) + #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1-theta)*VEL[i] + theta*np.linalg.norm(VEL[i])*fh + VEL[i] = (1 - theta) * VEL[i] + theta * np.linalg.norm( + VEL[i]) * fh #------------------------------------------------------------ - + #----- TIME STEP and THETA UPGRADE --------------------------- - if Np>5: - - alpha = 1.1*alpha - - mu = 1.1*mu - - theta = 0.99*theta - - - #----- NEW ELEMENT in the lists ----------------------------------- + if Np > 5: + + alpha = 1.1 * alpha + + mu = 1.1 * mu + + theta = 0.99 * theta + + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) VEL.append(0) F.append(0) norm_force.append(0) E.append(0) #--------------- NAG-SUTSKEVER-- --------------------------------- - + #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = mu*VEL[i] + alpha*F[i] + VEL[i + 1] = mu * VEL[i] + alpha * F[i] #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i+1] + POS[i + 1] = POS[i] + VEL[i + 1] #-- FORCE --------------------------------------------------------- - F[i+1] =Lennard_Jones_Potential(POS[i+1] + mu*VEL[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + + mu * VEL[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break - #------------------------------------------------------------------ + #------------------------------------------------------------------ - #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -138,6 +152,6 @@ def __init__(self,r0): self.Np = Np self.alpha = alpha self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/__init__.py b/src/python/structurefinder/fire/velocity_verlet/__init__.py index 2979804..7cf8985 100644 --- a/src/python/structurefinder/fire/velocity_verlet/__init__.py +++ b/src/python/structurefinder/fire/velocity_verlet/__init__.py @@ -39,7 +39,8 @@ def run_(self, inputs, submods): xyz = "" xyz += (str(molecule.size()) + "\n\n") for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") + xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + + str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") # Loads the geometry string into the Berny optimizer # object. @@ -54,22 +55,29 @@ def run_(self, inputs, submods): print('Lines of geom2xyz: \n' + str(lines) + '\n') mol_string = '\n'.join(lines[2:]) print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as(MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + str(xyz2chem_mol.nuclei) + '\n') + xyz2chem_mol = submods["StringConv"].run_as( + MoleculeFromString(), mol_string) + print('String conversion from xyz to chem sys: \n' + + str(xyz2chem_mol.nuclei) + '\n') geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + str(geom.molecule.nuclei) + '\n') + print('Chemical system of xyz2chem_mol: \n' + + str(geom.molecule.nuclei) + '\n') geom_nuclei = geom.molecule.nuclei.as_nuclei() geom_points = geom_nuclei.charges.point_set # Main optimizer operation energy = submods["Energy"].run_as(TotalEnergy(), geom) print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as(EnergyNuclearGradientStdVectorD(), geom, geom_points.as_point_set()) + gradients = submods["Gradient"].run_as( + EnergyNuclearGradientStdVectorD(), geom, + geom_points.as_point_set()) print('Interim gradient: \n' + str(gradients) + '\n') optimizer.send((energy, gradients)) - + opt_geom = geom.molecule.nuclei - print('Resulting relaxed geometry (assigned to variable opt_geom): \n' + str(opt_geom)) + print( + 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + + str(opt_geom)) # Optimized energy is of type "float" e = tw.Tensor(energy) print(e) diff --git a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py index 3442532..b2cc0ca 100644 --- a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py +++ b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -10,73 +23,74 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class VV_FIRE(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) #<-- Position minimum - h = h0 #<-- Time step + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #<-- Position minimum + h = h0 #<-- Time step #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - alpha = 0.1 - t_max = 0.3 #<-- Max time step + alpha = 0.1 + t_max = 0.3 #<-- Max time step #--------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- FIRE ------------------------------------------------------- #---- alpha RESET and Half time step setting -------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 - h = 0.5*h + h = 0.5 * h alpha = 0.1 Np = 0 Nreset = Nreset + 1 - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - + #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i]/np.linalg.norm(F[i]) - + + fh = F[i] / np.linalg.norm(F[i]) + #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1-alpha)*VEL[i] + alpha*np.linalg.norm(VEL[i])*fh + VEL[i] = (1 - alpha) * VEL[i] + alpha * np.linalg.norm( + VEL[i]) * fh #------------------------------------------------------------ - + #----- alpha, time step UPGRADE ------------------------------ - if Np>5: - - h = min(1.1*h,t_max) - - - alpha = 0.99*alpha - - #----- NEW ELEMENT in the lists ----------------------------------- + if Np > 5: + + h = min(1.1 * h, t_max) + + alpha = 0.99 * alpha + + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -84,44 +98,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break - #------------------------------------------------------------------ + #------------------------------------------------------------------ - #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -134,6 +147,6 @@ def __init__(self,r0,h0): self.Np = Np self.alpha = alpha self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py index 22a071a..44826db 100644 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py +++ b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -10,53 +23,53 @@ import numpy as np from LJ_potential import Lennard_Jones_Potential + class VV_DC_NVT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) h = h0 #--------------------------------------------------------------------- - E0= Lennard_Jones_Potential(r0).LJ_energy + E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - - k=0 - i=0 + + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 Np = 0 Nreset = Nreset + 1 - #------------------------------------------------------------------ + #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -64,43 +77,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]= Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]= Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - + #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -112,7 +125,6 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code --------------------------------------------------------- - diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py index 8a9b15d..f5ed759 100644 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py +++ b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py @@ -1,5 +1,18 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. """ Created on Fri Aug 11 11:26:48 2023 @@ -12,58 +25,57 @@ class VV_DC_VarT(): - - def __init__(self,r0,h0): - + + def __init__(self, r0, h0): + #---- DATA INITIALIZAION --------------------------------------------- r0 = np.array([r0]) - h = h0 #<-- time step - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1/6) + h = h0 #<-- time step + POS = [r0] #<-- Position list + MIN = -1 #<-- Energy minimum + pos_minima = 2**(1 / 6) #--------------------------------------------------------------------- E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy E = [E0] #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [ np.linalg.norm(F[0])] + F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force + F = [F0] #<-- Forces List + norm_force = [np.linalg.norm(F[0])] #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list + v0 = np.array(0) #<-- Initial Velocity + VEL = [v0] #<-- Velocity list #---------------------------------------------------------------------- Ncycle = 1000 Np = 0 Nreset = 0 #--------------------------------------------------------------------- - t_max = 0.3 #<-- Maximum time step + t_max = 0.3 #<-- Maximum time step #-------------------------------------------------------------------- - k=0 - i=0 + k = 0 + i = 0 while k < (Ncycle): k = k + 1 #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0]-MIN) - pos_norm_error = (up_pos_norm_error/down_pos_norm_error) + down_pos_norm_error = np.linalg.norm(POS[0] - MIN) + pos_norm_error = (up_pos_norm_error / down_pos_norm_error) #------------------------------------------------------------------ if pos_norm_error < 10**(-8): break #----- Direction Correction --------------------------------------- - if np.dot(VEL[i],F[i])<=0: + if np.dot(VEL[i], F[i]) <= 0: VEL[i] = v0 h = h0 Np = 0 Nreset = Nreset + 1 #------ TIME STEP UPDATE ------------------------------------------ - elif np.dot(VEL[i],F[i])>0: + elif np.dot(VEL[i], F[i]) > 0: Np = Np + 1 - h = h = min(1.1*h,t_max) - #------------------------------------------------------------------ + h = h = min(1.1 * h, t_max) + #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- + #----- NEW ELEMENT in the lists ----------------------------------- POS.append(0) F.append(0) norm_force.append(0) @@ -71,43 +83,43 @@ def __init__(self,r0,h0): E.append(0) #--------------- VELOCITY VERLET ---------------------------------- #-- POSITION ------------------------------------------------------ - POS[i+1] = POS[i] + VEL[i]*h + (F[i]/2)*h**2 + POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 #-- FORCE --------------------------------------------------------- - F[i+1]=Lennard_Jones_Potential(POS[i+1]).force_cart - norm_force[i+1] = np.linalg.norm(F[i+1]) + F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart + norm_force[i + 1] = np.linalg.norm(F[i + 1]) #-- VELOCITY ------------------------------------------------------ - VEL[i+1] = VEL[i] + ((F[i]+F[i+1])/2)*h + VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h #-- ENERGY ------------------------------------------------------- - E[i+1]=Lennard_Jones_Potential(POS[i+1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i+1]-MIN)/abs(E[0]-MIN) < 10**(-8): - + E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy + + #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- + if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): + break #------------------------------------------------------------------ - + #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i+1])<10**(-8): - + if np.linalg.norm(F[i + 1]) < 10**(-8): + break #------------------------------------------------------------------ - + #--- LIST position update------------------------------------------ i = i + 1 #--------- END OF OPTIMIZTION PROCESS --------------------------------- - + #--- COLLECTED DATA ANALYSIS ------------------------------------------ #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors + POS = np.array(POS) #<--- To calculate the position errors ini_dist = np.linalg.norm(r0 - pos_minima) #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis =1)/ini_dist + position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist #--------------------------------------------------------------------- - + #----------------- Energy Error calculations ------------------------- - E = np.array(E)#<---- To calculate Energy errors + E = np.array(E) #<---- To calculate Energy errors #--------------------------------------------------------------------- - energy_errors = abs((E - MIN)/(E[0]-MIN)) + energy_errors = abs((E - MIN) / (E[0] - MIN)) #------- ATRIBUTES ---------------------------------------------------- self.steps = len(E) self.positions = POS @@ -119,7 +131,6 @@ def __init__(self,r0,h0): self.energy_errors = energy_errors self.Np = Np self.Nreset = Nreset - self.min_force =min(norm_force) + self.min_force = min(norm_force) #---------------------------------------------------------------------- # END of code --------------------------------------------------------- - diff --git a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py index 7ef8dae..5ede7f3 100644 --- a/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py +++ b/tests/python/unit_tests/test_optimizers/test_backward_euler_fire.py @@ -1,3 +1,17 @@ +# Copyright 2025 NWChemEx Community +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # # Copyright 2024 NWChemEx Community # # # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,18 +35,17 @@ import numpy as np import tensorwrapper as tw + def print_pointset(pointset): printout = ' ' for i in range(pointset.size()): - printout+= '[' + printout += '[' for j in range(3): - printout+= str(pointset.at(i).coord(j)) + ' ' - printout+= ']' + printout += str(pointset.at(i).coord(j)) + ' ' + printout += ']' print(printout) - - class Test_TotalEnergyNuclearOptimization(unittest.TestCase): def test_optimize_BEfire(self): @@ -41,12 +54,13 @@ def test_optimize_BEfire(self): structurefinder.load_modules(mm) mm.change_input("NWChem : SCF", "basis set", "sto-3g") mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g") - mm.change_submod("BackwardEulerFire", "Gradient", "NWChem : SCF Gradient") + mm.change_submod("BackwardEulerFire", "Gradient", + "NWChem : SCF Gradient") mm.change_submod("BackwardEulerFire", "Energy", "NWChem : SCF") mm.change_submod("BackwardEulerFire", "StringConv", "ChemicalSystem via QCElemental") - egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), "BackwardEulerFire", - self.sys, self.pointset) + egy, pts = mm.run_as(TotalEnergyNuclearOptimization(), + "BackwardEulerFire", self.sys, self.pointset) print("Energy = " + str(egy)) print_pointset(pts) #print(self.sys.molecule) From dd43daf9672efbdf4614a1a2640d8235ef918361 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 2 Jul 2025 03:50:15 +0000 Subject: [PATCH 20/23] Committing clang-format changes --- src/python/structurefinder/fire/backward_euler/backward_euler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index 6bfe3a2..3e58098 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -93,7 +93,6 @@ def create_coord_string(molecule): # Optimized energy is of type "float" - #----------------------------------------------------------------------------------------------------------------- def backwardeuler_FIRE(molecule, From 8ea88dc8eea5b34b094129358986ad9e56eb748a Mon Sep 17 00:00:00 2001 From: leothan Date: Tue, 1 Jul 2025 22:57:58 -0500 Subject: [PATCH 21/23] prints tst.xyz --- .../structurefinder/fire/backward_euler/backward_euler.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/python/structurefinder/fire/backward_euler/backward_euler.py b/src/python/structurefinder/fire/backward_euler/backward_euler.py index 3e58098..29f869a 100644 --- a/src/python/structurefinder/fire/backward_euler/backward_euler.py +++ b/src/python/structurefinder/fire/backward_euler/backward_euler.py @@ -206,6 +206,10 @@ def backwardeuler_FIRE(molecule, force_error = np.linalg.norm(FORCE[i] - FORCE[i + 1]) force_error_list.append(force_error) + #--- LIST OF COORDINATES + mol_string = create_coord_string(molecule) + coord_list.append(mol_string) + if (Rxyz_error < error) and (egy_error < error) and (force_error < error): From 9ebefd05aec5fb234215e4bd30df547839d5f78f Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 2 Jul 2025 12:08:29 -0500 Subject: [PATCH 22/23] clean gitignore --- .gitignore | 3 +-- .vscode/settings.json | 8 -------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 22bb655..2f684fc 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ build/ .venv/ install/ toolchain.cmake -.vscode/* -!.vscode/settings.json +.vscode/ StructureFinder.code-workspace diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 9ef1d57..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "cmake.configureOnOpen": false, - "cmake.buildDirectory": "${workspaceFolder}/build", - "cmake.sourceDirectory": "${workspaceFolder}", - "cmake.generator": "Ninja", - "cmake.buildOnSave": false, - "cmake.configureOnEdit": false -} \ No newline at end of file From b7805c8c160a1d9c416566b7417bbc1b462676f1 Mon Sep 17 00:00:00 2001 From: leothan Date: Wed, 2 Jul 2025 12:17:35 -0500 Subject: [PATCH 23/23] file removal --- .../structurefinder/NSTOVSUT/__init__.py | 89 ---------- .../NSTOVSUT/nesterov_SUT_NDC.py | 121 -------------- .../fire/nesterov_sutskever/__init__.py | 89 ---------- .../nesterov_sutskever/nesterov_SUT_DC_NVT.py | 131 --------------- .../nesterov_SUT_DC_VarT.py | 141 ---------------- .../nesterov_sutskever/nesterov_SUT_NDC.py | 121 -------------- .../nesterov_sutskever/nesterov_sutskever.py | 157 ------------------ .../fire/velocity_verlet/__init__.py | 89 ---------- .../fire/velocity_verlet/velocity_verlet.py | 152 ----------------- .../fire/velocity_verlet/vv_DC_NVT.py | 130 --------------- .../fire/velocity_verlet/vv_DC_VarT.py | 136 --------------- 11 files changed, 1356 deletions(-) delete mode 100644 src/python/structurefinder/NSTOVSUT/__init__.py delete mode 100644 src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py delete mode 100644 src/python/structurefinder/fire/nesterov_sutskever/__init__.py delete mode 100644 src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py delete mode 100644 src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py delete mode 100644 src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py delete mode 100644 src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py delete mode 100644 src/python/structurefinder/fire/velocity_verlet/__init__.py delete mode 100644 src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py delete mode 100644 src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py delete mode 100644 src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py diff --git a/src/python/structurefinder/NSTOVSUT/__init__.py b/src/python/structurefinder/NSTOVSUT/__init__.py deleted file mode 100644 index 7cf8985..0000000 --- a/src/python/structurefinder/NSTOVSUT/__init__.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2023 NWChemEx-Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pluginplay as pp -from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString -from berny import Berny, geomlib -import chemist -import numpy as np -import tensorwrapper as tw - - -class GeomoptViaPyberny(pp.ModuleBase): - - def __init__(self): - pp.ModuleBase.__init__(self) - self.satisfies_property_type(TotalEnergy()) - self.description("Performs PyBerny optimization") - self.add_submodule(TotalEnergy(), "Energy") - self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") - self.add_submodule(MoleculeFromString(), "StringConv") - - def run_(self, inputs, submods): - pt = TotalEnergy() - mol, = pt.unwrap_inputs(inputs) - molecule = mol.molecule - - # Convert Chemist Chemical System to XYZ - xyz = "" - xyz += (str(molecule.size()) + "\n\n") - for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + - str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") - - # Loads the geometry string into the Berny optimizer - # object. - optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) - - for geom in optimizer: - - # Converts the "Berny" geometry object to Chemical System - geom2xyz = geom.dumps('xyz') - print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') - lines = geom2xyz.split('\n') - print('Lines of geom2xyz: \n' + str(lines) + '\n') - mol_string = '\n'.join(lines[2:]) - print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as( - MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + - str(xyz2chem_mol.nuclei) + '\n') - geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + - str(geom.molecule.nuclei) + '\n') - geom_nuclei = geom.molecule.nuclei.as_nuclei() - geom_points = geom_nuclei.charges.point_set - - # Main optimizer operation - energy = submods["Energy"].run_as(TotalEnergy(), geom) - print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as( - EnergyNuclearGradientStdVectorD(), geom, - geom_points.as_point_set()) - print('Interim gradient: \n' + str(gradients) + '\n') - optimizer.send((energy, gradients)) - - opt_geom = geom.molecule.nuclei - print( - 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + - str(opt_geom)) - # Optimized energy is of type "float" - e = tw.Tensor(energy) - print(e) - rv = self.results() - return pt.wrap_results(rv, e) - - -def load_pyberny_modules(mm): - mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py b/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py deleted file mode 100644 index b4a7503..0000000 --- a/src/python/structurefinder/NSTOVSUT/nesterov_SUT_NDC.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Mon Apr 29 12:30:09 2024 - -@author: Felix Rojas -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class NAG_SUT_NDC(): - - def __init__(self, r0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - Ncycle = 1000 - #--------------------------------------------------------------------- - alpha = 0.001 - mu = 0.9 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - VEL.append(0) - F.append(0) - norm_force.append(0) - E.append(0) - #--------------- NAG-SUTSKEVER-- --------------------------------- - - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = mu * VEL[i] + alpha * F[i] - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i + 1] - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + - mu * VEL[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.min_force = min(norm_force) - - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py b/src/python/structurefinder/fire/nesterov_sutskever/__init__.py deleted file mode 100644 index 7cf8985..0000000 --- a/src/python/structurefinder/fire/nesterov_sutskever/__init__.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2023 NWChemEx-Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pluginplay as pp -from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString -from berny import Berny, geomlib -import chemist -import numpy as np -import tensorwrapper as tw - - -class GeomoptViaPyberny(pp.ModuleBase): - - def __init__(self): - pp.ModuleBase.__init__(self) - self.satisfies_property_type(TotalEnergy()) - self.description("Performs PyBerny optimization") - self.add_submodule(TotalEnergy(), "Energy") - self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") - self.add_submodule(MoleculeFromString(), "StringConv") - - def run_(self, inputs, submods): - pt = TotalEnergy() - mol, = pt.unwrap_inputs(inputs) - molecule = mol.molecule - - # Convert Chemist Chemical System to XYZ - xyz = "" - xyz += (str(molecule.size()) + "\n\n") - for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + - str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") - - # Loads the geometry string into the Berny optimizer - # object. - optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) - - for geom in optimizer: - - # Converts the "Berny" geometry object to Chemical System - geom2xyz = geom.dumps('xyz') - print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') - lines = geom2xyz.split('\n') - print('Lines of geom2xyz: \n' + str(lines) + '\n') - mol_string = '\n'.join(lines[2:]) - print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as( - MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + - str(xyz2chem_mol.nuclei) + '\n') - geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + - str(geom.molecule.nuclei) + '\n') - geom_nuclei = geom.molecule.nuclei.as_nuclei() - geom_points = geom_nuclei.charges.point_set - - # Main optimizer operation - energy = submods["Energy"].run_as(TotalEnergy(), geom) - print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as( - EnergyNuclearGradientStdVectorD(), geom, - geom_points.as_point_set()) - print('Interim gradient: \n' + str(gradients) + '\n') - optimizer.send((energy, gradients)) - - opt_geom = geom.molecule.nuclei - print( - 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + - str(opt_geom)) - # Optimized energy is of type "float" - e = tw.Tensor(energy) - print(e) - rv = self.results() - return pt.wrap_results(rv, e) - - -def load_pyberny_modules(mm): - mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py deleted file mode 100644 index 4167c01..0000000 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_NVT.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Mon Apr 29 12:30:09 2024 - -@author: Felix Rojas -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class NAG_SUT_DCNVT(): - - def __init__(self, r0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) - VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - alpha = 0.001 - mu = 0.9 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- Direction Correction --------------------------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = v0 - Nreset = Nreset + 1 - #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - VEL.append(0) - F.append(0) - norm_force.append(0) - E.append(0) - #--------------- NAG-SUTSKEVER-- --------------------------------- - - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = mu * VEL[i] + alpha * F[i] - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i + 1] - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + - mu * VEL[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.Nreset = Nreset - self.min_force = min(norm_force) - - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py deleted file mode 100644 index 31e9a4d..0000000 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_DC_VarT.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Mon Apr 29 12:30:09 2024 - -@author: Felix Rojas -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class NAG_SUT_DC_VarT(): - - def __init__(self, r0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) - VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - alpha = 0.001 - mu = 0.9 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- Direction Correction --------------------------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = v0 - alpha = 0.001 - mu = 0.9 - Nreset = Nreset + 1 - #------ TIME STEP UPDATE ----------------------------------------- - elif np.dot(VEL[i], F[i]) > 0: - Np = Np + 1 - #--- TIME STEP UPGRADE -------------------------------------- - alpha = 1.1 * alpha - mu = 1.1 * mu - #------------------------------------------------------------------ - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - VEL.append(0) - F.append(0) - norm_force.append(0) - E.append(0) - #--------------- NAG-SUTSKEVER-- --------------------------------- - - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = mu * VEL[i] + alpha * F[i] - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i + 1] - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + - mu * VEL[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.Nreset = Nreset - self.alpha = alpha - self.mu = mu - self.min_force = min(norm_force) - - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py deleted file mode 100644 index b4a7503..0000000 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_SUT_NDC.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Mon Apr 29 12:30:09 2024 - -@author: Felix Rojas -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class NAG_SUT_NDC(): - - def __init__(self, r0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - VEL = [np.array(0)] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - Ncycle = 1000 - #--------------------------------------------------------------------- - alpha = 0.001 - mu = 0.9 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - VEL.append(0) - F.append(0) - norm_force.append(0) - E.append(0) - #--------------- NAG-SUTSKEVER-- --------------------------------- - - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = mu * VEL[i] + alpha * F[i] - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i + 1] - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + - mu * VEL[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.min_force = min(norm_force) - - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py b/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py deleted file mode 100644 index dba0e2a..0000000 --- a/src/python/structurefinder/fire/nesterov_sutskever/nesterov_sutskever.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Tue Apr 30 04:13:14 2024 - -@author: Felix Rojas -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class NAG_FIRE(): - - def __init__(self, r0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #--------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - alpha = 0.001 - mu = 0.9 - theta = 0.1 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- FIRE ------------------------------------------------------- - #---- TIME STEPS and Theta Reset ---------------------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = VEL[0] - alpha = 0.001 - mu = 0.9 - theta = 0.1 - Np = 0 - Nreset = Nreset + 1 - elif np.dot(VEL[i], F[i]) > 0: - Np = Np + 1 - - #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i] / np.linalg.norm(F[i]) - - #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1 - theta) * VEL[i] + theta * np.linalg.norm( - VEL[i]) * fh - #------------------------------------------------------------ - - #----- TIME STEP and THETA UPGRADE --------------------------- - if Np > 5: - - alpha = 1.1 * alpha - - mu = 1.1 * mu - - theta = 0.99 * theta - - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - VEL.append(0) - F.append(0) - norm_force.append(0) - E.append(0) - #--------------- NAG-SUTSKEVER-- --------------------------------- - - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = mu * VEL[i] + alpha * F[i] - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i + 1] - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1] + - mu * VEL[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.alpha = alpha - self.Nreset = Nreset - self.min_force = min(norm_force) - #---------------------------------------------------------------------- - # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/__init__.py b/src/python/structurefinder/fire/velocity_verlet/__init__.py deleted file mode 100644 index 7cf8985..0000000 --- a/src/python/structurefinder/fire/velocity_verlet/__init__.py +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2023 NWChemEx-Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pluginplay as pp -from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString -from berny import Berny, geomlib -import chemist -import numpy as np -import tensorwrapper as tw - - -class GeomoptViaPyberny(pp.ModuleBase): - - def __init__(self): - pp.ModuleBase.__init__(self) - self.satisfies_property_type(TotalEnergy()) - self.description("Performs PyBerny optimization") - self.add_submodule(TotalEnergy(), "Energy") - self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient") - self.add_submodule(MoleculeFromString(), "StringConv") - - def run_(self, inputs, submods): - pt = TotalEnergy() - mol, = pt.unwrap_inputs(inputs) - molecule = mol.molecule - - # Convert Chemist Chemical System to XYZ - xyz = "" - xyz += (str(molecule.size()) + "\n\n") - for i in range(molecule.size()): - xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " + - str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n") - - # Loads the geometry string into the Berny optimizer - # object. - optimizer = Berny(geomlib.loads(xyz, fmt='xyz')) - - for geom in optimizer: - - # Converts the "Berny" geometry object to Chemical System - geom2xyz = geom.dumps('xyz') - print('Berny Geom to XYZ value: \n' + geom2xyz + '\n') - lines = geom2xyz.split('\n') - print('Lines of geom2xyz: \n' + str(lines) + '\n') - mol_string = '\n'.join(lines[2:]) - print('Lines to string: \n' + mol_string + '\n') - xyz2chem_mol = submods["StringConv"].run_as( - MoleculeFromString(), mol_string) - print('String conversion from xyz to chem sys: \n' + - str(xyz2chem_mol.nuclei) + '\n') - geom = chemist.ChemicalSystem(xyz2chem_mol) - print('Chemical system of xyz2chem_mol: \n' + - str(geom.molecule.nuclei) + '\n') - geom_nuclei = geom.molecule.nuclei.as_nuclei() - geom_points = geom_nuclei.charges.point_set - - # Main optimizer operation - energy = submods["Energy"].run_as(TotalEnergy(), geom) - print('Interim energy: \n' + str(energy) + '\n') - gradients = submods["Gradient"].run_as( - EnergyNuclearGradientStdVectorD(), geom, - geom_points.as_point_set()) - print('Interim gradient: \n' + str(gradients) + '\n') - optimizer.send((energy, gradients)) - - opt_geom = geom.molecule.nuclei - print( - 'Resulting relaxed geometry (assigned to variable opt_geom): \n' + - str(opt_geom)) - # Optimized energy is of type "float" - e = tw.Tensor(energy) - print(e) - rv = self.results() - return pt.wrap_results(rv, e) - - -def load_pyberny_modules(mm): - mm.add_module("PyBerny", GeomoptViaPyberny()) diff --git a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py b/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py deleted file mode 100644 index b2cc0ca..0000000 --- a/src/python/structurefinder/fire/velocity_verlet/velocity_verlet.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Fri Aug 11 11:26:48 2023 - -@author: leothan -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class VV_FIRE(): - - def __init__(self, r0, h0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) #<-- Position minimum - h = h0 #<-- Time step - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list - #---------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - alpha = 0.1 - t_max = 0.3 #<-- Max time step - #--------------------------------------------------------------------- - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- FIRE ------------------------------------------------------- - #---- alpha RESET and Half time step setting -------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = v0 - h = 0.5 * h - alpha = 0.1 - Np = 0 - Nreset = Nreset + 1 - elif np.dot(VEL[i], F[i]) > 0: - Np = Np + 1 - - #----- FORCE UNITE VECTOR ------------------------------------ - - fh = F[i] / np.linalg.norm(F[i]) - - #---- FIRE VELOCITY CORRECTION --------------------- - VEL[i] = (1 - alpha) * VEL[i] + alpha * np.linalg.norm( - VEL[i]) * fh - #------------------------------------------------------------ - - #----- alpha, time step UPGRADE ------------------------------ - if Np > 5: - - h = min(1.1 * h, t_max) - - alpha = 0.99 * alpha - - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - F.append(0) - norm_force.append(0) - VEL.append(0) - E.append(0) - #--------------- VELOCITY VERLET ---------------------------------- - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.alpha = alpha - self.Nreset = Nreset - self.min_force = min(norm_force) - #---------------------------------------------------------------------- - # END of code -------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py deleted file mode 100644 index 44826db..0000000 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_NVT.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Fri Aug 11 11:26:48 2023 - -@author: leothan -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class VV_DC_NVT(): - - def __init__(self, r0, h0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - h = h0 - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy - #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list - #---------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- Direction Correction --------------------------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = v0 - Np = 0 - Nreset = Nreset + 1 - #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - F.append(0) - norm_force.append(0) - VEL.append(0) - E.append(0) - #--------------- VELOCITY VERLET ---------------------------------- - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.Nreset = Nreset - self.min_force = min(norm_force) - #---------------------------------------------------------------------- - # END of code --------------------------------------------------------- diff --git a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py b/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py deleted file mode 100644 index f5ed759..0000000 --- a/src/python/structurefinder/fire/velocity_verlet/vv_DC_VarT.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright 2025 NWChemEx Community -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Created on Fri Aug 11 11:26:48 2023 - -@author: leothan -""" - -# Imported modules -import numpy as np -from LJ_potential import Lennard_Jones_Potential - - -class VV_DC_VarT(): - - def __init__(self, r0, h0): - - #---- DATA INITIALIZAION --------------------------------------------- - r0 = np.array([r0]) - h = h0 #<-- time step - POS = [r0] #<-- Position list - MIN = -1 #<-- Energy minimum - pos_minima = 2**(1 / 6) - #--------------------------------------------------------------------- - E0 = Lennard_Jones_Potential(r0).LJ_energy - #<-Initial Energy - E = [E0] - #--------------------------------------------------------------------- - F0 = Lennard_Jones_Potential(r0).force_cart #<-- Initial Force - F = [F0] #<-- Forces List - norm_force = [np.linalg.norm(F[0])] - #---------------------------------------------------------------------- - v0 = np.array(0) #<-- Initial Velocity - VEL = [v0] #<-- Velocity list - #---------------------------------------------------------------------- - Ncycle = 1000 - Np = 0 - Nreset = 0 - #--------------------------------------------------------------------- - t_max = 0.3 #<-- Maximum time step - #-------------------------------------------------------------------- - k = 0 - i = 0 - while k < (Ncycle): - k = k + 1 - #------------ NORMALIZED POS ERROR CONVERGENCE -------------------- - up_pos_norm_error = np.linalg.norm(POS[i] - MIN) - down_pos_norm_error = np.linalg.norm(POS[0] - MIN) - pos_norm_error = (up_pos_norm_error / down_pos_norm_error) - #------------------------------------------------------------------ - if pos_norm_error < 10**(-8): - break - #----- Direction Correction --------------------------------------- - if np.dot(VEL[i], F[i]) <= 0: - VEL[i] = v0 - h = h0 - Np = 0 - Nreset = Nreset + 1 - #------ TIME STEP UPDATE ------------------------------------------ - elif np.dot(VEL[i], F[i]) > 0: - Np = Np + 1 - h = h = min(1.1 * h, t_max) - #------------------------------------------------------------------ - - #----- NEW ELEMENT in the lists ----------------------------------- - POS.append(0) - F.append(0) - norm_force.append(0) - VEL.append(0) - E.append(0) - #--------------- VELOCITY VERLET ---------------------------------- - #-- POSITION ------------------------------------------------------ - POS[i + 1] = POS[i] + VEL[i] * h + (F[i] / 2) * h**2 - #-- FORCE --------------------------------------------------------- - F[i + 1] = Lennard_Jones_Potential(POS[i + 1]).force_cart - norm_force[i + 1] = np.linalg.norm(F[i + 1]) - #-- VELOCITY ------------------------------------------------------ - VEL[i + 1] = VEL[i] + ((F[i] + F[i + 1]) / 2) * h - #-- ENERGY ------------------------------------------------------- - E[i + 1] = Lennard_Jones_Potential(POS[i + 1]).LJ_energy - - #-------------- NORMALIZED ENERGY ERROR CONVERGENCE --------------- - if abs(E[i + 1] - MIN) / abs(E[0] - MIN) < 10**(-8): - - break - #------------------------------------------------------------------ - - #------------- NORM OF FORCE CONVERGENCE -------------------------- - if np.linalg.norm(F[i + 1]) < 10**(-8): - - break - #------------------------------------------------------------------ - - #--- LIST position update------------------------------------------ - i = i + 1 - #--------- END OF OPTIMIZTION PROCESS --------------------------------- - - #--- COLLECTED DATA ANALYSIS ------------------------------------------ - #---------------------------------------------------------------------- - POS = np.array(POS) #<--- To calculate the position errors - ini_dist = np.linalg.norm(r0 - pos_minima) - #---- position error calculation ------------------------------------- - position_errors = np.linalg.norm((POS - pos_minima), axis=1) / ini_dist - #--------------------------------------------------------------------- - - #----------------- Energy Error calculations ------------------------- - E = np.array(E) #<---- To calculate Energy errors - #--------------------------------------------------------------------- - energy_errors = abs((E - MIN) / (E[0] - MIN)) - #------- ATRIBUTES ---------------------------------------------------- - self.steps = len(E) - self.positions = POS - self.minima_error = position_errors - self.forces = F - self.norm_forces = np.array(norm_force) - self.velocity = VEL - self.energy = E - self.energy_errors = energy_errors - self.Np = Np - self.Nreset = Nreset - self.min_force = min(norm_force) - #---------------------------------------------------------------------- - # END of code ---------------------------------------------------------