grrmpy.automate.auto_opt のソースコード

from pathlib import Path
from ase.io import write
from ase.optimize import LBFGS
from tqdm.notebook import tqdm_notebook as tqdm

# USER
from grrmpy.io import log2atoms
from grrmpy.optimize.attach import automate_maxstep
from grrmpy.calculator import pfp_calculator
try:
    from grrmpy.optimize import FIRELBFGS
except:
    pass

[ドキュメント]class AutoOpt(): """最適化後の構造は'Structure'フォルダ内にtrajファイルで保存される. 計算後の構造を一括で読み込むには >>> import grrmpy.io import read_traj >>> atoms_list = read_traj('Structure') Parameters: atomslist: list of Atoms Atomsのリスト optimizer: object 使用するOptimizer.デフォルトはLBFGS. constraints: ASE constraint | FixAtoms等の制約. | 複数設定する場合はリストで与える. | eq_list中のAtomsに既にconstraintがある場合,改めて設定する必要はない. trajectory: bool | Trueの場合,最適化途中の構造をtrajに保存する. | 'trajectory'フォルダー内に保存される. logfile: bool | Trueの場合, logファイルを保存する. | 'log'フォルダー内に保存される. calc_func: object calculatorを返す関数 """ def __init__(self, atomslist, optimizer = LBFGS, constraints = [], trajectory = False, logfile = True, calc_func = pfp_calculator, errorfile = "ERROR", traj_foldername = "trajectory", log_foldername = "log", save_foldername = "Structures"): """ 最適化後の構造は'Structure'フォルダ内にtrajファイルで保存される. Parameters: atomslist: list of Atoms Atomsのリスト optimizer: object 使用するOptimizer.デフォルトはLBFGS. constraints: ASE constraint FixAtoms等の制約. 複数設定する場合はリストで与える. eq_list中のAtomsに既にconstraintがある場合,改めて設定する必要はない. trajectory: bool Trueの場合,最適化途中の構造をtrajに保存する. 'trajectory'フォルダー内に保存される. logfile: bool Trueの場合, logファイルを保存する. 'log'フォルダー内に保存される. calc_func: object calculatorを返す関数 """ self.optimizer = optimizer self.trajectory = trajectory self.logfile = logfile self.maxstep_dict = None self.attach_list = [] self.atomslist = atomslist for atoms in self.atomslist: atoms.set_constraint(constraints) atoms.calc = calc_func() # フォルダ名,ファイル名 self.errorfile = f"{errorfile}_{id(self)}" self.log_foldername = log_foldername self.traj_foldername = traj_foldername self.save_foldername = save_foldername # フォルダの作成 self.make_folder(self.save_foldername) if self.trajectory: self.make_folder(self.traj_foldername) if self.logfile: self.make_folder(self.log_foldername) def make_folder(self,foldername): p = Path(foldername) if not p.exists(): # フォルダが存在しなければ作成 p.mkdir() def set_maxstep(self,maxstep): if type(maxstep) == list: self.maxstep = maxstep else: self.maxstep = [maxstep] def set_steps(self,steps): if type(steps) == list: self.steps = steps else: self.steps = [steps]
[ドキュメント] def set_automaxstep(self,maxstep_dict): """auto_maxstepsを用いる場合のパラメータを変更する Examples: >>> obj.set_automaxstep({10:0.1, 5:0.2, 2:0.3, 0:0.35}) 必ず0のキーを含める必要があるので注意する. """ self.maxstep_dict = maxstep_dict
def check_param(self): if len(self.maxstep) != len(self.steps): raise Exception("maxstepとstepsの要素数が一致しません") if self.restart is not None and self.indexes is not None: raise Exception("restartとindexesは同時に指定できません") def errorlog(self,massage): with open(self.errorfile,"a") as f: f.write(massage) f.write("\n") def attach(self,*args,**kwargs): self.attach_list.append((args,kwargs)) def irun(self,atoms,name:int,optimizer,maxstep_list,steps_list,fmax,**kwargs): logfile = f"{self.log_foldername}/{name}.log" if self.logfile else None trajectory = f"{self.traj_foldername}/{name}.traj" if self.trajectory else None savefile = f"{self.save_foldername}/{name}.traj" try: for maxstep,steps in zip(maxstep_list,steps_list): ms = 0.2 if maxstep is None else maxstep if optimizer == FIRELBFGS: opt = FIRELBFGS(atoms,logfile=logfile,maxstep_fire=ms,maxstep_lbfgs=ms,**kwargs) else: opt = optimizer(atoms,maxstep=ms,logfile=logfile,trajectory=trajectory,**kwargs) if maxstep is None: opt.attach(lambda:automate_maxstep(opt,self.maxstep_dict)) for args,kwargs in self.attach_list: opt.attach(*args,**kwargs) opt.run(fmax=fmax,steps=steps) if opt.converged: write(savefile,atoms) return True else: self.errorlog(f"{name}の計算:未収束") except Exception as e: self.errorlog(f"{name}の計算:\n{e}") return False
[ドキュメント] def run(self, maxstep_list=[0.05,0.2], steps_list=[200,10000], fmax=0.001, indexes = None, restart = None, **kwargs): """ Parameters: maxstep_list: float or list of float | maxstep. | optimizeをFIRELBFGSにした場合,maxstep_fire,maxstep_lbfgsどちらもmaxstepで指定した値になる. steps_list: int or list of int steps fmax: float 収束条件 indexes: list of int | index番号で指定した構造のみを計算する | indexesとrestartは同時に指定できない. restart: int | 指定した番号から計算を開始する. | indexesとrestartは同時に指定できない. kwargs: その他,optimizer(LBFGSなど)ののインスタンス引数を指定できる. """ self.set_maxstep(maxstep_list) self.set_steps(steps_list) self.indexes = indexes self.restart = restart self.check_param() if self.indexes is None: self.indexes = [i for i in range(len(self.atomslist))] if self.restart is not None: self.indexes = [i for i in range(self.restart,len(self.atomslist))] for i in tqdm(self.indexes): atoms = self.atomslist[i] self.irun(atoms,i,self.optimizer,maxstep_list,steps_list,fmax,**kwargs)