From 1cb81571d8e520d7ca3a8e26fe5d4b21390a3b2c Mon Sep 17 00:00:00 2001 From: Callow Date: Tue, 10 Oct 2023 16:54:12 +0200 Subject: [PATCH 1/5] Add suppress warnings variable to config --- atoMEC/check_inputs.py | 28 +++++++++++++++++----------- atoMEC/config.py | 3 +++ atoMEC/staticKS.py | 4 ++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/atoMEC/check_inputs.py b/atoMEC/check_inputs.py index 6cf9907..8fc4f0e 100644 --- a/atoMEC/check_inputs.py +++ b/atoMEC/check_inputs.py @@ -118,14 +118,16 @@ def check_temp(self, temp, units_temp): temp = unitconv.ev_to_ha * temp elif units_temp.lower() == "k": temp = unitconv.K_to_ha * temp - # check if temperature is within some reasonable limits + # check if temperature is within some reasonable limits (<1000 and > 0.1 eV) if temp < 0: raise InputError.temp_error("temperature is negative") - if temp < 0.01: - print(InputWarning.temp_warning("low")) + if temp < 0.0036: + if not config.suppress_warnings: + print(InputWarning.temp_warning("low")) return temp - elif temp > 3.5: - print(InputWarning.temp_warning("high")) + elif temp > 36.7: + if not config.suppress_warnings: + print(InputWarning.temp_warning("high")) return temp else: return temp @@ -715,10 +717,12 @@ def check_grid_params(grid_params): # check that ngrid is a positive number if ngrid < 0: raise InputError.grid_error("Number of grid points must be positive") - elif ngrid < 500: - print(InputWarning.ngrid_warning("low", "inaccurate")) - elif ngrid > 5000: - print(InputWarning.ngrid_warning("high", "expensive")) + elif ngrid < 300: + if not config.suppress_warnings: + print(InputWarning.ngrid_warning("low", "inaccurate")) + elif ngrid > 10000: + if not config.supppress_warnings: + print(InputWarning.ngrid_warning("high", "expensive")) # check that ngrid_coarse is an integer if not isinstance(ngrid_coarse, intc): @@ -727,9 +731,11 @@ def check_grid_params(grid_params): if ngrid_coarse < 0: raise InputError.grid_error("Number of coarse grid points must be positive") elif ngrid_coarse < 100: - print(InputWarning.ngrid_warning("low", "inaccurate")) + if not config.suppress_warnings: + print(InputWarning.ngrid_warning("low", "inaccurate")) elif ngrid_coarse > 500: - print(InputWarning.ngrid_warning("high", "expensive")) + if not config.suppress_warnings: + print(InputWarning.ngrid_warning("high", "expensive")) # check that x0 is reasonable if x0 > -3: diff --git a/atoMEC/config.py b/atoMEC/config.py index 0fc828d..80e7f56 100644 --- a/atoMEC/config.py +++ b/atoMEC/config.py @@ -33,3 +33,6 @@ # parallelization numcores = 0 # defaults to serial + +# whether to suppress warnings (not errors) +suppress_warnings = False diff --git a/atoMEC/staticKS.py b/atoMEC/staticKS.py index 389d40a..c4158de 100644 --- a/atoMEC/staticKS.py +++ b/atoMEC/staticKS.py @@ -170,9 +170,9 @@ def occnums_w(self): norbs_ok, lorbs_ok = self.check_orbs( self._occnums_w, config.conv_params["bandtol"] ) - if not norbs_ok: + if not norbs_ok and not config.suppress_warnings: print(check_inputs.InputWarning.norbs_warning("nmax")) - if not lorbs_ok: + if not lorbs_ok and not config.suppress_warnings: print(check_inputs.InputWarning.norbs_warning("lmax")) return self._occnums_w From 1d3dab3f00340adaeba65f61b3e66be4a7f1466b Mon Sep 17 00:00:00 2001 From: Timothy Callow Date: Wed, 11 Oct 2023 09:23:00 +0200 Subject: [PATCH 2/5] Fix typo --- atoMEC/check_inputs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atoMEC/check_inputs.py b/atoMEC/check_inputs.py index 8fc4f0e..3c04f02 100644 --- a/atoMEC/check_inputs.py +++ b/atoMEC/check_inputs.py @@ -721,7 +721,7 @@ def check_grid_params(grid_params): if not config.suppress_warnings: print(InputWarning.ngrid_warning("low", "inaccurate")) elif ngrid > 10000: - if not config.supppress_warnings: + if not config.suppress_warnings: print(InputWarning.ngrid_warning("high", "expensive")) # check that ngrid_coarse is an integer @@ -1195,7 +1195,7 @@ def ngrid_warning(err1, err2): + ". Proceeding anyway, but results may be " + err2 + "\n" - + "Suggested grid range is between 1000-5000 but should be tested wrt" + + "Suggested grid range is between 500-10000 but should be tested wrt" " convergence \n" ) return warning From 6a4259c7e8c61fe912decc8cd873c55c4d69a2ac Mon Sep 17 00:00:00 2001 From: Timothy Callow Date: Wed, 11 Oct 2023 09:23:41 +0200 Subject: [PATCH 3/5] Catch more exceptions --- tests/exceptions_test.py | 38 +++++++++++++++++++------------------- tests/pressure_log_test.py | 1 + tests/serial_test.py | 12 ++++++------ 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/tests/exceptions_test.py b/tests/exceptions_test.py index d584fff..9caca78 100644 --- a/tests/exceptions_test.py +++ b/tests/exceptions_test.py @@ -18,13 +18,13 @@ class TestAtom: def test_element(self, ele_input): """Check chemical species input.""" with pytest.raises(SystemExit): - atom = Atom(ele_input, 0.05, radius=1) + atom = Atom(ele_input, 0.01, radius=1) return atom def test_temp_units(self): """Check temperature units input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, radius=1, units_temp="jk") + atom = Atom("H", 0.01, radius=1, units_temp="jk") return atom @pytest.mark.parametrize("temp_input", [("a"), (-0.2)]) @@ -37,45 +37,45 @@ def test_temp(self, temp_input): def test_charge(self): """Check charge input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, radius=1.0, charge="jk") + atom = Atom("H", 0.01, radius=1.0, charge="jk") return atom def test_radius_units(self): """Check radius units input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, radius=1.0, units_radius="cm") + atom = Atom("H", 0.01, radius=1.0, units_radius="cm") return atom def test_density_units(self): """Check density units input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, density=0.1, units_density="ggcm3") + atom = Atom("H", 0.01, density=0.1, units_density="ggcm3") return atom @pytest.mark.parametrize("rad_input", [("a"), (-0.2)]) def test_radius(self, rad_input): """Check radius input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, radius=rad_input) + atom = Atom("H", 0.01, radius=rad_input) return atom @pytest.mark.parametrize("dens_input", [("a"), (-0.2)]) def test_density(self, dens_input): """Check density input.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, density=dens_input) + atom = Atom("H", 0.01, density=dens_input) return atom def test_rad_dens_1(self): """Check radius and density compatibility.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05, radius=2.0, density=10.0) + atom = Atom("H", 0.01, radius=2.0, density=10.0) return atom def test_rad_dens_2(self): """Check one of radius or density specified.""" with pytest.raises(SystemExit): - atom = Atom("H", 0.05) + atom = Atom("H", 0.01) return atom @@ -88,7 +88,7 @@ class TestModel: ) def test_xc(self, xc_input): """Test the exchange-correlation (xc) input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) with pytest.raises((SystemExit, TypeError)): model = models.ISModel(atom, xfunc_id=xc_input) @@ -104,7 +104,7 @@ def test_xc(self, xc_input): ) def test_unbound(self, unbound_input): """Test unbound input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) with pytest.raises(SystemExit): model = models.ISModel(atom, unbound=unbound_input, bc="bands") @@ -119,7 +119,7 @@ def test_unbound(self, unbound_input): ) def test_bcs(self, bcs_input): """Test boundary conditions input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) with pytest.raises(SystemExit): model = models.ISModel(atom, bc=bcs_input) @@ -127,7 +127,7 @@ def test_bcs(self, bcs_input): def test_spinpol(self): """Test spin polarization input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) with pytest.raises(SystemExit): model = models.ISModel(atom, spinpol="a") @@ -139,7 +139,7 @@ def test_spinpol(self): ) def test_spinmag(self, spinmag_input): """Test spin magnetization input.""" - atom = Atom(spinmag_input[1], 0.05, radius=1) + atom = Atom(spinmag_input[1], 0.01, radius=1) with pytest.raises(SystemExit): model = models.ISModel(atom, spinmag=spinmag_input[0]) @@ -147,7 +147,7 @@ def test_spinmag(self, spinmag_input): def test_v_shift(self): """Test v shift input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) with pytest.raises(SystemExit): model = models.ISModel(atom, v_shift="a") @@ -169,7 +169,7 @@ class TestCalcEnergy: ) def test_grid_params(self, grid_input): """Test the grid_params input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) model = models.ISModel(atom) with pytest.raises(SystemExit): @@ -184,7 +184,7 @@ def test_grid_params(self, grid_input): ) def test_conv_params(self, conv_input): """Test the conv_params input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) model = models.ISModel(atom) with pytest.raises(SystemExit): @@ -201,7 +201,7 @@ def test_conv_params(self, conv_input): ) def test_scf_params(self, scf_input): """Test the scf_params input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) model = models.ISModel(atom) with pytest.raises(SystemExit): @@ -218,7 +218,7 @@ def test_scf_params(self, scf_input): ) def test_band_params(self, bands_input): """Test the band params input.""" - atom = Atom("Al", 0.05, radius=1) + atom = Atom("Al", 0.01, radius=1) model = models.ISModel(atom, bc="bands", unbound="quantum") with pytest.raises(SystemExit): diff --git a/tests/pressure_log_test.py b/tests/pressure_log_test.py index 51725d0..e418f5e 100644 --- a/tests/pressure_log_test.py +++ b/tests/pressure_log_test.py @@ -35,6 +35,7 @@ class TestPressure: def SCF_output(self): """Run a spin-unpolarized SCF calc and save the output.""" config.numcores = -1 + config.suppress_warnings = True return self._run_SCF() @pytest.mark.parametrize( diff --git a/tests/serial_test.py b/tests/serial_test.py index 3e76e6d..1b8e21f 100644 --- a/tests/serial_test.py +++ b/tests/serial_test.py @@ -7,8 +7,8 @@ # expected values and tolerance -dense_expected = -0.5620194349606303 -coarse_expected = -0.5625664849484403 +dense_expected = -0.5620111902408967 +coarse_expected = -0.56341460946266 accuracy = 1e-3 @@ -23,8 +23,8 @@ class TestSerial: @pytest.mark.parametrize( "test_input,expected", [ - (400, coarse_expected), - (5001, dense_expected), + (250, coarse_expected), + (10001, dense_expected), ], ) def test_serial(self, test_input, expected): @@ -69,7 +69,7 @@ def _run(ngrid): if __name__ == "__main__": config.numcores = 0 - dense = TestSerial._run(5001) - coarse = TestSerial._run(400) + dense = TestSerial._run(10001) + coarse = TestSerial._run(250) print("dense_expected =", dense) print("coarse_expected =", coarse) From e6d4062d7ab8b00668b6a4890a5d9ca08e0afe8c Mon Sep 17 00:00:00 2001 From: Timothy Callow Date: Wed, 11 Oct 2023 10:32:22 +0200 Subject: [PATCH 4/5] Add checker for s0 --- atoMEC/check_inputs.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/atoMEC/check_inputs.py b/atoMEC/check_inputs.py index 3c04f02..75af605 100644 --- a/atoMEC/check_inputs.py +++ b/atoMEC/check_inputs.py @@ -743,6 +743,13 @@ def check_grid_params(grid_params): "x0 is too high, calculation will likely not converge" ) + if s0 <= 1e-6: + raise InputError.grid_error("s0 is too small, numerical problems likely") + elif s0 >= 1e-2: + raise InputError.grid_error( + "s0 is too large, calculation will likely not converge" + ) + grid_params = {"ngrid": ngrid, "x0": x0, "ngrid_coarse": ngrid_coarse, "s0": s0} return grid_params From ad0aea7e811d9d2edc5e386e44699daa3864e6d1 Mon Sep 17 00:00:00 2001 From: Timothy Callow Date: Wed, 11 Oct 2023 10:32:45 +0200 Subject: [PATCH 5/5] Add ngrid_coarse checks --- tests/boundary_conditions_test.py | 2 +- tests/conductivity_test.py | 5 ++++- tests/energy_alt_test.py | 5 ++++- tests/exceptions_test.py | 2 ++ tests/functionals_test.py | 2 +- tests/gramschmidt_test.py | 5 ++++- tests/localization_test.py | 2 +- tests/pressure_log_test.py | 2 +- tests/pressure_sqrt_test.py | 2 +- tests/serial_test.py | 2 +- tests/spin_test.py | 2 +- tests/unbound_test.py | 2 +- 12 files changed, 22 insertions(+), 11 deletions(-) diff --git a/tests/boundary_conditions_test.py b/tests/boundary_conditions_test.py index 4bf9d64..68242ac 100644 --- a/tests/boundary_conditions_test.py +++ b/tests/boundary_conditions_test.py @@ -70,7 +70,7 @@ def _run(bc): 4, 4, scf_params={"maxscf": 5, "mixfrac": 0.3}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 600}, band_params={"nkpts": nkpts}, ) diff --git a/tests/conductivity_test.py b/tests/conductivity_test.py index 3727ebc..b40ee08 100644 --- a/tests/conductivity_test.py +++ b/tests/conductivity_test.py @@ -126,7 +126,10 @@ def _run_SCF(): # run the SCF calculation output = model.CalcEnergy( - 4, 4, scf_params={"mixfrac": 0.3, "maxscf": 6}, grid_params={"ngrid": 1200} + 4, + 4, + scf_params={"mixfrac": 0.3, "maxscf": 6}, + grid_params={"ngrid": 1200, "ngrid_coarse": 300}, ) output_dict = {"Atom": F_at, "model": model, "SCF_out": output} diff --git a/tests/energy_alt_test.py b/tests/energy_alt_test.py index cf6eddb..5b49368 100644 --- a/tests/energy_alt_test.py +++ b/tests/energy_alt_test.py @@ -63,7 +63,10 @@ def _run(unbound): # run the SCF calculation output = model.CalcEnergy( - 10, 5, scf_params={"maxscf": 6, "mixfrac": 0.3}, grid_params={"ngrid": 1000} + 10, + 5, + scf_params={"maxscf": 6, "mixfrac": 0.3}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, ) # construct the EnergyAlt object diff --git a/tests/exceptions_test.py b/tests/exceptions_test.py index 9caca78..4f243b3 100644 --- a/tests/exceptions_test.py +++ b/tests/exceptions_test.py @@ -165,6 +165,8 @@ class TestCalcEnergy: ({"ngrid_coarse": "a"}), ({"ngrid_coarse": -100}), ({"x0": -2}), + ({"s0": 1e-7}), + ({"s0": 1e-1}), ], ) def test_grid_params(self, grid_input): diff --git a/tests/functionals_test.py b/tests/functionals_test.py index 73ec107..92fdb28 100644 --- a/tests/functionals_test.py +++ b/tests/functionals_test.py @@ -90,7 +90,7 @@ def _run(func): 6, 6, scf_params={"maxscf": 5, "mixfrac": 0.3}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 90}, band_params={"nkpts": 30}, ) diff --git a/tests/gramschmidt_test.py b/tests/gramschmidt_test.py index 4400194..83e23c1 100644 --- a/tests/gramschmidt_test.py +++ b/tests/gramschmidt_test.py @@ -61,7 +61,10 @@ def _run_SCF(): # run SCF calculation output = model.CalcEnergy( - 4, 4, scf_params={"mixfrac": 0.3, "maxscf": 5}, grid_params={"ngrid": 1000} + 4, + 4, + scf_params={"mixfrac": 0.3, "maxscf": 5}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, ) return output diff --git a/tests/localization_test.py b/tests/localization_test.py index 6be6149..ea71a5b 100644 --- a/tests/localization_test.py +++ b/tests/localization_test.py @@ -100,7 +100,7 @@ def _run_SCF(spinpol): 3, 2, scf_params={"mixfrac": 0.3, "maxscf": 50}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, ) output_dict = {"Atom": Al_at, "model": model, "SCF_out": output} diff --git a/tests/pressure_log_test.py b/tests/pressure_log_test.py index e418f5e..4ecd096 100644 --- a/tests/pressure_log_test.py +++ b/tests/pressure_log_test.py @@ -112,7 +112,7 @@ def _run_SCF(): 3, 3, scf_params={"maxscf": 5, "mixfrac": 0.3}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, band_params={"nkpts": 50}, verbosity=1, grid_type="log", diff --git a/tests/pressure_sqrt_test.py b/tests/pressure_sqrt_test.py index 4067fa0..b54c864 100644 --- a/tests/pressure_sqrt_test.py +++ b/tests/pressure_sqrt_test.py @@ -103,7 +103,7 @@ def _run_SCF(): 6, 8, scf_params={"maxscf": 5, "mixfrac": 0.3}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, band_params={"nkpts": 50}, verbosity=1, grid_type="sqrt", diff --git a/tests/serial_test.py b/tests/serial_test.py index 1b8e21f..bfa7870 100644 --- a/tests/serial_test.py +++ b/tests/serial_test.py @@ -59,7 +59,7 @@ def _run(ngrid): 2, scf_params={"maxscf": 1, "mixfrac": 0.7}, band_params={"nkpts": 30}, - grid_params={"ngrid": ngrid}, + grid_params={"ngrid": ngrid, "ngrid_coarse": 300}, ) # extract the total free energy diff --git a/tests/spin_test.py b/tests/spin_test.py index 4ade323..1f78336 100644 --- a/tests/spin_test.py +++ b/tests/spin_test.py @@ -66,7 +66,7 @@ def _run(spinmag): 5, scf_params={"maxscf": 4, "mixfrac": 0.3}, band_params={"nkpts": 50}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, ) # extract the total free energy diff --git a/tests/unbound_test.py b/tests/unbound_test.py index 0b2e7e0..b758a85 100644 --- a/tests/unbound_test.py +++ b/tests/unbound_test.py @@ -49,7 +49,7 @@ def _run(): 3, 3, scf_params={"maxscf": 3, "mixfrac": 0.3}, - grid_params={"ngrid": 1000}, + grid_params={"ngrid": 1000, "ngrid_coarse": 300}, force_bound=[[0, 0, 0]], )