nexus: gaussian basis set manipulation, interface smoothing

git-svn-id: https://subversion.assembla.com/svn/qmcdev/trunk@6556 e5b18d87-469d-4833-9cc0-8cdfa06e9491
This commit is contained in:
Jaron Krogel 2015-08-17 14:40:03 +00:00
parent d0d704f013
commit a797abadea
8 changed files with 358 additions and 60 deletions

View File

@ -6,6 +6,7 @@
from generic import obj
from periodic_table import pt as ptable
from pseudopotential import GaussianPP
from developer import error
molecule_symm_text = '''
@ -140,13 +141,29 @@ def write_basis(pseudos,occupations,formats):
#end def write_basis
def write_hamiltonian(theory):
def write_hamiltonian(theory = None,
system = None,
spinlock_cycles = 100,
levshift = None,
levshift_lock = 1,
maxcycle = None,
):
s = ''
theory = theory.lower()
if theory=='uhf':
theory = theory.lower().strip()
known_theories = set(['rhf','uhf'])
if theory in known_theories:
s+=theory.upper()+'\n'
else:
error('unknown theory: '+theory)
error('unknown theory: '+theory,'write_hamiltonian')
#end if
if system!=None:
s+='SPINLOCK\n{0} {1}\n'.format(system.net_spin,spinlock_cycles)
#end if
if levshift!=None:
s+='LEVSHIFT\n{0} {1}\n'.format(levshift,levshift_lock)
#end if
if maxcycle!=None:
s+='MAXCYCLE\n{0}\n'.format(maxcycle)
#end if
s += 'END\n'
return s

View File

@ -55,7 +55,7 @@ def warn(message,location,header=None,post_header=' Warning:'):
else:
header = location+' warning:'
#end if
log(header)
log('\n '+header)
log(pad+message.replace('\n','\n'+pad))
#end def warn
@ -67,7 +67,7 @@ def error(message,location=None,exit=True,trace=True):
else:
header = location+' error:'
#end if
log(header)
log('\n '+header)
log(pad+message.replace('\n','\n'+pad))
if exit:
log(' exiting.\n')

View File

@ -167,8 +167,8 @@ class obj(AllAbilities):
if header==None:
header = cls.__name__
#end if
cls.logfile.write(header+post_header+'\n')
cls.logfile.write(('\n'+message).replace('\n','\n'+pad)+'\n')
cls.logfile.write('\n'+header+post_header+'\n')
cls.logfile.write((pad+message).replace('\n','\n'+pad)+'\n')
if exit:
cls.logfile.write(' exiting.\n\n')
if trace:

View File

@ -1864,6 +1864,37 @@ class PeriodicTable(DevBase):
pt = PeriodicTable()
periodic_table = pt
ptable = pt
def is_element(name,symbol=False):
s = name
iselem = False
if isinstance(name,str):
iselem = name in periodic_table.elements
if not iselem:
nlen = len(name)
if name.find('_')!=-1:
s,n = name.split('_',1)
#iselem = n.isdigit() and s in periodic_table.elements
iselem = s in periodic_table.elements
elif nlen>1 and name[1:].isdigit():
s = name[0:1]
iselem = s in periodic_table.elements
elif nlen>2 and name[2:].isdigit():
s = name[0:2]
iselem = s in periodic_table.elements
#end if
#end if
#end if
if symbol:
return iselem,s
else:
return iselem
#end if
#end def is_element

View File

@ -38,6 +38,7 @@ from numpy.linalg import inv
from generic import obj
from developer import DevBase
from unit_converter import convert
from periodic_table import is_element
from structure import Structure
from debug import *
@ -61,29 +62,7 @@ class Matter(DevBase):
#end def new_particles
def is_element(self,name,symbol=False):
s = None
iselem = name in self.elements
if not iselem and isinstance(name,str):
nlen = len(name)
if name.find('_')!=-1:
s,n = name.split('_',1)
#iselem = n.isdigit() and s in self.elements
iselem = s in self.elements
elif nlen>1 and name[1:].isdigit():
s = name[0:1]
iselem = s in self.elements
elif nlen>2 and name[2:].isdigit():
s = name[0:2]
iselem = s in self.elements
#end if
else:
s = name
#end if
if symbol:
return iselem,s
else:
return iselem
#end if
return is_element(name,symbol=symbol)
#end def is_element
#end class Matter
@ -236,16 +215,15 @@ plist = [
Particle('up_electron' ,1.0,-1, 1),
Particle('down_electron',1.0,-1,-1),
]
from periodic_table import PeriodicTable
pt = PeriodicTable()
for name,a in pt.elements.iteritems():
from periodic_table import ptable
for name,a in ptable.elements.iteritems():
spin = 0 # don't have this data
protons = a.atomic_number
neutrons = int(round(a.atomic_weight['amu']-a.atomic_number))
p = Ion(a.symbol,a.atomic_weight['me'],a.atomic_number,spin,protons,neutrons)
plist.append(p)
#end for
for name,iso in pt.isotopes.iteritems():
for name,iso in ptable.isotopes.iteritems():
for mass_number,a in iso.iteritems():
spin = 0 # don't have this data
protons = a.atomic_number
@ -255,11 +233,10 @@ for name,iso in pt.isotopes.iteritems():
#end for
#end for
Matter.set_elements(pt.elements.keys())
Matter.set_elements(ptable.elements.keys())
Matter.set_particle_collection(Particles(plist))
del plist
del pt
@ -438,6 +415,17 @@ class PhysicalSystem(Matter):
def rename(self,folded=True,**name_pairs):
self.particles.rename(**name_pairs)
self.structure.rename(folded=False,**name_pairs)
if self.pseudized:
for old,new in name_pairs.iteritems():
if old in self.valency:
if new not in self.valency:
self.valency[new] = self.valency[old]
#end if
del self.valency[old]
#end if
#end for
self.valency_in = self.valency
#end if
if self.folded_system!=None and folded:
self.folded_system.rename(folded=folded,**name_pairs)
#end if
@ -644,7 +632,8 @@ def generate_physical_system(**kwargs):
valency = dict()
remove = []
for var in kwargs:
if var in Matter.elements:
#if var in Matter.elements:
if is_element(var):
valency[var] = kwargs[var]
remove.append(var)
#end if

View File

@ -42,10 +42,10 @@
import os
from subprocess import Popen
from execute import execute
from numpy import linspace,array,zeros,append,mgrid,empty,exp,minimum,maximum,sqrt
from numpy import linspace,array,zeros,append,mgrid,empty,exp,minimum,maximum,sqrt,arange
from xmlreader import readxml
from superstring import string2val,split_delims
from periodic_table import pt
from periodic_table import pt,is_element
from unit_converter import convert
from generic import obj
from developer import DevBase,unavailable,error
@ -71,13 +71,21 @@ except:
# basic interface for nexus, only gamess really needs this for now
class PseudoFile(DevBase):
def __init__(self,filepath=None):
self.element = None
self.filename = None
self.location = None
self.element = None
self.element_label = None
self.filename = None
self.location = None
if filepath!=None:
self.filename = os.path.basename(filepath)
self.location = os.path.abspath(filepath)
self.element = self.filename[0:2].strip('._-')
elem_label = self.filename.split('.')[0]
is_elem,symbol = is_element(elem_label,symbol=True)
if not is_elem:
self.error('cannot determine element for pseudopotential file: {0}\npseudopotential file names must be prefixed by an atomic symbol or label\n(e.g. Si, Si1, etc)'.format(filename))
#end if
self.element = symbol
self.element_label = elem_label
#self.element = self.filename[0:2].strip('._-')
self.read(filepath)
#end if
#end def __init__
@ -210,7 +218,7 @@ class Pseudopotentials(DevBase):
for ppfile in ppfiles:
if ppfile in self:
pp = self[ppfile]
pps[pp.element] = pp
pps[pp.element_label] = pp
#end if
#end for
return pps
@ -1129,18 +1137,184 @@ class GaussianBasisSet(DevBase):
#end def contracted_basis_size
def basis_size(self):
def uncontracted_basis_size(self):
if self.uncontracted():
return self.contracted_basis_size()
#end if
uc = self.copy()
uc.uncontract()
bs = self.contracted_basis_size()
ps = uc.contracted_basis_size()
return '({0})/[{1}]'.format(ps,bs)
return uc.contracted_basis_size()
#end def uncontracted_basis_size
def basis_size(self):
us = self.uncontracted_basis_size()
cs = self.contracted_basis_size()
return '({0})/[{1}]'.format(us,cs)
#end def basis_size
def incorporate(self,other):
lbasis = self.lbasis()
lbasis_other = other.lbasis()
def prim_expons(self):
if self.contracted():
self.error('cannot find primitive gaussian expons because basis is contracted')
#end if
lbasis = self.lbasis()
gexpon = obj()
for l,lbas in lbasis.iteritems():
e = []
for n in range(len(lbas)):
e.append(lbas[n].terms[0].expon)
#end for
gexpon[l] = array(e,dtype=float)
#end for
return gexpon
#end def prim_expons
def prim_widths(self):
if self.contracted():
self.error('cannot find primitive gaussian widths because basis is contracted')
#end if
lbasis = self.lbasis()
gwidth = obj()
for l,lbas in lbasis.iteritems():
w = []
for n in range(len(lbas)):
w.append(1./sqrt(2.*lbas[n].terms[0].expon))
#end for
gwidth[l] = array(w,dtype=float)
#end for
return gwidth
#end def prim_widths
def remove_prims(self,comp=None,keep=None,**lselectors):
lbasis = self.lbasis()
if comp!=None:
gwidths = self.prim_widths()
#end if
for l,lsel in lselectors.iteritems():
if l not in lbasis:
self.error('cannot remove basis functions from channel {0}, channel not present'.format(l))
#end if
lbas = lbasis[l]
if isinstance(lsel,float):
rcut = lsel
less = False
if comp=='<':
less = True
elif comp=='>':
less = False
elif comp is None:
self.error('comp argument must be provided (< or >)')
else:
self.error('comp must be < or >, you provided: {0}'.format(comp))
#end if
gw = gwidths[l]
iw = arange(len(gw))
nkeep = 0
if keep!=None and l in keep:
nkeep = keep[l]
#end if
if less:
rem = iw[gw<rcut]
for i in xrange(len(rem)-nkeep):
del lbas[rem[i]]
#end for
else:
rem = iw[gw>rcut]
for i in xrange(nkeep,len(rem)):
del lbas[rem[i]]
#end for
#end if
elif isinstance(lsel,int):
if comp=='<':
if lsel>len(lbas):
self.error('cannot remove {0} basis functions from channel {1} as it only has {2}'.format(lsel,l,len(lbas)))
#end if
for i in xrange(lsel):
del lbas[i]
#end for
elif comp=='>':
if lsel>len(lbas):
self.error('cannot remove {0} basis functions from channel {1} as it only has {2}'.format(lsel,l,len(lbas)))
#end if
for i in xrange(len(lbas)-lsel,len(lbas)):
del lbas[i]
#end for
else:
if lsel>=len(lbas):
self.error('cannot remove basis function {0} from channel {1} as it only has {2}'.format(lsel,l,len(lbas)))
#end if
del lbas[lsel]
#end if
else:
for ind in lsel:
del lbas[ind]
#end for
#end if
#end for
self.basis.clear()
for l in self.lset_full:
if l in lbasis:
lbas = lbasis[l]
for k in sorted(lbas.keys()):
self.basis.append(lbas[k])
#end for
#end if
#end for
#end def remove_prims
def remove_small_prims(self,**keep):
lsel = obj()
for l,lbas in self.lbasis().iteritems():
if l in keep:
lsel[l] = len(lbas)-keep[l]
#end if
#end for
self.remove_prims(comp='<',**lsel)
#end def remove_small_prims
def remove_large_prims(self,**keep):
lsel = obj()
for l,lbas in self.lbasis().iteritems():
if l in keep:
lsel[l] = len(lbas)-keep[l]
#end if
#end for
self.remove_prims(comp='>',**lsel)
#end def remove_large_prims
def remove_small_prims_rel(self,other,**keep):
gwidths = other.prim_widths()
lsel = obj()
for l,gw in gwidths.iteritems():
lsel[l] = gw.min()
#end for
self.remove_prims(comp='<',keep=keep,**lsel)
#end def remove_small_prims_rel
def remove_large_prims_rel(self,other,**keep):
gwidths = other.prim_widths()
lsel = obj()
for l,gw in gwidths.iteritems():
lsel[l] = gw.max()
#end for
self.remove_prims(comp='>',keep=keep,**lsel)
#end def remove_large_prims_rel
def remove_channels(self,llist):
lbasis = self.lbasis()
for l in llist:
if l in lbasis:
del lbasis[l]
#end if
#end for
self.basis.clear()
for l in self.lset_full:
if l in lbasis:
@ -1150,14 +1324,63 @@ class GaussianBasisSet(DevBase):
self.basis.append(bf)
#end for
#end if
if l in lbasis_other:
lbas = lbasis_other[l]
for n in range(len(lbas)):
bf = lbas[n]
#end for
#end def remove_channels
def incorporate(self,other,tol=1e-3):
uncontracted = self.uncontracted() and other.uncontracted()
lbasis = self.lbasis()
lbasis_other = other.lbasis()
if uncontracted:
gwidths = self.prim_widths()
gwidths_other = other.prim_widths()
#end if
self.basis.clear()
if not uncontracted: # simple, direct merge of basis sets
for l in self.lset_full:
if l in lbasis:
lbas = lbasis[l]
for n in range(len(lbas)):
bf = lbas[n]
self.basis.append(bf)
#end for
#end if
if l in lbasis_other:
lbas = lbasis_other[l]
for n in range(len(lbas)):
bf = lbas[n]
self.basis.append(bf)
#end for
#end if
#end for
else: # merge uncontracted basis sets preserving order
for l in self.lset_full:
primitives = []
widths = []
orig_widths = array([])
if l in lbasis:
primitives.extend(lbasis[l].list())
widths.extend(gwidths[l])
orig_widths = gwidths[l]
#end if
if l in lbasis_other:
prims = lbasis_other[l].list()
owidths = gwidths_other[l]
for n in range(len(prims)):
w = owidths[n]
if len(orig_widths)==0 or abs(orig_widths-w).min()>tol:
primitives.append(prims[n])
widths.append(w)
#end if
#end if
#end if
primitives = array(primitives,dtype=object)[array(widths).argsort()]
for bf in primitives:
self.basis.append(bf)
#end for
#end if
#end for
#end for
#end if
#end def incorporate
@ -1452,10 +1675,15 @@ class GaussianPP(SemilocalPP):
tline += ' {0}'.format(len(cloc))
channels.append(cloc)
#end if
ccount = 1
for c in channel_order[1:]:
channel = self.channels[c]
tline += ' {0}'.format(len(channel))
channels.append(channel)
ccount += 1
#end for
for i in range(6-ccount): # crystal14 goes up to g (hence the 6)
tline += ' 0'
#end for
text += tline+'\n'
for channel in channels:
@ -1481,6 +1709,22 @@ class GaussianPP(SemilocalPP):
return bs
#end def get_basis
def set_basis(self,bs):
self.basis = bs.basis
#end def set_basis
def uncontract(self):
if self.basis!=None:
bs = GaussianBasisSet()
bs.basis = self.basis.copy()
bs.uncontract()
self.basis = bs.basis
#end if
#end def uncontract
def write_basis(self,filepath=None,format=None):
basis = self.get_basis()
text = ''

View File

@ -69,6 +69,7 @@ import os
import shutil
import string
from generic import obj
from periodic_table import is_element
from physical_system import PhysicalSystem
from machines import Job
from project_base import Pobj
@ -232,13 +233,14 @@ class Simulation(Pobj):
if not isinstance(system,PhysicalSystem):
Simulation.class_error('system object must be of type PhysicalSystem')
#end if
species_labels,species = system.structure.species(symbol=True)
pseudopotentials = Simulation.pseudopotentials
for ppfile in pseudos:
if not ppfile in pseudopotentials:
Simulation.class_error('pseudopotential file {0} cannot be found'.format(ppfile))
#end if
pp = pseudopotentials[ppfile]
if not pp.element in system.structure.elem:
if not pp.element_label in species_labels and not pp.element in species:
Simulation.class_error('the element {0} for pseudopotential file {1} is not in the physical system provided'.format(pp.element,ppfile))
#end if
#end for

View File

@ -33,7 +33,7 @@ from numpy.linalg import inv,det,norm
from types import NoneType
from unit_converter import convert
from extended_numpy import nearest_neighbors,convex_hull,voronoi_neighbors
from periodic_table import pt
from periodic_table import pt,is_element
from generic import obj
from developer import DevBase,unavailable,error,warn
from debug import ci,ls,gs
@ -1173,6 +1173,21 @@ class Structure(Sobj):
#end def point_defect
def species(self,symbol=False):
if not symbol:
return set(self.elem)
else:
species_labels = set(self.elem)
species = set()
for e in species_labels:
is_elem,symbol = is_element(e,symbol=True)
species.add(symbol)
#end for
return species_labels,species
#end if
#end def species
def order_by_species(self,folded=False):
species = []
species_counts = []