From 70fb106b9e6f80f02f5712eedb8392cccd8550d8 Mon Sep 17 00:00:00 2001 From: Timothy Nunn Date: Wed, 21 Feb 2024 14:36:02 +0000 Subject: [PATCH 1/2] Parse non-scientific reals using exponents rather than factors --- source/fortran/input.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/fortran/input.f90 b/source/fortran/input.f90 index 8cc0ce9c1c..3fbd87482f 100644 --- a/source/fortran/input.f90 +++ b/source/fortran/input.f90 @@ -4082,7 +4082,7 @@ subroutine string_to_real(string,length,rval,icode) ! Local variables - real(dp) :: valbdp,valadp,xfact + real(dp) :: valbdp,valadp,xexp integer :: iptr,izero,iexpon logical :: negatm,negate @@ -4142,7 +4142,7 @@ subroutine string_to_real(string,length,rval,icode) ! *** Parse the mantissa - before the decimal point valbdp = 0.0D0 - xfact = 0.1D0 + xexp = -1.0D0 20 continue if ((string(iptr:iptr) >= '0').and.(string(iptr:iptr) <= '9')) then valbdp = (valbdp * 10.0D0) + dble(ichar(string(iptr:iptr))-izero) @@ -4163,8 +4163,8 @@ subroutine string_to_real(string,length,rval,icode) valadp = 0.0D0 30 continue if ((string(iptr:iptr) >= '0').and.(string(iptr:iptr) <= '9')) then - valadp = valadp + (dble(ichar(string(iptr:iptr))-izero)*xfact) - xfact = xfact * 0.1D0 + valadp = valadp + (dble(ichar(string(iptr:iptr))-izero)*(10.0D0 ** xexp)) + xexp = xexp - 1.0D0 iptr = iptr + 1 if (iptr > length) goto 50 goto 30 From a44852ea398b24e8232ca1e252d31a724ade76ed Mon Sep 17 00:00:00 2001 From: Timothy Nunn Date: Wed, 21 Feb 2024 15:23:46 +0000 Subject: [PATCH 2/2] Add tests for parsing real inputs in IN.DAT --- tests/unit/test_input.py | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/unit/test_input.py diff --git a/tests/unit/test_input.py b/tests/unit/test_input.py new file mode 100644 index 0000000000..05ea93f795 --- /dev/null +++ b/tests/unit/test_input.py @@ -0,0 +1,60 @@ +import pytest +from process import fortran + + +def _create_input_file(directory, content: str): + file_location = directory / "IN.DAT" + with open(file_location, "w") as f: + f.write(content) + + return str(file_location) + + +@pytest.mark.parametrize( + ["epsvmc", "expected"], + [ + (string, 1.0) + for string in [ + "1.0", + "1.0D0", + "1.0d0", + "1.0e0", + "1.0E0", + "1.0D+0", + "1.0d+0", + "1.0e+0", + "1.0E+0", + "1.0D-0", + "1.0d-0", + "1.0e-0", + "1.0E-0", + "0.10D1", + "0.10d1", + "0.10E1", + "0.10e1", + "0.10D+1", + "0.10d+1", + "0.10E+1", + "0.10e+1", + "10.0D-1", + "10.0d-1", + "10.0E-1", + "10.0e-1", + ] + ] + + [ + (string, 0.0080000000000000002) + for string in ["0.008", "8.0E-3", "8.0D-3", "8.0d-3", "8.0e-3"] + ], +) +def test_parse_real(epsvmc, expected, tmp_path): + """Tests the parsing of real numbers into PROCESS. + + Program to get the expected value for 0.008 provided at https://github.com/ukaea/PROCESS/pull/3067 + """ + fortran.global_variables.fileprefix = _create_input_file( + tmp_path, f"epsvmc = {epsvmc}" + ) + fortran.init_module.init() + + assert fortran.numerics.epsvmc.item() == expected