def test_generate_mo_symmetry(self, molecule_filepath, delete_tmp_dir): define_opt = get_define_template("dscf") define_opt["desy"] = True with temp_dir(delete_tmp_dir) as tmp: # run the full to generate all the files self.run_define_runner(define_opt, molecule_filepath) s = States.from_file("control") # check that there are other irreps coming from the mos assert len(s.irreps) != 1 or s.irreps[0] != "a" # do not remove mos to trigger another path in DefineRunner self.run_define_runner({"sym": "c1"}, None, "mo") assert os.path.isfile("mos") s_new = States.from_file("control") assert s_new.irreps[0] == "a"
def test_hole(mo_dirpath, delete_tmp_dir): with temp_dir(delete_tmp_dir): for f in ["mos", "control"]: shutil.copy2(os.path.join(mo_dirpath, f), f) s = States.from_file() # create a fake hole high_state = s.pop(-1) high_state.eigenvalue = -0.5 s.insert(2, high_state) assert s.has_hole with pytest.raises(RuntimeError): s.generate_lowest_filled_states() lowest = s.generate_lowest_filled_states(allow_fractional=True) assert not lowest.has_hole assert lowest[2].irrep_index == 6 lowest = s.generate_lowest_filled_states(only_occupied=True, allow_fractional=True) assert len(lowest) == 4 lowest = s.generate_lowest_filled_states(allow_fractional=True, reorder_irrep_index=True) assert lowest[2].irrep_index == 1
def test_closed(mo_dirpath, delete_tmp_dir): with temp_dir(delete_tmp_dir): for f in ["mos", "control"]: shutil.copy2(os.path.join(mo_dirpath, f), f) s = States.from_file() assert len(s) == 14 assert s[0].eigenvalue == pytest.approx(-13.968369531218) assert_MSONable(s) eiger_out = EigerOutput.from_file(os.path.join(mo_dirpath, "eiger")) assert eiger_out.compare_states(s) is None assert not s.is_uhf assert not s.has_hole assert s.total_electrons == 10 assert s.irreps[0] == "a1" assert s.occupations[0] == 2 assert s.spins[0] is None assert s.eigenvalues[-1] == pytest.approx(2.55164050421) assert s.irrep_indices[0] == 1 assert str(s) # test filter s = States.from_file() with pytest.raises(ValueError): s.filter_states(spin="a", irrep="a1") assert len(s.filter_states(irrep="z")) == 0 filtered = s.filter_states(irrep="a1") assert filtered[0].irrep == "a1" # test get_shells s = States.from_file() with pytest.raises(ValueError): s.get_shells(spin="a") shell = s.get_shells() assert shell.occupations[0] == 2 assert shell.states[0] == ("a1", 1)
def testrun_update_internal_coords(self, molecule_filepath, delete_tmp_dir): define_opt = get_define_template("dscf") define_opt["ired"] = True with temp_dir(delete_tmp_dir) as tmp: # run the full to generate all the files self.run_define_runner(define_opt, molecule_filepath) s = States.from_file("control") dg = DataGroups.from_file("coord") dg.kdg("redundant") dg.to_file("coord") # do not remove mos to trigger another path in DefineRunner self.run_define_runner({"ired": True}, None, "internal") dg_new = DataGroups.from_file("coord") assert dg_new.sdg("redundant")
def test_uhf(mo_dirpath, delete_tmp_dir): with temp_dir(delete_tmp_dir): for f in ["alpha", "beta", "control"]: shutil.copy2(os.path.join(mo_dirpath, f), f) s = States.from_file() assert len(s) == 28 assert s.n_states == 28 assert s[0].eigenvalue == pytest.approx(-14.457427310212) assert_MSONable(s) eiger_out = EigerOutput.from_file(os.path.join(mo_dirpath, "eiger")) eiger_wrong_val = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_val")) eiger_wrong_length = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_length")) eiger_wrong_gap = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_gap")) eiger_wrong_nel = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_nelec")) eiger_wrong_occ = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_occ")) eiger_wrong_match = EigerOutput.from_file( os.path.join(mo_dirpath, "eiger_wrong_match")) assert eiger_out.compare_states(s) is None assert "gap" in eiger_wrong_gap.compare_states(s) assert "states" in eiger_wrong_length.compare_states(s) assert "eigenvalue" in eiger_wrong_val.compare_states(s) assert "electrons" in eiger_wrong_nel.compare_states(s) assert "occupation" in eiger_wrong_occ.compare_states(s) assert "match" in eiger_wrong_match.compare_states(s) assert s.is_uhf assert not s.has_hole assert s.total_electrons == 9 assert s.irreps[0] == "a1" assert s.occupations[0] == 1 assert s.spins[0] == "a" assert s.eigenvalues[-1] == pytest.approx(2.1425788573507) assert s.irrep_indices[0] == 1 assert str(s) s.pop(0) assert len(s) == 27 s[0] = s[1] assert s[0] == s[1] s.insert(0, s[-1]) assert s[0] == s[-1] # test filter s = States.from_file() assert len(s.filter_states(irrep="z")) == 0 filtered = s.filter_states(spin="b", irrep="a1") assert filtered[0].spin == "b" assert filtered[0].irrep == "a1" # test get_shells s = States.from_file() with pytest.raises(ValueError): s.get_shells(spin=None) shell = s.get_shells(spin="a") assert shell.occupations[0] == 1 assert shell.states[0] == ("a1", 1)
def test_no_empty_states(): s = States([]) assert s.lumo_index is None assert s.lumo is None assert s.gap is None
def test_error_homo(): s = States([]) with pytest.raises(RuntimeError): s.homo_index
def run_itest(executables, define_options, coord_filename, control_reference_filename, file_classes, arguments=None, datagroups_options=None): """ Runs the integration tests. First define is executed and the produced control file is compared with the reference. If successful the required turbomole executables are run and the numerical values of the outputs will be checked with the reference. Args: executables: string or list of strings identifying the list of programs that should be executed. define_options (dict): the options passed to DefineRunner. coord_filename (str): the filename of the coord used. Will be taken from the testfiles/structures folder. control_reference_filename (str): the name of the reference control file used to check the correctness of the execution of DefineRunner. Will be taken from the testfiles/integration/control folder. file_classes: a list of classes subclassing BaseData (or even a single one if only one program required) they will be used to generate outputs from stdout and compared with the reference. arguments: string or list of strings with the arguments to be passed to the each executable. datagroups_options (dict): a dict of the form {"datagroup_name": "datagroup_value"}. Can contain additional datagroups that will be set with the cdg utility before running the calculation. Returns: bool: True if the test passed successfully """ if not isinstance(executables, (list, tuple)): executables = [executables] if not isinstance(file_classes, (list, tuple)): file_classes = [file_classes] if arguments is None: arguments = [None] * len(executables) elif not isinstance(arguments, (list, tuple)): arguments = [arguments] opt_define_timeout = ItestConfig.define_timeout opt_generate_ref = ItestConfig.generate_ref opt_tol = ItestConfig.tol with temp_dir(ItestConfig.delete_tmp_dir) as tmp_dir: # get the coord file (for the structure defined in the string) shutil.copyfile(get_sp(coord_filename), 'coord') dr = DefineRunner(define_options, timeout=opt_define_timeout) define_out = dr.run_full() # define should complete normally if not define_out: raise ItestError("Define did not complete normally.") if datagroups_options: c = Control.from_file() for k, v in datagroups_options.items(): c.cdg(k, v) c.to_file() if opt_generate_ref: # pragma: no cover shutil.copy2("control", get_control_integration(control_reference_filename)) ref_control = Control.from_file( get_control_integration(control_reference_filename)) current_control = Control.from_file("control") compare_control = current_control.compare(ref_control, tol=opt_tol) # print the output of Control.compare if the compare fails assert compare_control is None, compare_control for executable, exec_args, out_parser in zip(executables, arguments, file_classes): cmd = [executable] if exec_args: cmd += shlex.split(exec_args) process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') program_std_out, program_std_err = process.communicate() try: ret_code = process.wait() if ret_code or "ended normally" not in program_std_err: raise ItestError( "Executable {} has failed with return code {}".format( executable, ret_code)) if out_parser: # for jobex the outputs are not in the stdout but in the job.last file if executable == "jobex": out = out_parser.from_file("job.last").as_dict() else: out = out_parser.from_string(program_std_out).as_dict() out_ref_path = os.path.join( get_tfp(), "integration", "logs_json", "{}_{}.json".format(control_reference_filename, executable)) if opt_generate_ref: dumpfn(out, out_ref_path) out_ref = loadfn(out_ref_path, cls=None) assert_almost_equal( out, out_ref, atol=opt_tol, ignored_values=ignored_itest_parsed_keys) c = Control.from_file("control") e = c.energy if e is not None: e_ref_path = os.path.join( get_tfp(), "integration", "energy", "{}_{}.json".format(control_reference_filename, executable)) if opt_generate_ref: dumpfn(e, e_ref_path) e_ref = loadfn(e_ref_path) np.testing.assert_allclose(e.scf, e_ref.scf, atol=opt_tol) np.testing.assert_allclose(e.total, e_ref.total, atol=opt_tol) g = c.gradient if g is not None: g_ref_path = os.path.join( get_tfp(), "integration", "gradient", "{}_{}.json".format(control_reference_filename, executable)) if opt_generate_ref: dumpfn(g, g_ref_path) g_ref = loadfn(g_ref_path) np.testing.assert_allclose(g.gradients, g_ref.gradients, atol=opt_tol) # check that the output from eiger and our parser give the same results states = States.from_file() eiger_runner = EigerRunner() eiger_runner.run() eiger_out = eiger_runner.get_eiger_output() assert eiger_out.compare_states(states) is None with open("{}_stdout".format(executable), "w") as f: f.write(program_std_out) except: # if an exception is raised write down the output file for debugging then reraise with open("{}_stdout".format(executable), "w") as f: f.write(program_std_out) with open("{}_stderr".format(executable), "w") as f: f.write(program_std_err) raise return True