def write_poscar(self, dst): # pylint: disable=unused-argument """ Write the POSCAR. Passes the structures node (StructureData) to the POSCAR parser for preparation and writes to dst. :param dst: absolute path of the file to write to """ settings = self.inputs.get('settings') settings = settings.get_dict() if settings else {} poscar_precision = settings.get('poscar_precision', 10) poscar_parser = PoscarParser(data=self._structure(), precision=poscar_precision) poscar_parser.write(dst)
def vasp_structure_poscar(vasp_structure): """Fixture: Well formed POSCAR contents.""" aiida_structure = vasp_structure if isinstance(vasp_structure, get_data_class('cif')): ase_structure = vasp_structure.get_ase() aiida_structure = get_data_node('structure', ase=ase_structure) writer = PoscarParser(data=aiida_structure) return writer
def test_parse_poscar_silly_write(fresh_aiida_env, vasp_structure, tmpdir): """ Parse (read, write) a reference POSCAR with silly elemental names. Using the PoscarParser and compare the result to a reference structure. """ parser = PoscarParser(data=vasp_structure) result = parser.get_quantity('poscar-structure', {}) names = result['poscar-structure'].get_site_kindnames() assert names == ['Hamburger', 'Pizza'] symbols = result['poscar-structure'].get_symbols_set() assert symbols == set(['As', 'In']) temp_file = str(tmpdir.join('POSCAR')) parser.write(temp_file) parser = PoscarParser(file_path=temp_file) result_reparse = parser.structure names = result_reparse.get_site_kindnames() assert names == ['Hamburger', 'Pizza'] symbols = result_reparse.get_symbols_set() assert symbols == set(['X', 'X'])
def test_relax_wc(fresh_aiida_env, vasp_params, potentials, mock_vasp): # def test_relax_wc(fresh_aiida_env, vasp_params, potentials, mock_vasp, mock_relax_wc): """Test submitting only, not correctness, with mocked vasp code.""" from aiida.orm import Code from aiida.plugins import WorkflowFactory from aiida.engine import run workchain = WorkflowFactory('vasp.relax') mock_vasp.store() create_authinfo(computer=mock_vasp.computer, store=True) structure = PoscarParser(file_path=data_path('test_relax_wc', 'inp', 'POSCAR')).structure kpoints = KpointsParser(file_path=data_path('test_relax_wc', 'inp', 'KPOINTS')).kpoints parameters = IncarParser(file_path=data_path('test_relax_wc', 'inp', 'INCAR')).incar parameters['system'] = 'test-case:test_relax_wc' parameters = {'incar': {k: v for k, v in parameters.items() if k not in ['isif', 'ibrion', 'nsw', 'ediffg']}} parameters['relax'] = {} parameters['relax']['perform'] = True parameters['relax']['algo'] = 'cg' parameters['relax']['force_cutoff'] = 0.01 inputs = AttributeDict() inputs.code = Code.get_from_string('mock-vasp@localhost') inputs.structure = structure inputs.kpoints = kpoints inputs.parameters = get_data_node('dict', dict=parameters) inputs.potential_family = get_data_node('str', POTCAR_FAMILY_NAME) inputs.potential_mapping = get_data_node('dict', dict=POTCAR_MAP) inputs.options = get_data_node('dict', dict={ 'withmpi': False, 'queue_name': 'None', 'max_wallclock_seconds': 1, 'import_sys_environment': True, 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, }) inputs.max_iterations = get_data_node('int', 1) inputs.clean_workdir = get_data_node('bool', False) inputs.verbose = get_data_node('bool', True) results, node = run.get_node(workchain, **inputs) assert node.exit_status == 0 assert 'relax' in results relax = results['relax'] assert 'structure' in relax sites = relax['structure'].sites assert sites[0].kind_name == 'Si' assert sites[1].kind_name == 'Si' np.testing.assert_allclose(sites[0].position, [4.8125, 4.8125, 4.8125]) np.testing.assert_allclose(sites[1].position, [0.6875, 0.6875, 0.715])
def mock_vasp(): """Verify input files are parseable and copy in output files.""" from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER # pylint: disable=import-outside-toplevel pwd = Path().absolute() aiida_path = Path(AIIDA_CONFIG_FOLDER) aiida_cfg = aiida_path / 'config.json' click.echo('DEBUG: AIIDA_PATH = {}'.format(os.environ.get('AIIDA_PATH'))) click.echo('DEBUG: AIIDA_CONFIG_FOLDER = {}'.format(str(aiida_path))) assert aiida_path.exists() assert aiida_cfg.is_file() click.echo(aiida_cfg.read_text()) incar = pwd / 'INCAR' assert incar.is_file(), 'INCAR input file was not found.' potcar = pwd / 'POTCAR' assert potcar.is_file(), 'POTCAR input file not found.' poscar = pwd / 'POSCAR' assert poscar.is_file(), 'POSCAR input file not found.' kpoints = pwd / 'KPOINTS' assert kpoints.is_file(), 'KPOINTS input file not found.' incar_parser = IncarParser(file_path=str(incar)) assert incar_parser, 'INCAR could not be parsed.' assert PotcarIo(path=str(potcar)), 'POTCAR could not be parsed.' assert PoscarParser(file_path=str(poscar)), 'POSCAR could not be parsed.' assert KpointsParser( file_path=str(kpoints)), 'KPOINTS could not be parsed.' system = incar_parser.incar.get('system', '') try: test_case = system.strip().split(':')[1].strip() except IndexError: test_case = '' if not test_case: shutil.copy(output_file('outcar', 'OUTCAR'), pwd / 'OUTCAR') shutil.copy(output_file('vasprun', 'vasprun.xml'), pwd / 'vasprun.xml') shutil.copy(output_file('chgcar', 'CHGCAR'), pwd / 'CHGCAR') shutil.copy(output_file('wavecar', 'WAVECAR'), pwd / 'WAVECAR') shutil.copy(output_file('eigenval', 'EIGENVAL'), pwd / 'EIGENVAL') shutil.copy(output_file('doscar', 'DOSCAR'), pwd / 'DOSCAR') shutil.copy(output_file('basic_run', 'vasp_output'), pwd / 'vasp_output') shutil.copy(poscar, pwd / 'CONTCAR') else: test_data_path = data_path(test_case, 'out') for out_file in Path(test_data_path).iterdir(): shutil.copy(out_file, pwd)
def mock_vasp(): """Verify input files are parseable and copy in output files.""" from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER # pylint: disable=import-outside-toplevel pwd = py_path.local('.') aiida_path = py_path.local(AIIDA_CONFIG_FOLDER) aiida_cfg = aiida_path.join('config.json') click.echo('DEBUG: AIIDA_PATH = {}'.format(os.environ.get('AIIDA_PATH'))) click.echo('DEBUG: AIIDA_CONFIG_FOLDER = {}'.format(aiida_path.strpath)) assert aiida_path.isdir() assert aiida_cfg.isfile() click.echo(aiida_cfg.read()) incar = pwd.join('INCAR') assert incar.isfile(), 'INCAR input file was not found.' potcar = pwd.join('POTCAR') assert potcar.isfile(), 'POTCAR input file not found.' poscar = pwd.join('POSCAR') assert poscar.isfile(), 'POSCAR input file not found.' kpoints = pwd.join('KPOINTS') assert kpoints.isfile(), 'KPOINTS input file not found.' incar_parser = IncarParser(file_path=incar.strpath) assert incar_parser, 'INCAR could not be parsed.' assert PotcarIo(path=potcar.strpath), 'POTCAR could not be parsed.' assert PoscarParser(file_path=poscar.strpath), 'POSCAR could not be parsed.' assert KpointsParser(file_path=kpoints.strpath), 'KPOINTS could not be parsed.' system = incar_parser.incar.get('system', '') try: test_case = system.strip().split(':')[1].strip() except IndexError: test_case = '' if not test_case: output_file('outcar', 'OUTCAR').copy(pwd.join('OUTCAR')) output_file('vasprun', 'vasprun.xml').copy(pwd.join('vasprun.xml')) output_file('chgcar', 'CHGCAR').copy(pwd.join('CHGCAR')) output_file('wavecar', 'WAVECAR').copy(pwd.join('WAVECAR')) output_file('eigenval', 'EIGENVAL').copy(pwd.join('EIGENVAL')) output_file('doscar', 'DOSCAR').copy(pwd.join('DOSCAR')) poscar.copy(pwd.join('CONTCAR')) else: test_data_path = data_path(test_case, 'out') for out_file in py_path.local(test_data_path).listdir(): out_file.copy(pwd)
def test_parse_poscar_silly_read(fresh_aiida_env): """ Parse (read) a reference POSCAR with silly elemental names. Using the PoscarParser and compare the result to a reference structure. """ path = data_path('poscar', 'POSCARSILLY') parser = PoscarParser(file_path=path) result = parser.structure names = result.get_site_kindnames() assert names == ['Hamburger', 'Pizza'] symbols = result.get_symbols_set() assert symbols == set(['X', 'X'])
def test_parse_poscar(fresh_aiida_env, vasp_structure): """ Parse a reference POSCAR file. Using the PoscarParser and compare the result to a reference structure. """ path = data_path('poscar', 'POSCAR') parser = PoscarParser(file_path=path) result = parser.structure structure = vasp_structure assert result.cell == structure.cell assert result.get_site_kindnames() == structure.get_site_kindnames() assert result.sites[2].position == structure.sites[2].position
def test_parse_poscar_undercase(fresh_aiida_env, vasp_structure, tmpdir): """ Parse a reference POSCAR. With potential elemental names using the PoscarParser and compare the result to a reference structure. """ parser = PoscarParser(data=vasp_structure) result = parser.get_quantity('poscar-structure', {}) names = result['poscar-structure'].get_site_kindnames() assert names == ['In', 'As', 'As', 'In_d', 'In_d', 'As'] symbols = result['poscar-structure'].get_symbols_set() assert symbols == set(['As', 'In']) temp_file = str(tmpdir.join('POSCAR')) parser.write(temp_file) parser = PoscarParser(file_path=temp_file) result_reparse = parser.structure names = result_reparse.get_site_kindnames() assert names == ['In', 'As', 'As', 'In_d', 'In_d', 'As'] symbols = result_reparse.get_symbols_set() assert symbols == set(['As', 'In'])
def test_parse_poscar_reparse(fresh_aiida_env, vasp_structure, tmpdir): """ Parse (read) a reference POSCAR file. Using the PoscarParser, parse(write), parse (read), and compare to reference structure. """ path = data_path('poscar', 'POSCAR') parser = PoscarParser(file_path=path) temp_file = str(tmpdir.join('POSCAR')) parser.write(temp_file) parser = PoscarParser(file_path=temp_file) result = parser.structure structure = vasp_structure assert result.cell == structure.cell assert result.get_site_kindnames() == structure.get_site_kindnames() assert result.sites[2].position == structure.sites[2].position
def get_poscar_input(dir_path): return PoscarParser(file_path=str(dir_path / 'POSCAR')).structure
def test_converge_wc(fresh_aiida_env, potentials, mock_vasp): """Test submitting only, not correctness, with mocked vasp code.""" from aiida.orm import Code from aiida.plugins import WorkflowFactory from aiida.engine import run workchain = WorkflowFactory('vasp.converge') mock_vasp.store() create_authinfo(computer=mock_vasp.computer, store=True) structure = PoscarParser( file_path=data_path('test_converge_wc', 'inp', 'POSCAR')).structure parameters = IncarParser( file_path=data_path('test_converge_wc', 'inp', 'INCAR')).incar parameters['system'] = 'test-case:test_converge_wc' parameters = { k: v for k, v in parameters.items() if k not in ['isif', 'ibrion', 'encut', 'nsw'] } restart_clean_workdir = get_data_node('bool', False) restart_clean_workdir.store() inputs = AttributeDict() inputs.code = Code.get_from_string('mock-vasp@localhost') inputs.structure = structure inputs.parameters = get_data_node('dict', dict={'incar': parameters}) inputs.potential_family = get_data_node('str', POTCAR_FAMILY_NAME) inputs.potential_mapping = get_data_node('dict', dict=POTCAR_MAP) inputs.options = get_data_node('dict', dict={ 'withmpi': False, 'queue_name': 'None', 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, 'max_wallclock_seconds': 3600 }) inputs.max_iterations = get_data_node('int', 1) inputs.clean_workdir = get_data_node('bool', False) relax = AttributeDict() converge = AttributeDict() converge.relax = get_data_node('bool', False) converge.compress = get_data_node('bool', False) converge.displace = get_data_node('bool', False) converge.pwcutoff_samples = get_data_node('int', 3) converge.k_samples = get_data_node('int', 3) relax.perform = get_data_node('bool', True) inputs.relax = relax inputs.converge = converge inputs.verbose = get_data_node('bool', True) results, node = run.get_node(workchain, **inputs) assert node.exit_status == 0 converge = results['converge'] assert 'data' in converge conv_data = converge['data'] try: conv_data.get_array('pw_regular') except KeyError: pytest.fail('Did not find pw_regular in converge.data') try: conv_data.get_array('kpoints_regular') except KeyError: pytest.fail('Did not find kpoints_regular in converge.data') assert 'pwcutoff_recommended' in converge try: _encut = converge['pwcutoff_recommended'].value except AttributeError: pytest.fail('pwcutoff_recommended does not have the expected format') assert 'kpoints_recommended' in converge try: _kpoints = converge['kpoints_recommended'].get_kpoints_mesh() except AttributeError: pytest.fail('kpoints_recommended does not have the expected format')
def test_converge_wc_pw(fresh_aiida_env, vasp_params, potentials, mock_vasp): """Test convergence workflow using mock code.""" from aiida.orm import Code from aiida.plugins import WorkflowFactory from aiida.engine import run workchain = WorkflowFactory('vasp.converge') mock_vasp.store() create_authinfo(computer=mock_vasp.computer).store() structure = PoscarParser(file_path=data_path('test_converge_wc/pw/200', 'inp', 'POSCAR')).structure parameters = IncarParser( file_path=data_path('test_converge_wc/pw/200', 'inp', 'INCAR')).incar parameters['system'] = 'test-case:test_converge_wc' parameters = { k: v for k, v in parameters.items() if k not in ['isif', 'ibrion', 'encut', 'nsw'] } kpoints = KpointsParser(file_path=data_path('test_converge_wc/pw/200', 'inp', 'KPOINTS')).kpoints restart_clean_workdir = get_data_node('bool', False) restart_clean_workdir.store() inputs = AttributeDict() inputs.code = Code.get_from_string('mock-vasp@localhost') inputs.structure = structure inputs.kpoints = kpoints inputs.parameters = get_data_node('dict', dict={'incar': parameters}) inputs.potential_family = get_data_node('str', POTCAR_FAMILY_NAME) inputs.potential_mapping = get_data_node('dict', dict=POTCAR_MAP) inputs.options = get_data_node('dict', dict={ 'withmpi': False, 'queue_name': 'None', 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, 'max_wallclock_seconds': 3600 }) inputs.max_iterations = get_data_node('int', 1) inputs.clean_workdir = get_data_node('bool', False) relax = AttributeDict() converge = AttributeDict() relax.perform = get_data_node('bool', False) converge.relax = get_data_node('bool', False) converge.testing = get_data_node('bool', True) converge.compress = get_data_node('bool', False) converge.displace = get_data_node('bool', False) converge.pwcutoff_samples = get_data_node('int', 3) converge.k_samples = get_data_node('int', 3) inputs.relax = relax inputs.converge = converge inputs.verbose = get_data_node('bool', True) results, node = run.get_node(workchain, **inputs) assert node.exit_status == 0 assert 'converge' in results converge = results['converge'] assert 'data' in converge conv_data = converge['data'] try: conv_data = conv_data.get_array('pw_regular') except KeyError: pytest.fail('Did not find pw_regular in converge.data') conv_data_test = np.array([[200.0, -10.77974998, 0.0, 0.0, 0.5984], [250.0, -10.80762044, 0.0, 0.0, 0.5912], [300.0, -10.82261992, 0.0, 0.0, 0.5876]]) np.testing.assert_allclose(conv_data, conv_data_test) assert 'pwcutoff_recommended' in converge try: _encut = converge['pwcutoff_recommended'].value np.testing.assert_equal(_encut, 300) except AttributeError: pytest.fail('pwcutoff_recommended does not have the expected format')
def test_bands_wc(fresh_aiida_env, potentials, mock_vasp): """Test with mocked vasp code.""" from aiida.orm import Code, Log, RemoteData from aiida.plugins import WorkflowFactory from aiida.engine import run workchain = WorkflowFactory('vasp.bands') mock_vasp.store() create_authinfo(computer=mock_vasp.computer, store=True) structure = PoscarParser(file_path=data_path('test_bands_wc', 'inp', 'POSCAR')).structure parameters = IncarParser(file_path=data_path('test_bands_wc', 'inp', 'INCAR')).incar parameters['system'] = 'test-case:test_bands_wc' # Make sure we replace encut with pwcutoff del parameters['encut'] parameters = {'vasp': parameters} parameters['electronic'] = {'pwcutoff': 200} inputs = AttributeDict() inputs.code = Code.get_from_string('mock-vasp@localhost') inputs.structure = structure inputs.parameters = get_data_node('dict', dict=parameters) inputs.potential_family = get_data_node('str', POTCAR_FAMILY_NAME) inputs.potential_mapping = get_data_node('dict', dict=POTCAR_MAP) inputs.options = get_data_node('dict', dict={ 'withmpi': False, 'queue_name': 'None', 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, 'max_wallclock_seconds': 3600 }) inputs.max_iterations = get_data_node('int', 1) inputs.clean_workdir = get_data_node('bool', False) inputs.verbose = get_data_node('bool', True) # Also set the restart folder as we assume a bands data will start from # a previous calculation that is sitting in the restart folder inputs.restart_folder = RemoteData(computer=inputs.code.computer, remote_path=data_path('test_bands_wc', 'inp')) results, node = run.get_node(workchain, **inputs) assert node.exit_status == 0 assert 'bands' in results kpoints = results['bands'].get_kpoints() test_array = np.array([[0., 0., 0.], [0.02272727, 0., 0.02272727], [0.04545454, 0., 0.04545454], [0.06818182, 0., 0.06818182], [0.09090909, 0., 0.09090909], [0.11363636, 0., 0.11363636], [0.13636364, 0., 0.13636364], [0.15909091, 0., 0.15909091], [0.18181818, 0., 0.18181818], [0.20454545, 0., 0.20454545], [0.22727273, 0., 0.22727273], [0.25, 0., 0.25], [0.27272727, 0., 0.27272727], [0.29545455, 0., 0.29545455], [0.31818182, 0., 0.31818182], [0.34090909, 0., 0.34090909], [0.36363636, 0., 0.36363636], [0.38636364, 0., 0.38636364], [0.40909091, 0., 0.40909091], [0.43181818, 0., 0.43181818], [0.45454545, 0., 0.45454545], [0.47727273, 0., 0.47727273], [0.5, 0., 0.5], [0.51785714, 0.03571429, 0.51785714], [0.53571429, 0.07142857, 0.53571429], [0.55357143, 0.10714286, 0.55357143], [0.57142857, 0.14285714, 0.57142857], [0.58928571, 0.17857143, 0.58928571], [0.60714286, 0.21428571, 0.60714286], [0.625, 0.25, 0.625], [0.375, 0.375, 0.75], [0.35869565, 0.35869565, 0.7173913], [0.3423913, 0.3423913, 0.68478261], [0.32608696, 0.32608696, 0.65217391], [0.30978261, 0.30978261, 0.61956522], [0.29347826, 0.29347826, 0.58695652], [0.27717391, 0.27717391, 0.55434783], [0.26086957, 0.26086957, 0.52173913], [0.24456522, 0.24456522, 0.48913043], [0.22826087, 0.22826087, 0.45652174], [0.21195652, 0.21195652, 0.42391304], [0.19565217, 0.19565217, 0.39130435], [0.17934783, 0.17934783, 0.35869565], [0.16304348, 0.16304348, 0.32608696], [0.14673913, 0.14673913, 0.29347826], [0.13043478, 0.13043478, 0.26086957], [0.11413044, 0.11413044, 0.22826087], [0.09782609, 0.09782609, 0.19565217], [0.08152174, 0.08152174, 0.16304348], [0.06521739, 0.06521739, 0.13043478], [0.04891304, 0.04891304, 0.09782609], [0.0326087, 0.0326087, 0.06521739], [0.01630435, 0.01630435, 0.0326087], [0., 0., 0.], [0.02631579, 0.02631579, 0.02631579], [0.05263158, 0.05263158, 0.05263158], [0.07894737, 0.07894737, 0.07894737], [0.10526316, 0.10526316, 0.10526316], [0.13157895, 0.13157895, 0.13157895], [0.15789474, 0.15789474, 0.15789474], [0.18421053, 0.18421053, 0.18421053], [0.21052632, 0.21052632, 0.21052632], [0.2368421, 0.2368421, 0.2368421], [0.26315789, 0.26315789, 0.26315789], [0.28947368, 0.28947368, 0.28947368], [0.31578947, 0.31578947, 0.31578947], [0.34210526, 0.34210526, 0.34210526], [0.36842105, 0.36842105, 0.36842105], [0.39473684, 0.39473684, 0.39473684], [0.42105263, 0.42105263, 0.42105263], [0.44736842, 0.44736842, 0.44736842], [0.47368421, 0.47368421, 0.47368421], [0.5, 0.5, 0.5], [0.5, 0.48333333, 0.51666667], [0.5, 0.46666667, 0.53333333], [0.5, 0.45, 0.55], [0.5, 0.43333333, 0.56666667], [0.5, 0.41666667, 0.58333333], [0.5, 0.4, 0.6], [0.5, 0.38333333, 0.61666667], [0.5, 0.36666667, 0.63333333], [0.5, 0.35, 0.65], [0.5, 0.33333333, 0.66666667], [0.5, 0.31666667, 0.68333333], [0.5, 0.3, 0.7], [0.5, 0.28333333, 0.71666667], [0.5, 0.26666667, 0.73333333], [0.5, 0.25, 0.75], [0.5, 0.225, 0.725], [0.5, 0.2, 0.7], [0.5, 0.175, 0.675], [0.5, 0.15, 0.65], [0.5, 0.125, 0.625], [0.5, 0.1, 0.6], [0.5, 0.075, 0.575], [0.5, 0.05, 0.55], [0.5, 0.025, 0.525], [0.5, 0., 0.5]]) np.testing.assert_allclose(kpoints, test_array) bands = results['bands'].get_bands() assert bands.shape == (1, 98, 20) np.testing.assert_allclose(bands[0, 0, 0:3], np.array([-6.0753, 6.0254, 6.0254])) np.testing.assert_allclose(bands[0, 2, 0:3], np.array([-6.0386, 5.7955, 5.8737])) np.testing.assert_allclose(bands[0, 97, 0:3], np.array([-1.867, -1.867, 3.1102]))
def get_poscar_input(dir_path): return PoscarParser(file_path=dir_path.join('POSCAR').strpath).structure