def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the system sys = System.from_file(args.wfn) # Define a list of optional arguments for the WPartClass: WPartClass = wpart_schemes[args.scheme] kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in WPartClass.options) # Load the proatomdb if args.atoms is not None: proatomdb = ProAtomDB.from_file(args.atoms) proatomdb.normalize() kwargs['proatomdb'] = proatomdb else: proatomdb = None # Run the partitioning agspec = AtomicGridSpec(args.grid) molgrid = BeckeMolGrid(sys, agspec, mode='only') sys.update_grid(molgrid) # for the grid to be written to the output wpart = wpart_schemes[args.scheme](sys, molgrid, **kwargs) names = wpart.do_all() write_part_output(fn_h5, grp_name, wpart, names, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the system sys = System.from_file(args.cube) ugrid = sys.grid if not isinstance(ugrid, UniformGrid): raise TypeError( 'The specified file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = sys.extra['cube_data'] # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme](sys, ugrid, True, moldens, proatomdb, wcor_numbers, args.wcor_rcut_max, args.wcor_rcond, **kwargs) names = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: sys_sym = System.from_file(args.symmetry) sym = sys_sym.extra.get('symmetry') if sym is None: raise ValueError('No symmetry information found in %s.' % args.symmetry) sys_results = dict((name, cpart[name]) for name in names) sym_results = symmetry_analysis(sys, sym, sys_results) cpart.cache.dump('symmetry', sym_results) names.append('symmetry') sys.extra['symmetry'] = sym write_part_output(fn_h5, grp_name, cpart, names, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the system sys = System.from_file(args.cube) ugrid = sys.grid if not isinstance(ugrid, UniformGrid): raise TypeError('The specified file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = sys.extra['cube_data'] # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme]( sys, ugrid, True, moldens, proatomdb, wcor_numbers, args.wcor_rcut_max, args.wcor_rcond, **kwargs) names = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: sys_sym = System.from_file(args.symmetry) sym = sys_sym.extra.get('symmetry') if sym is None: raise ValueError('No symmetry information found in %s.' % args.symmetry) sys_results = dict((name, cpart[name]) for name in names) sym_results = symmetry_analysis(sys, sym, sys_results) cpart.cache.dump('symmetry', sym_results) names.append('symmetry') sys.extra['symmetry'] = sym write_part_output(fn_h5, grp_name, cpart, names, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the system mol = IOData.from_file(args.wfn) # Define a list of optional arguments for the WPartClass: WPartClass = wpart_schemes[args.scheme] kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in WPartClass.options) # Load the proatomdb if args.atoms is not None: proatomdb = ProAtomDB.from_file(args.atoms) proatomdb.normalize() kwargs['proatomdb'] = proatomdb else: proatomdb = None # Run the partitioning agspec = AtomicGridSpec(args.grid) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, agspec, mode='only') dm_full = mol.get_dm_full() moldens = mol.obasis.compute_grid_density_dm(dm_full, grid.points, epsilon=args.epsilon) dm_spin = mol.get_dm_spin() if dm_spin is not None: kwargs['spindens'] = mol.obasis.compute_grid_density_dm( dm_spin, grid.points, epsilon=args.epsilon) wpart = wpart_schemes[args.scheme](mol.coordinates, mol.numbers, mol.pseudo_numbers, grid, moldens, **kwargs) keys = wpart.do_all() if args.slow: # ugly hack for the slow analysis involving the AIM overlap operators. wpart_slow_analysis(wpart, mol) keys = list(wpart.cache.iterkeys(tags='o')) write_part_output(fn_h5, grp_name, wpart, keys, args)
def _get_eos(filename, scheme): # build proatom database atoms = glob.glob('chemtools/data/atom_0*') proatomdb = ProAtomDB.from_files(atoms, "power:5e-8:20:40:146") # load molecule & make grid, denspart, and eos instances with path('chemtools.data', filename) as file_path: mol = Molecule.from_file(file_path) grid = MolecularGrid.from_molecule(mol, specs='power:5e-8:20:40:146', k=4, rotate=False) part = DensPart.from_molecule(mol, scheme=scheme, grid=grid, local=False, proatomdb=proatomdb) return EOS(mol, part)
def __init__(self, coordinates, numbers, pseudo_numbers, density, grid, scheme="h", **kwargs): wpart = wpart_schemes[scheme] # make proatom database if scheme.lower() not in ["mbis", "b"]: if "proatomdb" not in kwargs.keys(): proatomdb = ProAtomDB.from_refatoms(numbers) kwargs["proatomdb"] = proatomdb # partition self.part = wpart(coordinates, numbers, pseudo_numbers, grid, density, **kwargs) self.part.do_all() self.grid = grid self.density = density self.coordines = coordinates self.numbers = numbers self.pseudo_numbers = pseudo_numbers self.charges = self.part['charges']
def __init__(self, coordinates, numbers, pseudo_numbers, density, grid, scheme="h", **kwargs): """Initialize class. Parameters ---------- coordinates : np.ndarray, shape=(M, 3) Cartesian coordinates of `M` atoms in the molecule. numbers : np.ndarray, shape=(M,) Atomic number of `M` atoms in the molecule. pseudo_numbers : np.ndarray, shape=(M,) Pseudo-number of `M` atoms in the molecule. density : np.ndarray, shape=(N,) Total density to be partitioned. grid : BeckeMolGrid Instance of BeckeMolGrid numerical integration grid. scheme : str Type of atoms-in-molecule partitioning scheme. """ wpart = wpart_schemes[scheme] # make proatom database if scheme.lower() not in ["mbis", "b"]: if "proatomdb" not in kwargs.keys(): proatomdb = ProAtomDB.from_refatoms(numbers) kwargs["proatomdb"] = proatomdb kwargs["local"] = False # partition self.part = wpart(coordinates, numbers, pseudo_numbers, grid, density, **kwargs) self.part.do_charges() self.grid = grid self.density = density self.coordines = coordinates self.numbers = numbers self.pseudo_numbers = pseudo_numbers self.charges = self.part['charges']
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the system mol = IOData.from_file(args.wfn) # Define a list of optional arguments for the WPartClass: WPartClass = wpart_schemes[args.scheme] kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in WPartClass.options) # Load the proatomdb if args.atoms is not None: proatomdb = ProAtomDB.from_file(args.atoms) proatomdb.normalize() kwargs['proatomdb'] = proatomdb else: proatomdb = None # Run the partitioning agspec = AtomicGridSpec(args.grid) grid = BeckeMolGrid(mol.coordinates, mol.numbers, mol.pseudo_numbers, agspec, mode='only') dm_full = mol.get_dm_full() moldens = mol.obasis.compute_grid_density_dm(dm_full, grid.points, epsilon=args.epsilon) dm_spin = mol.get_dm_spin() if dm_spin is not None: kwargs['spindens'] = mol.obasis.compute_grid_density_dm(dm_spin, grid.points, epsilon=args.epsilon) wpart = wpart_schemes[args.scheme](mol.coordinates, mol.numbers, mol.pseudo_numbers,grid, moldens, **kwargs) keys = wpart.do_all() if args.slow: # ugly hack for the slow analysis involving the AIM overlap operators. wpart_slow_analysis(wpart, mol) keys = list(wpart.cache.iterkeys(tags='o')) write_part_output(fn_h5, grp_name, wpart, keys, args)
def main(): args = parse_args() fn_h5, grp_name = parse_h5(args.output, 'output') # check if the group is already present (and not empty) in the output file if check_output(fn_h5, grp_name, args.overwrite): return # Load the IOData mol = IOData.from_file(args.cube) ugrid = mol.grid if not isinstance(ugrid, UniformGrid): raise TypeError('The density cube file does not contain data on a rectangular grid.') ugrid.pbc[:] = parse_pbc(args.pbc) moldens = mol.cube_data # Reduce the grid if required if args.stride > 1 or args.chop > 0: moldens, ugrid = reduce_data(moldens, ugrid, args.stride, args.chop) # Load the spin density (optional) if args.spindens is not None: molspin = IOData.from_file(args.spindens) if not isinstance(molspin.grid, UniformGrid): raise TypeError('The spin cube file does not contain data on a rectangular grid.') spindens = molspin.cube_data if args.stride > 1 or args.chop > 0: spindens = reduce_data(spindens, molspin.grid, args.stride, args.chop)[0] if spindens.shape != moldens.shape: raise TypeError('The shape of the spin cube does not match the shape of the density cube.') else: spindens = None # Load the proatomdb and make pro-atoms more compact if that is requested proatomdb = ProAtomDB.from_file(args.atoms) if args.compact is not None: proatomdb.compact(args.compact) proatomdb.normalize() # Select the partitioning scheme CPartClass = cpart_schemes[args.scheme] # List of element numbers for which weight corrections are needed: if args.wcor == '0': wcor_numbers = [] else: wcor_numbers = list(iter_elements(args.wcor)) # Run the partitioning kwargs = dict((key, val) for key, val in vars(args).iteritems() if key in CPartClass.options) cpart = cpart_schemes[args.scheme]( mol.coordinates, mol.numbers, mol.pseudo_numbers, ugrid, moldens, proatomdb, spindens=spindens, local=True, wcor_numbers=wcor_numbers, wcor_rcut_max=args.wcor_rcut_max, wcor_rcond=args.wcor_rcond, **kwargs) keys = cpart.do_all() # Do a symmetry analysis if requested. if args.symmetry is not None: mol_sym = IOData.from_file(args.symmetry) if not hasattr(mol_sym, 'symmetry'): raise ValueError('No symmetry information found in %s.' % args.symmetry) aim_results = dict((key, cpart[key]) for key in keys) sym_results = symmetry_analysis(mol.coordinates, ugrid.get_cell(), mol_sym.symmetry, aim_results) cpart.cache.dump('symmetry', sym_results) keys.append('symmetry') write_part_output(fn_h5, grp_name, cpart, keys, args)
def get_proatomdb_hf_lan(): '''Return a proatomdb of H, O, Si at hf/LANL2MB for testing purposes''' fns = glob(context.get_fn('test/atom_???_???_hf_lan.fchk')) return ProAtomDB.from_files(fns)
def get_proatomdb_hf_sto3g(): '''Return a proatomdb of H and O at hf/sto-3g for testing purposes''' fns = glob(context.get_fn('test/atom_???_???_hf_sto3g.fchk')) return ProAtomDB.from_files(fns)
def get_proatomdb_cp2k(): '''Return a proatomdb of pseudo oxygens and one silicon for testing purposes''' fns = glob(context.get_fn('test/atom_*.cp2k.out')) return ProAtomDB.from_files(fns)
def main_convert(args): # The atomic grid specification agspec = AtomicGridSpec(args.grid) # The program is detected based on the run script that is present run_scripts = glob("run_*.sh") if len(run_scripts) != 1: raise RuntimeError( 'Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.' % len(run_scripts)) program = atom_programs[run_scripts[0][4:-3]] # Loop over all sensible directories energy_table = EnergyTable() records = [] for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")): number = int(dn_state[:3]) pop = int(dn_state[7:10]) cases = [] for dn_mult in sorted(glob('%s/mult??' % dn_state)): if log.do_medium: log('Loading from', dn_mult) data, energy = program.load_atom(dn_mult) if energy is None: if log.do_medium: log('No (sensible) results found: ', dn_mult) continue cases.append((energy, data)) if len(cases) == 0: if log.do_medium: log('Nothing found in: ', dn_state) continue # Get the lowest in energy and write to chk file cases.sort() energy, data = cases[0] # Add case to energy table energy_table.add(number, pop, energy) # Write atom to HORTON file if possible if data is not None: data.to_file('%s/horton.h5' % dn_state) # Construct a record for the proatomdb records.append(ProAtomRecord.from_iodata(data, agspec)) # Release memory data = None del cases # Let user know we are alive. if log.do_medium: log('Succesfull: ', dn_state) # Report energies if log.do_medium: energy_table.log() # Write out atoms file proatomdb = ProAtomDB(records) proatomdb.to_file('atoms.h5') if log.do_medium: log('Written atoms.h5') # Make nice figures plot_atoms(proatomdb)
def get_dict_population(molecule, approach, scheme, **kwargs): r"""Return dictionary of number of electrons and corresponding atomic charges values. Parameters ---------- molecule : Molecule or Sequence of Molecule Instance of Molecule class, or sequence of Molecule class instances. approach : str, optional Choose between "FMR" (fragment of molecular response) or "RMF" (response of molecular fragment). scheme : str Partitioning scheme. kwargs : optional """ # check approach if approach.lower() not in ["rmf", "fmr"]: raise ValueError("Argument approach={0} is not valid.".format(approach)) # case of populations available in molecule if scheme.lower() not in wpart_schemes: # check approach & molecule instances if approach.lower() != "rmf": raise ValueError("Condensing with scheme={0} is only possible in combination with " "approach='RMF'! Given approach={1}".format(scheme, approach)) if (not hasattr(type(molecule), "__iter__") or len(molecule) != 3 or not np.all([isinstance(mol, Molecule) for mol in molecule])): raise ValueError("Condensing with scheme={0} needs 3 molecules!".format(scheme)) # get populations pops = [getattr(mol, scheme + "_charges") for mol in molecule] if np.any([isinstance(pop, type(None)) for pop in pops]): raise ValueError("Condensing scheme={0} is not possible, because attribute {1}_charges " "of molecule instances is 'None'.".format(scheme, scheme.lower())) # make dictionary of populations dict_pops = dict([(sum(m.mo.nelectrons), m.numbers - pop) for m, pop in zip(molecule, pops)]) return dict_pops # case of condensing the density using denspart try: # check whether molecules have the same coordinates get_matching_attr(molecule, "coordinates", 1.e-4) same_coordinates = True except ValueError: if approach.lower() == "fmr": raise ValueError("When geometries of molecules are different, only approach='RMF' " "is possible! Given approach={0}".format(approach.upper())) same_coordinates = False # find reference molecule if isinstance(molecule, Molecule): mol0 = molecule elif np.all([isinstance(mol, Molecule) for mol in molecule]): if len(molecule) != 3: raise ValueError("Condensing within FD approach, currently works for " "only 3 molecules! Given {0} molecules.".format(len(molecule))) # reference molecule is the middle molecule (for 3 molecules) dict_mols = {sum(mol.mo.nelectrons): mol for mol in molecule} mol0 = dict_mols.pop(sorted(dict_mols.keys())[1]) else: raise ValueError("Argument molecule not recognized!") # check and generate partitioning class & proatomdb wpart = wpart_schemes[scheme] # make proatom database if scheme.lower() not in ["mbis", "b"]: if "proatomdb" not in list(kwargs.keys()) or kwargs["proatomdb"] is None: proatomdb = ProAtomDB.from_refatoms(mol0.numbers) kwargs["proatomdb"] = proatomdb # check or generate molecular grid grid = get_molecular_grid(molecule, kwargs.pop("grid", None)) # compute dictionary of number of electron and density dict_dens = get_dict_density(molecule, grid.points) # compute population of reference molecule part0 = wpart(mol0.coordinates, mol0.numbers, mol0.pseudo_numbers, grid, dict_dens[sum(mol0.mo.nelectrons)], **kwargs) part0.do_all() # record population of reference system dict_pops = dict([(sum(mol0.mo.nelectrons), part0["populations"])]) del dict_dens[sum(mol0.mo.nelectrons)] # compute and record populations given grid in a dictionary for nelec, dens in dict_dens.items(): if approach.lower() == "fmr": # fragment of molecular response pops = condense_to_atoms(dens, part0) elif approach.lower() == "rmf": # response of molecular fragment if not same_coordinates: mol = dict_mols[nelec] grid = get_molecular_grid(molecule, None) dens = molecule.compute_density(grid.points, "ab", None) else: mol = mol0 parts = wpart(mol.coordinates, mol.numbers, mol.pseudo_numbers, grid, dens, **kwargs) parts.do_all() pops = parts["populations"] else: raise ValueError("Condensing approach {0} is not recognized!".format(approach)) # Store number of electron and populations in a dictionary dict_pops[nelec] = pops return dict_pops
def main_convert(args): # The atomic grid specification agspec = AtomicGridSpec(args.grid) # The program is detected based on the run script that is present run_scripts = glob("run_*.sh") if len(run_scripts) != 1: raise RuntimeError('Found %i run_*.sh scripts while exactly one is needed to know which program was used to run the atomic computations.' % len(run_scripts)) program = atom_programs[run_scripts[0][4:-3]] # Loop over all sensible directories energy_table = EnergyTable() records = [] for dn_state in sorted(glob("[01]??_??_[01]??_q[+-]??")): number = int(dn_state[:3]) pop = int(dn_state[7:10]) cases = [] for dn_mult in sorted(glob('%s/mult??' % dn_state)): if log.do_medium: log('Loading from', dn_mult) system, energy = program.load_atom(dn_mult) if energy is None: if log.do_medium: log('No (sensible) results found: ', dn_mult) continue cases.append((energy, system)) if len(cases) == 0: if log.do_medium: log('Nothing found in: ', dn_state) continue # Get the lowest in energy and write to chk file cases.sort() energy, system = cases[0] # Add case to energy table energy_table.add(number, pop, energy) # Write system to Horton file if possible if system is not None: system.assign_chk('%s/horton.h5' % dn_state) # Construct a record for the proatomdb records.append(ProAtomRecord.from_system(system, agspec)) # Release memory and close h5 files system = None del cases # Let user know we are alive. if log.do_medium: log('Succesfull: ', dn_state) # Report energies if log.do_medium: energy_table.log() # Write out atoms file proatomdb = ProAtomDB(records) proatomdb.to_file('atoms.h5') if log.do_medium: log('Written atoms.h5') # Make nice figures plot_atoms(proatomdb)