def __init__(self, path): lg.debug('Importing Molecule from \n{}\n'.format(path)) self.id = None # If none there is some problem! self.xyzp = os.path.abspath(path) self.belonging_dataset = None self.myprm_full = params.ParamsManager() self.myprm_func = params.ParamsManager() self._full_energy = None self._uni_energy = None self._func_energy = None self._molecule_creator() self._run = Run(molID=self.id, dset=self.belonging_dataset)
class Molecule(object): """Create a molecule object starting from an xyz file. Providing an xyz file as argument when instantiating the class, a molecule object will be created. This object provide a name for the molecule (the xyz file name), an ID as the name of the dataset + the name of the molecule. Moreover it provides method to compute the energy for the molecule even if based on a different module. Args: path (str): xyz file relative or absolute path. Attributes: id (str): Human redeable string that identify the Molecule. xyzp (str): Storage of the absolute xyz file path. density_path (ToImplement[str]): Absolute path for the density file. belonging_dataset (str): Name of the dataset the molecule belongs. dft_energy (float): Energy computed at fulldft level. func_energy (float): Energy computed with the "fast" method. Exceptions: """ def __init__(self, path): lg.debug('Importing Molecule from \n{}\n'.format(path)) self.id = None # If none there is some problem! self.xyzp = os.path.abspath(path) self.belonging_dataset = None self.myprm_full = params.ParamsManager() self.myprm_func = params.ParamsManager() self._full_energy = None self._uni_energy = None self._func_energy = None self._molecule_creator() self._run = Run(molID=self.id, dset=self.belonging_dataset) def __str__(self): """Return a human readable string when the object is printed. """ return 'Molecule-' + self.id def _molecule_creator(self): """Create all what is needed for the object. Take the path attribute and use it to create all the others attribute. """ p, file = os.path.split(self.xyzp) p = os.path.split(p)[0] p = os.path.split(p)[1] self.belonging_dataset = p self.name = file[:-4] self.id = '{DATASET:s}.{NAME:s}'.format(DATASET=self.belonging_dataset, NAME=self.name) lg.debug("""Molecule Information: * Dataset: {DATASET:s} * Name: {NAME:s} * ID: {ID:s} * Path: {PATH:s} """.format(DATASET=self.belonging_dataset, NAME=self.name, ID=self.id, PATH=self.xyzp)) @property def uni_energy(self): """Total DFT energy - dispersion - XCcontribution. This energy will be used to get the total energy of a molecule when only the XC contribution is computed (func_energy). It is a property mostly for consistency since it is never as property. """ return self._uni_energy @uni_energy.getter def uni_energy(self): self.full_energy_calc() return self._uni_energy @property def full_energy(self): """Total DFT energy computed after a density optimization. """ return self._full_energy @full_energy.getter def full_energy(self): self.full_energy_calc() return self._full_energy @property def func_energy(self): """Total DFT energy computed after a single XC evaluation. Energy computed with a freezed density and different XC-d parameters. """ return self._func_energy @func_energy.getter def func_energy(self): self.func_energy_calc() return self._func_energy def full_energy_calc(self): """Retrieve the energy at fulldft level. Check if the parameters are changed from the last computation and in that case compute the fulldft energy from scratch, otherwise will return the last computed energy. Returns: self """ lg.debug('Full Energy for {ID:s} started'.format(ID=self.id)) lg.debug('Check if needed: Energy -> {:s}, CheckPar -> {:s}' .format(str(self._full_energy), str(self.myprm_full.check_prms()))) if not self._full_energy or not self.myprm_full.check_prms(): full_energy, full_exc, full_disp = self._run.full() uni_energy = full_energy - full_exc - full_disp lg.debug('Full Energy for {ID:s} is {ENERGY:12.6f}' ' and UNIENERGY is{UNIENERGY:12.6f}' .format(ID=self.id, ENERGY=full_energy, UNIENERGY=uni_energy)) self._full_energy = full_energy self._uni_energy = uni_energy self.myprm_full.refresh() return self def func_energy_calc(self): """Retrieve the energy computed with the optimized density. Check if the parameters are changed from the last computation and in that case compute the "functional" energy from scratch, otherwise will return the last computed energy. Returns: self """ if self._uni_energy is None: msg = 'UNIENERGY NOT DEFINED' lg.critical(msg) raise(ValueError(msg)) lg.debug('Func Energy for {ID:s} started'.format(ID=self.id)) lg.debug('Check if needed: Energy -> {:s}, CheckPar -> {:s}' .format(str(self._full_energy), str(self.myprm_func.check_prms()))) if not self._func_energy or not self.myprm_func.check_prms(): func_energy = self._run.func() lg.debug('Func Energy for {ID:s} is {ENERGY:12.6f}' .format(ID=self.id, ENERGY=func_energy)) self.myprm_func.refresh() if not isinstance(self._uni_energy, float): msg = 'UniEnergy is not a float for {MOLID:s}!'\ .format(MOLID=self.id) raise(RuntimeError(msg)) self._func_energy = func_energy + self._uni_energy return self
def main(): init_logging() prms = ParamsManager() i=0 # while not prms.check_saved(): while True: # print("Not all Parameters Converged!") # print(list(map(str,prms._actual_params))) print("BIG GAMESS computation number: "+str(i)) run = Run(run_name=config['run_name'], tset_path=config['training_set_path']) run.index = 'DENS-'+str(i) trset = TrainingSet(config['training_set_path'], config['training_set_file']) prms.prms = dict(tta=[13.300000190734863], ttb=[1.5299999713897705], cxhf=[0.157706], omega=[0.3], cx_aa=[0.842294, 0.726479, 1.04760, -5.70635, 13.2794], cc_aa=[1.000000, -4.33879, 18.2308, -31.7430, 17.2901], cc_ab=[1.000000, 2.37031, -11.3995, 6.58405, -3.78132]) # optim = Optim(['tta', 'ttb']) optim = Optim(['tta', 'ttb', 'cx_aa_0','cx_aa_1','cx_aa_2','cx_aa_3','cc_aa_1','cc_aa_2','cc_aa_3','cc_ab_1','cc_ab_2','cc_ab_3']) #x0_ = [13.3, 1.53] with open('/home/afabrizi/wb97xddsc/TMP_DATA/FUNC_PAR.dat','r') as f2: OldParams = [line.rstrip('\n') for line in f2] print("Old Parameters", OldParams) with open('/dev/shm/afabrizi/TMP_DATA/x0','r') as f1: x0_ = [line.rstrip('\n') for line in f1] # bnds=((None,None),(None,None)) bnds=((None,None),(None,None),(0,1),(None,None),(None,None),(None,None),(None,None),(None,None),(None,None),(None,None),(None,None),(None,None)) def compute_error(params, trset, optim, kind, error_type): optim.set_prms(params) if error_type == 'MAE': minim = trset.compute_MAE(kind) print('PAR: '+" ".join(list(map(str,params)))+' MAE: '+str(minim)) return minim print(compute_error(x0_, trset, optim, 'full', 'MAE')) def printer(xc): print('END of STEP') with open('/dev/shm/afabrizi/TMP_DATA/x0','w') as f: for s in xc: f.write(str(s) + '\n') print(xc) i+=1 OptRes=minimize(compute_error,x0_,args=(trset,optim,'func','MAE'), method='L-BFGS-B', bounds=bnds, callback=printer, options={'disp': True,'gtol': 1e-2,'maxiter':100000,'ftol':1e-4}) # OptRes=minimize(compute_error,x0_,args=(trset,optim,'func','MAE'), method='L-BFGS-B', bounds=bnds, callback=printer, options={'disp': True,'gtol': 1e-2,'maxiter':10000,'ftol':1e-4,'eps':1e-1}) print(OptRes) print("Time for this density: %s seconds ---" % (time.time() - start_time)) folder = '/dev/shm/afabrizi/tmp_density_dir/' for the_file in os.listdir(folder): file_path = os.path.join(folder, the_file) try: if os.path.isfile(file_path): os.remove(the_file) except: pass shutil.copy('/dev/shm/afabrizi/TMP_DATA/FUNC_PAR.dat', '/home/afabrizi/wb97xddsc/TMP_DATA/FUNC_PAR.dat') shutil.copy('/dev/shm/afabrizi/TMP_DATA/a0b0', '/home/afabrizi/wb97xddsc/TMP_DATA/a0b0') with open('/home/afabrizi/wb97xddsc/TMP_DATA/FUNC_PAR.dat','r') as f3: NewParams = [line.rstrip('\n') for line in f3] print("New Parameters", NewParams) if all(x in OldParams for x in NewParams): print("Total time: %s seconds ---" % (time.time() - start_time)) break else: print("Not all parameters converged.") pass