def test_nio_sto3g_afm(): path = os.path.join(TEST_DIR, "input_files", 'nio_sto3g_afm.crystal.d12') with open(path) as f: input_str = f.read() output_dict, basis_sets, atom_props = extract_data(input_str) assert len(basis_sets) == 2 assert atom_props == {'spin_alpha': [1], 'spin_beta': [2]} assert output_dict == { 'scf': { 'single': 'UHF', 'numerical': { 'FMIXING': 30 }, 'post_scf': ['PPAN'], 'spinlock': { 'SPINLOCK': [0, 15] }, 'k_points': (8, 8) }, 'title': 'NiO Bulk with AFM spin' }
def test_mgo_sto3g_scf(): path = os.path.join(TEST_DIR, "input_files", 'mgo_sto3g_scf.crystal.d12') with open(path) as f: input_str = f.read() output_dict, basis_sets, atom_props = extract_data(input_str) assert len(basis_sets) == 2 assert atom_props == {} assert output_dict == {'scf': {'k_points': (8, 8)}, 'title': 'MgO bulk'}
def create_inputs(inpath, outpath): """ create ``crystal17.main`` input nodes from an existing run NB: none of the nodes are stored, also existing basis will be retrieved if availiable :param inpath: path to .d12 file :param outpath: path to .out file :return: dictionary of inputs, with keys 'structure', 'parameters', 'settings', 'structure', 'basis' """ from aiida.orm import DataFactory, CalculationFactory calc_cls = CalculationFactory('crystal17.main') basis_cls = DataFactory('crystal17.basisset') struct_cls = DataFactory('structure') structsettings_cls = DataFactory('crystal17.structsettings') inputs = {} with open(inpath) as f: d12content = f.read() output_dict, basis_sets, atom_props = extract_data(d12content) cryparse = CrystalOutputPlugin() if not os.path.exists(outpath): raise OutputParsingError( "The raw data file does not exist: {}".format(outpath)) with open(outpath) as f: try: data = cryparse.read_file(f, log_warnings=False) except IOError as err: raise OutputParsingError( "Error in CRYSTAL 17 run output: {}".format(err)) # we retrieve the initial primitive geometry and symmetry atoms = _create_atoms(data) # convert fragment (i.e. unfixed) to fixed if "fragment" in atom_props: frag = atom_props.pop("fragment") atom_props["fixed"] = [ i + 1 for i in range(atoms.get_number_of_atoms()) if i + 1 not in frag ] atoms.set_tags(_create_tags(atom_props, atoms)) structure = struct_cls(ase=atoms) inputs['structure'] = structure settings_dict = {"kinds": {}} for key, vals in atom_props.items(): settings_dict["kinds"][key] = [ structure.sites[i - 1].kind_name for i in vals ] settings_dict["operations"] = data["initial"]["primitive_symmops"] # TODO retrieve centering code, crystal system and spacegroup settings_dict["space_group"] = 1 settings_dict["crystal_type"] = 1 settings_dict["centring_code"] = 1 settings = structsettings_cls(data=settings_dict) parameters = calc_cls.prepare_and_validate(output_dict, structure, settings) inputs['parameters'] = parameters inputs['settings'] = settings inputs["basis"] = {} for bset in basis_sets: bfile = tempfile.NamedTemporaryFile(delete=False) try: with open(bfile.name, "w") as f: f.write(bset) bdata, _ = basis_cls.get_or_create( bfile.name, use_first=False, store_basis=False) # TODO report if bases created or retrieved finally: os.remove(bfile.name) inputs["basis"][bdata.element] = bdata return inputs
def test_full_read(input_str): output_dict, basis_sets, atom_props = extract_data(input_str) assert len(basis_sets) == 2 assert atom_props == { 'fragment': [1, 3], 'ghosts': [5, 6], 'spin_alpha': [1, 3], 'spin_beta': [2, 4] } expected = { "title": "a title", "geometry": { "info_print": ["ATOMSYMM", "SYMMOPS"], "info_external": ["STRUCPRT"], "optimise": { "type": "FULLOPTG", "hessian": "HESSIDEN", "gradient": "NUMGRATO", "info_print": ["PRINTOPT", "PRINTFORCES"], "convergence": { "TOLDEG": 0.0003, "TOLDEX": 0.0012, "TOLDEE": 7, "MAXCYCLE": 50, "FINALRUN": 4 }, } }, "basis_set": { "CHARGED": True, }, "scf": { "dft": { "xc": ["LDA", "PZ"], # or # "xc": "HSE06", # or # "xc": { # "LSRSH-PBE": [0.11, 0.25, 0.00001] # }, "SPIN": True, "grid": "XLGRID", "grid_weights": "BECKE", "numerical": { "TOLLDENS": 6, "TOLLGRID": 14, "LIMBEK": 400 } }, # or # "single": "UHF", "k_points": [8, 8], "numerical": { "BIPOLAR": [18, 14], "BIPOSIZE": 4000000, "EXCHSIZE": 4000000, "EXCHPERM": True, "ILASIZE": 6000, "INTGPACK": 0, "MADELIND": 50, "POLEORDR": 4, "TOLINTEG": [6, 6, 6, 6, 12], "TOLPSEUD": 6, "FMIXING": 0, "MAXCYCLE": 50, "TOLDEE": 6, "LEVSHIFT": [2, 1], "SMEAR": 0.1 }, "fock_mixing": "DIIS", # or # "fock_mixing": ["BROYDEN", 0.0001, 50, 2], "spinlock": { "SPINLOCK": [1, 10] }, "post_scf": ["GRADCAL", "PPAN"] } } assert edict.diff(output_dict, expected) == {}
def test_read_fail(input_str): input_str = input_str.replace("PPAN", "WRONG") with pytest.raises(NotImplementedError): extract_data(input_str)