def nearest_neighbors(n,points,qpoints=None,return_distances=False,slow=False): extra = 0 if qpoints is None: qpoints=points if len(points)>1: extra=1 elif return_distances: return array([]),array([]) else: return array([]) #end if #end if if n>len(qpoints)-extra: error('requested more than the total number of neighbors\nmaximum is: {0}\nyou requested: {1}\nexiting.'.format(len(qpoints)-extra,n),'nearest_neighbors') #end if slow = slow or scipy_unavailable if not slow: kt = KDTree(points) dist,ind = kt.query(qpoints,n+extra) else: dtable,order = distance_table(points,qpoints,ordering=2) dist = dtable[:,0:n+extra] ind = order[:,0:n+extra] #end if if extra==0 and n==1 and not slow: nn = atleast_2d(ind).T else: nn = ind[:,extra:] #end if if not return_distances: return nn else: return nn,dist
def check_jackknife_inputs(args,kwargs,position): argpos = False kwargpos = False if position!=None: if isinstance(position,int): argpos = True elif isinstance(position,str): kwargpos = True else: error('position must be an integer or keyword, received: {0}'.format(position),'jackknife') #end if elif args is None and kwargs is None: args = [None] argpos = True position = 0 elif kwargs is None and position is None: argpos = True position = 0 else: error('function argument position for input data must be provided','jackknife') #end if if args is None: args = [] #end if if kwargs is None: kwargs = dict() #end if return argpos,kwargpos,args,kwargs,position
def eos_fit(V,E,type='vinet',p0=None,cost='least_squares',optimizer='fmin',jackknife=False): if isinstance(V,(list,tuple)): V = array(V,dtype=float) #end if if isinstance(E,(list,tuple)): E = array(E,dtype=float) #end if if type not in eos_funcs: error('"{0}" is not a valid EOS type\nvalid options are: {1}'.format(sorted(eos_funcs.keys()))) #end if eos_func = eos_funcs[type] if p0 is None: pp = polyfit(V,E,2) V0 = -pp[1]/(2*pp[0]) B0 = -pp[1] Bp0 = 0.0 Einf = E[-1] p0 = Einf,V0,B0,Bp0 #end if # get an optimized fit of the means pf = curve_fit(V,E,eos_func,p0,cost) return pf
def write_geometry(title, bcond, system, symmetry=1, pseudo=True): t = '{0}\n{1}\n'.format(title, bcond.upper()) bcond = bcond.lower() if not bcond in symm_map: error('unknown boundary conditions: {0}'.format(bcond)) #end if smap = symm_map[bcond] if isinstance(symmetry, int): t += str(symmetry) + '\n' elif symmetry in symm_map: t += str(smap[symmetry]) + '\n' else: error('symmetry {0} is unknown'.format(symmetry), 'write_geometry') #end if s = system.structure.copy() s.change_units('A') t += '{0}\n'.format(len(s.elem)) if pseudo: an_base = 200 # for 'conventional' atomic numbers else: an_base = 0 #end if for n in xrange(len(s.elem)): e = s.elem[n] p = s.pos[n] conv_atomic_number = ptable[e].atomic_number + an_base t += '{0} {1: 12.8f} {2: 12.8f} {3: 12.8f}\n'.format( conv_atomic_number, p[0], p[1], p[2]) #end for t += 'END\n' return t
def write_hamiltonian(theory = None, system = None, spinlock_cycles = 100, levshift = None, levshift_lock = 1, maxcycle = None, ): s = '' theory = theory.lower().strip() dft_functionals = set(['pbe0']) known_theories = set(['rhf','uhf']) | dft_functionals if theory in known_theories: if theory not in dft_functionals: s+=theory.upper()+'\n' else: s+='DFT\n'+theory.upper()+'\nSPIN\nEND\n' #end if else: 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
def write_geometry(title,bcond,system,symmetry=1,pseudo=True): t = '{0}\n{1}\n'.format(title,bcond.upper()) bcond = bcond.lower() if not bcond in symm_map: error('unknown boundary conditions: {0}'.format(bcond)) #end if smap = symm_map[bcond] if isinstance(symmetry,int): t += str(symmetry)+'\n' elif symmetry in symm_map: t += str(smap[symmetry])+'\n' else: error('symmetry {0} is unknown'.format(symmetry),'write_geometry') #end if s = system.structure.copy() s.change_units('A') t += '{0}\n'.format(len(s.elem)) if pseudo: an_base = 200 # for 'conventional' atomic numbers else: an_base = 0 #end if for n in xrange(len(s.elem)): e = s.elem[n] p = s.pos[n] conv_atomic_number = ptable[e].atomic_number+an_base t += '{0} {1: 12.8f} {2: 12.8f} {3: 12.8f}\n'.format(conv_atomic_number,p[0],p[1],p[2]) #end for t+='END\n' return t
def write_hamiltonian( theory=None, system=None, spinlock_cycles=100, levshift=None, levshift_lock=1, maxcycle=None, ): s = '' theory = theory.lower().strip() dft_functionals = set(['pbe0']) known_theories = set(['rhf', 'uhf']) | dft_functionals if theory in known_theories: if theory not in dft_functionals: s += theory.upper() + '\n' else: s += 'DFT\n' + theory.upper() + '\nSPIN\nEND\n' #end if else: 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
def set_verbosity(level): if level not in self.verbosity_levels: vlinv = self.verbosity_levels.inverse() error('Cannot set verbosity level to "{}".\nValid options are: {}'. format(level, [vlinv[i] for i in sorted(vlinv.keys())])) #end if self.verbosity = self.verbosity_levels[level]
def gen_crystal_molecule_sim( identifier='crystal', path=None, job=None, title='atom', system=None, pseudos=None, occupations=None, formats=None, theory=None, levshift=None, maxcycle=None, ): required = obj(path=path, system=system, pseudos=pseudos, occupations=occupations, formats=formats, theory=theory, job=job) for k, v in required.iteritems(): if v is None: error(k + ' is a required input', 'gen_crystal_molecule_sim') #end if #end for pseudos_in = pseudos pseudos = [] for pp in pseudos_in: pseudos.append(os.path.join(nexus_noncore.pseudo_dir, pp)) #end for crys_input = input_template_dev() crys_input.read_text( write_geometry(title=title, bcond='molecule', system=system) + write_basis( pseudos=pseudos, occupations=occupations, formats=formats, ) + write_hamiltonian( theory=theory, system=system, levshift=levshift, maxcycle=maxcycle) ) #crys = generate_simulation( # identifier = identifier, # path = path, # job = job(cores=1,serial=True,app_command='crystal<{0}.d12>&{0}.out&'.format(identifier)), # input = crys_input, # infile = '{0}.d12'.format(identifier), # outfile = '{0}.out'.format(identifier), # ) crys = Crystal_1( identifier=identifier, path=path, job=job, input=crys_input, ) return crys
def eos_param(p,param,type='vinet'): if type not in eos_param_funcs: error('"{0}" is not a valid EOS type\nvalid options are: {1}'.format(sorted(eos_param_funcs.keys()))) #end if eos_pfuncs = eos_param_funcs[type] if param not in eos_pfuncs: error('"{0}" is not an available parameter for a {1} fit\navailable parameters are: {2}'.format(param,type,sorted(eos_pfuncs.keys()))) #end if return eos_pfuncs[param](p)
def extract_input_specification(*ezfio_paths): if len(ezfio_paths) == 1 and isinstance(ezfio_paths[0], (list, tuple)): ezfio_paths = ezfio_paths[0] #end if log('\nextracting Quantum Package input specification from ezfio directories' ) typedict = {bool: 'bool', int: 'int', float: 'float', str: 'str'} new_input_spec = obj() for vpath, vtype in input_specification.items(): new_input_spec[vpath] = typedict[vtype] #end for for epath in ezfio_paths: epath = epath.rstrip('/') if not epath.endswith('.ezfio'): error( 'cannot extract input spec from path\ninput path provided is not an ezfio directory\ninput path provided: {0}' .format(epath), 'Quantum Package') elif not os.path.exists(epath): error( 'cannot extract input spec from path\ninput path provided does not exist\ninput path provided: {0}' .format(epath), 'Quantum Package') #end if log(' extracting from: {0}'.format(epath)) for path, dirs, files in os.walk(epath): for file in files: if 'save' not in path and 'work' not in path: if not file.startswith('.') and not file.endswith('.gz'): filepath = os.path.join(path, file) vtype = read_qp_value_type(filepath) vpath = filepath.replace(epath, '').strip('/') if vpath not in new_input_spec: new_input_spec[vpath] = vtype #end if #end if #end if #end for #end for #end for log(' extraction complete') old_vpaths = set(input_specification.keys()) new_vpaths = set(new_input_spec.keys()) if new_vpaths == old_vpaths: log('\ninput specification in quantum_package_input.py needs no changes\n' ) else: log('\nplease replace input_specification in quantum_package_input.py with the following:\n' ) log('input_specification = obj({') s = '' for vpath in sorted(new_input_spec.keys()): vtype = new_input_spec[vpath] s += " '{0}' : {1},\n".format(vpath, vtype) #end for s += ' })\n' log(s)
def read_eshdf_eig_data(filename, Ef_list): import numpy as np from numpy import array, pi from numpy.linalg import inv from unit_converter import convert from hdfreader import read_hdf from developer import error def h5int(i): return array(i, dtype=int)[0] #end def h5int h = read_hdf(filename, view=True) axes = array(h.supercell.primitive_vectors) kaxes = 2 * pi * inv(axes).T nk = h5int(h.electrons.number_of_kpoints) ns = h5int(h.electrons.number_of_spins) if len(Ef_list) != ns: msg = 'Ef "%s" must have same length as nspin=%d' % (str(Ef_list), ns) error(msg) data = obj() for k in range(nk): kp = h.electrons['kpoint_' + str(k)] for s, Ef in zip(range(ns), Ef_list): E_fermi = Ef + 1e-8 eig_s = [] path = 'electrons/kpoint_{0}/spin_{1}'.format(k, s) spin = h.get_path(path) eig = convert(array(spin.eigenvalues), 'Ha', 'eV') nst = h5int(spin.number_of_states) for st in range(nst): e = eig[st] if e < E_fermi: eig_s.append(e) #end if #end for data[k, s] = obj( kpoint=array(kp.reduced_k), eig=array(eig_s), ) #end for #end for res = obj( orbfile=filename, axes=axes, kaxes=kaxes, nkpoints=nk, nspins=ns, data=data, ) return res
def convert(value, source_unit, target_unit): ui = UnitConverter.unit_dict[source_unit] uo = UnitConverter.unit_dict[target_unit] if (ui.type != uo.type): error( 'in UnitConverter.convert()\ntype conversion attempted between ' + ui.type + ' and ' + uo.type) else: value_out = (value - ui.shift) * ui.value / uo.value + uo.shift #end if return (value_out, target_unit)
def curve_fit(x,y,f,p0,cost='least_squares',optimizer='fmin'): if isinstance(cost,str): if cost not in cost_functions: error('"{0}" is an invalid cost function\nvalid options are: {1}'.format(cost,sorted(cost_functions.keys()))) #end if cost = cost_functions[cost] #end if if optimizer=='fmin': p = fmin(cost,p0,args=(x,y,f),maxiter=10000,maxfun=10000,disp=0) else: error('optimizers other than fmin are not supported yet','curve_fit') #end if return p
def render_array(a, n): indent = n * ' ' s = '' if len(a.shape) == 1: s += 'array(' + repr(list(a)) + ')' elif len(a.shape) == 2: s += 'array([\n' for a1 in a: s += indent + repr(list(a1)) + ',\n' #end for s = s[:-2] + '])' else: error('render_array only supports up to 2D arrays') #end if return s
def write_basis(pseudos,occupations,formats): s = '' if len(pseudos)!=len(occupations): error('must provide one set of occupations for each pseudopotential','write_basis') #end if if len(pseudos)!=len(formats): error('must specify file format for each pseudopotential','write_basis') #end if for n in range(len(pseudos)): pp = GaussianPP(pseudos[n],format=formats[n]) s += pp.write_text(format='crystal',occ=occupations[n]) #end for s += '99 0\n' s += 'END\n' return s
def write_basis(pseudos, occupations, formats): s = '' if len(pseudos) != len(occupations): error('must provide one set of occupations for each pseudopotential', 'write_basis') #end if if len(pseudos) != len(formats): error('must specify file format for each pseudopotential', 'write_basis') #end if for n in range(len(pseudos)): pp = GaussianPP(pseudos[n], format=formats[n]) s += pp.write_text(format='crystal', occ=occupations[n]) #end for s += '99 0\n' s += 'END\n' return s
def index_by_layer_1d(xpoints, tol, uniform=True, check=True, full_return=False): # Get layer means xlayer, xmin, xmax = layer_means_1d(xpoints, tol, full_return=True) # Get layer separations dxlayer = xlayer[1:] - xlayer[:-1] # Find appropriate layer separation for indexing if uniform: dxmin = dxlayer.min() dxmax = dxlayer.max() if np.abs(dxmax - dxmin) > 2 * tol: error( 'Could not determine layer separation.\nLayers are not evenly spaced.\nMin layer spacing: {}\nMax layer spacing: {}\nSpread : {}\nTolerance: {}' .format(dxmin, dxmax, dxmax - dxmin, 2 * tol), 'index_by_layer_1d') #end if dx = dxlayer.mean() else: dx = dxlayer.min() #end if # Find indices for each layer ipoints = np.array(np.around((xpoints - xmin) / dx), dtype=int) # Check the layer indices, if requested if check: if np.abs(ipoints * dx + xmin - xpoints).max() > 3 * tol: # Tolerance accounts for merge error('Layer indexing failed.', 'index_by_layer_1d') #end if #end if if not full_return: return ipoints else: return ipoints, xmin, xmax
def gen_properties(**kwargs): if 'systype' not in kwargs: error('systype is a required input','gen_properties') #end if systype = kwargs['systype'] del kwargs['systype'] if systype=='molecule_qmc': text = molecule_text elif systype=='periodic_qmc': text = periodic_text else: error('invalid systype encountered\nsystype provided: {0}\nvalid options are: molecule_qmc, periodic_qmc'.format(systype)) #end if sim_args,inp_args = Simulation.separate_inputs(kwargs) if len(inp_args)>0: error('invalid arguments encountered\ninvalid keywords: {0}'.format(sorted(inp_args.keys())),'gen_properties') #end if if not 'input' in sim_args: sim_args.input = input_template_dev(text=text.strip()) #end if prop = Properties_1(**sim_args) return prop
def gen_properties(**kwargs): if 'systype' not in kwargs: error('systype is a required input', 'gen_properties') #end if systype = kwargs['systype'] del kwargs['systype'] if systype == 'molecule_qmc': text = molecule_text elif systype == 'periodic_qmc': text = periodic_text else: error( 'invalid systype encountered\nsystype provided: {0}\nvalid options are: molecule_qmc, periodic_qmc' .format(systype)) #end if sim_args, inp_args = Simulation.separate_inputs(kwargs) if len(inp_args) > 0: error( 'invalid arguments encountered\ninvalid keywords: {0}'.format( sorted(inp_args.keys())), 'gen_properties') #end if if not 'input' in sim_args: sim_args.input = input_template_dev(text=text.strip()) #end if prop = Properties_1(**sim_args) return prop
def read_input(filepath, format=None): if not os.path.exists(filepath): error( 'cannot read input file\nfile does not exist: {0}'.format( filepath), 'read_input') #end if if format is None: if filepath.endswith('in.xml'): format = 'qmcpack' else: error( 'cannot identify file format\nplease provide format for file: {0}' .format(filepath)) #end if #end if format = format.lower() if format == 'qmcpack': input = QmcpackInput(filepath) elif format == 'pwscf': input = PwscfInput(filepath) elif format == 'gamess': input = GamessInput(filepath) else: error( 'cannot read input file\nfile format "{0}" is unsupported'.format( format)) #end if return input
def demo(name): """ Function used to run the demos. """ name = 'demo_' + name g = globals() if name not in g: error('requested "{}" does not exist'.format(name)) #end if demo_function = g[name] def write_header(s): print('') print(s) print(len(s) * '-') #end def write_header print(80 * '=') write_header('demo code:') print(inspect.getsource(demo_function)) write_header('demo execution:') demo_function()
def distance_table(p1, p2, ordering=0): n1 = len(p1) n2 = len(p2) same = id(p1) == id(p2) if not isinstance(p1, ndarray): p1 = array(p1, dtype=float) #end if if same: p2 = p1 elif not isinstance(p2, ndarray): p2 = array(p2, dtype=float) #end if dt = zeros((n1, n2), dtype=float) for i1 in range(n1): for i2 in range(n2): dt[i1, i2] = norm(p1[i1] - p2[i2]) #end for #end for if ordering == 0: return dt else: if ordering == 1: n = n1 elif ordering == 2: n = n2 dt = dt.T else: error('ordering must be 1 or 2,\nyou provided ' + str(ordering), 'distance_table') #end if order = empty(dt.shape, dtype=int) for i in range(n): o = dt[i].argsort() order[i] = o dt[i, :] = dt[i, o] #end for return dt, order
def process_gaussian_text(text, format, pp=True, basis=True, preserve_spacing=False): if format == 'gamess' or format == 'gaussian' or format == 'atomscf': rawlines = text.splitlines() sections = [] last_empty = True for rline in rawlines: line = rline.strip() if (not line.startswith('!')) and ( not line.startswith('#')) and len(line) > 0: if last_empty: lines = [] sections.append(lines) #end if if preserve_spacing: lines.append(rline) else: lines.append(line) #end if last_empty = False else: last_empty = True #end if #end for del lines if len(sections) == 2: basis_lines = sections[0] pp_lines = sections[1] elif pp: basis_lines = None pp_lines = sections[0] elif basis: basis_lines = sections[0] pp_lines = None #end if elif format == 'crystal': rawlines = text.splitlines() pp_lines = [] basis_lines = [] foundpp = False for line in rawlines: if not foundpp: foundpp = len(line.split()) == 5 #end if if not foundpp: pp_lines.append(line) else: basis_lines.append(line) #end if #end for if len(pp_lines) == 0: pp_lines = None #end if if len(basis_lines) == 0: basis_lines = None #end if else: error('{0} format is unknown'.format(format), 'process_gaussian_text') #end if if pp and basis: return pp_lines, basis_lines elif pp: return pp_lines elif basis: return basis_lines else: error('must request pp or basis')
def morse_fit(r,E,p0=None,jackknife=False,cost=least_squares,auxfuncs=None,auxres=None,capture=None): if isinstance(E,(list,tuple)): E = array(E,dtype=float) #end if Edata = None if len(E)!=E.size and len(E.shape)==2: Edata = E E = Edata.mean(axis=0) #end if pp = None if p0 is None: # make a simple quadratic fit to get initial guess for morse fit pp = polyfit(r,E,2) r0 = -pp[1]/(2*pp[0]) E0 = pp[2]+.5*pp[1]*r0 d2E = 2*pp[0] Einf = E[-1] #0.0 # r_eqm, pot_width, E_bind, E_infinity p0 = r0,sqrt(2*(Einf-E0)/d2E),Einf-E0,Einf #end if calc_aux = auxfuncs!=None and auxres!=None capture_results = capture!=None jcapture = None jauxcapture = None if capture_results: jcapture = obj() jauxcapture = obj() capture.r = r capture.E = E capture.p0 = p0 capture.jackknife = jackknife capture.cost = cost capture.auxfuncs = auxfuncs capture.auxres = auxres capture.Edata = Edata capture.pp = pp elif calc_aux: jcapture = obj() #end if # get an optimized morse fit of the means pf = curve_fit(r,E,morse,p0,cost) # obtain jackknife (mean+error) estimates of fitted parameters and/or fitted curves pmean = None perror = None if jackknife: if Edata is None: error('cannot perform jackknife fit because blocked data was not provided (only the means are present)','morse_fit') #end if pmean,perror = numerics_jackknife(data = Edata, function = curve_fit, args = [r,None,morse,pf,cost], position = 1, capture = jcapture) # compute auxiliary jackknife quantities, if desired (e.g. morse_freq, etc) if calc_aux: psamples = jcapture.jsamples for auxname,auxfunc in auxfuncs.items(): auxcap = None if capture_results: auxcap = obj() jauxcapture[auxname] = auxcap #end if auxres[auxname] = jackknife_aux(psamples,auxfunc,capture=auxcap) #end for #end if #end if if capture_results: capture.pmean = pmean capture.perror = perror capture.jcapture = jcapture capture.jauxcapture = jauxcapture #end if # return desired results if not jackknife: return pf else: return pf,pmean,perror
def numerics_error(*args, **kwargs): error(*args, **kwargs)
def jackknife_aux(jsamples,auxfunc,args=None,kwargs=None,position=None,capture=None): # unpack the argument list if compressed if not inspect.isfunction(auxfunc): if len(auxfunc)==1: auxfunc = auxfunc[0] elif len(auxfunc)==2: auxfunc,args = auxfunc elif len(auxfunc)==3: auxfunc,args,kwargs = auxfunc elif len(auxfunc)==4: auxfunc,args,kwargs,position = auxfunc else: error('between 1 and 4 fields (auxfunc,args,kwargs,position) can be packed into original auxfunc input, received {0}'.format(len(auxfunc))) #end if #end if # check the requested argument position argpos,kwargpos,args,kwargs,position = check_jackknife_inputs(args,kwargs,position) capture_results = capture!=None if capture_results: capture.auxfunc = auxfunc capture.args = args capture.kwargs = kwargs capture.position = position capture.jdata = [] capture.jsamples = [] #end if nblocks = len(jsamples) nb = float(nblocks) for b in range(nblocks): jdata = jsamples[b] if argpos: args[position] = jdata elif kwargpos: kwargs[position] = jdata #end if jsample = auxfunc(*args,**kwargs) if b==0: jsum = jsample.copy() jsum2 = jsum**2 else: jsum += jsample jsum2 += jsample**2 #end if if capture_results: capture.jdata.append(jdata) capture.jsamples.append(jsample) #end if #end for jmean = jsum/nb jerror = sqrt( (nb-1.)/nb*(jsum2-jsum**2/nb) ) if capture_results: capture.nblocks = nblocks capture.jsum = jsum capture.jsum2 = jsum2 capture.jmean = jmean capture.jerror = jerror #end if return jmean,jerror
def gen_crystal_molecule_sim( identifier = 'crystal', path = None, job = None, title = 'atom', system = None, pseudos = None, occupations = None, formats = None, theory = None, levshift = None, maxcycle = None, ): required = obj(path=path,system=system,pseudos=pseudos,occupations=occupations,formats=formats,theory=theory,job=job) for k,v in required.iteritems(): if v is None: error(k+' is a required input','gen_crystal_molecule_sim') #end if #end for pseudos_in = pseudos pseudos = [] for pp in pseudos_in: pseudos.append(os.path.join(nexus_noncore.pseudo_dir,pp)) #end for crys_input = input_template_dev() crys_input.read_text( write_geometry( title = title, bcond = 'molecule', system = system )+ write_basis( pseudos = pseudos, occupations = occupations, formats = formats, )+ write_hamiltonian( theory = theory, system = system, levshift = levshift, maxcycle = maxcycle ) ) #crys = generate_simulation( # identifier = identifier, # path = path, # job = job(cores=1,serial=True,app_command='crystal<{0}.d12>&{0}.out&'.format(identifier)), # input = crys_input, # infile = '{0}.d12'.format(identifier), # outfile = '{0}.out'.format(identifier), # ) crys = Crystal_1( identifier = identifier, path = path, job = job, input = crys_input, ) return crys
def layers_1d(xpoints, tol, xmin=None, xmax=None, merge=True, periodic=False, full_return=False): # Update inputs to be consistent with periodic merge, if requested if merge and periodic: if xmax is None: error('"xmax" must be provided.', 'layers_1d') elif xmin is None: xmin = 0.0 #end if #end if # Setup a virtual fine grid along x with grid cell width of tol if xmin is None: xmin = xpoints.min() #end if if xmax is None: xmax = xpoints.max() #end if nbins = np.uint64(np.round(np.ceil((xmax - xmin + tol) / tol))) dx = (xmax - xmin + tol) / nbins # Find the points belonging to each grid cell/layer layers = obj() for i, x in enumerate(xpoints): n = np.uint64(x / dx) if n not in layers: layers[n] = obj(ilist=[i], xsum=x, nsum=1) else: l = layers[n] l.ilist.append(i) l.xsum += x l.nsum += 1 #end if #end for # Find the mean of each set of points for l in layers: l.xmean = l.xsum / l.nsum #end for # Merge neighboring layers if the means are within the tolerance if merge: lprev = None for n in sorted(layers.keys()): l = layers[n] if lprev is not None and np.abs(l.xmean - lprev.xmean) < tol: lprev.ilist.extend(l.ilist) lprev.xsum += l.xsum lprev.nsum += l.nsum lprev.xmean = lprev.xsum / lprev.nsum del layers[n] else: lprev = l #end if #end for # Merge around periodic boundary if periodic: nleft = 0 nright = nbins - 1 if nleft in layers and nright in layers: ll = layers[nleft] lr = layers[nright] L = xmax - xmin if np.abs(ll.xmean + L - lr.xmean) < tol: ll.ilist.extend(lr.ilist) ll.xsum += lr.xsum ll.nsum += lr.nsum ll.xmean = ll.xsum / ll.nsum del layers[nright] #end if #end if #end if #end if if not full_return: return layers else: return layers, xmin, xmax
def eos_eval(p,V,type='vinet'): if type not in eos_funcs: error('"{0}" is not a valid EOS type\nvalid options are: {1}'.format(sorted(eos_funcs.keys()))) #end if return eos_funcs[type](p,V)
def numerics_error(*args,**kwargs): error(*args,**kwargs)
def read_poscar_chgcar(host,text): is_poscar = isinstance(host,PoscarFile) is_chgcar = isinstance(host,ChgcarFile) if not is_poscar and not is_chgcar: error('read_poscar_chgcar must be used in conjunction with PoscarFile or ChgcarFile objects only\nencountered object of type: {0}'.format(host.__class__.__name__)) #end if # read lines and remove fortran comments raw_lines = text.splitlines() lines = [] for line in raw_lines: # remove fortran comments cloc1 = line.find('!') cloc2 = line.find('#') has1 = cloc1!=-1 has2 = cloc2!=-1 if has1 or has2: if has1 and has2: cloc = min(cloc1,cloc2) elif has1: cloc = cloc1 else: cloc = cloc2 #end if line = line[:cloc] #end if lines.append(line.strip()) #end for # extract file information nlines = len(lines) min_lines = 8 if nlines<min_lines: host.error('file {0} must have at least {1} lines\nonly {2} lines found'.format(filepath,min_lines,nlines)) #end if description = lines[0] dim = 3 scale = float(lines[1].strip()) axes = empty((dim,dim)) axes[0] = array(lines[2].split(),dtype=float) axes[1] = array(lines[3].split(),dtype=float) axes[2] = array(lines[4].split(),dtype=float) tokens = lines[5].split() if tokens[0].isdigit(): counts = array(tokens,dtype=int) elem = None lcur = 6 else: elem = array(tokens,dtype=str) counts = array(lines[6].split(),dtype=int) lcur = 7 #end if if lcur<len(lines) and len(lines[lcur])>0: c = lines[lcur].lower()[0] lcur+=1 else: host.error('file {0} is incomplete (missing positions)'.format(filepath)) #end if selective_dynamics = c=='s' if selective_dynamics: # Selective dynamics if lcur<len(lines) and len(lines[lcur])>0: c = lines[lcur].lower()[0] lcur+=1 else: host.error('file {0} is incomplete (missing positions)'.format(filepath)) #end if #end if cartesian = c=='c' or c=='k' if cartesian: coord = 'cartesian' else: coord = 'direct' #end if npos = counts.sum() if lcur+npos>len(lines): host.error('file {0} is incomplete (missing positions)'.format(filepath)) #end if spos = [] for i in range(npos): spos.append(lines[lcur+i].split()) #end for lcur += npos spos = array(spos) pos = array(spos[:,0:3],dtype=float) if selective_dynamics: dynamic = array(spos[:,3:6],dtype=str) dynamic = dynamic=='T' else: dynamic = None #end if def is_empty(lines,start=None,end=None): if start is None: start = 0 #end if if end is None: end = len(lines) #end if is_empty = True for line in lines[start:end]: is_empty &= len(line)==0 #end for return is_empty #end def is_empty # velocities may be present for poscar # assume they are not for chgcar if is_poscar and lcur<len(lines) and not is_empty(lines,lcur): cline = lines[lcur].lower() lcur+=1 if lcur+npos>len(lines): host.error('file {0} is incomplete (missing velocities)'.format(filepath)) #end if cartesian = len(cline)>0 and (cline[0]=='c' or cline[0]=='k') if cartesian: vel_coord = 'cartesian' else: vel_coord = 'direct' #end if svel = [] for i in range(npos): svel.append(lines[lcur+i].split()) #end for lcur += npos vel = array(svel,dtype=float) else: vel_coord = None vel = None #end if # grid data is present for chgcar if is_chgcar: lcur+=1 if lcur<len(lines) and len(lines[lcur])>0: grid = array(lines[lcur].split(),dtype=int) lcur+=1 else: host.error('file {0} is incomplete (missing grid)'.format(filepath)) #end if if lcur<len(lines): ng = grid.prod() density = [] for line in lines[lcur:]: density.extend(line.split()) #end for if len(density)>0: def is_float(val): try: v = float(val) return True except: return False #end try #end def is_float # remove anything but the densities (e.g. augmentation charges) n=0 while is_float(density[n]) and n+ng<len(density): n+=ng #end while density = array(density[:n],dtype=float) else: host.error('file {0} is incomplete (missing density)'.format(filepath)) #end if if density.size%ng!=0: host.error('number of density data entries is not a multiple of the grid\ngrid shape: {0}\ngrid size: {1}\ndensity size: {2}'.format(grid,ng,density.size)) #end if ndens = density.size/ng if ndens==1: charge_density = density spin_density = None elif ndens==2: charge_density = density[:ng] spin_density = density[ng:] elif ndens==4: charge_density = density[:ng] spin_density = empty((ng,3),dtype=float) for i in range(3): spin_density[:,i] = density[(i+1)*ng:(i+2)*ng] #end for else: host.error('density data must be present for one of the following situations\n 1) charge density only (1 density)\n2) charge and collinear spin densities (2 densities)\n 3) charge and non-collinear spin densities (4 densities)\nnumber of densities found: {0}'.format(ndens)) #end if else: host.error('file {0} is incomplete (missing density)'.format(filepath)) #end if #end if if is_poscar: poscar = host elif is_chgcar: poscar = PoscarFile() #end if poscar.set( description = description, scale = scale, axes = axes, elem = elem, elem_count = counts, coord = coord, pos = pos, dynamic = dynamic, vel_coord = vel_coord, vel = vel ) if is_chgcar: host.set( poscar = poscar, grid = grid, charge_density = charge_density, spin_density = spin_density, )
def process_gaussian_text(text,format,pp=True,basis=True,preserve_spacing=False): if format=='gamess' or format=='gaussian' or format=='atomscf': rawlines = text.splitlines() sections = [] last_empty = True for rline in rawlines: line = rline.strip() if (not line.startswith('!')) and (not line.startswith('#')) and len(line)>0: if last_empty: lines = [] sections.append(lines) #end if if preserve_spacing: lines.append(rline) else: lines.append(line) #end if last_empty = False else: last_empty = True #end if #end for del lines if len(sections)==2: basis_lines = sections[0] pp_lines = sections[1] elif pp: basis_lines = None pp_lines = sections[0] elif basis: basis_lines = sections[0] pp_lines = None #end if elif format=='crystal': rawlines = text.splitlines() pp_lines = [] basis_lines = [] foundpp = False for line in rawlines: if not foundpp: foundpp = len(line.split())==5 #end if if not foundpp: pp_lines.append(line) else: basis_lines.append(line) #end if #end for if len(pp_lines)==0: pp_lines = None #end if if len(basis_lines)==0: basis_lines = None #end if else: error('{0} format is unknown'.format(format),'process_gaussian_text') #end if if pp and basis: return pp_lines,basis_lines elif pp: return pp_lines elif basis: return basis_lines else: error('must request pp or basis')