def test_add_bonds(): atoms = bulk("NaCl", "rocksalt", 5.64) dct = atoms_to_dict(atoms, "NaCl") print() # print(dct) dct = add_bonds(dct, "Na", "Cl", 4, 0.5) expected_dct = { 'elements': [{ 'type': 'repeat_cell', 'name': 'NaCl', 'centre': [2.82, 2.82, 2.82], 'color_bbox': 'black', 'cell_vectors': { 'a': [0.0, 2.82, 2.82], 'b': [2.82, 0.0, 2.82], 'c': [2.82, 2.82, 0.0] }, 'sites': [{ 'label': 'Na', 'ccoord': [0.0, 0.0, 0.0], 'cell': [0, 0, 0], 'radius': 1.66, 'color_fill': '#ab5cf2', 'color_outline': None, 'transparency': 1, 'anum': 11 }, { 'label': 'Cl', 'ccoord': [2.82, 0.0, 0.0], 'cell': [0, 0, 0], 'radius': 1.02, 'color_fill': '#1ff01f', 'color_outline': None, 'transparency': 1, 'anum': 17 }], 'bonds': [{ "label": "Na", "coord_label": "Cl", "radius": 0.5, "max_dist": 4, "include_periodic": True, "color_by_dist": False, "cmap_name": "jet", "drange": (0, 10) }], 'transforms': [] }], 'transforms': [] } assert edict.diff(dct, expected_dct, np_allclose=True) == {}
def test_format_maximal(): file_obj = utils.MockPath('config.yml', is_file=True, content=example_file_maximal) output = format_config_yaml(file_obj) # handy for updating # import json # print(json.dumps(output, indent=4)) assert edict.diff(output, expected_output_maximal) == {}
def test_opt_scflog_merge(): plugins.load_plugin_classes([CrystalOutputPlugin, CrystalSCFLogPlugin], "parsers") opt = plugins.parse(os.path.join(file_folder, "scf_and_opt.crystal.out")) scflog = plugins.parse( os.path.join(file_folder, "scf_and_opt.crystal.scflog")) opt_all = edict.merge([opt, scflog], list_of_dicts=True) # with open(os.path.join(file_folder, "opt_merge_scflog.crystal.out.json"), "w") as f: # json.dump(opt_all, f, indent=1, default=plugins.encode) expected = ejson.to_dict( os.path.join(file_folder, "opt_merge_scflog.crystal.out.json")) assert edict.diff(opt_all, expected, np_allclose=True) == {}
def test_plugins(testplugin, filename): plugins.unload_all_plugins() plugins.load_plugin_classes([Encode_NDArray]) plugins.load_plugin_classes([testplugin], "parsers") inpath = os.path.join(file_folder, filename) output = plugins.parse(inpath) # print(json.dumps(output, indent=2, default=plugins.encode)) outpath = os.path.join(file_folder, filename + ".json") # if ".crystal.out" in filename: # with open(outpath, "w") as f: # json.dump(output, f, indent=1, default=plugins.encode) print("reading expected") expected = ejson.to_dict(outpath) assert edict.diff(output, expected, np_allclose=True, atol=1e-5) == {}
def test_color_by_cna(): atoms = bulk("Fe") dct = atoms_to_dict(atoms, "Iron") new_dct = color_by_cna(dct, color_outline=True) expected = {'elements': [ {'type': 'repeat_cell', 'name': 'Iron', 'centre': [0.7175, 0.7175, 0.7175], 'cell_vectors': {'a': [-1.435, 1.435, 1.435], 'b': [1.435, -1.435, 1.435], 'c': [1.435, 1.435, -1.435]}, "color_bbox": "black", 'sites': [ {'ccoord': [0.0, 0.0, 0.0], 'label': 'Fe, BCC', 'anum': 26, 'color_fill': 'green', 'color_outline': 'green', 'radius': 1.32, 'transparency': 1, 'cell': [0, 0, 0]}], 'transforms': []}], 'transforms': []} assert edict.diff(new_dct, expected, np_allclose=True) == {}
def ejdict_to_gcube(data, fpath=None, density=0, include_atoms=True, adata=None, cell_tol=1E-3): """ Parameters ---------- data: dict fpath: str or None output file path or, if None, write to MockPath density: int take density from data["densities"][density] include_atoms: bool include atoms in gaussian cube adata: dict or None separate atom data (for instance for Crystal output) cell_tol: float or None if not None, raise and error if the data and adata cell vectors are not within this tolerance Returns ------- fpath: pathlib.Path or jsonextended.mockpath.MockPath """ if include_atoms and adata is not None: if cell_tol: cdiff = edict.diff(data["cell_vectors"], adata["cell_vectors"], np_allclose=True, rtol=cell_tol, atol=cell_tol) if cdiff: raise ValueError( "data and adata have different cell vectors: {}".format( cdiff)) data["atoms"] = adata["atoms"] validate_against_schema(data, "edensity") if fpath is None: fpath = mockpath.MockPath("test.cube", is_file=True) else: fpath = pathlib.Path(fpath) with fpath.open("w") as f: data = units.combine_quantities(data) data = units.apply_unitschema(data, { "a": "angstrom", "b": "angstrom", "c": "angstrom", "ccoords": "angstrom" }, as_quantity=False) natoms = 0 if "atoms" not in data or not include_atoms else len( data["atoms"]["ccoords"]) avec = np.asarray( data["cell_vectors"]["a"]) / codata[("Bohr", "Angstrom")] bvec = np.asarray( data["cell_vectors"]["b"]) / codata[("Bohr", "Angstrom")] cvec = np.asarray( data["cell_vectors"]["c"]) / codata[("Bohr", "Angstrom")] centre = 0.5 * (avec + bvec + cvec) centre_offset = -1 * centre f.write(data["title"] + "\n") f.write(data["densities"][density]["type"] + "\n") dense = np.asarray(data["densities"][density]["magnitude"]) na, nb, nc = dense.shape f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format( natoms, *centre_offset.tolist())) f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format( na, *(avec / na).tolist())) f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format( nb, *(bvec / nb).tolist())) f.write("{0:6d} {1:10.6f} {2:10.6f} {3:10.6f}\n".format( nc, *(cvec / nc).tolist())) if data.get("atoms", False): for i, c in enumerate(data["atoms"]["ccoords"]): atomic_number = data["atoms"]["atomic_number"][i] nuclear_charge = data["atoms"]["nuclear_charge"][i] ccoord = (np.array(c) / codata[("Bohr", "Angstrom")]) + centre_offset f.write( "{0:6d} {1:10.6f} {2:10.6f} {3:10.6f} {4:10.6f}\n".format( atomic_number, nuclear_charge, *ccoord.tolist())) dense = dense.flatten().tolist() dlength = len(dense) output = [] for i in range(int(dlength / 6.) + 1): if dlength > i * 6 + 6: output.append( "{0:12.5E} {1:12.5E} {2:12.5E} {3:12.5E} {4:12.5E} {5:12.5E}" .format(*dense[i * 6:i * 6 + 6])) else: output.append(" ".join( ["{0:12.5E}".format(v) for v in dense[i * 6:dlength]])) f.write("\n".join(output)) return fpath
def test_full_run(new_database_with_daemon, new_workdir): """Test running a calculation""" from aiida.orm.data.singlefile import SinglefileData from aiida.common.datastructures import calc_states # get code code = get_basic_code(new_workdir, configure=True) # Prepare input parameters infile = SinglefileData( file=os.path.join(TEST_DIR, "input_files", 'mgo_sto3g_scf.crystal.d12')) # set up calculation calc = code.new_calc() inputs_dict = { "input_file": infile, "code": code, "options": { "resources": { "num_machines": 1, "num_mpiprocs_per_machine": 1 }, "withmpi": False, "max_wallclock_seconds": 30 } } # , "_use_cache": Bool(False)} process = calc.process() calcnode = run_get_node(process, inputs_dict) print(calcnode) assert '_aiida_cached_from' not in calcnode.extras() assert calcnode.get_state() == calc_states.FINISHED assert set(calcnode.get_outputs_dict().keys()).issuperset([ 'output_structure', 'output_parameters', 'output_settings', 'retrieved' ]) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'parser_class': 'CryBasicParser', 'parser_warnings': ["no initial structure available, creating new kinds for atoms"], 'errors': [], 'warnings': [], 'energy': -2.7121814374931E+02 * 27.21138602, 'energy_units': 'eV', # hartree to eV 'calculation_type': 'restricted closed shell', 'calculation_spin': False, # 'wall_time_seconds': # 3, 'number_of_atoms': 2, 'number_of_assymetric': 2, 'scf_iterations': 7, 'volume': 18.65461527264623, } outputs = calcnode.get_outputs_dict()['output_parameters'].get_dict() # remove wall time, because it is run dependent outputs.pop('wall_time_seconds', None) assert edict.diff( outputs, expected_params, np_allclose=True) == {}
def test_parser_opt(new_database, new_workdir): """ Test the parser """ from aiida.parsers import ParserFactory from aiida.common.datastructures import calc_states from aiida.common.folders import SandboxFolder from aiida.orm import DataFactory code = get_basic_code(new_workdir) calc = code.new_calc() calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1}) calc.store_all() calc._set_state(calc_states.PARSING) parser_cls = ParserFactory("crystal17.basic") parser = parser_cls(calc) with SandboxFolder() as folder: main_out_path = os.path.join( os.path.dirname(tests.__file__), "output_files", "mgo_sto3g_opt.crystal.out") with open(main_out_path) as f: folder.create_file_from_filelike(f, "main.out") fdata = DataFactory("folder")() fdata.replace_with_folder(folder.abspath) mock_retrieved = {calc._get_linkname_retrieved(): fdata} success, node_list = parser.parse_with_retrieved(mock_retrieved) assert success node_dict = dict(node_list) assert set(['output_parameters', 'output_settings', 'output_structure']) == set(node_dict.keys()) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'parser_class': 'CryBasicParser', 'parser_warnings': ["no initial structure available, creating new kinds for atoms"], 'errors': [], 'warnings': ['WARNING **** INT_SCREEN **** CELL PARAMETERS OPTIMIZATION ONLY'], 'energy': -2.712596206888E+02 * 27.21138602, 'energy_units': 'eV', # hartree to eV 'calculation_type': 'restricted closed shell', 'calculation_spin': False, # 'wall_time_seconds': # 102, 'number_of_atoms': 2, 'number_of_assymetric': 2, 'scf_iterations': 8, 'opt_iterations': 6, 'volume': 14.652065094424696, } out_params_dict = node_dict['output_parameters'].get_dict() out_params_dict.pop('wall_time_seconds', None) assert edict.diff( out_params_dict, expected_params, np_allclose=True) == {} expected_struct_attrs = { 'cell': [[0.0, 1.94218061274, 1.94218061274], [1.94218061274, 0.0, 1.94218061274], [1.94218061274, 1.94218061274, 0.0]], 'kinds': [{'mass': 24.305, 'name': 'Mg', 'symbols': [u'Mg'], 'weights': [1.0]}, {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}], 'pbc1': True, 'pbc2': True, 'pbc3': True, 'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]}, {'kind_name': 'O', 'position': [1.94218061274, 1.94218061274, 1.94218061274]}] } assert edict.diff( dict(node_dict['output_structure'].get_attrs()), expected_struct_attrs, np_allclose=True) == {}
def test_parser_with_init_struct(new_database, new_workdir): """ Test the parser """ from aiida.parsers import ParserFactory from aiida.common.datastructures import calc_states from aiida.common.folders import SandboxFolder from aiida.orm import DataFactory code = get_main_code(new_workdir) calc = code.new_calc() calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1}) from aiida.orm.data.structure import StructureData struct = StructureData() struct.append_atom(position=[0, 0, 0], symbols="Mg", name="Mgx") struct.append_atom(position=[0.5, 0.5, 0.5], symbols="O", name="Ox") calc.use_structure(struct) calc.store_all() calc._set_state(calc_states.PARSING) parser_cls = ParserFactory("crystal17.basic") parser = parser_cls(calc) with SandboxFolder() as folder: main_out_path = os.path.join(os.path.dirname(tests.__file__), "output_files", "mgo_sto3g_scf.crystal.out") with open(main_out_path) as f: folder.create_file_from_filelike(f, "main.out") fdata = DataFactory("folder")() fdata.replace_with_folder(folder.abspath) mock_retrieved = {calc._get_linkname_retrieved(): fdata} success, node_list = parser.parse_with_retrieved(mock_retrieved) assert success node_dict = dict(node_list) assert set(['output_parameters', 'output_settings']) == set(node_dict.keys()) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'parser_class': 'CryBasicParser', 'parser_warnings': [], 'errors': [], 'warnings': [], 'energy': -2.7121814374931E+02 * 27.21138602, 'energy_units': 'eV', # hartree to eV 'calculation_type': 'restricted closed shell', 'calculation_spin': False, 'wall_time_seconds': 3, 'number_of_atoms': 2, 'number_of_assymetric': 2, 'scf_iterations': 7, 'volume': 18.65461527264623, } assert edict.diff(node_dict['output_parameters'].get_dict(), expected_params, np_allclose=True) == {}
def test_basic(): """ $a=1$ {#a b=$2$} ![a](a/b.jpg){b .x a=$1$ b=2} """ in_json = { "meta": {}, "pandoc-api-version": [1, 17, 5, 1], "blocks": [{ "t": "Para", "c": [{ "t": "Math", "c": [{ "t": "InlineMath" }, "a=1"] }, { "t": "Space" }, { "t": "Str", "c": "{#a" }, { "t": "Space" }, { "t": "Str", "c": ".a" }, { "t": "Space" }, { "t": "Str", "c": "b=" }, { "t": "Math", "c": [{ "t": "InlineMath" }, "2"] }, { "t": "Str", "c": "}" }] }, { "t": "Para", "c": [{ "t": "Image", "c": [["b", ["x"], [["a", "$1$"], ["b", "2"]]], [{ "t": "Str", "c": "a" }], ["a/b.jpg", "fig:"]] }] }] } out_json = apply_to_json(in_json, main) assert edict.diff( out_json, { "pandoc-api-version": [1, 17, 5, 1], "meta": { "$$references": { "t": "MetaMap", "c": { "a": { "t": "MetaMap", "c": { "type": { "t": "MetaString", "c": "Math" }, "number": { "t": "MetaString", "c": "1" } } }, "b": { "t": "MetaMap", "c": { "type": { "t": "MetaString", "c": "Image" }, "number": { "t": "MetaString", "c": "1" } } } } } }, "blocks": [{ "t": "Para", "c": [{ "t": "Span", "c": [["a", ["labelled-Math", "a"], [["b", "2"]]], [{ "t": "Math", "c": [{ "t": "InlineMath" }, "a=1"] }]] }] }, { "t": "Para", "c": [{ "t": "Image", "c": [["b", ["x"], [["a", "$1$"], ["b", "2"]]], [{ "t": "Str", "c": "a" }], ["a/b.jpg", "fig:"]] }] }] }) == {}
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_bonds(): atoms = bulk("NaCl", "rocksalt", 5.64) dct = atoms_to_dict(atoms, "NaCl") print() # print(dct) expected_dct = { 'elements': [{ 'type': 'repeat_cell', 'name': 'NaCl', 'centre': [2.82, 2.82, 2.82], 'color_bbox': 'black', 'cell_vectors': { 'a': [0.0, 2.82, 2.82], 'b': [2.82, 0.0, 2.82], 'c': [2.82, 2.82, 0.0] }, 'sites': [{ 'label': 'Na', 'ccoord': [0.0, 0.0, 0.0], 'cell': [0, 0, 0], 'radius': 1.66, 'color_fill': '#ab5cf2', 'color_outline': None, 'transparency': 1, 'anum': 11 }, { 'label': 'Cl', 'ccoord': [2.82, 0.0, 0.0], 'cell': [0, 0, 0], 'radius': 1.02, 'color_fill': '#1ff01f', 'color_outline': None, 'transparency': 1, 'anum': 17 }], 'bonds': [], 'transforms': [] }], 'transforms': [] } dct['elements'][0]['bonds'] = [ { "label": "Na", "coord_label": "Cl", "radius": 1, "max_dist": 4, "include_periodic": False, "color_by_dist": False, "cmap_name": "jet", "drange": (0, 10) }, { "label": "Na", "coord_label": "Cl", "radius": 2, "max_dist": 4, "include_periodic": True, "color_by_dist": False, "cmap_name": "jet", "drange": (0, 10) }, { "label": "Na", "coord_label": "Na", "radius": 3, "max_dist": 4, "include_periodic": False, "color_by_dist": False, "cmap_name": "jet", "drange": (0, 10) }, { "label": "Na", "coord_label": "Na", "radius": 4, "max_dist": 4, "include_periodic": True, "color_by_dist": False, "cmap_name": "jet", "drange": (0, 10) }, ] bonds = compute_bonds(dct) # edict.pprint(dict(enumerate(bonds))) #print(bonds) expected_bonds = [ [[0.0, 0.0, 0.0], [2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 1], [[0.0, 0.0, 0.0], [0.0, 2.82, 0.0], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [0.0, -2.82, 0.0], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [0.0, 0.0, 2.82], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [-2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [2.82, 0.0, 0.0], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [0.0, 0.0, -2.82], '#ab5cf2', '#1ff01f', 2], [[0.0, 0.0, 0.0], [0.0, 2.82, -2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [-2.82, 2.82, 0.0], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [2.82, 2.82, 0.0], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [0.0, -2.82, 2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [-2.82, 0.0, -2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [0.0, 2.82, 2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [-2.82, -2.82, 0.0], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [-2.82, 0.0, 2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [0.0, -2.82, -2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [2.82, 0.0, -2.82], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [2.82, -2.82, 0.0], '#ab5cf2', '#ab5cf2', 4], [[0.0, 0.0, 0.0], [2.82, 0.0, 2.82], '#ab5cf2', '#ab5cf2', 4] ] assert edict.diff(bonds, expected_bonds, np_allclose=True) == {}
def test_full_run_nio_afm_opt(new_database_with_daemon, new_workdir): """Test running a calculation""" """Test submitting a calculation""" from aiida.orm import DataFactory from aiida.common.datastructures import calc_states StructureData = DataFactory('structure') from aiida_crystal17.data.basis_set import get_basissets_from_structure from aiida_crystal17.data.basis_set import BasisSetData upload_basisset_family = BasisSetData.upload_basisset_family # get code code = get_main_code(new_workdir, configure=True) # Prepare input parameters params = { "title": "NiO Bulk with AFM spin", "geometry.optimise.type": "FULLOPTG", "scf.single": "UHF", "scf.k_points": (8, 8), "scf.spinlock.SPINLOCK": (0, 15), "scf.numerical.FMIXING": 30, "scf.post_scf": ["PPAN"] } # Ni0 atoms = crystal(symbols=[28, 8], basis=[[0, 0, 0], [0.5, 0.5, 0.5]], spacegroup=225, cellpar=[4.164, 4.164, 4.164, 90, 90, 90]) atoms.set_tags([1, 1, 2, 2, 0, 0, 0, 0]) instruct = StructureData(ase=atoms) settings = {"kinds.spin_alpha": ["Ni1"], "kinds.spin_beta": ["Ni2"]} from aiida_crystal17.workflows.symmetrise_3d_struct import ( run_symmetrise_3d_structure) instruct, settings = run_symmetrise_3d_structure(instruct, settings) upload_basisset_family(os.path.join(TEST_DIR, "input_files", "sto3g"), "sto3g", "minimal basis sets", stop_if_existing=True, extension=".basis") # basis_map = BasisSetData.get_basis_group_map("sto3g") # set up calculation calc = code.new_calc() params = calc.prepare_and_validate(params, instruct, settings, "sto3g", True) # set up calculation calc = code.new_calc() inputs_dict = { "parameters": params, "structure": instruct, "settings": settings, "basisset": get_basissets_from_structure(instruct, "sto3g", by_kind=False), "code": code, "options": { "resources": { "num_machines": 1, "num_mpiprocs_per_machine": 1 }, "withmpi": False, "max_wallclock_seconds": 30 } } process = calc.process() calcnode = run_get_node(process, inputs_dict) print(calcnode) print(get_calc_log(calcnode)) assert '_aiida_cached_from' not in calcnode.extras() try: print(calcnode.out.output_parameters.get_dict()) except AttributeError: pass assert calcnode.get_state() == calc_states.FINISHED assert set(calcnode.get_outputs_dict().keys()).issuperset( ['output_structure', 'output_parameters', 'retrieved']) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'parser_class': 'CryBasicParser', 'parser_warnings': [], 'errors': [], 'warnings': ['WARNING **** INT_SCREEN **** CELL PARAMETERS OPTIMIZATION ONLY'], 'calculation_type': 'unrestricted open shell', 'calculation_spin': True, 'wall_time_seconds': 3018, 'scf_iterations': 16, 'opt_iterations': 19, 'number_of_atoms': 4, 'number_of_assymetric': 4, 'volume': 42.4924120856802, 'energy': -85125.8766752194, 'energy_units': 'eV', 'mulliken_charges': [0.363, 0.363, -0.363, -0.363], 'mulliken_electrons': [27.637, 27.637, 8.363, 8.363], 'mulliken_spin_total': 0.0, 'mulliken_spins': [3.234, -3.234, -0.172, 0.172] } assert edict.diff( calcnode.get_outputs_dict()['output_parameters'].get_dict(), expected_params, np_allclose=True) == {} expected_struct_attrs = { 'cell': [[0.0, -2.17339440672, -2.17339440672], [0.0, -2.17339440672, 2.17339440672], [-4.49784306967, 0.0, 0.0]], 'kinds': [{ 'mass': 58.6934, 'name': 'Ni1', 'symbols': ['Ni'], 'weights': [1.0] }, { 'mass': 58.6934, 'name': 'Ni2', 'symbols': ['Ni'], 'weights': [1.0] }, { 'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0] }], 'pbc1': True, 'pbc2': True, 'pbc3': True, 'sites': [{ 'kind_name': 'Ni1', 'position': [0.0, -2.17339440672, -2.17339440672] }, { 'kind_name': 'Ni2', 'position': [-2.248921534835, -2.17339440672, 0.0] }, { 'kind_name': 'O', 'position': [-2.248921534835, -2.17339440672, -2.17339440672] }, { 'kind_name': 'O', 'position': [0.0, -2.17339440672, 0.0] }] } assert edict.diff(dict(calcnode.out.output_structure.get_attrs()), expected_struct_attrs, np_allclose=True, atol=1e-3) == {}
def test_full_run_nio_afm(new_database_with_daemon, new_workdir): """Test running a calculation""" """Test submitting a calculation""" from aiida.orm import DataFactory from aiida.common.datastructures import calc_states StructureData = DataFactory('structure') from aiida_crystal17.data.basis_set import get_basissets_from_structure from aiida_crystal17.data.basis_set import BasisSetData upload_basisset_family = BasisSetData.upload_basisset_family # get code code = get_main_code(new_workdir, configure=True) # Prepare input parameters params = { "title": "NiO Bulk with AFM spin", "scf.single": "UHF", "scf.k_points": (8, 8), "scf.spinlock.SPINLOCK": (0, 15), "scf.numerical.FMIXING": 30, "scf.post_scf": ["PPAN"] } # Ni0 atoms = crystal(symbols=[28, 8], basis=[[0, 0, 0], [0.5, 0.5, 0.5]], spacegroup=225, cellpar=[4.164, 4.164, 4.164, 90, 90, 90]) atoms.set_tags([1, 1, 2, 2, 0, 0, 0, 0]) instruct = StructureData(ase=atoms) settings = {"kinds.spin_alpha": ["Ni1"], "kinds.spin_beta": ["Ni2"]} from aiida_crystal17.workflows.symmetrise_3d_struct import run_symmetrise_3d_structure instruct, settings = run_symmetrise_3d_structure(instruct, settings) upload_basisset_family(os.path.join(TEST_DIR, "input_files", "sto3g"), "sto3g", "minimal basis sets", stop_if_existing=True, extension=".basis") # basis_map = BasisSetData.get_basis_group_map("sto3g") # set up calculation calc = code.new_calc() params = calc.prepare_and_validate(params, instruct, settings, "sto3g", True) # set up calculation calc = code.new_calc() inputs_dict = { "parameters": params, "structure": instruct, "settings": settings, "basisset": get_basissets_from_structure(instruct, "sto3g", by_kind=False), "code": code, "options": { "resources": { "num_machines": 1, "num_mpiprocs_per_machine": 1 }, "withmpi": False, "max_wallclock_seconds": 30 } } process = calc.process() calcnode = run_get_node(process, inputs_dict) print(calcnode) assert '_aiida_cached_from' not in calcnode.extras() try: print(calcnode.out.output_parameters.get_dict()) except AttributeError: pass assert calcnode.get_state() == calc_states.FINISHED assert set(calcnode.get_outputs_dict().keys()).issuperset( ['output_parameters', 'retrieved']) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'number_of_atoms': 4, 'errors': [], 'warnings': [], 'energy': -85124.8936673389, 'number_of_assymetric': 4, 'volume': 36.099581472, 'scf_iterations': 13, 'energy_units': 'eV', 'calculation_type': 'unrestricted open shell', 'parser_warnings': [], 'wall_time_seconds': 187, 'parser_class': 'CryBasicParser', 'calculation_spin': True, 'mulliken_spin_total': 0.0, 'mulliken_spins': [3.057, -3.057, -0.072, 0.072], 'mulliken_electrons': [27.602, 27.603, 8.398, 8.397], 'mulliken_charges': [0.398, 0.396999999999998, -0.398, -0.397] } assert edict.diff( calcnode.get_outputs_dict()['output_parameters'].get_dict(), expected_params, np_allclose=True) == {}
def test_full_mgo_opt(db_test_app, data_regression): code = db_test_app.get_or_create_code("crystal17.main") with SandboxFolder() as folder: with open_resource_binary("crystal", "mgo_sto3g_opt", "INPUT") as handle: folder.create_file_from_filelike(handle, "INPUT", mode="wb") with open_resource_binary("crystal", "mgo_sto3g_opt", "main.out") as handle: folder.create_file_from_filelike(handle, "main.out", mode="wb") remote = RemoteData( remote_path=folder.abspath, computer=db_test_app.get_or_create_computer() ) builder = populate_builder(remote, code=code, metadata=get_default_metadata()) node = immigrate_existing(builder, remote) attributes = node.attributes attributes["remote_workdir"] = "path/to/remote" attributes["version"] = None data_regression.check(attributes) assert set(node.inputs) == set( ["basissets__Mg", "basissets__O", "parameters", "structure", "symmetry", "code"] ) assert set(node.outputs) == set( ["results", "retrieved", "structure", "remote_folder"] ) expected_instruct_attrs = { "cell": [[0.0, 2.105, 2.105], [2.105, 0.0, 2.105], [2.105, 2.105, 0.0]], "kinds": [ {"mass": 24.305, "name": "Mg", "symbols": ["Mg"], "weights": [1.0]}, {"mass": 15.9994, "name": "O", "symbols": ["O"], "weights": [1.0]}, ], "pbc1": True, "pbc2": True, "pbc3": True, "sites": [ {"kind_name": "Mg", "position": [0.0, 0.0, 0.0]}, {"kind_name": "O", "position": [2.105, 2.105, 2.105]}, ], } assert ( edict.diff( dict(node.inputs.structure.attributes), expected_instruct_attrs, np_allclose=True, atol=1e-3, ) == {} ) expected_outstruct_attrs = { "cell": [ [0.0, 1.94218061274, 1.94218061274], [1.94218061274, 0.0, 1.94218061274], [1.94218061274, 1.94218061274, 0.0], ], "kinds": [ {"mass": 24.305, "name": "Mg", "symbols": ["Mg"], "weights": [1.0]}, {"mass": 15.9994, "name": "O", "symbols": ["O"], "weights": [1.0]}, ], "pbc1": True, "pbc2": True, "pbc3": True, "sites": [ {"kind_name": "Mg", "position": [0.0, 0.0, 0.0]}, { "kind_name": "O", "position": [1.94218061274, 1.94218061274, 1.94218061274], }, ], } assert ( edict.diff( dict(node.outputs.structure.attributes), expected_outstruct_attrs, np_allclose=True, atol=1e-3, ) == {} )
def read_cell(lines, start_line): """ Read unit cell parameters from the PWSCF output file Parameters ---------- lines: list Returns ------- cell: dict """ alat = None cell = {} # TODO you can get a section after the optimisation ("Begin final coordinates") but then a final scf calculation # followed by a recalculated final unit cell (see ejplugins/test_files/qe_vc_relax_with_multiple_final_coords.out) final_coords = False # additional unit cell information # bli_lines = [line for line in lines if 'bravais-lattice index' in line] # brav_latt_indices = [int(line.split('=')[1].strip()) for line in bli_lines] for i, line in enumerate(lines): line = line.strip() if 'lattice parameter (alat)' in line: if "a.u." not in line: raise_error("expecting alat in a.u.", line, i, start_line) if alat is not None and not final_coords: raise_error("found multiple alat values", line, i, start_line) alat = split_numbers(line)[0] * codata[("Bohr", "Angstrom")] # initial and final if 'crystal axes: (cart. coord. in units of alat)' in line: if cell and not final_coords: raise_error("found multiple cell coordinates", line, i, start_line) if not alat: raise_error("expecting to have found alat before", line, i, start_line) for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]): x, y, z = split_numbers(newline.split('=')[1]) cell[key] = { "units": "angstrom", "magnitude": (x * alat, y * alat, z * alat) } if "Begin final coordinates" in line: final_coords = True # optimisation step if fnmatch(line, "CELL_PARAMETERS*(*alat*=*)"): alat = split_numbers(line)[0] * codata[("Bohr", "Angstrom")] if cell and final_coords: # there can be a 'Begin/End final coordinates' in the final opt step new_cell = {} for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]): x, y, z = split_numbers(newline) new_cell[key] = { "units": "angstrom", "magnitude": (x * alat, y * alat, z * alat) } if edict.diff(cell, new_cell, np_allclose=True): raise_error( "normal and final cell coordinates are different", line, i, start_line) elif cell: raise_error("found multiple cell coordinates", line, i, start_line) else: for key, newline in zip(["a", "b", "c"], lines[i + 1:i + 4]): x, y, z = split_numbers(newline) cell[key] = { "units": "angstrom", "magnitude": (x * alat, y * alat, z * alat) } return cell if cell else None
def test_multiple_on_line(): """" $a=1$ {#a b=$2$} $g=3$ {#gid} ![a](a/b.jpg) """ in_json = { "pandoc-api-version": [1, 17, 5, 1], "meta": {}, "blocks": [{ "t": "Para", "c": [{ "t": "Math", "c": [{ "t": "InlineMath" }, "a=1"] }, { "t": "Space" }, { "t": "Str", "c": "{#a" }, { "t": "Space" }, { "t": "Str", "c": "b=" }, { "t": "Math", "c": [{ "t": "InlineMath" }, "2"] }, { "t": "Str", "c": "}" }, { "t": "Space" }, { "t": "Math", "c": [{ "t": "InlineMath" }, "g=3"] }, { "t": "Space" }, { "t": "Str", "c": "{#gid}" }] }, { "t": "Para", "c": [{ "t": "Image", "c": [["", [], []], [{ "t": "Str", "c": "a" }], ["a/b.jpg", "fig:"]] }] }] } out_json = apply_to_json(in_json, main) assert edict.diff( out_json, { "pandoc-api-version": [1, 17, 5, 1], "meta": { "$$references": { "t": "MetaMap", "c": { "a": { "t": "MetaMap", "c": { "type": { "t": "MetaString", "c": "Math" }, "number": { "t": "MetaString", "c": "1" } } }, "gid": { "t": "MetaMap", "c": { "type": { "t": "MetaString", "c": "Math" }, "number": { "t": "MetaString", "c": "2" } } } } } }, "blocks": [{ "t": "Para", "c": [{ "t": "Span", "c": [["a", ["labelled-Math"], [["b", "2"]]], [{ "t": "Math", "c": [{ "t": "InlineMath" }, "a=1"] }]] }, { "t": "Space" }, { "t": "Span", "c": [["gid", ["labelled-Math"], []], [{ "t": "Math", "c": [{ "t": "InlineMath" }, "g=3"] }]] }] }, { "t": "Para", "c": [{ "t": "Image", "c": [["", [], []], [{ "t": "Str", "c": "a" }], ["a/b.jpg", "fig:"]] }] }] }) == {}
def test_parser_external(new_database, new_workdir): """ Test the parser """ from aiida.parsers import ParserFactory from aiida.common.datastructures import calc_states from aiida.common.folders import SandboxFolder from aiida.orm import DataFactory code = get_basic_code(new_workdir) calc = code.new_calc() calc.set_resources({"num_machines": 1, "num_mpiprocs_per_machine": 1}) calc.store_all() calc._set_state(calc_states.PARSING) parser_cls = ParserFactory("crystal17.basic") parser = parser_cls(calc) with SandboxFolder() as folder: main_out_path = os.path.join( os.path.dirname(tests.__file__), "output_files", "mgo_sto3g_external.crystal.out") with open(main_out_path) as f: folder.create_file_from_filelike(f, "main.out") fdata = DataFactory("folder")() fdata.replace_with_folder(folder.abspath) mock_retrieved = {calc._get_linkname_retrieved(): fdata} success, node_list = parser.parse_with_retrieved(mock_retrieved) assert success node_dict = dict(node_list) assert set(['output_parameters', 'output_settings', 'output_structure']) == set(node_dict.keys()) expected_params = { 'parser_version': str(aiida_crystal17.__version__), 'ejplugins_version': str(ejplugins.__version__), 'parser_class': 'CryBasicParser', 'parser_warnings': ["no initial structure available, creating new kinds for atoms"], 'errors': [], 'warnings': [], 'energy': -2.7121814374931E+02 * 27.21138602, 'energy_units': 'eV', # hartree to eV 'calculation_type': 'restricted closed shell', 'calculation_spin': False, # 'wall_time_seconds': # 3, 'number_of_atoms': 2, 'number_of_assymetric': 2, 'scf_iterations': 7, 'volume': 18.65461527264623, 'mulliken_charges': [0.777, -0.777], 'mulliken_electrons': [11.223, 8.777], } out_params_dict = node_dict['output_parameters'].get_dict() out_params_dict.pop('wall_time_seconds', None) assert edict.diff( out_params_dict, expected_params, np_allclose=True) == {} # read from nio_sto3g_afm.crystal.out expected_operations = [[ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ], [0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [ -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0 ], [1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], [ -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [ 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ], [-1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], [ 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0 ], [-1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0 ], [1.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, -1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 ], [1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [ 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0 ], [-1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0], [ -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0 ], [0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [ 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, -1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, -1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 ], [-1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0], [ 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, -1.0, 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], [ 0.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0 ], [1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0], [ 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ], [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 ], [-1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0 ], [-1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0], [ 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 ], [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0], [ -1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 ], [1.0, 0.0, 0.0, -1.0, -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0]] print(node_dict['output_settings'].data.operations) assert node_dict['output_settings'].compare_operations( expected_operations) == {} expected_struct_attrs = { 'cell': [[0.0, 2.105, 2.105], [2.105, 0.0, 2.105], [2.105, 2.105, 0.0]], 'kinds': [ {'mass': 24.305, 'name': 'Mg', 'symbols': ['Mg'], 'weights': [1.0]}, {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}], 'pbc1': True, 'pbc2': True, 'pbc3': True, 'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]}, {'kind_name': 'O', 'position': [2.105, 2.105, 2.105]}] } assert edict.diff( dict(node_dict['output_structure'].get_attrs()), expected_struct_attrs, np_allclose=True) == {}
def test_with_tables(): """ Some text a b c - - - 1 2 3 4 5 6 Table: Caption. {#tbl:id} """ in_json = { "pandoc-api-version": [1, 17, 5, 1], "meta": {}, "blocks": [{ "t": "Para", "c": [{ "t": "Str", "c": "Some" }, { "t": "Space" }, { "t": "Str", "c": "text" }] }, { "t": "Table", "c": [[{ "t": "Str", "c": "Caption." }, { "t": "Space" }, { "t": "Str", "c": "{#tbl:id}" }], [{ "t": "AlignDefault" }, { "t": "AlignDefault" }, { "t": "AlignDefault" }], [0, 0, 0], [[{ "t": "Plain", "c": [{ "t": "Str", "c": "a" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "b" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "c" }] }]], [[[{ "t": "Plain", "c": [{ "t": "Str", "c": "1" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "2" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "3" }] }]], [[{ "t": "Plain", "c": [{ "t": "Str", "c": "4" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "5" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "6" }] }]]]] }], } out_json = apply_to_json(in_json, main) assert edict.diff( out_json, { "pandoc-api-version": [1, 17, 5, 1], "meta": { "$$references": { "t": "MetaMap", "c": { "tbl:id": { "t": "MetaMap", "c": { "type": { "t": "MetaString", "c": "Table" }, "number": { "t": "MetaString", "c": "1" } } } } } }, "blocks": [{ "t": "Para", "c": [{ "t": "Str", "c": "Some" }, { "t": "Space" }, { "t": "Str", "c": "text" }] }, { "t": "Div", "c": [["tbl:id", ["labelled-Table"], []], [{ "t": "Table", "c": [[{ "t": "Str", "c": "Caption." }, { "t": "Space" }], [{ "t": "AlignDefault" }, { "t": "AlignDefault" }, { "t": "AlignDefault" }], [0, 0, 0], [[{ "t": "Plain", "c": [{ "t": "Str", "c": "a" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "b" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "c" }] }]], [[[{ "t": "Plain", "c": [{ "t": "Str", "c": "1" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "2" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "3" }] }]], [[{ "t": "Plain", "c": [{ "t": "Str", "c": "4" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "5" }] }], [{ "t": "Plain", "c": [{ "t": "Str", "c": "6" }] }]]]] }]] }] }) == {}
def test_full_mgo_opt(new_database): from aiida.orm import DataFactory from aiida_crystal17.workflows.cry_main_immigrant import migrate_as_main # from aiida.common.datastructures import calc_states work_dir = TEST_DIR inpath = os.path.join("input_files", 'mgo_sto3g_opt.crystal.d12') outpath = os.path.join("output_files", 'mgo_sto3g_opt.crystal.out') node = migrate_as_main( work_dir, inpath, outpath, input_links={ 'structure': { "struct_setup": DataFactory('parameter')() } }) print(list(node.attrs())) assert node.is_stored assert set(node.get_inputs_dict().keys()) == set( ['basis_Mg', 'basis_O', 'parameters', 'structure', 'settings']) struct = node.inp.structure assert "struct_setup" in struct.get_inputs_dict()[ 'structure'].get_inputs_dict() # print(node.get_outputs_dict()) assert set(node.get_outputs_dict().keys()).issuperset( ['output_parameters', 'output_structure', 'retrieved']) assert '_aiida_cached_from' not in node.extras() # assert node.get_attr("state") == calc_states.FINISHED expected_instruct_attrs = { 'cell': [ [0.0, 2.105, 2.105], [2.105, 0.0, 2.105], [2.105, 2.105, 0.0]], 'kinds': [ {'mass': 24.305, 'name': 'Mg', 'symbols': ['Mg'], 'weights': [1.0]}, {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}], 'pbc1': True, 'pbc2': True, 'pbc3': True, 'sites': [{'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]}, {'kind_name': 'O', 'position': [2.105, 2.105, 2.105]}] } assert edict.diff( dict(node.inp.structure.get_attrs()), expected_instruct_attrs, np_allclose=True, atol=1e-3) == {} expected_outstruct_attrs = { 'cell': [ [0.0, 1.94218061274, 1.94218061274], [1.94218061274, 0.0, 1.94218061274], [1.94218061274, 1.94218061274, 0.0]], 'kinds': [ {'mass': 24.305, 'name': 'Mg', 'symbols': ['Mg'], 'weights': [1.0]}, {'mass': 15.9994, 'name': 'O', 'symbols': ['O'], 'weights': [1.0]}], 'pbc1': True, 'pbc2': True, 'pbc3': True, 'sites': [ {'kind_name': 'Mg', 'position': [0.0, 0.0, 0.0]}, {'kind_name': 'O', 'position': [1.94218061274, 1.94218061274, 1.94218061274]}] } assert edict.diff( dict(node.get_outputs_dict()['output_structure'].get_attrs()), expected_outstruct_attrs, np_allclose=True, atol=1e-3) == {}