def test_read_cif(): """ Read La2CuO4 structure from a CIF file. """ from structure import read_structure, generate_structure files = get_files() # Read from CIF file s = read_structure(files['La2CuO4_ICSD69312.cif']) ref = generate_structure( units='A', axes=[[2.665, 0., -6.5525], [0., 5.4126, 0.], [2.665, 0., 6.5525]], elem='La La La La Cu Cu O O O O O O O O'.split(), pos=[[2.665, 5.37038172, -1.8071795], [2.665, 2.74851828, 4.7453205], [2.665, 2.66408172, -4.7453205], [2.665, 0.04221828, 1.8071795], [0., 0., 0.], [2.665, 2.7063, 0.], [1.3325, 1.35315, -0.128429], [3.9975, 4.05945, 0.128429], [3.9975, 1.35315, -0.128429], [1.3325, 4.05945, 0.128429], [2.665, 0.23490684, -4.1398695], [2.665, 2.47139316, 2.4126305], [2.665, 2.94120684, -2.4126305], [2.665, 5.17769316, 4.1398695]], ) assert (structure_same(s, ref))
def test_bounding_box(): import numpy as np from structure import generate_structure, read_structure files = get_files() h2o = generate_structure( elem=['O', 'H', 'H'], pos=[[0.000000, 0.000000, 0.000000], [0.000000, -0.757160, 0.586260], [0.000000, 0.757160, 0.586260]], units='A', # Angstroms ) # add a box by hand to the water molecule h2o_diy = h2o.copy() h2o_diy.set_axes(8.0 * np.eye(3)) assert (value_eq(h2o_diy.axes, 8. * np.eye(3))) # automatically add a bounding box to the water molecule h2o_auto = h2o.copy() h2o_auto.bounding_box(box='cubic', minsize=8.0) assert (value_eq(h2o_auto.axes, 8. * np.eye(3))) assert (value_eq(tuple(h2o_auto.pos[-1]), (4., 4.75716, 4.29313))) s = read_structure(files['coronene.xyz']) # make a bounding box that is at least 5 A from the nearest atom s.bounding_box(mindist=5.0) ref_axes = np.array([[16.4035, 0., 0.], [0., 16.3786, 0.], [0., 0., 10.]]) assert (value_eq(s.axes, ref_axes)) assert (value_eq(s.pos[:, 2].min(), 5.0)) assert (value_eq(s.pos[:, 2].max(), 5.0))
def test_read_write(): """ Write/read conventional diamond cell to/from XYZ, XSF, and POSCAR formats. """ import os from structure import generate_structure, read_structure tpath = testing.setup_unit_test_output_directory('structure', 'test_read_write') d8 = generate_structure( structure='diamond', cell='conv', ) # Write an XYZ file xyz_file = os.path.join(tpath, 'diamond8.xyz') d8.write(xyz_file) # Write an XSF file xsf_file = os.path.join(tpath, 'diamond8.xsf') d8.write(xsf_file) # Write a POSCAR file poscar_file = os.path.join(tpath, 'diamond8.POSCAR') d8.write(poscar_file) # Read an XYZ file d8_xyz = read_structure(xyz_file) # no cell info assert (value_eq(d8_xyz.elem, d8.elem)) assert (value_eq(d8_xyz.pos, d8.pos)) # Read an XSF file d8_xsf = read_structure(xsf_file) assert (structure_same(d8_xsf, d8)) # Read a POSCAR file d8_poscar = read_structure(poscar_file) assert (structure_same(d8_poscar, d8))
def demo_read_cif(): """ Read La2CuO4 structure from a CIF file. """ # Note: this demo requires PyCifRW # Read from CIF file s = read_structure('La2CuO4_ICSD69312.cif') # Print out the structure print('La2CuO4 in POSCAR format:') print(s.write_poscar())
def demo_read(): """ Read conventional diamond cell from XYZ, XSF, and POSCAR formats. """ # Read an XYZ file d8_xyz = read_structure('diamond8.xyz') # no cell info # Read an XSF file d8_xsf = read_structure('diamond8.xsf') # Read a POSCAR file d8_poscar = read_structure('diamond8.POSCAR') # Compare with the reference structure d8 = generate_structure( structure='diamond', cell='conv', ) def struct_same(s1, s2, axes=True): same = True same &= value_eq(s1.elem, s2.elem) same &= value_eq(s1.pos, s2.pos) if axes: same &= value_eq(s1.axes, s2.axes) #end if return same #end def struct_same print('\nXYZ valid? {}'.format(struct_same(d8_xyz, d8, axes=False))) print('\nXSF valid? {}'.format(struct_same(d8_xsf, d8))) print('\nPOSCAR valid? {}'.format(struct_same(d8_poscar, d8)))
def demo_coronene_box(): """ Place coronene in a well apportioned box. """ s = read_structure('./coronene.xyz') # make a bounding box that is at least 5 A from the nearest atom s.bounding_box(mindist=5.0) # print the resulting box print(s.axes) # plot the coronene molecule with an automatic box plt.figure(tight_layout=True) s.plot2d_ax(0, 1, 'k', lw=2) s.plot2d_pos(0, 1, 'bo') plt.axis('equal') plt.xlabel('x (A)') plt.ylabel('y (A)') plt.title('demo coronene box: box with minimum distance') plt.show()
def generate_physical_system(**kwargs): for var, val in ps_defaults.items(): if not var in kwargs: kwargs[var] = val #end if #end for type = kwargs['type'] if type == 'atom' or type == 'dimer' or type == 'trimer': del kwargs['kshift'] del kwargs['tiling'] #if not 'units' in kwargs: # kwargs['units'] = 'B' ##end if tiling = None else: tiling = kwargs['tiling'] #end if if 'structure' in kwargs: s = kwargs['structure'] is_str = isinstance(s, str) if is_str: if os.path.exists(s): if 'elem' in kwargs: s = read_structure(s, elem=kwargs['elem']) else: s = read_structure(s) #end if if 'axes' in kwargs: s.reset_axes(kwargs['axes']) #end if kwargs['structure'] = s else: slow = s.lower() format = None if '.' in slow: format = slow.rsplit('.')[1] elif 'poscar' in slow: format = 'poscar' #end if is_path = '/' in s is_file = format in set('xyz xsf poscar cif fhi-aims'.split()) if is_path or is_file: PhysicalSystem.class_error( 'user provided structure file does not exist\nstructure file path: ' + s, 'generate_physical_system') #end if #end if #end if #end if generation_info = obj() generation_info.transfer_from(deepcopy(kwargs)) net_charge = kwargs['net_charge'] net_spin = kwargs['net_spin'] tiled_spin = kwargs['tiled_spin'] extensive = kwargs['extensive'] del kwargs['net_spin'] del kwargs['net_charge'] del kwargs['tiled_spin'] del kwargs['extensive'] if 'particles' in kwargs: particles = kwargs['particles'] del kwargs['particles'] else: generation_info.particles = None #end if pretile = kwargs['pretile'] del kwargs['pretile'] valency = dict() remove = [] for var in kwargs: #if var in Matter.elements: if is_element(var): valency[var] = kwargs[var] remove.append(var) #end if #end if generation_info.valency = deepcopy(valency) for var in remove: del kwargs[var] #end for if pretile is None: structure = generate_structure(**kwargs) else: for d in range(len(pretile)): if tiling[d] % pretile[d] != 0: PhysicalSystem.class_error( 'pretile does not divide evenly into tiling\n tiling provided: {0}\n pretile provided: {1}' .format(tiling, pretile), 'generate_physical_system') #end if #end for tiling = tuple(array(tiling) // array(pretile)) kwargs['tiling'] = pretile pre = generate_structure(**kwargs) pre.remove_folded_structure() structure = pre.tile(tiling) #end if if tiling != None and tiling != (1, 1, 1) and structure.has_folded(): fps = PhysicalSystem(structure=structure.folded_structure, net_charge=net_charge, net_spin=net_spin, **valency) structure.remove_folded() folded_structure = fps.structure if extensive: ncells = int(round(structure.volume() / folded_structure.volume())) net_charge = ncells * net_charge if not isinstance(net_spin, str): net_spin = ncells * net_spin #end if #end if if tiled_spin != None: net_spin = tiled_spin #end if ps = PhysicalSystem(structure=structure, net_charge=net_charge, net_spin=net_spin, **valency) structure.set_folded(folded_structure) ps.folded_system = fps else: ps = PhysicalSystem(structure=structure, net_charge=net_charge, net_spin=net_spin, **valency) #end if ps.generation_info = generation_info return ps
def generate_physical_system(**kwargs): for var,val in ps_defaults.iteritems(): if not var in kwargs: kwargs[var] = val #end if #end for type = kwargs['type'] if type=='atom' or type=='dimer' or type=='trimer': del kwargs['kshift'] del kwargs['tiling'] #if not 'units' in kwargs: # kwargs['units'] = 'B' ##end if tiling = None else: tiling = kwargs['tiling'] #end if if 'structure' in kwargs: s = kwargs['structure'] is_str = isinstance(s,str) if is_str and os.path.exists(s):# and '.' in os.path.split(s)[1]: if 'elem' in kwargs: print 'system using elem' kwargs['structure'] = read_structure(s,elem=kwargs['elem']) else: kwargs['structure'] = read_structure(s) #end if elif is_str and '/' in s: PhysicalSystem.class_error('path provided for structure file does not exist: '+s,'generate_physical_system') #end if #end if generation_info = obj() generation_info.transfer_from(deepcopy(kwargs)) net_charge = kwargs['net_charge'] net_spin = kwargs['net_spin'] tiled_spin = kwargs['tiled_spin'] extensive = kwargs['extensive'] del kwargs['net_spin'] del kwargs['net_charge'] del kwargs['tiled_spin'] del kwargs['extensive'] if 'particles' in kwargs: particles = kwargs['particles'] del kwargs['particles'] else: generation_info.particles = None #end if pretile = kwargs['pretile'] del kwargs['pretile'] valency = dict() remove = [] for var in kwargs: #if var in Matter.elements: if is_element(var): valency[var] = kwargs[var] remove.append(var) #end if #end if generation_info.valency = deepcopy(valency) for var in remove: del kwargs[var] #end for if pretile is None: structure = generate_structure(**kwargs) else: for d in range(len(pretile)): if tiling[d]%pretile[d]!=0: PhysicalSystem.class_error('pretile does not divide evenly into tiling\n tiling provided: {0}\n pretile provided: {1}'.format(tiling,pretile),'generate_physical_system') #end if #end for tiling = tuple(array(tiling)/array(pretile)) kwargs['tiling'] = pretile pre = generate_structure(**kwargs) pre.remove_folded_structure() structure = pre.tile(tiling) #end if if tiling!=None and tiling!=(1,1,1): fps = PhysicalSystem( structure = structure.folded_structure, net_charge = net_charge, net_spin = net_spin, **valency ) structure.remove_folded() folded_structure = fps.structure if extensive: ncells = int(round(structure.volume()/folded_structure.volume())) net_charge = ncells*net_charge net_spin = ncells*net_spin #end if if tiled_spin!=None: net_spin = tiled_spin #end if ps = PhysicalSystem( structure = structure, net_charge = net_charge, net_spin = net_spin, **valency ) structure.set_folded(folded_structure) ps.folded_system = fps else: ps = PhysicalSystem( structure = structure, net_charge = net_charge, net_spin = net_spin, **valency ) #end if ps.generation_info = generation_info return ps
def test_input(): # imports import os import numpy as np import pwscf_input as pwi from generic import obj from structure import read_structure from physical_system import generate_physical_system from pwscf_input import check_new_variables,check_section_classes from pwscf_input import PwscfInput,generate_pwscf_input # directories tpath = testing.setup_unit_test_output_directory('pwscf_input','test_input') # files files = get_files() # divert logging function divert_nexus_log() # definitions def check_pw_same(pw1_,pw2_,l1='pw1',l2='pw2'): pw_same = object_eq(pw1_,pw2_,int_as_float=True) if not pw_same: d,d1,d2 = object_diff(pw1_,pw2_,full=True,int_as_float=True) diff = obj({l1:obj(d1),l2:obj(d2)}) failed(str(diff)) #end if #end def check_pw_same # test internal spec check_new_variables(exit=False) check_section_classes(exit=False) # test compose compositions = obj() # based on sample_inputs/Fe_start_ns_eig.in pw = PwscfInput() pw.control.set( calculation = 'scf' , restart_mode = 'from_scratch' , wf_collect = True , outdir = './output' , pseudo_dir = '../pseudo/' , prefix = 'fe' , etot_conv_thr = 1.0e-9 , forc_conv_thr = 1.0e-6 , tstress = True , tprnfor = True , ) pw.system.set( ibrav = 1, nat = 2, ntyp = 1, ecutwfc = 100 , ecutrho = 300 , nbnd = 18, occupations = 'smearing', degauss = 0.0005 , smearing = 'methfessel-paxton' , nspin = 2 , assume_isolated = 'martyna-tuckerman', lda_plus_u = True , ) pw.system.set({ 'celldm(1)' : 15, 'starting_magnetization(1)' : 0.9, 'hubbard_u(1)' : 3.1, 'starting_ns_eigenvalue(1,2,1)' : 0.0, 'starting_ns_eigenvalue(2,2,1)' : 0.0476060, 'starting_ns_eigenvalue(3,2,1)' : 0.0476060, 'starting_ns_eigenvalue(4,2,1)' : 0.9654373, 'starting_ns_eigenvalue(5,2,1)' : 0.9954307, }) pw.electrons.set( conv_thr = 1.0e-9 , mixing_beta = 0.7 , diagonalization = 'david' , mixing_fixed_ns = 500, ) pw.atomic_species.set( atoms = ['Fe'], masses = obj(Fe=58.69000), pseudopotentials = obj(Fe='Fe.pbe-nd-rrkjus.UPF'), ) pw.atomic_positions.set( specifier = 'angstrom', atoms = ['Fe','Fe'], positions = np.array([ [2.070000000, 0.000000000, 0.000000000], [0.000000000, 0.000000000, 0.000000000], ]), ) pw.k_points.set( specifier = 'automatic', grid = np.array((1,1,1)), shift = np.array((1,1,1)), ) compositions['Fe_start_ns_eig.in'] = pw # test read pwr = PwscfInput(files['Fe_start_ns_eig.in']) pwc = pw.copy() pwc.standardize_types() check_pw_same(pwc,pwr,'compose','read') # test write infile = os.path.join(tpath,'pwscf.in') pw.write(infile) pw2 = PwscfInput() pw2.read(infile) check_pw_same(pw2,pwr) # test read/write/read reads = obj() for infile in input_files: read_path = files[infile] write_path = os.path.join(tpath,infile) if os.path.exists(write_path): os.remove(write_path) #end if pw = PwscfInput(read_path) pw.write(write_path) pw2 = PwscfInput(write_path) check_pw_same(pw,pw2,'read','write/read') reads[infile] = pw #end for # test generate generations = obj() # based on sample_inputs/VO2_M1_afm.in infile = 'VO2_M1_afm.in' struct_file = files['VO2_M1_afm.xsf'] read_path = files[infile] write_path = os.path.join(tpath,infile) s = read_structure(struct_file) s.elem[0] = 'V1' s.elem[1] = 'V2' s.elem[2] = 'V1' s.elem[3] = 'V2' vo2 = generate_physical_system( structure = s, V1 = 13, V2 = 13, O = 6, ) pw = generate_pwscf_input( selector = 'generic', calculation = 'scf', disk_io = 'low', verbosity = 'high', wf_collect = True, input_dft = 'lda', hubbard_u = obj(V1=3.5,V2=3.5), ecutwfc = 350, bandfac = 1.3, nosym = True, occupations = 'smearing', smearing = 'fermi-dirac', degauss = 0.0001, nspin = 2, start_mag = obj(V1=1.0,V2=-1.0), diagonalization = 'david', conv_thr = 1e-8, mixing_beta = 0.2, electron_maxstep = 1000, system = vo2, pseudos = ['V.opt.upf','O.opt.upf'], kgrid = (6,6,6), kshift = (0,0,0), # added for reverse compatibility celldm = {1:1.0}, cell_option = 'alat', positions_option = 'alat', ) generations[infile] = pw if os.path.exists(write_path): os.remove(write_path) #end if pw.write(write_path) pw2 = PwscfInput(read_path) pw3 = PwscfInput(write_path) check_pw_same(pw2,pw3,'generate','read') # based on sample_inputs/Fe_start_ns_eig.in infile = 'Fe_start_ns_eig.in' read_path = files[infile] write_path = os.path.join(tpath,infile) pw = generate_pwscf_input( selector = 'generic', calculation = 'scf', restart_mode = 'from_scratch', wf_collect = True, outdir = './output', pseudo_dir = '../pseudo/', prefix = 'fe', etot_conv_thr = 1.0e-9, forc_conv_thr = 1.0e-6, tstress = True, tprnfor = True, ibrav = 1, nat = 2, ntyp = 1, ecutwfc = 100, ecutrho = 300, nbnd = 18, occupations = 'smearing', degauss = 0.0005, smearing = 'methfessel-paxton', nspin = 2, assume_isolated = 'martyna-tuckerman', lda_plus_u = True, conv_thr = 1.0e-9, mixing_beta = 0.7, diagonalization = 'david', mixing_fixed_ns = 500, mass = obj(Fe=58.69000), pseudos = ['Fe.pbe-nd-rrkjus.UPF'], elem = ['Fe','Fe'], pos = [[2.070000000, 0.000000000, 0.000000000], [0.000000000, 0.000000000, 0.000000000]], pos_specifier = 'angstrom', kgrid = np.array((1,1,1)), kshift = np.array((1,1,1)), ) pw.system.set({ 'celldm(1)' : 15, 'starting_magnetization(1)' : 0.9, 'hubbard_u(1)' : 3.1, 'starting_ns_eigenvalue(1,2,1)' : 0.0, 'starting_ns_eigenvalue(2,2,1)' : 0.0476060, 'starting_ns_eigenvalue(3,2,1)' : 0.0476060, 'starting_ns_eigenvalue(4,2,1)' : 0.9654373, 'starting_ns_eigenvalue(5,2,1)' : 0.9954307, }) generations[infile] = pw pw2 = compositions[infile] check_pw_same(pw,pw2,'generate','compose') if os.path.exists(write_path): os.remove(write_path) #end if pw.write(write_path) pw3 = PwscfInput(write_path) pw4 = reads[infile] check_pw_same(pw3,pw4,'generate','read') # based on sample_inputs/Fe_start_ns_eig.in # variant that uses direct pwscf array input pw = generate_pwscf_input( selector = 'generic', calculation = 'scf', restart_mode = 'from_scratch', wf_collect = True, outdir = './output', pseudo_dir = '../pseudo/', prefix = 'fe', etot_conv_thr = 1.0e-9, forc_conv_thr = 1.0e-6, tstress = True, tprnfor = True, ibrav = 1, nat = 2, ntyp = 1, ecutwfc = 100, ecutrho = 300, nbnd = 18, occupations = 'smearing', degauss = 0.0005, smearing = 'methfessel-paxton', nspin = 2, assume_isolated = 'martyna-tuckerman', lda_plus_u = True, conv_thr = 1.0e-9, mixing_beta = 0.7, diagonalization = 'david', mixing_fixed_ns = 500, mass = obj(Fe=58.69000), pseudos = ['Fe.pbe-nd-rrkjus.UPF'], elem = ['Fe','Fe'], pos = [[2.070000000, 0.000000000, 0.000000000], [0.000000000, 0.000000000, 0.000000000]], pos_specifier = 'angstrom', kgrid = np.array((1,1,1)), kshift = np.array((1,1,1)), starting_ns_eigenvalue = {(1,2,1) : 0.0, (2,2,1) : 0.0476060, (3,2,1) : 0.0476060, (4,2,1) : 0.9654373, (5,2,1) : 0.9954307,}, celldm = {1 : 15 }, starting_magnetization = {1 : 0.9}, hubbard_u = {1 : 3.1}, ) pwg = pw.copy() pwg.standardize_types() generations[infile] = pw pw2 = compositions[infile].copy() pw2.standardize_types() check_pw_same(pwg,pw2,'generate','compose') pw3 = reads[infile] check_pw_same(pwg,pw3,'generate','read') if os.path.exists(write_path): os.remove(write_path) #end if pw.write(write_path) pw4 = PwscfInput(write_path) check_pw_same(pwg,pw3,'generate','write') # restore logging function restore_nexus_log()