Boyce, S.E., 2024, Batteries Included Fortran Library (BiF-Lib), version 1.2.0: U.S. Geological Survey Software Release, https://doi.org/10.5066/P9K2IQ6Y
Part of these utilities were developed for the following project:
Boyce, S.E., 2024, MODFLOW One-Water Hydrologic Flow Model (MF-OWHM) Conjunctive Use and Integrated Hydrologic Flow Modeling Software, version 2.x: U.S. Geological Survey Software Release, https://doi.org/10.5066/P9P8I8GS
Boyce, S.E., Hanson, R.T., Ferguson, I., Schmid, W., Henson, W., Reimann, T., Mehl, S.M., and Earll, M.M., 2020, One-Water Hydrologic Flow Model: A MODFLOW based conjunctive-use simulation software: U.S. Geological Survey Techniques and Methods 6–A60, 435 p., https://doi.org/10.3133/tm6A60
USGS Git Respository Published Documentation This Repository Branch's README.md
[[TOC]]
2024-1-10
Major release
Includes a new modules simple_file_io
, ``file_info_interface, and
circular_queue_instruction` that writes to a file 1D and 2D arrays.
-
Simple, dependency free file io routines Gadded in
src/io/simple_file_io.f90
-
Contains a set of convenience routines for parsing input files and opening read only or write only files.
-
The module is self-contained with simplified versions of multiple files from the full library.
- Its use is not recommended with other parts of BiF to avoid import conflicts.
- Provided for programs that require easy file io and do not want the full BiF dependency tree.
-
-
Circular Queue Data Type added in
src/types_and_containers/circular_queue_instruction.f90
-
This type is a linked list whose end points to the start to form a circle list.
-
Currently only supports
integer(int64) numbers
.
-
-
File Info Data Type added in
src/io/file_info_interface.f90
-
Queries and populates the type with all file properties of an open file (that is, something associated with a fortran unit number).
-
The information query can be done by unit number or file name.
-
-
EXECUTE_COMMAND_GET_OUTPUT
added tosystem/system_call.f90
(new file).
This procedure executes a command using the operating system shell and returns the output from the command.SUBROUTINE EXECUTE_COMMAND_GET_OUTPUT(command, output, stat, keep_empty_lines)
character(*), intent(in ) :: command
character(*), dimension(:), allocatable, intent(out) :: output
integer, optional, intent(out) :: stat
logical, optional, intent(in ) :: keep_empty_lines
- where
command
- Command passed to terminal to be executed
output
- Output generated from command, dimension is set to the number of non-empty/blank lines returned
stat
- Status generated from command. If not present and error occurs, invokesERROR STOP
. If present,OUTPUT
contains error message
keep_empty_lines
- If present, and TRUE, then empty/blank lines are included inOUTPUT
-
src/system/path_interface.f90
added additional procedures: andSUBROUTINE SET_TO_CWD(CWD, LENGTH)
FUNCTION GET_CWD()
returns the current working directory.SUBROUTINE SET_TO_CWD(CWD, LENGTH)
sets the variableCHARACTER(*):: CWD
to the current working directory and optional integer variable,LENGTH
, as the size of the character array.- Pretty much this routine just does
CWD = GET_CWD()
andLENGTH = LEN(GET_CWD())
- Note it is possible to have,
LENGTH > LEN(CWD)
, that caseCWD
does not hold the entire path. SUBROUTINE GET_FILE_EXTENSION(FILE_NAME, EXT)
given a file name returns the extension (anything after last.
)- For example:
"doc/myfile.txt"
would return"txt"
- For example:
-
src/io/generic_open_interface.fpp
subroutineGENERIC_OPEN()
added the optional argumentPOSITION
- All Fortran
OPEN(POSITION=)
strings are accepted.
However it is recommended to only use:POSITION="APPEND"
POSITION="ASIS"
POSITION="REWIND"
- If not specified, then it is set to
POSITION="REWIND"
.
- All Fortran
-
src/io/file_io_interface.f90
data typeUNIT_ARRAY_BUILDER
added theFUNCTION PRINT_STR()
type bound routine.- This routine is identical to
SUBROUTINE UNIT_ARRAY_BUILDER%PRINT(IOUT)
, except that it returns acharacter(*)
rather than writing to a file. - The function call is:
str = UNIT_ARRAY_BUILDER%PRINT_STR()
- This routine is identical to
-
src/io/post_key_sub.f90
added the optional argumentNO_WARN
toSUBROUTINE CHECK_FOR_POST_KEY
.-
If present, and set to
.TRUE.
will disable any warning messages when searching for a post-keyword option. -
This optional argument is also added:
-
src/io/generic_input_file_instruction.f90
in the routineGENERIC_INPUT%OPEN
-
src/io/generic_output_file_instruction.f90
in the routineGENERIC_OUTPUT%OPEN
-
-
-
Added test for
MODULE GENERIC_INPUT_FILE_INSTRUCTION
-
src/strings/num2str_interface.f90
added check for 0.0;
that is:NUM2STR(0.0)
returns'0.0'
instead of'0.00000000E+00'
-
All code was shifted to be within the first 132 columns to be compatible with gfortran.
-
Fortran 95 free format standard limits the file width to 132 columns.
-
Note, code still fails to compile with gfortran because it does not support the destructor statement
FINAL::
-
-
src/datetime/calendar_functions.f90
uses the functionjulianday_to_date(jdn_in, year_in, day, month, year, jdn, leap)
for converting Julian Day of the Year (jdn_in
) to a calendar month, day, and year. However ifjdn_in > 364
, then the routine would only check if year_in is a leap year rather than each interval of Julian days overlapped a leap year. This has been fixed to account the appropriate 365 and 366 day years. -
src/input_reader/uload_and_sfac_interface.f90
when loading aGENERIC_INPUT_FILE
variable withSUBROUTINE ULOAD_SCALAR
that has a specified unit number (IU /= 0
) reads an extra line fromIN
.- This effected
MODULE LIST_ARRAY_INPUT_INTERFACE
when usingTYPE GENERIC_LINE_INPUT
that reads a transient file reader (TFR) with theDATAFILE
orDATAUNIT
keyword (bypass TFR and read input directly). The resulting call to theMODULE TRANSIENT_FILE_READER_INSTRUCTION
reads a line to check forSFAC
, but sinceIU
is specified the extra read of the line is not needed because not file is parsed.
- This effected
-
src/system/directory_iso_c_binding.f90
FUNCTION MAKE_C_CHAR
takes a Fortran character type and converts it to a C-string. The function was modified to return a character array (correct method) instead of CHARACTER(*).- That is, the function previously returned:
CHARACTER(len=LEN(F_STR)+1, kind=C_CHAR)
now returns:
CHARACTER(len=1, kind=C_CHAR), DIMENSION(LEN(F_STR)+1)
- That is, the function previously returned:
-
C_LOC
requires argument that has either theTARGET
orPOINTER
attribute but does NOT supportALLOCATABLE
arrays. Routines that make use ofC_LOC
had the TARGET attribute added to incoming arrays. AlsoFUNCTION GET_C_LOC
was added that adds to an array theTARGET
attribute and returns itsC_LOC
. This effected the following files:src/util_misc/same_memory_address_interface.f90
src/dynamic_arrays/dynamic_array_int32.f90
-
src/math_numbers/number_conversion_interface.f90
MODULE NUMBER_CONVERSION_INTERFACE
converts all the major integer types from/to binary to decimal, octal, or hexadecimal. A set of parameters were added to ensure that zero and one comparisons are made with the same type integer as that of the routine. That is:-
converting INT8 to Octal uses only INT8 operations
-
converting INT16 to Octal uses only INT16 operations
-
converting INT32 to Octal uses only INT32 operations
-
converting INT64 to Octal uses only INT64 operations
-
-
makefile
added gfortran complier flag fno-range-check to prevent compiler errors. -
Sort routines removed redundant use of
USE ISO_FORTRAN_ENV
MODULE SORT_INTERFACE
contains a set ofSUBMODULE
s that sort each of the major Fortran data types. The problem is that aSUBMODULE
imports all the global variables from the parentMODULE
. The parent module has:
USE, INTRINSIC:: ISO_FORTRAN_ENV, ONLY: INT8, INT32, INT64, REL32=>REAL32, REL64=>REAL64
so that declaration is not necessary in the submodules.
-
Added
int( )
around BOZ constants (binary, octal, hexadecimal constants) to conform to Fortran standard.- For example, fortran standard requires the binary notation
b''
to be converted to the desired integer type:
int(b'1100000010000000', int32)
- For example, fortran standard requires the binary notation
-
Added decimal to literal real numbers in a variaty of files. For example, changes
1D0
to1.D0
-
src/datetime/calendar_functions.f90
src/datetime/date_operator_instruction.f90
src/math_numbers/EquationParser.f90
src/math_numbers/log2_interface.f90
src/math_numbers/secant_interface.f90
src/spatial/xy_grid_coordinate_interface.f90
src/types_and_containers/array_data_types_instruction.f90
src/types_and_containers/linked_list_instruction.f90
src/unit_test/unit_testing_instruction.f90
tests/src/main_tests.f90
-
-
src/math_numbers/descriptive_statistics.f90
changed the intent for theonline_stats%merge
routine fromintent(in)
tointent(inout)
- This routine was generic for
MERGE_OUT_SG_qp(st, st1, st2)
and changed:toSUBROUTINE MERGE_OUT_SG_qp(st, st1, st2) CLASS(ONLINE_STATS), intent(in):: st
SUBROUTINE MERGE_OUT_SG_qp(st, st1, st2) CLASS(ONLINE_STATS), intent(inout):: st
- This routine was generic for
-
Rewrite of
GENERIC_INPUT_FILE_INSTRUCTION
andGENERIC_OUTPUT_FILE_INSTRUCTION
modules to have consistent interfaces and code structure.- BREAKING CHANGE: This changed the order of optional arguments in
%OPEN()
for theGENERIC_INPUT_FILE
andGENERIC_OUTPUT_FILE
data types. However, they know use the same arguments, and argument order, in their common type bound procedures. This also changed some of the components in the data types to be the same name. In particular:-
The attribute
%NULL_FILE
replaced%SKIP
-
%IU == 0
only indicates implied internal, and added%IS_INTERNAL
to indicate if file is internal and%IU
is set the internal file unit. -
%IS_OPEN
is added and set to True if file is open andIU
is connected to a file, and False otherwise.
-
- BREAKING CHANGE: This changed the order of optional arguments in
-
src/io/generic_input_file_instruction.f90
andsrc/io/generic_output_file_instruction.f90
improved error messages. -
src/strings/parse_word_interface.f90
replaced" "
with theCONSTANT
module parameterBLNK
-
src/strings/string_routines.f90
embedded thePARSE_WORD
subroutine to increase the likelihood that the compiler will inline it for faster execution. This also removes the dependency on thePARSE_WORD_INTERFACE
module. -
src/input_reader/sub_block_input_interface.f90
removed unused module imports. -
src/input_reader/uload_and_sfac_interface.f90
changed.ne.
to/=
for clarity. -
src/input_reader/uload_and_sfac_interface.f90
switched toget_word
routine to replace using the following routines:comment_index()
,parse_word()
andupper()
. -
Convert all capital case error messages to sentence case.
-
Change all odd number check code from using IAND to BTEST.
-
The code previously used IAND to check if a number is odd with the following code:
IAND( num, 1 ) == 1
This bit folding only checks to see if the least significant bit is set, which indicates the number is odd. -
Rather than doing two operations, the code was changed to:
BTEST( num, 0 )
which returns TRUE if the lest significant bit is set.
-
-
Remove the integer type-spec from do concurrent-header for all source files that use it.
-
The gfortran compiler does not support the DO CONCURRENT type-spec in the concurrent-header. This has been removed to improve compatibility with gfortran. The following is an example of changed code.
- That is,
do concurrent ( integer:: i = 1 : 10 )
is changed to:
integer:: i
do concurrent (i = 1 : 10 )
- That is,
-
2022-2-09
Major release
Includes a new module WRITE_ARRAY_INTERFACE
that writes to a file 1D and 2D arrays.
This also includes a substantial improvement to the NUM2STR_INTERFACE
module.
-
src/strings/num2str_interface.f90
- now supports the Fortran data types:
INT8
,INT16
,INT32
,INT64
, andREAL32
,REAL64
- now supports the Fortran data types:
-
src/io/generic_input_file_instruction.f90
and
src/io/generic_output_file_instruction.f90
now offer nearly the same%open
interface.- All features that can be applied to both are now present in both.
-
src/io/write_array_interface.f90
added.-
MODULE WRITE_ARRAY_INTERFACE
provides the generic subroutineWRITE_ARRAY
. -
Supports writing of the
INT8
,INT16
,INT32
,INT64
, andREAL32
,REAL64
to a unit number of file name.- The array is written with the first dimension being along the rows.
For example, aDIMENSION(3,5)
array would write an array with 3 columns that occupy 5 lines of text.
- The array is written with the first dimension being along the rows.
-
DIMENSION(:)
, 1D, array interface
WRITE_ARRAY(IU, ARR, [WIDTH, FMT, SEP, TRANSPOSE, HED, SEP_ON_LAST, ADVANCE])
WRITE_ARRAY(FNAME, ARR, ERROR, [WIDTH, FMT, SEP, TRANSPOSE, HED, SEP_ON_LAST, ADVANCE, IU, NO_CLOSE])
-
DIMENSION(:,:)
, 2D, array interface
WRITE_ARRAY(IU, ARR, [WIDTH, FMT, SEP, TRANSPOSE, HED, SEP_ON_LAST])
WRITE_ARRAY(FNAME, ARR, ERROR, [WIDTH, FMT, SEP, TRANSPOSE, HED, SEP_ON_LAST, IU, NO_CLOSE])
-
where:
ARR
is the 1D or 2D array that is written to a file.character(*):: FNAME
is a file name write the array to.
If the file exists, it is over written.
If the file is already opened, then it is appended to.integer:: IU
is the unit number connected to an open file to write to.
IfFNAME
andIU
are provided, thenIU
is the unit number to open the file on.
IfFNAME
is provided andIU=0
, thenIU
is returned with theNEWUNIT
used to open the file.logical:: ERROR
is set to.TRUE.
if there is a problem opening the fileFNAME
, otherwise it is set to.FALSE.
.integer, optional:: WIDTH
Specify the minimum width when writing each number.
For example,WIDTH=12
will contain one number for every 12 characters.
If the number exceeds the width, then it will occupy the minimal space
to represent the number, plus 1 blank space afterwards.character(*), optional:: FMT
Specify a Fortran format edit descriptor kernel.
If specified, thenWIDTH
is ignored.
Each number is written using the format plus a 1 space buffer (1x
) between numbers.
If you want to disable the 1 space buffer you must specifySEP=""
The format kernel is a Fortran format code for a single number (does not contain the repeat count).
For example, the format codes are used to transfer integer valuesI
isnIw.m
This would not include the repeat count (n
) and
can optionally include the width (w
) and zero padding (m
).
This format, must match the array type (that is,I
for integer andF
,E
,EN
,ES
, orG
for real).
For example, to have real number output of width 8 and 3 decimal places, thenFMT = 'F8.3'
character(*), optional:: SEP
If present that the character appended to each number, except for the last one.
For example,SEP="A b"
would print the numbers 2, 4, 6 as "2A b4A b6
" and
SEP=", "
would print "2, 4, 6
". IfSEP
andFMT
are specified, thenSEP
is the separator between numbers and not the 1 space buffer.logical, optional:: TRANPOSE
If present and true, then the written array is tranposed.
Example 2D, an array withdimension(3,5)
with:
.false.
- writes an array with 3 columns that occupy 5 lines of text (default).
.true .
- writes an array with 5 columns that occupy 3 lines of text.
Example 1D, an array withdimension(3)
with:
.false.
- writes an array with 3 values along a single line of text (default).
.true .
- writes an array with 1 value per line, occupying a total of 3 lines of text.character(*), optional:: HED
If present, then it is written to the file before the actual array (a header).logical, optional:: SEP_ON_LAST
If present, set to.true.
andSEP
is defined, then the separator is added to the last number on each line.
For example,SEP=", "
andSEP_ON_LAST=.true.
would print the numbers 2, 4, 6 as "2, 4, 6,
"logical, optional:: ADVANCE
If present, and true, the a 1D array will not include a carriage return (new line) after the numbers are written.logical, optional:: NO_CLOSE
If present, and true, then the file that is opened is not closed when the routine exits. The unit number
-
src/system/path_interface.f90
functionIS_WINDOWS()
is optimized to store the if the OS is Windows or not with the SAVE attribute. This makes it so that theOS
environmental variable is checked once. Previously, each time the function was called would query the operating system environmental variable. A new option,always_check
is added to force the query the operating system environmental variable even if it has already been set.
src/types_and_containers/array_data_types_instruction.f90
subroutineSET_ID_VAL_TYPE_POS(TYP, POS, ID, VAL, INUL, NUL)
added the optional parametersINUL
andNUL
.- If
POS
is greater than the size ofID_VAL_TYPE
, which isN
, then it is expanded to includePOS
and theID
is set toINUL
andVAL
set toNUL
for the values located betweenN+1
andPOS-1
(inclusive).
- If
-
src/io/post_key_sub.f90
added the routinefile_and_post_key_parse
.- This routine given a
line
and starting position (lloc
) returns theline(istart:istop)
that contains the file directive that is used by generic input/output and any post-keywords. The return value also setslloc = istop + 1
. - This is useful if an input line contains multiple keywords in addition to a ULOAD or Generic Input or Generic Output.
- Note, this assumes that SF is used for any inline scale factors,
such as./input.txt SF 0.3048
and the multiline scale factor, SFAC, is not used. - For example, if an input expected 2 integers, 1 output file, and 2 integers,
then the input line might look like this:
2 4 ./output/results.txt BUF 64 SPLIT 1024 6 8
and given alloc=6
(before the./
) would setline(istart:istop)
to:
./output/results.txt BUF 64 SPLIT 1024
and setlloc=47
, which is just before the6 8
- This routine given a
src/strings/num2str_interface.f90
added a decimal place for real literals.- For example
1e5
, is treated by the compiler as the integer100000
rather than real. - To fix this, the number must be written as
1.e5
- For example
src/math_numbers/random_routines_interface.f90
fixed spelling errors.
2022-1-15
Minor release
src/types_and_containers/linked_list_instruction.f90
added aREAL64_LINKED_LIST
type.- This is a clone of
INTEGER_LINKED_LIST
, but instead constructs a list ofREAL64
floating point numbers.
- This is a clone of
src/system/path_interface.f90
functionIS_WINDOWS()
is optimized to store the if the OS is Windows or not with the SAVE attribute. This makes it so that theOS
environmental variable is checked once. Previously, each time the function was called would query the operating system environmental variable. A new option,always_check
is added to force the query the operating system environmental variable even if it has already been set.
src/types_and_containers/array_data_types_instruction.f90
subroutineSET_ID_VAL_TYPE_POS(TYP, POS, ID, VAL, INUL, NUL)
added the optional parametersINUL
andNUL
.- If
POS
is greater than the size ofID_VAL_TYPE
, which isN
, then it is expanded to includePOS
and theID
is set toINUL
andVAL
set toNUL
for the values located betweenN+1
andPOS-1
(inclusive).
- If
src/io/post_key_sub.f90
added the routinefile_and_post_key_parse
.- This routine given a
line
and starting position (lloc
) returns theline(istart:istop)
that contains the file directive that is used by generic input/output and any post-keywords. The return value also setslloc = istop + 1
. - This is useful if an input line contains multiple keywords in addition to a ULOAD or Generic Input or Generic Output.
- Note, this assumes that SF is used for any inline scale factors,
such as./input.txt SF 0.3048
and the multiline scale factor, SFAC, is not used. - For example, if an input expected 2 integers, 1 output file, and 2 integers,
then the input line might look like this:
2 4 ./output/results.txt BUF 64 SPLIT 1024 6 8
and given alloc=6
(before the./
) would setline(istart:istop)
to:
./output/results.txt BUF 64 SPLIT 1024
and setlloc=47
, which is just before the6 8
- This routine given a
src/error/error_interface.f90
minor spelling corrections.
2021-4-14
Minor release
src/io/post_key_sub.f90
routinecheck_for_post_key
added the optional logical inputonly_check
If present and true, then only moves LLOC past the post-keywords and does not process them.
sort
minor optimization by not sorting arrays of size 1.
sort
routines now always initialize the optional permutation vector (P
) if it is included in the subroutine call. Previously, if the array to be sorted was already sorted, thenP
was not initialized.
sort
2D array routines now correctly handle sorting when one of the dimensions is 1. That is, an array ofdimension(X,1)
ordimension(1,X)
whereX ≥ 1
. Previously, sort would pass the array to a 1D sort routine without checking if the array should be sorted or the dimension to sort on.
unit_testing_instruction.f90
file fixed theASSERT_UNIT_TEST_0D_NONZERO_XYZ
routines that specifiedWANT
as being logical rather than the correspondingXYZ
type being checked against.
src/datetime/date_operator_instruction.f90
fixed format error fordate_operator%str_dyear()
Minor refactoring that converted .NE.
to /=
and indentation for:
src/io/generic_input_file_instruction.f90
src/io/generic_open_interface.fpp
src/math_numbers/EquationParser.f90
src/strings/parse_word_interface.f90
2020-10-28
Initial Release.