Source code for nexus.gamess

##################################################################
##  (c) Copyright 2015-  by Jaron T. Krogel                     ##
##################################################################


#====================================================================#
#  gamess.py                                                         #
#    Nexus interface to the GAMESS simulation code.                  #
#                                                                    #
#  Content summary:                                                  #
#    GamessInput                                                     #
#      Input class for the GAMESS code.                              #
#      Capable of reading/writing arbitrary GAMESS input files.      #
#                                                                    #
#    generate_gamess_input                                           #
#      User function to create arbitrary GAMESS input.               #
#                                                                    #
#    KeywordGroup                                                    #
#      Represents an arbitrary keyword group in the input file.       #
#                                                                    #
#    KeywordSpecGroup                                                #
#      Base class for specialized keyword groups.                    #
#      Derived classes enforce the keyword specification.            #
#      See ContrlGroup, SystemGroup, GuessGroup, ScfGroup,           #
#        McscfGroup, DftGroup, GugdiaGroup, DrtGroup, CidrtGroup,    #
#        and DetGroup                                                #
#                                                                    #
#    FormattedGroup                                                  #
#      Represents strict machine-formatted input groups.             #
#                                                                    #
#====================================================================#


import os
import numpy as np
from .developer import obj
from .simulation import Simulation
from .gamess_input import GamessInput, generate_gamess_input, FormattedGroup, GuessGroup, GIarray
from .gamess_analyzer import GamessAnalyzer


[docs] class Gamess(Simulation): input_type = GamessInput analyzer_type = GamessAnalyzer generic_identifier = 'gamess' application = 'gamess.x' infile_extension = '.inp' application_properties = set(['serial','mpi']) application_results = set(['orbitals']) ericfmt = None mcppath = None
[docs] @staticmethod def settings(ericfmt=None,mcppath=None): Gamess.ericfmt = ericfmt Gamess.mcppath = mcppath
#end def settings
[docs] @staticmethod def restore_default_settings(): Gamess.ericfmt = None Gamess.mcppath = None
#end def restore_default_settings def __init__(self,**kwargs): self.mo_reorder = None mo_reorder = kwargs.pop('mo_reorder',None) if mo_reorder is not None: self.mo_reorder = [s.lower() for s in mo_reorder] #end if Simulation.__init__(self,**kwargs) #end def __init__
[docs] def init_job_extra(self): # gamess seems to need lots of environment variables to run properly # nearly all of these are names of output/work files # setup the environment to run gamess if not isinstance(self.ericfmt,str): self.error('you must set ericfmt with settings() or Gamess.settings()') #end if env = obj() for file,unit in GamessInput.file_units.items(): env[file] = '{0}.F{1}'.format(self.identifier,str(unit).zfill(2)) #end for env.INPUT = self.infile env.ERICFMT = self.ericfmt env.MCPPATH = self.mcppath self.job.set_environment(**env)
#end def init_job_extra
[docs] def check_result(self,result_name,sim): input = self.input if result_name=='orbitals': calculating_result = 'contrl' in input and 'scftyp' in input.contrl and input.contrl.scftyp.lower() in ('rhf','rohf','uhf','mcscf','none') else: calculating_result = False #end if return calculating_result
#end def check_result
[docs] def get_result(self,result_name,sim): result = obj() input = self.input analyzer = self.load_analyzer_image() if result_name=='orbitals': result.location = os.path.join(self.locdir,self.outfile) result.outfile = result.location result.vec = None # vec from punch result.norbitals = 0 # orbital count in punch result.mos = 0 # orbital count (MO's) from log file result.scftyp = input.contrl.scftyp.lower() if 'counts' in analyzer and 'mos' in analyzer.counts: result.mos = analyzer.counts.mos #end if if 'punch' in analyzer and 'vec' in analyzer.punch: result.norbitals = analyzer.punch.norbitals result.vec = analyzer.punch.vec #end if if 'orbitals' in analyzer: result.orbitals = analyzer.orbitals #end if else: self.error('ability to get result '+result_name+' has not been implemented') #end if return result
#end def get_result
[docs] def incorporate_result(self,result_name,result,sim): input = self.input if result_name=='orbitals': if result.vec is None or result.norbitals<1: self.error('could not obtain orbitals from previous GAMESS run') #end if if 'guess' not in input: input.guess = GuessGroup() #end if if 'norb' in input.guess: # user provided norb norb = input.guess.norb else: norb = result.norbitals #end if if 'norder' not in input.guess: input.guess.clear() #end if if self.mo_reorder is not None: if 'orbitals' not in result: self.error('Orbital information from prior calculation "{}" located at {} cannot be found. You requested orbital reordering via the "mo_reorder" input keyword. Due to missing information, this operation cannot be performed. The current simulation "{}" is located at {}.'.format(sim.identifier,sim.locdir,self.identifier,self.locdir)) self.block() #end if guess_inputs = obj() ecounts = self.system.particles.electron_counts() orbs = result.orbitals order_map = obj(up='iorder',down='jorder') nelec_map = obj(up=ecounts[0],down=ecounts[1]) for spin,vname in order_map.items(): nelec = nelec_map[spin] if len(self.mo_reorder)<nelec: self.error('Too few symmetries provided in "mo_reorder" for spin "{0}".\nNumber of electrons with spin "{0}": {1}\nNumber of entries in "mo_reorder": {2}\nContents of "mo_reorder": {3}\nSimulation identifier: {4}\nSimulation location: {5}'.format(spin,nelec,len(self.mo_reorder),self.mo_reorder,self.identifier,self.locdir)) #end if symmetries = [s.lower() for s in orbs[spin].symmetry] missing = set(self.mo_reorder)-set(symmetries) if len(missing)>0: self.error('Symmetries provided by "mo_reorder" keyword are not found in the outputted MOs.\nSet of symmetries provided in "mo_reorder": {}\nSet of symmetries present in MOs: {}\nContents of "mo_reorder": {}\nSimulation identifier: {}\nSimulation location: {}'.format(sorted(set(self.mo_reorder)),sorted(set(symmetries)),self.mo_reorder,self.identifier,self.locdir)) #end if occ = np.zeros(len(symmetries),dtype=bool) for symm in self.mo_reorder[:nelec]: for i,(s,o) in enumerate(zip(symmetries,occ)): if not o and symm==s: occ[i] = True break #end if #end for #end for if occ.sum()<nelec: self.error('Too few orbitals occupied based on "mo_reorder" request.\nNumber of orbitals occupied: {}\nNumber of spin "{}" electrons: {}\nContents of "mo_reorder": {}\nSimulation identifier: {}\nSimulation location: {}'.format(occ.sum(),spin,nelec,self.mo_reorder,self.identifier,self.locdir)) #end if indices = np.arange(len(symmetries),dtype=int)[occ]+1 start = 0 found = False for i in range(len(indices)): start = i if indices[i]!=i+1: found = True break #end if #end if if found: reduced_indices = indices[start:] start+=1 else: reduced_indices = [] #end if if len(reduced_indices)>0: guess_inputs.norder = 1 guess_inputs[vname] = GIarray({start:reduced_indices}) #end if #end for input.guess.set(**guess_inputs) #end if input.guess.set( guess = 'moread', norb = norb, prtmo = True, ) input.vec = FormattedGroup(result.vec) else: self.error('ability to incorporate result '+result_name+' has not been implemented')
#end if #end def incorporate_result
[docs] def app_command(self): if self.app_name == 'rungms': return 'rungms '+self.infile else: return self.app_name+' '+self.infile.replace('.inp','')
#end if #end def app_command
[docs] def check_sim_status(self): with open(os.path.join(self.locdir,self.outfile), "r") as out: output = out.read() #errors = open(os.path.join(self.locdir,self.errfile),'r').read() self.failed = 'EXECUTION OF GAMESS TERMINATED -ABNORMALLY-' in output self.finished = self.failed or 'EXECUTION OF GAMESS TERMINATED NORMALLY' in output
#end def check_sim_status
[docs] def get_output_files(self): output_files = [] return output_files
#end def get_output_files
[docs] def output_filename(self,name): name = name.upper() if name not in GamessInput.file_units: self.error('gamess does not produce a file matching the requested description: {0}'.format(name)) #end if unit = GamessInput.file_units[name] filename = '{0}.F{1}'.format(self.identifier,str(unit).zfill(2)) return filename
#end def output_filename
[docs] def output_filepath(self,name): filename = self.output_filename(name) filepath = os.path.join(self.locdir,filename) filepath = os.path.abspath(filepath) return filepath
#end def #end class Gamess
[docs] def generate_gamess(**kwargs): sim_args,inp_args = Gamess.separate_inputs(kwargs,copy_pseudos=False,sim_kw=['mo_reorder']) if 'input' not in sim_args: sim_args.input = generate_gamess_input(**inp_args) #end if gamess = Gamess(**sim_args) return gamess
#end def generate_gamess