From c0141b3a39e7a2f0b611bf127b4d442d2439dcec Mon Sep 17 00:00:00 2001 From: Brad Richardson Date: Tue, 26 Jan 2016 13:32:02 -0600 Subject: [PATCH 001/325] Change how python is called - This is for a system where /usr/bin/python points to 2.6, but /usr/bin/env python runs 2.7. --- fort_depend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 03cd8cc..08b9a84 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python import os import re From 78c275ef009f9249ec26571f9b2c9d58b92e5b12 Mon Sep 17 00:00:00 2001 From: Gaetan Kenway Date: Tue, 30 Aug 2016 12:16:20 -0400 Subject: [PATCH 002/325] Check if a file depends on itself and not include it in the depends list. Also slight modification to use regex to not detect variables starting with use --- fort_depend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 60484dc..0538790 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -77,7 +77,7 @@ def create_file_objs(files=None, macros={}): def get_uses(infile=None, macros={}): "Return which modules are used in infile after expanding macros" - p=re.compile("^\s*use\s*(?P\w*)\s*(,)?\s*(only)?\s*(:)?.*?$",re.IGNORECASE).match + p=re.compile("^\s*use\s+(?P\w*)\s*(,)?\s*(only)?\s*(:)?.*?$",re.IGNORECASE).match uses=[] @@ -130,10 +130,10 @@ def get_depends(fob=[],m2f=[]): tmp=[] for j in i.uses: try: - tmp.append(m2f[j.lower()]) + if m2f[j.lower()] != i.file_name: + tmp.append(m2f[j.lower()]) except: print "\033[031mError\033[039m module \033[032m"+j+"\033[039m not defined in any files. Skipping..." - deps[i.file_name]=tmp return deps From 4ea85bc5e73c4f07060eb87136340874009e6574 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 22 Oct 2016 21:46:26 -0600 Subject: [PATCH 003/325] update for files in different directories if file uses module in whose original file is in different direcotry, add it to the list on dependency file but do not check it any more --- fort_depend.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 60484dc..16e1b2c 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -10,10 +10,10 @@ def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): depends=get_depends(fob=l,m2f=mod2fil) if verbose: - for i in depends.keys(): - print "\033[032m"+i+"\033[039m depends on :\033[034m" - for j in depends[i]: print "\t"+j - print "\033[039m" + for i in depends.keys(): + print ("\033[032m"+i+"\033[039m depends on :\033[034m") + for j in depends[i]: print( "\t"+j) + print ("\033[039m") if output is None: output = "makefile.dep" @@ -27,7 +27,7 @@ def write_depend(outfile="makefile.dep",dep=[],overwrite=False,build=''): #Test file doesn't exist if os.path.exists(outfile): if not(overwrite): - print "\033[031mWarning file exists.\033[039m" + print ("\033[031mWarning file exists.\033[039m") opt=raw_input("Overwrite? Y... for yes.") else: opt="y" @@ -131,8 +131,10 @@ def get_depends(fob=[],m2f=[]): for j in i.uses: try: tmp.append(m2f[j.lower()]) - except: - print "\033[031mError\033[039m module \033[032m"+j+"\033[039m not defined in any files. Skipping..." + except KeyError: + tmp.append(j.lower()) + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") + print ("adding it to dependency file but not checking it any further \033[032m") deps[i.file_name]=tmp From 16f05d693446ecc10fdcd4d0aa46368ad16d531b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 23 Oct 2016 10:34:31 -0600 Subject: [PATCH 004/325] complete update for project which has modules located in different directories - the script now looks into all directories in project root dorectory and tries to find modules in there too additional parameter -r PATH where PATH is path to project root directory --- fort_depend.py | 105 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 11 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 16e1b2c..c9730e4 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,13 +1,24 @@ #!/usr/bin/python import os import re +import glob +import fnmatch +import os +import sys #Definitions -def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): + + cwd = os.getcwd() + + path = check_path(path=path) + cwd = check_path(path=cwd) + + ff=get_all_files(path=path) l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) - depends=get_depends(fob=l,m2f=mod2fil) + depends=get_depends(fob=l,m2f=mod2fil,ffiles=ff) if verbose: for i in depends.keys(): @@ -18,11 +29,11 @@ def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): if output is None: output = "makefile.dep" - tmp=write_depend(outfile=output,dep=depends,overwrite=overwrite,build=build) + tmp=write_depend(path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) return depends -def write_depend(outfile="makefile.dep",dep=[],overwrite=False,build=''): +def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): "Write the dependencies to outfile" #Test file doesn't exist if os.path.exists(outfile): @@ -43,8 +54,17 @@ def write_depend(outfile="makefile.dep",dep=[],overwrite=False,build=''): tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") for j in dep[i]: - tmp,fil=os.path.split(j) - stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") + npathseg = j.count('/') + if npathseg == 0: + tmp,fil=os.path.split(j) + else: + fil = get_relative_path_name(j,path=path,cwd=cwd) + + if "../" in fil: + stri = stri + " \\\n\t" + fil + else: + stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") + stri=stri+"\n" f.write(stri) f.close() @@ -58,6 +78,33 @@ def get_source(ext=[".f90",".F90"]): fil.extend(filter(lambda x: x.endswith(i),tmp)) return fil +def get_all_files(path): + #l=[] + + #for filename in glob.iglob('/home/jka/OSS_CFD/trunk/**/*.f90', recursive=True): + #print(filename) + #l.append(filename) + + #return l + + matches = [] + for root, dirnames, filenames in os.walk(path): + for filename in fnmatch.filter(filenames, '*.f90'): + matches.append(os.path.join(root, filename)) + + return matches + +def check_if_there(use,file): + "return if you see module name" + with open(file) as f: + for line in f: + if "module" in line.lower(): + if use in line: + return 1 + + return 0 + + def create_file_objs(files=None, macros={}): l=[] @@ -124,7 +171,7 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(fob=[],m2f=[]): +def get_depends(fob=[],m2f=[], ffiles=[]): deps={} for i in fob: tmp=[] @@ -132,14 +179,44 @@ def get_depends(fob=[],m2f=[]): try: tmp.append(m2f[j.lower()]) except KeyError: - tmp.append(j.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") - print ("adding it to dependency file but not checking it any further \033[032m") + for k in ffiles: + retval=check_if_there(use=j,file=k) + if retval > 0: + name=os.path.splitext(k)[0]+'.o' + tmp.append(name.lower()) + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") + print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") + print ("\033[031m..... \033[039m adding it to dependency file, not checking its dependency further \033[032m") deps[i.file_name]=tmp return deps +def check_path(path): + if path.endswith("/"): + print("Path correct") + else: + print( "adding / to the path in "+path) + path=path + "/" + + return path + +def get_relative_path_name(file,path,cwd): + length = len(path) + #tmp,fil=os.path.split(j) + filetmp = file + fil = filetmp.replace(filetmp[:length], '') + + loccwd = cwd + loccwd = loccwd.replace(loccwd[:length], '') + + npathseg = loccwd.count('/') + for x in range(0, npathseg): + fil = "../"+fil + + return fil + + class file_obj: def __init__(self): self.file_name=None @@ -162,6 +239,7 @@ def __init__(self): parser.add_argument('-o','--output',nargs=1,help='Output file') parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') + parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') # Parse the command line arguments args = parser.parse_args() @@ -176,5 +254,10 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' + root_dir = args.root_dir[0] if args.root_dir else None + + if not root_dir: + print ("\033[031mError: \033[039m missing path to project root directory \033[032m") + sys.exit() - run(files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(path=root_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From c882f9bb7d862b2e49849c21c3d7d82117566a02 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 26 Oct 2016 21:27:50 -0600 Subject: [PATCH 005/325] Initial commit --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f404b36 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# fll \ No newline at end of file From 1ae65315b97f098548d4f331a1bb47afb5b804ab Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 26 Oct 2016 21:28:46 -0600 Subject: [PATCH 006/325] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f404b36..9e32f96 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# fll \ No newline at end of file +# fll is a fortran linked list library From a4758b04ad5778f927c71aeb5c143971eb5035ac Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 26 Oct 2016 21:31:27 -0600 Subject: [PATCH 007/325] initial commit --- ERR_LINE_IDEF_SCRIPT | 42 +++ config.mk | 42 +++ data_util/ERR_LINE_IDEF_SCRIPT | 42 +++ data_util/Makefile | 34 ++ data_util/ll_cat.f90 | 215 +++++++++++++ data_util/ll_cp.f90 | 237 ++++++++++++++ data_util/ll_deattach.f90 | 76 +++++ data_util/ll_duplicate.f90 | 407 ++++++++++++++++++++++++ data_util/ll_funct_prt.f90 | 86 ++++++ data_util/ll_locate.f90 | 135 ++++++++ data_util/ll_mk.f90 | 191 ++++++++++++ data_util/ll_mods.f90 | 20 ++ data_util/ll_modules | 10 + data_util/ll_mv.f90 | 194 ++++++++++++ data_util/ll_nnodes.f90 | 124 ++++++++ data_util/ll_read.f90 | 545 +++++++++++++++++++++++++++++++++ data_util/ll_rm.f90 | 256 ++++++++++++++++ data_util/ll_stich.f90 | 111 +++++++ data_util/ll_sweep.f90 | 101 ++++++ data_util/ll_type.f90 | 109 +++++++ data_util/ll_write.f90 | 396 ++++++++++++++++++++++++ data_util/project.dep | 79 +++++ data_util/reshape | 8 + data_util/src_dir_path | 1 + fort_depend.py | 263 ++++++++++++++++ rules.mk | 78 +++++ src_dir_path | 1 + test/Makefile | 45 +++ test/ll_test.f90 | 142 +++++++++ test/project.dep | 4 + test/src_dir_path | 1 + 31 files changed, 3995 insertions(+) create mode 100755 ERR_LINE_IDEF_SCRIPT create mode 100644 config.mk create mode 100755 data_util/ERR_LINE_IDEF_SCRIPT create mode 100644 data_util/Makefile create mode 100644 data_util/ll_cat.f90 create mode 100644 data_util/ll_cp.f90 create mode 100644 data_util/ll_deattach.f90 create mode 100644 data_util/ll_duplicate.f90 create mode 100644 data_util/ll_funct_prt.f90 create mode 100644 data_util/ll_locate.f90 create mode 100644 data_util/ll_mk.f90 create mode 100644 data_util/ll_mods.f90 create mode 100644 data_util/ll_modules create mode 100644 data_util/ll_mv.f90 create mode 100644 data_util/ll_nnodes.f90 create mode 100644 data_util/ll_read.f90 create mode 100644 data_util/ll_rm.f90 create mode 100644 data_util/ll_stich.f90 create mode 100644 data_util/ll_sweep.f90 create mode 100644 data_util/ll_type.f90 create mode 100644 data_util/ll_write.f90 create mode 100644 data_util/project.dep create mode 100644 data_util/reshape create mode 100644 data_util/src_dir_path create mode 100755 fort_depend.py create mode 100644 rules.mk create mode 100644 src_dir_path create mode 100644 test/Makefile create mode 100644 test/ll_test.f90 create mode 100644 test/project.dep create mode 100644 test/src_dir_path diff --git a/ERR_LINE_IDEF_SCRIPT b/ERR_LINE_IDEF_SCRIPT new file mode 100755 index 0000000..2bab129 --- /dev/null +++ b/ERR_LINE_IDEF_SCRIPT @@ -0,0 +1,42 @@ +#/bin/csh + + + set file_list=`find ./ -iname "*.f90"` + + foreach file ($file_list) + + echo $file + + set LINENUM = `sed -n '/ALLOCATING MEMORY/=' "$file"` + echo $LINENUM + + foreach num ($LINENUM) + + set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` + echo $text + + sed -i ''$num's/ALLOCATING MEMORY.*$/'"$text"' APOStroPHE/' $file + + end + sed -i "s/APOStroPHE/\'/g" $file + + end + + foreach file ($file_list) + + echo $file + + set LINENUM = `sed -n '/ALLOCATING ARRAYS/=' "$file"` + echo $LINENUM + + foreach num ($LINENUM) + + set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` + echo $text + + sed -i ''$num's/ALLOCATING ARRAYS.*$/'"$text"' APOStroPHE/' $file + + end + sed -i "s/APOStroPHE/\'/g" $file + + end diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..f26bf05 --- /dev/null +++ b/config.mk @@ -0,0 +1,42 @@ + +SHELL = /bin/bash +# +# Compilers and flags +# +FC = gfortran +FCMODINCFLAG = -I +FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +UPPER_MODFILE_NAME = +LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp +CC = gcc -fopenmp +CFLAGS = -g -fopenmp +C_LDFLAGS = -g -fopenmp +MPI_FC = mpif90 +MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp +# +# Global settings. +# +# prefix is the base directory where executables will be installed. +# +prefix = /home/jka/OSS_CFD/exec/data_util/exec/x86_64 +# +# MACHINE identifies the host machine type +# +MACHINE = x86_64 +# +# Install command (or cp -p if install is not found) +# +INSTALL = install -c +# +# Optional external libraries +# An empty definition means that this library is not available. +# +LIBM3L = -L/home/jka/Cprograms/Sources/libm3l/Source/ -lm3l -Wl,-rpath=/home/jka/Cprograms/Sources/libm3l/Source/ -lpthread +LSIPDX = -L/home/jka/Cprograms/Sources/lsipdx/Source -llsipdx -Wl,-rpath=/home/jka/Cprograms/Sources/lsipdx/Source +LIBM3LPATH = /home/jka/Cprograms/Sources/libm3l/Source/ +LSIPDXPATH = /home/jka/Cprograms/Sources/lsipdx/Source + +MAKEDEPEND=/home/jka/OSS_CFD/trunk/fort_depend.py + diff --git a/data_util/ERR_LINE_IDEF_SCRIPT b/data_util/ERR_LINE_IDEF_SCRIPT new file mode 100755 index 0000000..2bab129 --- /dev/null +++ b/data_util/ERR_LINE_IDEF_SCRIPT @@ -0,0 +1,42 @@ +#/bin/csh + + + set file_list=`find ./ -iname "*.f90"` + + foreach file ($file_list) + + echo $file + + set LINENUM = `sed -n '/ALLOCATING MEMORY/=' "$file"` + echo $LINENUM + + foreach num ($LINENUM) + + set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` + echo $text + + sed -i ''$num's/ALLOCATING MEMORY.*$/'"$text"' APOStroPHE/' $file + + end + sed -i "s/APOStroPHE/\'/g" $file + + end + + foreach file ($file_list) + + echo $file + + set LINENUM = `sed -n '/ALLOCATING ARRAYS/=' "$file"` + echo $LINENUM + + foreach num ($LINENUM) + + set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` + echo $text + + sed -i ''$num's/ALLOCATING ARRAYS.*$/'"$text"' APOStroPHE/' $file + + end + sed -i "s/APOStroPHE/\'/g" $file + + end diff --git a/data_util/Makefile b/data_util/Makefile new file mode 100644 index 0000000..e4d562c --- /dev/null +++ b/data_util/Makefile @@ -0,0 +1,34 @@ +############################################################################ +# Makefile for data_util library +############################################################################ +# +include src_dir_path +include ../config.mk + +# $(DEP_FILE) is a .dep file generated by fort_depend.py +DEP_FILE = project.dep + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) + +########################################################################### + +all: $(OFILES) +include ../rules.mk + +clean: + rm -f *.o *.mod + +test: + @echo No tests exist, yet. + + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk/ -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + + +-include $(srcdir)/$(DEP_FILE) + diff --git a/data_util/ll_cat.f90 b/data_util/ll_cat.f90 new file mode 100644 index 0000000..26abc15 --- /dev/null +++ b/data_util/ll_cat.f90 @@ -0,0 +1,215 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_CAT +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints linked list +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_CAT_M +CONTAINS + + SUBROUTINE LL_CAT(PNODE,IOUNIT,FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE,PCHILD + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + INTEGER(LINT) :: POS +! +! LOCAL TYPES +! +! +! BODY OF SUBROUTINE +! + + POS = 0 + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' CAT - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PCHILD => PNODE%PCHILD + IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' NODE HAS A PARENT, NAME IS ', PNODE%PPAR%LNAME + CALL LL_PRINT(PNODE, IOUNIT, POS, FPAR) +! +! IF NODE HAS CHILDREN PRINT THEM TOO +! + IF(ASSOCIATED(PCHILD))CALL LL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + + FPAR%SUCCESS = .TRUE. + + RETURN + END SUBROUTINE LL_CAT +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE LL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: POS + + TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD + INTEGER :: IOUNIT +! +! IF NODE HAS CHILDREN +! + PCURR => PNODE +! +! IF CHILDREN, PRINT THEM TOO +! + DO WHILE(ASSOCIATED(PCURR)) + + CALL LL_PRINT(PCURR, IOUNIT, POS, FPAR) + + PNEXT => PCURR%PNEXT + PCHILD => PCURR%PCHILD + IF(ASSOCIATED(PCHILD))THEN + CALL LL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + END IF + + PCURR => PNEXT + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE LL_CAT_RECURSIVE_NODE +! +! FREE MEMORY FOR NODE +! + SUBROUTINE LL_PRINT(PNODE, IOUNIT, POS, FPAR) + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: IOUNIT + INTEGER(LINT) :: POS,I,J,NDIM,NSIZE + LOGICAL :: SAVED + + SAVED = .FALSE. + + NDIM = 3 + NSIZE = 3 + + POS = POS + 1 +! +! 1D ARRAYS +! + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN +! WRITE(IOUNIT, *, FORMAT = 100)PNODE%LTYPE, PNODE%LNAME, PNODE%NDIM + WRITE(IOUNIT, *)TRIM(PNODE%LTYPE),' ', TRIM(PNODE%LNAME),' ', PNODE%NDIM + ELSE +! WRITE(IOUNIT, *, FORMAT = 110)PNODE%LTYPE, PNODE%LNAME, PNODE%NDIM, PNODE%NSIZE + WRITE(IOUNIT, *)TRIM(PNODE%LTYPE),' ', TRIM(PNODE%LNAME),' ', PNODE%NDIM, PNODE%NSIZE + END IF +! +! 1 D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + WRITE(IOUNIT, *)(PNODE%R1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + WRITE(IOUNIT, *)(PNODE%D1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + WRITE(IOUNIT, *)(PNODE%I1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) + SAVED = .TRUE. +! +! 2D ARRAYS +! + ELSE IF(ASSOCIATED(PNODE%R2))THEN + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + WRITE(IOUNIT, *)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + END IF +! +! CHECK IF NODE IS CONSTANT +! + IF(.NOT.SAVED)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT, *)PNODE%R0 + CASE('D') + WRITE(IOUNIT, *)PNODE%D0 + CASE('I') + WRITE(IOUNIT, *)PNODE%I0 + CASE('L') + WRITE(IOUNIT, *)PNODE%L0 + + CASE DEFAULT + + END SELECT + END IF + + POS = POS - 1 + RETURN +!100 FORMAT('-',A,) + END SUBROUTINE LL_PRINT + + +END MODULE LL_CAT_M diff --git a/data_util/ll_cp.f90 b/data_util/ll_cp.f90 new file mode 100644 index 0000000..e6d8dda --- /dev/null +++ b/data_util/ll_cp.f90 @@ -0,0 +1,237 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_CP +! +! Date: 2016-10-10 +! +! +! +! +! Description: moves or copies node +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_CP_M +CONTAINS + + FUNCTION LL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) +! +! FUNCTIONS COPIES PHAT TO PWHERE. +! IF PWHERE IS NULL, PWHAT WILL +! +! +! INPUT PARAMETERS: +! + USE LL_TYPE_M + USE LL_MV_M + USE LL_DUPLICATE_M + USE LL_CAT_M + + IMPLICIT NONE + TYPE(DNODE), POINTER :: PWHAT,PWHERE + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNEW + + NULLIFY(PNEW) + + IF(.NOT.ASSOCIATED(PWHAT))THEN + WRITE(*,*)' Cp - SOURCE IS NULL NODE' + WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + IF(.NOT.ASSOCIATED(PWHERE))THEN +! +! IF NOT SPECIFIED WHERE TO COPY +! JUST DUPLICATE NODE +! + PNEW => LL_DUPLICATE(PWHAT, FPAR) + ELSE +! +! DUPLICATE NODE AND MOVE IT +! TO PWHERE +! + PNEW => LL_CP_R(PWHAT,PWHERE,'C',FPAR) + END IF + + RETURN + END FUNCTION LL_CP + + + FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + + USE LL_TYPE_M + USE LL_RM_M + USE LL_STICH_M + USE LL_DUPLICATE_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + TYPE(DNODE), POINTER :: PWHAT,PWHERE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE +! +! LOCAL TYPES +! + TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& + PLAST, PSOURCETMP,PCHILD,PNEW +! +! BODY OF SUBROUTINE +! + PSOURCETMP => NULL() + + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PWHAT))THEN + WRITE(*,*)' Cp - SOURCE IS NULL NODE' + WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + IF(.NOT.ASSOCIATED(PWHERE))THEN + WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! + PTNEXT => PWHERE%PNEXT + PTPREV => PWHERE%PPREV + PTPAR => PWHERE%PPAR + + IF(MODE == 'C')THEN + PNEW => LL_DUPLICATE(PWHAT, FPAR) + PSOURCETMP => PNEW +! +! IN CASE NODE IS NOT COPIED ANYWAY, IT IS ONLY DUPLICATED, RETURN +! + IF(.NOT.ASSOCIATED(PWHERE)) RETURN + ELSE + PSOURCETMP => PWHAT + END IF +! +! GET TYPE OF TARGET NODE +! DISTINGUISH BETWEEN DIR, OTHER TYPES +! + SELECT CASE(PWHERE%LTYPE) + + CASE('N','DIR') +! +! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM +! + IF(MODE == 'M') CALL LL_STICH(PWHAT,FPAR) + + IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN +! +! DIR IS EMPTY +! + PWHERE%PCHILD => PSOURCETMP + PSOURCETMP%PPAR => PWHERE + PSOURCETMP%PPREV => NULL() + PSOURCETMP%PNEXT => NULL() + PWHERE%NDIM = 1 + + ELSE +! +! DIR HAS ALREADY CHILDREN, ADD TO THE END +! + PCHILD => PWHERE%PCHILD + DO WHILE(ASSOCIATED(PCHILD)) + PLAST => PCHILD + PCHILD => PCHILD%PNEXT + END DO + + PLAST%PNEXT => PSOURCETMP + PSOURCETMP%PPREV => PLAST + PSOURCETMP%PNEXT => NULL() + PSOURCETMP%PPAR => PWHERE + PWHERE%NDIM = PWHERE%NDIM + 1 + + END IF + + CASE DEFAULT +! +! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN +! DELETE TARGET NODE +! + CALL LL_RM(PWHERE, FPAR) +! +! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM +! + IF(MODE == 'M') CALL LL_STICH(PSOURCETMP,FPAR) +! +! ADD A NEW NODE +! + IF(.NOT.ASSOCIATED(PTPREV))THEN +! +! PWHERE WAS THE FIRST NODE IN THE LIST +! + PTPAR%PCHILD => PSOURCETMP + PSOURCETMP%PPAR => PTPAR + PSOURCETMP%PPREV => NULL() + PTPAR%NDIM = PTPAR%NDIM + 1 + + IF(ASSOCIATED(PTNEXT))THEN + PSOURCETMP%PNEXT => PTNEXT + ELSE + PSOURCETMP%PNEXT => NULL() + END IF + + ELSE +! +! NODE NOT THE FIRST IN THE LINE +! + PTPREV%PNEXT => PSOURCETMP + PSOURCETMP%PPREV => PTPREV + + IF(ASSOCIATED(PTNEXT))THEN + PSOURCETMP%PNEXT => PTNEXT + ELSE + PSOURCETMP%PNEXT => NULL() + END IF + PTPAR%NDIM = PTPAR%NDIM + 1 + + END IF + + END SELECT + + FPAR%SUCCESS = .TRUE. + + RETURN + END FUNCTION LL_CP_R + +END MODULE LL_CP_M diff --git a/data_util/ll_deattach.f90 b/data_util/ll_deattach.f90 new file mode 100644 index 0000000..ef50e59 --- /dev/null +++ b/data_util/ll_deattach.f90 @@ -0,0 +1,76 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_DEATTACH +! +! Date: 2016-10-10 +! +! +! +! +! Description: DEATTACHES NODE FROM THE LIST +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_DEATTACH_M +CONTAINS + + FUNCTION LL_DEATTACH(PWHAT,FPAR) RESULT(OK) + USE LL_TYPE_M + USE LL_STICH_M + IMPLICIT NONE + TYPE(DNODE), POINTER :: PWHAT + TYPE(FUNC_DATA_SET) :: FPAR + LOGICAL:: OK + + OK = .FALSE. + IF(.NOT.ASSOCIATED(PWHAT))THEN + WRITE(FPAR%MESG,'(A,A)')' Deattach - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM +! + CALL LL_STICH(PWHAT,FPAR) + PWHAT%PPAR => NULL() + PWHAT%PNEXT => NULL() + PWHAT%PPREV => NULL() + + FPAR%SUCCESS = .TRUE. + OK = .TRUE. + RETURN + END FUNCTION LL_DEATTACH + +END MODULE LL_DEATTACH_M diff --git a/data_util/ll_duplicate.f90 b/data_util/ll_duplicate.f90 new file mode 100644 index 0000000..aefa95e --- /dev/null +++ b/data_util/ll_duplicate.f90 @@ -0,0 +1,407 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_duplicate +! +! Date: 2016-10-10 +! +! +! +! +! Description: duplicates node with its children +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_DUPLICATE_M +CONTAINS + + FUNCTION LL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) + + USE LL_TYPE_M + USE LL_MK_M + USE LL_MV_M + + IMPLICIT NONE +! +! SUBROUTINE DUPLICATE NODE +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL TYPES +! + TYPE(DNODE), POINTER :: PCHILD +! +! BODY OF SUBROUTINE +! + PNEW => NULL() + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PCHILD => PNODE%PCHILD +! +! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM +! + IF(ASSOCIATED(PCHILD))THEN + PNEW => LL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + CALL LL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) + IF(.NOT.FPAR%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + ELSE +! +! NODE IS A FILE NODE +! + PNEW => LL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL LL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + + END IF + + FPAR%SUCCESS = .TRUE. + RETURN + + END FUNCTION LL_DUPLICATE +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) + + USE LL_TYPE_M + USE LL_MK_M + USE LL_MV_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR + + TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD + LOGICAL :: OK +! + PCURR => PNODE + PCHILD => PNODE%PCHILD +! +! NODE IS A FILE NODE +! + IF(.NOT.ASSOCIATED(PCHILD))THEN + + PNEW => LL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL LL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) + OK = LL_MV(PNEW, PDUPL, FPAR) + FPAR%SUCCESS = .TRUE. + ELSE +! +! NODE IS DIR +! LOOP OVER CHILDREN +! + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD + + PNEW => LL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF +! +! NODE HAS CHILDREN +! + DO WHILE(ASSOCIATED(PCHILD)) + + CALL LL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' + PCHILD => PCHILD%PNEXT + + END DO +! +! ADD TO PDUPL LIST +! + OK = LL_MV(PNEW,PDUPL,FPAR) + PCURR => PNEXT + + END DO + END IF + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE +! +! FREE MEMORY FOR NODE +! + SUBROUTINE LL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER(LINT) :: NDIM, NSIZE, NNDIM, NNSIZE + + IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! COPY JUST NAME AND TYPE +! THE REST IS GOING TO BE AUTOMATIC +! + PNEW%LNAME = PNODE%LNAME + PNEW%LTYPE = PNODE%LTYPE +! +! IF DIR NODE, RETURN +! + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR. TRIM(PNODE%LTYPE) == 'N') RETURN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%R1))THEN + NNDIM = SIZE(PNEW%R1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%R1 = PNODE%R1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%D1))THEN + NNDIM = SIZE(PNEW%D1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%D1 = PNODE%D1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%I1))THEN + + NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%I1))THEN + NNDIM = SIZE(PNEW%I1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%L1))THEN + NNDIM = SIZE(PNEW%L1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%L1 = PNODE%L1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%R2))THEN + NNDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%R2 = PNODE%R2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%D2))THEN + NNDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%D2 = PNODE%D2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%I2))THEN + NNDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%I2 = PNODE%I2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%L2))THEN + NNDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%L2 = PNODE%L2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + PNEW%R0 = PNODE%R0 + PNEW%D0 = PNODE%D0 + PNEW%I0 = PNODE%I0 + PNEW%L0 = PNODE%L0 + PNEW%S = PNODE%S + + END SUBROUTINE LL_COPPY_NODE_ARRAYS + + +END MODULE LL_DUPLICATE_M diff --git a/data_util/ll_funct_prt.f90 b/data_util/ll_funct_prt.f90 new file mode 100644 index 0000000..8b3143f --- /dev/null +++ b/data_util/ll_funct_prt.f90 @@ -0,0 +1,86 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_FUNC_PRT_M +! +! Date: 2016-10-10 +! +! +! +! +! Description: Finds node in a chain +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_FUNC_PRT_M +CONTAINS + + FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) + + USE LL_TYPE_M + IMPLICIT NONE + CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=TYPE_LENGTH) :: NTYPE + + CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG + + WRITE(MESG,'(A,A,A,A,A)')' Array ', TRIM(NAME),' TYPE ',TRIM(NTYPE),' not associated' + RETURN + END FUNCTION ERR_MSG + + FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) +! + USE LL_TYPE_M + IMPLICIT NONE + INTEGER :: IOSTAT + TYPE(FUNC_DATA_SET) :: FPAR + LOGICAL :: OK +! + OK = .FALSE. + IF (IOSTAT > 0) THEN + WRITE(FPAR%MESG,'(A)')' Read - error readig node data' + FPAR%SUCCESS = .FALSE. + ELSE IF (IOSTAT < 0) THEN + WRITE(FPAR%MESG,'(A)')' Read - EOF reached' + FPAR%SUCCESS = .FALSE. + ELSE + FPAR%SUCCESS = .TRUE. + OK =.TRUE. + END IF +! + RETURN +! + END FUNCTION TEST_IOSTAT + +END MODULE LL_FUNC_PRT_M diff --git a/data_util/ll_locate.f90 b/data_util/ll_locate.f90 new file mode 100644 index 0000000..ca51eaa --- /dev/null +++ b/data_util/ll_locate.f90 @@ -0,0 +1,135 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_LOCATE +! +! Date: 2016-10-10 +! +! +! +! +! Description: Finds node in a chain +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_LOCATE_M +CONTAINS + + RECURSIVE FUNCTION LL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) + + USE LL_TYPE_M + USE LL_FUNC_PRT_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LICOMPIL) :: NUMBER + LOGICAL :: RECURSE +! +! LOCAL TYPES +! + CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE + TYPE(DNODE), POINTER :: PCURR, PCHLD + INTEGER(LICOMPIL) :: LOCNUM,I +! +! BODY OF FUNCTION +! + NULLIFY(PFIND) + I = 1 + DO WHILE(LTYPE(I:I) == ' ') + I = I + 1 + END DO + + TLTYPE = TRIM(LTYPE(I:)) + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + + PCURR => PNODE%PCHILD + IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN + WRITE(*,*)' NODE NOT DIR NODE' + RETURN + END IF + + LOCNUM = 1 + DO WHILE(ASSOCIATED(PCURR)) +! +! IF RECURSIVE DO NOT CONSIDER NUMBERING AND RETURN THE FIRST FOUND NODE +! + IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN + PCHLD => PCURR%PCHILD + PFIND => LL_LOCATE(PCHLD,NAME,1_LICOMPIL,LTYPE,RECURSE,FPAR) + IF(ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .TRUE. + RETURN + END IF + END IF +! +! LOOK FOR NODE +! + IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(PCURR%LNAME) == '*') .AND. & + (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN + + IF(LOCNUM == NUMBER)THEN + PFIND => PCURR + RETURN + ELSE + LOCNUM = LOCNUM + 1 + END IF + + END IF + PCURR => PCURR%PNEXT + + END DO +! +! END OF LINKED LIST +! + PFIND => NULL() + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) + + RETURN + END FUNCTION LL_LOCATE + + +END MODULE LL_LOCATE_M diff --git a/data_util/ll_mk.f90 b/data_util/ll_mk.f90 new file mode 100644 index 0000000..78f6613 --- /dev/null +++ b/data_util/ll_mk.f90 @@ -0,0 +1,191 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_MK +! +! Date: 2016-10-19 +! +! +! +! +! Description: make nodes +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_MK_M +CONTAINS + + FUNCTION LL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) + + USE LL_TYPE_M + + IMPLICIT NONE + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNEW + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NDIM, NSIZE + + INTEGER :: ISTAT + + PNEW => NULL() +! +! Body +! + IF(LEN_TRIM(LTYPE)<1.OR.LEN_TRIM(LTYPE)>TYPE_LENGTH) THEN + WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) + RETURN + END IF + + IF(LEN_TRIM(NAME)>NAME_LENGTH) THEN + WRITE(FPAR%MESG,'(A,A)')' Wrong name: ',TRIM(NAME) + RETURN + END IF + + IF(.NOT.ANY(LTYPE(1:1)==(/'C','S','I','L','R','D','N'/))) THEN + WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) + RETURN + END IF + + ALLOCATE(PNEW, STAT = ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:82 ' + PNEW%LNAME = TRIM(NAME) + PNEW%LTYPE = LTYPE + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + PNEW%NDIM = 0 + PNEW%NSIZE = 0 + RETURN + ELSE + PNEW%NDIM = NDIM + PNEW%NSIZE = NSIZE + END IF + + PNEW%PPAR => NULL() + PNEW%PCHILD => NULL() + PNEW%PPREV => NULL() + PNEW%PNEXT => NULL() + PNEW%PLINK => NULL() + + IF(NDIM < 1 .OR. NSIZE < 1)THEN + WRITE(*,*)' WRONG DIMENSIONS ' + STOP + END IF +! +! ALLOCATE ARRAYS +! + SELECT CASE(LTYPE) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + ALLOCATE(PNEW%R1(NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:106 ' + END IF + ELSE + IF(NSIZE == 1)THEN + ALLOCATE(PNEW%R1(NDIM), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:111 ' + ELSE + ALLOCATE(PNEW%R2(NDIM,NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:114 ' + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + ALLOCATE(PNEW%D1(NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:122 ' + END IF + ELSE + IF(NSIZE == 1)THEN + ALLOCATE(PNEW%D1(NDIM), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:127 ' + ELSE + ALLOCATE(PNEW%D2(NDIM,NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:130 ' + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + ALLOCATE(PNEW%I1(NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:139 ' + END IF + ELSE + IF(NSIZE == 1)THEN + ALLOCATE(PNEW%I1(NDIM), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:144 ' + ELSE + ALLOCATE(PNEW%I2(NDIM,NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:147 ' + END IF + END IF + + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + ALLOCATE(PNEW%L1(NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:156 ' + END IF + ELSE + IF(NSIZE == 1)THEN + ALLOCATE(PNEW%L1(NDIM), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:161 ' + ELSE + ALLOCATE(PNEW%L2(NDIM,NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:164 ' + END IF + END IF + + + CASE('S') + + CASE('C') + + CASE('N','DIR') + RETURN + + + END SELECT + + RETURN + END FUNCTION LL_MK + + + + +END MODULE LL_MK_M diff --git a/data_util/ll_mods.f90 b/data_util/ll_mods.f90 new file mode 100644 index 0000000..053e2bd --- /dev/null +++ b/data_util/ll_mods.f90 @@ -0,0 +1,20 @@ + +MODULE LL_MODS_M + + USE LL_CAT_M + USE LL_CP_M + USE LL_DEATTACH_M + USE LL_DUPLICATE_M + USE LL_FUNC_PRT_M + USE LL_LOCATE_M + USE LL_MK_M + USE LL_MV_M + USE LL_NNODES_M + USE LL_READ_M + USE LL_RM_M + USE LL_STICH_M + USE LL_SWEEP_M + USE LL_TYPE_M + USE LL_WRITE_M + +END MODULE LL_MODS_M diff --git a/data_util/ll_modules b/data_util/ll_modules new file mode 100644 index 0000000..dcb1b1f --- /dev/null +++ b/data_util/ll_modules @@ -0,0 +1,10 @@ +USE LL_DUPLICATE_M +USE LL_RUNC_PRT_M +USE LL_LOCATE_M +USE LL_MK_M +USE LL_MVCP_M +USE LL_READ_M +USE LL_RM_M +USE LL_STICH_M +USE LL_TYPE_M +USE LL_WRITE_M diff --git a/data_util/ll_mv.f90 b/data_util/ll_mv.f90 new file mode 100644 index 0000000..e26ef0b --- /dev/null +++ b/data_util/ll_mv.f90 @@ -0,0 +1,194 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_MV +! +! Date: 2016-10-10 +! +! +! +! +! Description: moves or copies node +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_MV_M +CONTAINS + + FUNCTION LL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) + USE LL_TYPE_M + IMPLICIT NONE + TYPE(DNODE), POINTER :: PWHAT,PWHERE + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PSOURCETMP + LOGICAL OK + + PSOURCETMP => LL_MVCP(PWHAT,PWHERE,'M',FPAR) + OK = FPAR%SUCCESS + + RETURN + END FUNCTION LL_MV + + FUNCTION LL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + + USE LL_TYPE_M + USE LL_RM_M + USE LL_STICH_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + TYPE(DNODE), POINTER :: PWHAT,PWHERE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE +! +! LOCAL TYPES +! + TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& + PLAST, PSOURCETMP,PCHILD,PNEW +! +! BODY OF SUBROUTINE +! + PSOURCETMP => NULL() + + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PWHAT))THEN + WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + IF(.NOT.ASSOCIATED(PWHERE))THEN + WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! + PTNEXT => PWHERE%PNEXT + PTPREV => PWHERE%PPREV + PTPAR => PWHERE%PPAR + + PSOURCETMP => PWHAT +! +! GET TYPE OF TARGET NODE +! DISTINGUISH BETWEEN DIR, OTHER TYPES +! + SELECT CASE(PWHERE%LTYPE) + + CASE('N','DIR') +! +! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM +! + CALL LL_STICH(PWHAT,FPAR) + + IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN +! +! DIR IS EMPTY +! + PWHERE%PCHILD => PSOURCETMP + PSOURCETMP%PPAR => PWHERE + PSOURCETMP%PPREV => NULL() + PSOURCETMP%PNEXT => NULL() + PWHERE%NDIM = 1 + + ELSE +! +! DIR HAS ALREADY CHILDREN, ADD TO THE END +! + PCHILD => PWHERE%PCHILD + DO WHILE(ASSOCIATED(PCHILD)) + PLAST => PCHILD + PCHILD => PCHILD%PNEXT + END DO + + PLAST%PNEXT => PSOURCETMP + PSOURCETMP%PPREV => PLAST + PSOURCETMP%PNEXT => NULL() + PWHERE%NDIM = PWHERE%NDIM + 1 + + END IF + + CASE DEFAULT +! +! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN +! DELETE TARGET NODE +! + CALL LL_RM(PWHERE, FPAR) +! +! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM +! + CALL LL_STICH(PSOURCETMP,FPAR) +! +! ADD A NEW NODE +! + IF(.NOT.ASSOCIATED(PTPREV))THEN +! +! PWHERE WAS THE FIRST NODE IN THE LIST +! + PTPAR%PCHILD => PSOURCETMP + PSOURCETMP%PPAR => PTPAR + PSOURCETMP%PPREV => NULL() + PTPAR%NDIM = PTPAR%NDIM + 1 + + IF(ASSOCIATED(PTNEXT))THEN + PSOURCETMP%PNEXT => PTNEXT + ELSE + PSOURCETMP%PNEXT => NULL() + END IF + + ELSE +! +! NODE NOT THE FIRST IN THE LINE +! + PTPREV%PNEXT => PSOURCETMP + PSOURCETMP%PPREV => PTPREV + + IF(ASSOCIATED(PTNEXT))THEN + PSOURCETMP%PNEXT => PTNEXT + ELSE + PSOURCETMP%PNEXT => NULL() + END IF + PTPAR%NDIM = PTPAR%NDIM + 1 + + END IF + + END SELECT + + FPAR%SUCCESS = .TRUE. + + RETURN + END FUNCTION LL_MVCP + +END MODULE LL_MV_M diff --git a/data_util/ll_nnodes.f90 b/data_util/ll_nnodes.f90 new file mode 100644 index 0000000..439b2e7 --- /dev/null +++ b/data_util/ll_nnodes.f90 @@ -0,0 +1,124 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_NNODES +! +! Date: 2016-10-10 +! +! +! +! +! Description: Finds node in a chain +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_NNODES_M +CONTAINS + + RECURSIVE FUNCTION LL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) + + USE LL_TYPE_M + USE LL_FUNC_PRT_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LICOMPIL) :: NUMBER + LOGICAL :: RECURSE +! +! LOCAL TYPES +! + CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE + TYPE(DNODE), POINTER :: PCURR, PCHLD + INTEGER(LICOMPIL) :: I +! +! BODY OF FUNCTION +! + NUMBER = 0 + NULLIFY(PFIND) + I = 1 + DO WHILE(LTYPE(I:I) == ' ') + I = I + 1 + END DO + + TLTYPE = TRIM(LTYPE(I:)) + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + + PCURR => PNODE%PCHILD + IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN + WRITE(*,*)' NODE NOT DIR NODE' + RETURN + END IF + + DO WHILE(ASSOCIATED(PCURR)) +! +! IF RECURSIVE DO NOT CONSIDER NUMBERING AND RETURN THE FIRST FOUND NODE +! + IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN + PCHLD => PCURR%PCHILD + NUMBER = NUMBER + LL_NNODES(PCHLD,NAME,LTYPE,RECURSE,FPAR) + IF(ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .TRUE. + RETURN + END IF + END IF +! +! LOOK FOR NODE +! + IF( TRIM(PCURR%LNAME) == TRIM(NAME) .AND. & + (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN + + NUMBER = NUMBER + 1 + + END IF + PCURR => PCURR%PNEXT + + END DO + + RETURN + END FUNCTION LL_NNODES + + +END MODULE LL_NNODES_M diff --git a/data_util/ll_read.f90 b/data_util/ll_read.f90 new file mode 100644 index 0000000..9ec0d7f --- /dev/null +++ b/data_util/ll_read.f90 @@ -0,0 +1,545 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_READ +! +! Date: 2016-10-10 +! +! +! +! +! Description: reads a file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_READ_M +CONTAINS + + FUNCTION LL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + + USE LL_TYPE_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! LOCAL TYPES +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS + + + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! DETERMINE RORMAT' +! + SELECT CASE(FMT) + CASE('A','a') + FMT_LOC = 'A' + CASE('B','b') + FMT_LOC = 'B' + CASE('U','u','*') + FMT_LOC = 'U' + CASE DEFAULT + WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END SELECT +! +! OPEN THE FILE +! + SELECT CASE(FMT_LOC) + CASE('B') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + CASE('A') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& + IOSTAT=ISTAT, ACTION = 'READ') + END SELECT + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! READ INITIAL NODE +! + PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,FPAR) + + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + END IF + + RETURN + + END FUNCTION LL_READ +! +! READS NODE +! + RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) + + USE LL_TYPE_M + USE LL_MK_M + USE LL_MV_M + + IMPLICIT NONE + + INTEGER(LINT), INTENT(OUT) :: POS + TYPE(DNODE), POINTER :: PNODE,PNEW + CHARACTER :: FMT + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + + TYPE(FUNC_DATA_SET) :: FPAR_H + CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + INTEGER(LINT) :: NDIM, NSIZE,NNODES + LOGICAL :: OK +! +! READ HEADER +! + CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H) + +! write(*,*)name +! write(*,*)ltype +! write(*,*)ndim +! write(*,*)nsize +! write(*,*)FPAR_H%SUCCESS + + IF(.NOT.FPAR_H%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' Read - error reading header ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + PNODE => LL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + ELSE + PNODE => LL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) + END IF + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + DO NNODES = 1,NDIM + PNEW => READ_NODE(IOUNIT,FMT,POS,FPAR) + IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' +! +! ATTACH TO PNODE +! + OK = LL_MV(PNEW,PNODE,FPAR) + IF(.NOT.OK) STOP' ERROR MV' + + END DO + ELSE +! +! READ DATA +! + SELECT CASE(FMT) + CASE('A') + CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CASE('B') + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END SELECT + + END IF + + RETURN + + END FUNCTION READ_NODE +! +! READ HEADER OR EACH NODE +! + SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) + + USE LL_TYPE_M + USE LL_FUNC_PRT_M + + IMPLICIT NONE + + INTEGER(LINT) :: POS + CHARACTER :: FMT + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + + CHARACTER(*) :: LTYPE + CHARACTER(*) :: NAME + INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND + CHARACTER*255 :: TEXT_LINE,TRIM_LINE + INTEGER :: IOSTAT + LOGICAL :: OK + + + SELECT CASE(FMT) + CASE('A') + TEXT_LINE(1:1) = '*' + DO WHILE(TEXT_LINE(1:1)=='*') ! IGNORE COMMENT TEXT_LINE + READ(IOUNIT,'(A256)',IOSTAT=IOSTAT) TEXT_LINE + OK = TEST_IOSTAT(IOSTAT,FPAR) + IF(.NOT.OK) RETURN + END DO + + TRIM_LINE = TRIM(TEXT_LINE) +! +! GET NAME +! + IIND = 1 + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND + + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + NAME = TRIM_LINE(ISTART:IIND) + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET TYPE +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + LTYPE = TRIM_LINE(ISTART:IIND) + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET NDIM +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + READ(TRIM_LINE(ISTART:IIND),'(I30)',IOSTAT=IOSTAT) NDIM + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + NSIZE = 0 + RETURN + END IF + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET NSIZE +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + READ(TRIM_LINE(ISTART:IIND),'(I30)',IOSTAT=IOSTAT) NSIZE + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND + + FPAR%SUCCESS = .TRUE. + RETURN + + CASE('B') + NSIZE = 0 + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,nsize + FPAR%SUCCESS = .TRUE. + RETURN + END SELECT + + WRITE(FPAR%MESG,'(A)')' Read - reading header error ' + FPAR%SUCCESS = .FALSE. + RETURN + + WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' + FPAR%SUCCESS = .FALSE. + RETURN + + END SUBROUTINE READ_HEADER +! +! READ DATA +! + SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + + USE LL_TYPE_M + USE LL_FUNC_PRT_M + + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT + INTEGER(LINT) :: NDIM,NSIZE + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL DECLARATION +! + INTEGER(LINT) :: I,J + INTEGER :: IOSTAT + LOGICAL :: OK +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%R0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%D0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%I0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%L0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('S') + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + OK = TEST_IOSTAT(IOSTAT,FPAR) + + RETURN + + END SUBROUTINE READ_DATA_ASCII + + + + +! +! READ DATA +! + SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + + USE LL_TYPE_M + USE LL_FUNC_PRT_M + + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT + INTEGER(LINT) :: NDIM,NSIZE + CHARACTER(*) :: LTYPE + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL DECLARATION +! + INTEGER(LINT) :: I,J + INTEGER :: IOSTAT + LOGICAL :: OK +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%R0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%D0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%I0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%L0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('S') + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%S + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + OK = TEST_IOSTAT(IOSTAT,FPAR) + + RETURN + + END SUBROUTINE READ_DATA_BIN + +END MODULE LL_READ_M diff --git a/data_util/ll_rm.f90 b/data_util/ll_rm.f90 new file mode 100644 index 0000000..01d5d8c --- /dev/null +++ b/data_util/ll_rm.f90 @@ -0,0 +1,256 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_RM +! +! Date: 2016-10-10 +! +! +! +! +! Description: removes node and all its children +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_RM_M +CONTAINS + + SUBROUTINE LL_RM(PNODE,FPAR) + + USE LL_TYPE_M + USE LL_STICH_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE,PCHILD + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL TYPES +! + INTEGER :: ISTAT +! +! BODY OF SUBROUTINE +! + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' RM - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PCHILD => PNODE%PCHILD +! +! IF NODE HAS CHILDREN, REMOVE ALL OF THEM +! + IF(ASSOCIATED(PCHILD))CALL LL_RM_RECURSIVE_NODE(PCHILD,FPAR) + + CALL LL_DEALLOC_DATA(PNODE,FPAR) +! +! STICH AND SUBSTRACT FROM PARENT +! + CALL LL_STICH(PNODE,FPAR) +! +! NULLIFY NODE +! + DEALLOCATE(PNODE, STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:88 ' + NULLIFY(PNODE) + + FPAR%SUCCESS = .TRUE. + + RETURN + END SUBROUTINE LL_RM +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE LL_RM_RECURSIVE_NODE(PNODE,FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + TYPE(DNODE), POINTER :: PCURR, PNEXT + INTEGER :: ISTAT +! +! IF NODE HAS CHILDREN, DELET THEM FIRST +! + PCURR => PNODE +! +! IF CHILDREN, DELETE THEM FIRST +! + DO WHILE(ASSOCIATED(PCURR)) + PNEXT => PCURR%PNEXT + IF(ASSOCIATED(PCURR%PCHILD))THEN + CALL LL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR) + END IF + + IF(TRIM(PCURR%LTYPE) /= 'LINK')THEN + + CALL LL_DEALLOC_DATA(PCURR,FPAR) + + IF(ASSOCIATED(PCURR%PLINK))THEN + PNODE%PLINK%PCHILD => NULL(); + END IF + + DEALLOCATE(PCURR, STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> ll_rm ERR:132 ' + NULLIFY(PCURR) + FPAR%SUCCESS = .TRUE. + ELSE +! +! SPCIAL TREATMENT FOR LINKS +! + PCURR%PCHILD%PLINK => NULL() + PCURR%PCHILD => NULL() + DEALLOCATE(PCURR, STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> ll_rm ERR:142 ' + NULLIFY(PCURR) + FPAR%SUCCESS = .TRUE. + END IF + + PCURR => PNEXT + + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE LL_RM_RECURSIVE_NODE +! +! FREE MEMORY FOR NODE +! + SUBROUTINE LL_DEALLOC_DATA(PNODE,FPAR) + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: ISTAT +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + DEALLOCATE(PNODE%R1, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:174 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%D1))THEN + DEALLOCATE(PNODE%D1, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:184 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%I1))THEN + DEALLOCATE(PNODE%I1, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:194 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%L1))THEN + DEALLOCATE(PNODE%L1, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:204 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + DEALLOCATE(PNODE%R2, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:216 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%D2))THEN + DEALLOCATE(PNODE%D2, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:226 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%I2))THEN + DEALLOCATE(PNODE%I2, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:236 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + IF(ASSOCIATED(PNODE%L2))THEN + DEALLOCATE(PNODE%L2, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:246 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF + + END SUBROUTINE LL_DEALLOC_DATA + + +END MODULE LL_RM_M diff --git a/data_util/ll_stich.f90 b/data_util/ll_stich.f90 new file mode 100644 index 0000000..3ce16ed --- /dev/null +++ b/data_util/ll_stich.f90 @@ -0,0 +1,111 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_MV +! +! Date: 2016-10-10 +! +! +! +! +! Description: stiches list +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_STICH_M +CONTAINS + + SUBROUTINE LL_STICH(PNODE,FPAR) + + USE LL_TYPE_M + + IMPLICIT NONE +! +! STICHES THE LIST AFTER REMOVING NODES +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL TYPES +! + TYPE(DNODE), POINTER :: PNEXT=>NULL(), PPREV=>NULL(),PPAR=>NULL() +! +! BODY OF SUBROUTINE +! + IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN + WRITE(FPAR%MESG,'(A)')' Stich - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEXT => PNODE%PNEXT + PPREV => PNODE%PPREV + PPAR => PNODE%PPAR + + IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN + WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! NODE DOES NOT HAVE ANY NEIGHBOURS +! + IF(.NOT.ASSOCIATED(PNEXT) .AND. .NOT.ASSOCIATED(PPREV))THEN + PPAR%NDIM = 0 + FPAR%SUCCESS = .TRUE. +! +! STICH AND SUBSTRACT FROM PARENT +! + ELSE IF(ASSOCIATED(PPREV)) THEN + PPREV%PNEXT => PNEXT + IF(ASSOCIATED(PNEXT)) PNEXT%PPREV => PPREV + PPAR%NDIM = PPAR%NDIM -1 + ELSE +! +! FIRST CHILD NODE +! + IF(ASSOCIATED(PNEXT))THEN + PPAR%PCHILD => PNEXT + PNEXT%PPREV => NULL() + PNEXT%PPAR => PPAR + PPAR%NDIM = PPAR%NDIM - 1 + ELSE + PPAR%PCHILD => NULL() + PPAR%NDIM = 0 + END IF + END IF + + END SUBROUTINE LL_STICH + +END MODULE LL_STICH_M diff --git a/data_util/ll_sweep.f90 b/data_util/ll_sweep.f90 new file mode 100644 index 0000000..d91a2b0 --- /dev/null +++ b/data_util/ll_sweep.f90 @@ -0,0 +1,101 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_SWEEP +! +! Date: 2016-10-10 +! +! +! +! +! Description: sweep through list +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_SWEEP_M +CONTAINS + + FUNCTION LL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) + + USE LL_TYPE_M + USE LL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND ALL NODES WITH SPECIFIED NAME OR TYPE +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LICOMPIL) :: NUMBER + LOGICAL :: RECURSE +! +! LOCAL TYPES +! + CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE + TYPE(DNODE), POINTER :: PCURR, PCHLD + INTEGER(LICOMPIL) :: LOCNUM,I +! +! BODY OF FUNCTION +! + NULLIFY(PFIND) + I = 1 + DO WHILE(LTYPE(I:I) == ' ') + I = I + 1 + END DO + + TLTYPE = TRIM(LTYPE(I:)) + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + +! DO WHILE(PNODE) + + PCURR => PNODE%PCHILD + IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN + WRITE(*,*)' NODE NOT DIR NODE' + RETURN + END IF +! END DO + + + RETURN + END FUNCTION LL_SWEEP + + +END MODULE LL_SWEEP_M diff --git a/data_util/ll_type.f90 b/data_util/ll_type.f90 new file mode 100644 index 0000000..16f5bf1 --- /dev/null +++ b/data_util/ll_type.f90 @@ -0,0 +1,109 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_TYPE_M +! +! Date: 2016-10-10 +! +! Description: Definition of the data set type for linked list +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_TYPE_M +!#ifdef f2003 +!use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & +! stdout=>output_unit, & +! stderr=>error_unit +!#else +!#define stdin 5 +!#define stdout 6 +!#define stderr 0 +!#endif +! +! MODULE SPECIFIC VARIABLES +! + IMPLICIT NONE + INTEGER, PARAMETER :: RSINGLE = SELECTED_REAL_KIND(P=6,R=37) + INTEGER, PARAMETER :: RDOUBLE = KIND(0.D0) + INTEGER, PARAMETER :: SINT = SELECTED_INT_KIND(9) + INTEGER, PARAMETER :: LINT = SELECTED_INT_KIND(16) + + INTEGER, PARAMETER :: LICOMPIL = LINT + INTEGER, PARAMETER :: SICOMPIL = SINT + + INTEGER, PARAMETER :: NAME_LENGTH = 16 + INTEGER, PARAMETER :: TYPE_LENGTH = 4 + INTEGER, PARAMETER :: ERR_MSG_LENGTH = 256 + INTEGER, PARAMETER :: ERR_PATH_LENGTH = 1024 + INTEGER, PARAMETER :: FILE_NAME_LENGTH = 1024 + INTEGER, PARAMETER :: STRING_LENGHT = 24 +! +! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST +! + TYPE DNODE + CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list + INTEGER(LICOMPIL) :: NDIM = 0, NSIZE = 0 + INTEGER(LICOMPIL) :: POS = 0, LENGTH = 0 + + TYPE (DNODE), POINTER :: & + PPAR =>NULL(),& ! Pointer to parent list + PCHILD =>NULL(),& ! Pointer to first child list + PNEXT =>NULL(),& ! Pointer to next list + PPREV =>NULL(),& ! Pointer to previous list + PLINK =>NULL() ! Pointer to link target + + REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) =>NULL() + REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) =>NULL() + INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) =>NULL() + INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) =>NULL() + + REAL(RSINGLE) :: R0 + REAL(RDOUBLE) :: D0 + INTEGER(SINT) :: I0 + INTEGER(LINT) :: L0 + + CHARACTER :: C + CHARACTER(LEN=STRING_LENGHT) :: S + CHARACTER, POINTER :: S1(:) + + END TYPE DNODE + + TYPE FUNC_DATA_SET + LOGICAL :: SUCCESS, ERRMSG + CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG + CHARACTER(LEN=ERR_PATH_LENGTH) :: ERRPATH + END TYPE FUNC_DATA_SET + +END MODULE LL_TYPE_M diff --git a/data_util/ll_write.f90 b/data_util/ll_write.f90 new file mode 100644 index 0000000..5ab81af --- /dev/null +++ b/data_util/ll_write.f90 @@ -0,0 +1,396 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_WRITE +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints node +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE LL_WRITE_M +CONTAINS + + + FUNCTION LL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) + + USE LL_TYPE_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT + LOGICAL OK +! +! LOCAL TYPES +! + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS +! +! DETERMINE RORMAT' +! + SELECT CASE(FMT) + CASE('A','a') ! ASCII FORMAT + FMT_LOC = 'A' + CASE('B','b') ! BINARY FORMAT + FMT_LOC = 'B' + CASE('U','u','*')! UNKNOWN - UNSPECIFIED FORMAT + FMT_LOC = 'U' + CASE DEFAULT + WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + OK = .FALSE. + RETURN + END SELECT +! +! OPEN THE FILE +! + SELECT CASE(FMT_LOC) + CASE('B') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + CASE('A') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& + IOSTAT=ISTAT,ACTION='WRITE') + END SELECT + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Write - error opening file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF +! +! WRITE LINKED LIST +! + CALL LL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) + + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF + + OK = .TRUE. + RETURN + + END FUNCTION LL_WRITE + + + + SUBROUTINE LL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE WRITES LIST +! + TYPE(DNODE), POINTER :: PNODE,PCHILD + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT + INTEGER(LINT) :: POS +! +! LOCAL TYPES +! +! +! BODY OF SUBROUTINE +! + POS = 0 + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' CAT - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + IF(FMT == 'A')THEN + CALL LL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + ELSE + CALL LL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + END IF + + PCHILD => PNODE%PCHILD +! +! IF NODE HAS CHILDREN PRINT THEM TOO +! + IF(ASSOCIATED(PCHILD))CALL LL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + + FPAR%SUCCESS = .TRUE. + + RETURN + END SUBROUTINE LL_WRITE_LIST +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE LL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: POS + + TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! IF NODE HAS CHILDREN +! + PCURR => PNODE +! +! IF CHILDREN, PRINT THEM TOO +! + DO WHILE(ASSOCIATED(PCURR)) + + IF(FMT == 'A')THEN + CALL LL_SAVE_NODE_A(PCURR, IOUNIT, FPAR) + ELSE + CALL LL_SAVE_NODE_B(PCURR, IOUNIT, POS, FPAR) + END IF + + PNEXT => PCURR%PNEXT + PCHILD => PCURR%PCHILD + IF(ASSOCIATED(PCHILD))THEN + CALL LL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + END IF + + PCURR => PNEXT + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE LL_WRITE_RECURSIVE_NODE +! +! FREE MEMORY FOR NODE +! + SUBROUTINE LL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE SAVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: IOUNIT + INTEGER(LINT) :: I,J,NDIM,NSIZE + LOGICAL :: SAVED + + SAVED = .FALSE. +! +! 1D ARRAYS +! + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),' ', TRIM(PNODE%LTYPE),' ', PNODE%NDIM + ELSE + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),' ', TRIM(PNODE%LTYPE),' ', PNODE%NDIM, ' ',PNODE%NSIZE + END IF +! +! 1 D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%R1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%D1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%I1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) + SAVED = .TRUE. +! +! 2D ARRAYS +! + ELSE IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) + WRITE(IOUNIT, *)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) + WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + END IF +! +! CHECK IF NODE IS CONSTANT +! + IF(.NOT.SAVED)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT, *)PNODE%R0 + CASE('D') + WRITE(IOUNIT, *)PNODE%D0 + CASE('I') + WRITE(IOUNIT, *)PNODE%I0 + CASE('L') + WRITE(IOUNIT, *)PNODE%L0 + CASE('S') + WRITE(IOUNIT,*)PNODE%S + + CASE DEFAULT + + END SELECT + END IF + + + RETURN + END SUBROUTINE LL_SAVE_NODE_A + + SUBROUTINE LL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + + USE LL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE SAVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: IOUNIT + INTEGER(LINT) :: I,J,NDIM,NSIZE,POS + LOGICAL :: SAVED + + SAVED = .FALSE. +! +! 1D ARRAYS +! +! IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN +! WRITE(IOUNIT)TRIM(PNODE%LNAME),TRIM(PNODE%LTYPE), PNODE%NDIM +! ELSE + WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE +! END IF +! +! 1 D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%R1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%D1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%I1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) + SAVED = .TRUE. +! +! 2D ARRAYS +! + ELSE IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + END IF +! +! CHECK IF NODE IS CONSTANT +! + IF(.NOT.SAVED)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT)PNODE%R0 + CASE('D') + WRITE(IOUNIT)PNODE%D0 + CASE('I') + WRITE(IOUNIT)PNODE%I0 + CASE('L') + WRITE(IOUNIT)PNODE%L0 + CASE('S') + WRITE(IOUNIT)PNODE%S + + CASE DEFAULT + + END SELECT + END IF + + + RETURN + END SUBROUTINE LL_SAVE_NODE_B + +END MODULE LL_WRITE_M diff --git a/data_util/project.dep b/data_util/project.dep new file mode 100644 index 0000000..54bcc58 --- /dev/null +++ b/data_util/project.dep @@ -0,0 +1,79 @@ +# This file is generated automatically. DO NOT EDIT! + +ll_cat.o : \ + ll_type.o + +ll_cp.o : \ + ll_cat.o \ + ll_rm.o \ + ll_mv.o \ + ll_stich.o \ + ll_duplicate.o \ + ll_type.o + +ll_mk.o : \ + ll_type.o + +ll_mv.o : \ + ll_rm.o \ + ll_stich.o \ + ll_type.o + +ll_nnodes.o : \ + ll_type.o \ + ll_funct_prt.o + +ll_rm.o : \ + ll_stich.o \ + ll_type.o + +ll_duplicate.o : \ + ll_mk.o \ + ll_type.o \ + ll_mv.o + +ll_funct_prt.o : \ + ll_type.o + +ll_mods.o : \ + ll_cat.o \ + ll_nnodes.o \ + ll_deattach.o \ + ll_funct_prt.o \ + ll_mk.o \ + ll_rm.o \ + ll_cp.o \ + ll_write.o \ + ll_locate.o \ + ll_mv.o \ + ll_stich.o \ + ll_sweep.o \ + ll_duplicate.o \ + ll_type.o \ + ll_read.o + +ll_deattach.o : \ + ll_stich.o \ + ll_type.o + +ll_locate.o : \ + ll_type.o \ + ll_funct_prt.o + +ll_write.o : \ + ll_type.o + +ll_sweep.o : \ + ll_type.o \ + ll_locate.o + +ll_type.o : + +ll_stich.o : \ + ll_type.o + +ll_read.o : \ + ll_mk.o \ + ll_type.o \ + ll_funct_prt.o \ + ll_mv.o diff --git a/data_util/reshape b/data_util/reshape new file mode 100644 index 0000000..c959b4a --- /dev/null +++ b/data_util/reshape @@ -0,0 +1,8 @@ +program ptrtest + real, pointer :: a(:) + real, pointer :: b(:,:) + integer :: n = 10 + allocate(a(n**2)) + a = 42 + b (1:n, 1:n) => a +end program ptrtest diff --git a/data_util/src_dir_path b/data_util/src_dir_path new file mode 100644 index 0000000..927db3c --- /dev/null +++ b/data_util/src_dir_path @@ -0,0 +1 @@ +srcdir=/home/jka/OSS_CFD/trunk/data_util diff --git a/fort_depend.py b/fort_depend.py new file mode 100755 index 0000000..c9730e4 --- /dev/null +++ b/fort_depend.py @@ -0,0 +1,263 @@ +#!/usr/bin/python +import os +import re +import glob +import fnmatch +import os +import sys + +#Definitions + +def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): + + cwd = os.getcwd() + + path = check_path(path=path) + cwd = check_path(path=cwd) + + ff=get_all_files(path=path) + l=create_file_objs(files,macros) + mod2fil=file_objs_to_mod_dict(file_objs=l) + depends=get_depends(fob=l,m2f=mod2fil,ffiles=ff) + + if verbose: + for i in depends.keys(): + print ("\033[032m"+i+"\033[039m depends on :\033[034m") + for j in depends[i]: print( "\t"+j) + print ("\033[039m") + + if output is None: + output = "makefile.dep" + + tmp=write_depend(path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) + + return depends + +def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): + "Write the dependencies to outfile" + #Test file doesn't exist + if os.path.exists(outfile): + if not(overwrite): + print ("\033[031mWarning file exists.\033[039m") + opt=raw_input("Overwrite? Y... for yes.") + else: + opt="y" + if opt.lower().startswith("y"): + pass + else: + return + + #Open file + f=open(outfile,'w') + f.write('# This file is generated automatically. DO NOT EDIT!\n') + for i in dep.keys(): + tmp,fil=os.path.split(i) + stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") + for j in dep[i]: + npathseg = j.count('/') + if npathseg == 0: + tmp,fil=os.path.split(j) + else: + fil = get_relative_path_name(j,path=path,cwd=cwd) + + if "../" in fil: + stri = stri + " \\\n\t" + fil + else: + stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") + + stri=stri+"\n" + f.write(stri) + f.close() + return + +def get_source(ext=[".f90",".F90"]): + "Return all files ending with any of ext" + tmp=os.listdir(".") + fil=[] + for i in ext: + fil.extend(filter(lambda x: x.endswith(i),tmp)) + return fil + +def get_all_files(path): + #l=[] + + #for filename in glob.iglob('/home/jka/OSS_CFD/trunk/**/*.f90', recursive=True): + #print(filename) + #l.append(filename) + + #return l + + matches = [] + for root, dirnames, filenames in os.walk(path): + for filename in fnmatch.filter(filenames, '*.f90'): + matches.append(os.path.join(root, filename)) + + return matches + +def check_if_there(use,file): + "return if you see module name" + with open(file) as f: + for line in f: + if "module" in line.lower(): + if use in line: + return 1 + + return 0 + + +def create_file_objs(files=None, macros={}): + l=[] + + if files is None: + files = get_source() + + for i in files: + source_file = file_obj() + + source_file.file_name = i + source_file.uses = get_uses(i,macros) + source_file.contains = get_contains(i) + + l.append(source_file) + + return l + +def get_uses(infile=None, macros={}): + "Return which modules are used in infile after expanding macros" + p=re.compile("^\s*use\s*(?P\w*)\s*(,)?\s*(only)?\s*(:)?.*?$",re.IGNORECASE).match + + uses=[] + + with open(infile,'r') as f: + t=f.readlines() + + for i in t: + tmp=p(i) + if tmp: + uses.append(tmp.group('moduse').strip()) + + # Remove duplicates + uniq_mods = list(set(uses)) + + for i, mod in enumerate(uniq_mods): + for k, v in macros.items(): + if re.match(k, mod, re.IGNORECASE): + uniq_mods[i] = mod.replace(k,v) + + return uniq_mods + +def get_contains(infile=None): + "Return all the modules that are in infile" + p=re.compile("^\s*module\s*(?P\w*)",re.IGNORECASE).match + + contains=[] + + with open(infile,'r') as f: + t=f.readlines() + + for i in t: + tmp=p(i) + if tmp: + contains.append(tmp.group('modname').strip()) + + # Remove duplicates before returning + return list(set(contains)) + +def file_objs_to_mod_dict(file_objs=[]): + "Turn a list of file_objs in a dictionary, containing which modules depend on which files" + dic={} + for i in file_objs: + for j in i.contains: + dic[j.lower()]=i.file_name + return dic + +def get_depends(fob=[],m2f=[], ffiles=[]): + deps={} + for i in fob: + tmp=[] + for j in i.uses: + try: + tmp.append(m2f[j.lower()]) + except KeyError: + for k in ffiles: + retval=check_if_there(use=j,file=k) + if retval > 0: + name=os.path.splitext(k)[0]+'.o' + tmp.append(name.lower()) + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") + print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") + print ("\033[031m..... \033[039m adding it to dependency file, not checking its dependency further \033[032m") + + deps[i.file_name]=tmp + + return deps + +def check_path(path): + if path.endswith("/"): + print("Path correct") + else: + print( "adding / to the path in "+path) + path=path + "/" + + return path + +def get_relative_path_name(file,path,cwd): + length = len(path) + #tmp,fil=os.path.split(j) + filetmp = file + fil = filetmp.replace(filetmp[:length], '') + + loccwd = cwd + loccwd = loccwd.replace(loccwd[:length], '') + + npathseg = loccwd.count('/') + for x in range(0, npathseg): + fil = "../"+fil + + return fil + + +class file_obj: + def __init__(self): + self.file_name=None + self.uses=None + self.contains=None + self.depends_on=None + + +#Script +if __name__ == "__main__": + import argparse + + # Add command line arguments + parser = argparse.ArgumentParser(description='Generate Fortran dependencies') + parser.add_argument('-f','--files',nargs='+',help='Files to process') + parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', + help="""The macro NAME is replaced by DEFINITION in 'use' statements""") + parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', + default='') + parser.add_argument('-o','--output',nargs=1,help='Output file') + parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') + parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') + parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') + + # Parse the command line arguments + args = parser.parse_args() + + # Assemble a dictionary out of the macro definitions + macros = {} + if args.D: + for arg in args.D: + for var in arg: + temp = var.split('=') + macros[temp[0]] = temp[1] + + output = args.output[0] if args.output else None + build = args.build[0] if args.build else '' + root_dir = args.root_dir[0] if args.root_dir else None + + if not root_dir: + print ("\033[031mError: \033[039m missing path to project root directory \033[032m") + sys.exit() + + run(path=root_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) diff --git a/rules.mk b/rules.mk new file mode 100644 index 0000000..33258c6 --- /dev/null +++ b/rules.mk @@ -0,0 +1,78 @@ + +# Mark standard targets as phony (not real file targets). +# This helps avoid problems if there is also a file with the same name. +.PHONY: all clean test depend install cleanall doc chk chk-fix + +# Disable implicit rules (some of them may otherwise cause problems). +.SUFFIXES: + +# Define macro to handle compilers generating upper-case module filenames +# Note that the variable UPPER_MODFILE_NAME switches this +HANDLE_UPPER_CASE_MOD_NAMES = ! [ "$(UPPER_MODFILE_NAME)" ] || ! [[ $* = *_m ]] || cp `echo $* | tr a-z A-Z`.mod $*.mod + +# Rule for building free-form fortran from srcdir directory +%.o %.mod: $(srcdir)/%.f90 + $(FC) -c $(FFLAGS) $(FMODDIRS:%=$(FCMODINCFLAG)%) $< + -@$(HANDLE_UPPER_CASE_MOD_NAMES) + +# Rule for building fixed-form fortran from srcdir directory +%.o %.mod: $(srcdir)/%.f + $(FC) -c $(FFFLAGS) $(FMODDIRS:%=$(FCMODINCFLAG)%) $< + -@$(HANDLE_UPPER_CASE_MOD_NAMES) + +# Rule for building C from srcdir directory +%.o: $(srcdir)/%.c + $(CC) -c $(CFLAGS) $(CINCDIRS:%=-I%) $< + +# Rule for creating a build directory, if it doesn't already exist. +# Also links the corresponding Makefile from the sourcedirectory if +# it doesn't already exist. Also copies depend.mk from sourcedirectory +# if it exists. +%.mkdir: + @[ -d $* ] || mkdir $* + @! [ -h $*/Makefile ] || rm -f $*/Makefile + @[ -f $*/Makefile ] || ln -s $(srcdir)/$*/Makefile $*/Makefile + @rm -f $*/local_config.mk + @echo srcdir=$(if $(filter .,$(srcdir)),.,$(srcdir)/$*) \ + > $*/local_config.mk + +%: $(srcdir)/%.bash + sed 's:^#!/bin/bash:#!'"$(SHELL):" $< > $@ + chmod 755 $@ + +%: $(srcdir)/%.py + cat $< > $@ + chmod 755 $@ + +# +# Rules for recursion into subdirectories for standard targets. +# +%.all: %.mkdir + @cd $* && $(MAKE) all + +%.test: %.mkdir + @cd $* && $(MAKE) test + +%.clean: %.mkdir + @cd $* && $(MAKE) clean + +%.depend: %.mkdir + @cd $* && $(MAKE) depend + +%.install: %.mkdir + @cd $* && $(MAKE) install + +%.html-doc: %.mkdir + @cd $* && $(MAKE) html-doc + +%.doc: %.mkdir + @cd $* && $(MAKE) doc + +%.chk: %.mkdir + @cd $* && $(MAKE) chk + +chk: + $(F95CHK) --dry-run $(FFILES:%=$(srcdir)/%) + +chk-fix: + $(F95CHK) $(FFILES:%=$(srcdir)/%) diff --git a/src_dir_path b/src_dir_path new file mode 100644 index 0000000..847ef74 --- /dev/null +++ b/src_dir_path @@ -0,0 +1 @@ +srcdir=/home/jka/OSS_CFD/trunk/ diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..9c4b6c8 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,45 @@ +############################################################################ +# Makefile for ffalist +############################################################################ +# +# $HeadURL: https://costello.foi.se/svn/edge/branches/aeroelastics/programs/ffalist/Makefile $ +# $LastChangedDate: 2007-09-21 14:50:09 +0200 (Fri, 21 Sep 2007) $ +# $LastChangedBy: oskeno $ +# $LastChangedRevision: 1282 $ + +EXE = ll_test + +include src_dir_path +include ../config.mk + +DEP_FILE=project.dep + +FMODDIRS= ../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard $(FMODDIRS)/*.o) + +########################################################################### + +all: $(EXE).x $(EXE) + +include ../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk/ -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +install: $(EXE).x $(EXE) + $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) + $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x + +-include $(srcdir)/project.dep diff --git a/test/ll_test.f90 b/test/ll_test.f90 new file mode 100644 index 0000000..734af83 --- /dev/null +++ b/test/ll_test.f90 @@ -0,0 +1,142 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: duplicate +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM LL_TEST + + USE LL_MODS_M + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2 + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! LOCAL TYPES +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS +! +! read TEST file and store it in PNODE +! + PNODE => LL_READ('TEST',8,'A',FPAR) +! +! print Pnode on screen +! + CALL LL_CAT(PNODE, 6, FPAR) + WRITE(*,*)'------------------------------------------------------1' +! +! read TEST1 file and store it in PNODE1 +! + PNODE1 => LL_READ('TEST1',8,'A',FPAR) +! +! print PNODE1 on screen +! + CALL LL_CAT(PNODE1, 6, FPAR) + WRITE(*,*)'------------------------------------------------------2' +! +! save PNODE1 as binary and ascii file +! + OK = LL_WRITE(PNODE1,'File_2.txt',8,'B',FPAR) + OK = LL_WRITE(PNODE1,'File_1.txt',8,'A',FPAR) +! +! read bindary file and store it in PNODE2 +! then print it on screed and then delete it + PNODE2 => LL_READ('File_2.txt',8,'B',FPAR) + CALL LL_CAT(PNODE2, 6, FPAR) + CALL LL_RM(PNODE2,FPAR) + WRITE(*,*)'------------------------------------------------------3' +! +! MAKE A NEW NODE AND MOVE ENTIRE PNODE INTO IT +! PRINT IT ON THE SCREEN +! + PNEW1 => LL_MK("newnone","DIR",0_LINT, 0_LINT,FPAR) + OK = LL_MV(PNODE, PNEW1, FPAR) + CALL LL_CAT(PNEW1, 6, FPAR) + WRITE(*,*)'------------------------------------------------------4' +! +! COPY PNODE, BECASE THE TARGET IN COPY IS NULL +! THE PNEW IS GOING TO BE A DUPLICATE OF PNODE +! AND IS GOING TO BE A NEW NODE +! + PNEW => LL_CP(PNODE, NULL(), FPAR) + CALL LL_CAT(PNEW, 6, FPAR) + WRITE(*,*)'------------------------------------------------------5' +! +! REMOVE PNEW1 +! + CALL LL_RM(PNEW1,FPAR) +! +! COPY PNODE TO PNEW +! ON RETURN, THE LL_CP WILL GIVE BACK POINTER OF PNEW IN PNODE LIST +! + PNEW2 => LL_CP(PNEW, PNODE1, FPAR) + CALL LL_CAT(PNODE1, 6, FPAR) + WRITE(*,*)'------------------------------------------------------6' +! +! LOCATE 1st subdir IN PNODE1 AND PRINT IT ON THE SCREEN +! + PTMP => LL_LOCATE(PNODE1,'subdir',1_lint,'*',.false.,FPAR) + CALL LL_CAT(PTMP, 6, FPAR) + WRITE(*,*)'------------------------------------------------------7' +! +! CLEANUP ALL MEMORY +! + WRITE(*,*)' REMOVE ===========================' +! +! WE HAVE TO REMOVE PNODE1 AND PNEW WHICH WAS CREATED ON LINE 107 +! PNODE WAS DELETED AS PART OF PNEW1 WHERE IT WAS MOVED +! PNODE2 WAS DELETED RIGHT AFTER BEING RETURN FROM READ +! PNEW2 IS NOT A NEW NODE, IT POINTS TO A COPY SO DOES NOT NEED TO BE FREED +! + CALL LL_RM(PNEW,FPAR) + CALL LL_RM(PNODE1,FPAR) + + +END PROGRAM diff --git a/test/project.dep b/test/project.dep new file mode 100644 index 0000000..c835ccf --- /dev/null +++ b/test/project.dep @@ -0,0 +1,4 @@ +# This file is generated automatically. DO NOT EDIT! + +ll_test.o : \ + ../data_util/ll_mods.o diff --git a/test/src_dir_path b/test/src_dir_path new file mode 100644 index 0000000..0b3090b --- /dev/null +++ b/test/src_dir_path @@ -0,0 +1 @@ +srcdir=/home/jka/OSS_CFD/trunk/test From cf85f014f8eb5ab4eba5f071daa3618e7ff2aecf Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 27 Oct 2016 20:28:08 -0600 Subject: [PATCH 008/325] additional installations settings --- INSTALLATION | 54 ++++ Makefile | 49 ++++ config.mk | 42 +-- config/compset.gfortran | 17 ++ config/compset.gfortran_debug | 37 +++ config/compset.x86_64 | 20 ++ config/compset.x86_64_debug | 20 ++ configure.py | 272 ++++++++++++++++++++ data_util/ERR_LINE_IDEF_SCRIPT | 42 --- data_util/Makefile | 6 +- data_util/ll_cat.f90 | 32 +-- data_util/ll_cp.f90 | 42 +-- data_util/ll_deattach.f90 | 16 +- data_util/ll_duplicate.f90 | 52 ++-- data_util/ll_funct_prt.f90 | 10 +- data_util/ll_locate.f90 | 16 +- data_util/ll_mk.f90 | 12 +- data_util/ll_mods.f90 | 34 +-- data_util/ll_modules | 20 +- data_util/ll_mv.f90 | 30 +-- data_util/ll_nnodes.f90 | 16 +- data_util/ll_read.f90 | 36 +-- data_util/ll_rm.f90 | 36 +-- data_util/ll_stich.f90 | 12 +- data_util/ll_sweep.f90 | 14 +- data_util/ll_type.f90 | 6 +- data_util/ll_write.f90 | 50 ++-- data_util/project.dep | 90 +++---- data_util/src_dir_path | 1 - data_util/src_dir_path.mk | 1 + fort_depend.py => python_dep/fort_depend.py | 28 +- rules.mk | 28 +- src_dir_path | 1 - src_dir_path.mk | 1 + test/Makefile | 12 +- test/ll_test.f90 | 48 ++-- test/src_dir_path | 1 - test/src_dir_path.mk | 1 + 38 files changed, 785 insertions(+), 420 deletions(-) create mode 100644 INSTALLATION create mode 100644 Makefile create mode 100644 config/compset.gfortran create mode 100644 config/compset.gfortran_debug create mode 100644 config/compset.x86_64 create mode 100644 config/compset.x86_64_debug create mode 100755 configure.py delete mode 100755 data_util/ERR_LINE_IDEF_SCRIPT delete mode 100644 data_util/src_dir_path create mode 100644 data_util/src_dir_path.mk rename fort_depend.py => python_dep/fort_depend.py (90%) delete mode 100644 src_dir_path create mode 100644 src_dir_path.mk delete mode 100644 test/src_dir_path create mode 100644 test/src_dir_path.mk diff --git a/INSTALLATION b/INSTALLATION new file mode 100644 index 0000000..4543159 --- /dev/null +++ b/INSTALLATION @@ -0,0 +1,54 @@ +**************************************************** + +To install FLL you would need to: + +1. configure +2. compile + +1. CONFIGURATION +==================================================== + +Make a new directory where the compillation procees takes place +In this directory execute configure file from FLL project source directory. +For example, if the FLL source is in + +/home/usr/fll_souce/master + +and you want to compile and install everyting in + +/home/usr/fll_exec + +directory, then do: + +mkdir /home/usr/fll_exec +cd /home/usr/fll_exec +/home/usr/fll_souce/master/configure.py + + +NOTE: The configure script should be always located in the +project source directory, do not move or remove it + +2. COMPILATION: +==================================================== + +To compile, type + +gmake + + +3. DEVELOPERS: +==================================================== + +1. If modifying, adding removin or changing project in any way, developers +have to update project dependencies: +To update project dependencies, execute + +gmake depend + +in the project source directory or in each directory separately + +2. Source can be compiled separately in each directory by +changing location to the directory and issuing command + +gmake + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8c3ac0f --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +# +# Makefile +# Do not edit this file +# +# +# +include src_dir_path.mk +include config.mk + +SUBDIRS= \ +data_util\ +test\ + +########################################################################### + +all: $(SUBDIRS:%=%.all) + @echo '************************************************' + @echo '*' + @echo '* FLL built successfully!' + @MAKE=$(MAKE) && \ + echo "* Type \"$${MAKE##*/} install\" to install FLL into directory $(bin_dir)" + @echo "* " + @MAKE=$(MAKE) && \ + echo "* $${MAKE##*/} bin_dir=/usr/local/bin" + @echo '*' + @echo '************************************************' + +include rules.mk + +data_util.all: +test.all: data_util.all + +clean: $(SUBDIRS:%=%.clean) + +depend: $(SUBDIRS:%=%.depend) + +install: $(SUBDIRS:%=%.all) $(SUBDIRS:%=%.install) + +test: $(SUBDIRS:%=%.test) + +# +# The following target checks all .f90 files against +# some of the sourcecode standard rules. +# +CHK_SUBDIRS:=$(filter-out adaption lapack,$(SUBDIRS)) +chk: $(CHK_SUBDIRS:%=%.chk) +# +# +.PHONY: path diff --git a/config.mk b/config.mk index f26bf05..1d282c9 100644 --- a/config.mk +++ b/config.mk @@ -1,42 +1,4 @@ -SHELL = /bin/bash -# -# Compilers and flags -# -FC = gfortran -FCMODINCFLAG = -I -FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -UPPER_MODFILE_NAME = -LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -CC = gcc -fopenmp -CFLAGS = -g -fopenmp -C_LDFLAGS = -g -fopenmp -MPI_FC = mpif90 -MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -# -# Global settings. -# -# prefix is the base directory where executables will be installed. -# -prefix = /home/jka/OSS_CFD/exec/data_util/exec/x86_64 -# -# MACHINE identifies the host machine type -# -MACHINE = x86_64 -# -# Install command (or cp -p if install is not found) -# -INSTALL = install -c -# -# Optional external libraries -# An empty definition means that this library is not available. -# -LIBM3L = -L/home/jka/Cprograms/Sources/libm3l/Source/ -lm3l -Wl,-rpath=/home/jka/Cprograms/Sources/libm3l/Source/ -lpthread -LSIPDX = -L/home/jka/Cprograms/Sources/lsipdx/Source -llsipdx -Wl,-rpath=/home/jka/Cprograms/Sources/lsipdx/Source -LIBM3LPATH = /home/jka/Cprograms/Sources/libm3l/Source/ -LSIPDXPATH = /home/jka/Cprograms/Sources/lsipdx/Source - -MAKEDEPEND=/home/jka/OSS_CFD/trunk/fort_depend.py +PROJ_ROOT_PATH=/home/jka/OSS_CFD/trunk +MAKEDEPEND=$(PROJ_ROOT_PATH)/python_dep/fort_depend.py diff --git a/config/compset.gfortran b/config/compset.gfortran new file mode 100644 index 0000000..4694c3f --- /dev/null +++ b/config/compset.gfortran @@ -0,0 +1,17 @@ + +# Fortran compiler and flags +FC='gfortran' +FFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp' +FFFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp' +LDFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4' + +# C compiler +CC='gcc' +CFLAGS='-O2 -fopenmp' +C_LDFLAGS='-O2 -fopenmp' + +# MPI fortran compiler and flags. +# Set MPI_FC empty if you don't have/need MPI. +MPI_FC= +MPI_FFLAGS="$FFLAGS" +MPI_LDFLAGS="$LDFLAGS" diff --git a/config/compset.gfortran_debug b/config/compset.gfortran_debug new file mode 100644 index 0000000..513c8fd --- /dev/null +++ b/config/compset.gfortran_debug @@ -0,0 +1,37 @@ +# -*-sh-*- +# +# For GNU compiler collection (GCC) 4.0 +# + +echo ' +!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!! +! +! Versions up to 4.1.0 DO NOT WORK with edge due to compiler bugs. +! Also the binary file format for unformatted I/O is +! not compatible with the format used by most other compilers. +! +! This configuration file works with gfortran 4.3.2 and newer +! Note: older gfortran versions should include +! flags "-static-libgfortran" or "-static" +! +! MAKE SURE YOU HAVE gfortran VERSION 4.1.1 OR NEWER +! +!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!! +' + +# Fortran compiler and flags +FC='gfortran' +FFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' +FFFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' +LDFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' + +# C compiler +CC='gcc' +CFLAGS='-g' +C_LDFLAGS='-g' + +# MPI fortran compiler and flags. +# Set MPI_FC empty if you don't have/need MPI. +MPI_FC= +MPI_FFLAGS="$FFLAGS" +MPI_LDFLAGS="$LDFLAGS" diff --git a/config/compset.x86_64 b/config/compset.x86_64 new file mode 100644 index 0000000..cd299c3 --- /dev/null +++ b/config/compset.x86_64 @@ -0,0 +1,20 @@ +# -*-sh-*- +# +# For intel ifort 12 compiler. +# + +# Fortran compiler and flags +FC='ifort' +FFLAGS='-O2 -msse3 -ip -convert big_endian -r8 -std03 -fpp' +LDFLAGS='-O2 -msse3 -ip -convert big_endian -r8 -std03 -i-static' + +# C compiler +CC='icc' +CFLAGS='-O2 -msse3 -ip' +C_LDFLAGS='-O2 -msse3 -ip -i-static' + +# MPI fortran compiler and flags. +# Set MPI_FC empty if you don't have/need MPI. +MPI_FC= +MPI_FFLAGS="$FFLAGS" +MPI_LDFLAGS="$LDFLAGS" diff --git a/config/compset.x86_64_debug b/config/compset.x86_64_debug new file mode 100644 index 0000000..5fb3d0c --- /dev/null +++ b/config/compset.x86_64_debug @@ -0,0 +1,20 @@ +# -*-sh-*- +# +# For intel ifort 12 compiler, debug compilation. +# + +# Fortran compiler and flags +FC='ifort' +FFLAGS='-msse3 -g -traceback -check -warn -convert big_endian -r8 -std03 -fpe0 -ftrapuv' +LDFLAGS='-msse3 -g -traceback -check -warn -convert big_endian -r8 -std03 -i-static -fpe0 -ftrapuv' + +# C compiler +CC='icc' +CFLAGS='-msse3 -g -Wall -traceback' +C_LDFLAGS='-msse3 -w -Wall -traceback -i-static' + +# MPI fortran compiler and flags. +# Set MPI_FC empty if you don't have/need MPI. +MPI_FC= +MPI_FFLAGS="$FFLAGS" +MPI_LDFLAGS="$LDFLAGS" diff --git a/configure.py b/configure.py new file mode 100755 index 0000000..a4524c3 --- /dev/null +++ b/configure.py @@ -0,0 +1,272 @@ +#!/usr/bin/python +# +# +# this is a python script wj +# +import os +import re +import glob +import fnmatch +import os +import sys +import errno +import copy +import platform + +#Definitions + +def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +# +# definition of parameters +# + print_header() + linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep']) + exclude =(['python_dep', 'config', '.git']) +# +# + path = os.path.dirname(os.path.abspath(__file__)) +# + cwd = os.getcwd() + + path = check_path(path=path) + if not os.path.isdir(path): + print(" ") + print("\033[031mERROR:\033[039m specified project source location \033[032m"+path+"\033[039m does not exist, terminating .... ") + sys.exit() + + cwd = check_path(path=cwd) + + print(" ") + print("\033[031mDIAG:\033[039m project location is \033[032m"+path+"\033[039m") + print("\033[031mDIAG:\033[039m Intended location of compillation is \033[032m"+cwd+"\033[039m") + + if cwd == path: + print(".....") + print ("\033[031mError:\033[039m project location is the same as inteded location of compillation \033[032m"+path+"\033[039m") + print ("\033[031m \033[039m choose different location \033[032m" "\033[039m") + print(" terminating .... ") + sys.exit() +# +# creating config file +# + print(" ") + print("\033[031mDIAG:\033[039m creating configure file \033[032m \033[039m") + print(" ") + ok = mkconfigfile(path=path, cwd=cwd,version='gfortran', bin_dir=cwd) +# +# create structure and link necessary files +# + print(" ") + print("\033[031mDIAG:\033[039m Recreating project tree structure and linking files \033[032m \033[039m .....") + print("\033[031mDIAG:\033[039m Project root directory .... \033[032m \033[039m .....") + ok=prepare_root_dir(root_path=path, cwd=cwd, linkfiles=linkfiles) + print(" ") + print("\033[031mDIAG:\033[039m Subdirectories .... \033[032m \033[039m") + ok=mkdir_structure(root_path=path, cwd=cwd, exclude=exclude, linkfiles=linkfiles) + + print(" ") + print("\033[031mSUCCESS:\033[039m Setup was succesful \033[032m \033[039m") + print(" ") + +# list directories and subdirectories + +def get_all_dirs(path,exclude): + + matches = [] + matchesf = [] + + for root, dirnames, filenames in os.walk(path): + for filename in fnmatch.filter(dirnames, '*'): + matches.append(os.path.join(root, filename)) + + length = len(path) + for name in matches: + dirtmp = name.replace(name[:length], '') + matchesf.append(dirtmp) + + for d in list(matchesf): + for word in exclude: + if word in d: + matchesf.remove(d) + + print ("\033[031mDIAG:\033[039m Following list of subdirectories will be processed ... \033[032m \033[039m") + for name in matchesf: + print ("\033[032m "+name+"\033[039m") + + return matchesf + +def prepare_root_dir(root_path,cwd, linkfiles): +# +# list all dirs in project except directories specified in exclude +# + linknew = copy.copy(linkfiles) + linknew.append('rules.mk') + linknew.remove('project.dep') + + for word in linknew: + try: + os.remove(word) + print ("\033[031mDIAG: \033[039m file \033[032m"+word+"\033[039m already exists, removing ....") + except OSError: + pass + + source = root_path+'/'+word + dest = cwd+'/'+word + print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") + linkfile = os.symlink( source, dest) + + return + +def mkdir_structure(root_path,cwd, exclude, linkfiles): +# +# list all dirs in project except directories specified in exclude +# + dirs=get_all_dirs(path=root_path,exclude=exclude) + + print(" ") +# +# loop over diorectories and make them +# + for dir in dirs: + try: + os.makedirs(dir) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + else: + print ("\033[031mDIAG: \033[039m directory \033[032m"+dir+"\033[039m already exists, keeping it ....") +# +# loop over new directories and link the linkfiles +# from project directories +# + print(" ") + length = len(cwd) + + for subdir, dirs, files in os.walk(cwd): + for dir in dirs: + subdir = check_path(path=subdir) + newdir = subdir+dir + print ("\033[031mDIAG: \033[039m processing directory \033[032m"+newdir+"\033[039m ....") + dirtmp = subdir.replace(subdir[:length], '') + dirtmp = check_path(path=dirtmp) + dirtmp = root_path + dirtmp+dir + + os.chdir(newdir) + + for word in linkfiles: + try: + os.remove(word) + print ("\033[031mDIAG: \033[039m file \033[032m"+word+"\033[039m already exists, removing ....") + except OSError: + pass + + source = dirtmp+'/'+word + dest = newdir+'/'+word + print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") + linkfile = os.symlink( source, dest) + + os.chdir(cwd) + print(" ") + + + return + + +def check_path(path): + if not(path.endswith("/")): + path=path + "/" + + return path + +def mkconfigfile(path, cwd,version, bin_dir): + filename = path+'/config/compset.'+version + exec_dir=bin_dir+"/bin/" + + confname = 'config.mk' + + try: + os.remove(confname) + print ("\033[031mDIAG: \033[039m config.mk file \033[032m \033[039m already exists, removing ....") + except OSError: + pass + + fconfig = open(confname, 'w') + + fconfig.write("#\n") + fconfig.write("SHELL = /bin/bash\n") + fconfig.write("#\n") + + fconfig.write("#\n") + fconfig.write("Compiler settings\n") + fconfig.write("#\n") + + with open(filename) as f: + for line in f: + if ( not(line.startswith('#')) or not line.strip()): + print(line) + fconfig.write(line) + + fconfig.write("#\n") + fconfig.write("# bin_dir is the base directory where executables will be installed\n") + fconfig.write("#\n") + fconfig.write('bin_dir='+exec_dir) + fconfig.write("#\n") + fconfig.write("#\n") + fconfig.write("# MACHINE identifies the host machine type") + fconfig.write("#\n") + fconfig.write("MACHINE="+platform.machine()+"\n") + fconfig.write("#\n") + fconfig.write("# Install command (or cp -p if install is not found)\n") + fconfig.write("#\n") + fconfig.write("INSTALL = install -c\n") + fconfig.write("#\n") + fconfig.write("PROJ_ROOT_PATH="+path+"\n") + fconfig.write("MAKEDEPEND="+path+"/python_def/fort_depend.py\n") + + f.close() + fconfig.close() + +class file_obj: + def __init__(self): + self.file_name=None + self.uses=None + self.contains=None + self.depends_on=None + +def print_header(): + print(" ") + print ("\033[031m**************************************************************** \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m*\033[039m this is a configure file for FLL library \033[031m * \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m**************************************************************** \033[039m") +#Script +if __name__ == "__main__": + import argparse + + # Add command line arguments + parser = argparse.ArgumentParser(description='FLL configure script') + parser.add_argument('-f','--files',nargs='+',help='Files to process') + parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', + help="""The macro NAME is replaced by DEFINITION in 'use' statements""") + parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', + default='') + parser.add_argument('-o','--output',nargs=1,help='Output file') + parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') + parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') + + # Parse the command line arguments + args = parser.parse_args() + + # Assemble a dictionary out of the macro definitions + macros = {} + if args.D: + for arg in args.D: + for var in arg: + temp = var.split('=') + macros[temp[0]] = temp[1] + + output = args.output[0] if args.output else None + build = args.build[0] if args.build else '' + + run(verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) diff --git a/data_util/ERR_LINE_IDEF_SCRIPT b/data_util/ERR_LINE_IDEF_SCRIPT deleted file mode 100755 index 2bab129..0000000 --- a/data_util/ERR_LINE_IDEF_SCRIPT +++ /dev/null @@ -1,42 +0,0 @@ -#/bin/csh - - - set file_list=`find ./ -iname "*.f90"` - - foreach file ($file_list) - - echo $file - - set LINENUM = `sed -n '/ALLOCATING MEMORY/=' "$file"` - echo $LINENUM - - foreach num ($LINENUM) - - set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` - echo $text - - sed -i ''$num's/ALLOCATING MEMORY.*$/'"$text"' APOStroPHE/' $file - - end - sed -i "s/APOStroPHE/\'/g" $file - - end - - foreach file ($file_list) - - echo $file - - set LINENUM = `sed -n '/ALLOCATING ARRAYS/=' "$file"` - echo $LINENUM - - foreach num ($LINENUM) - - set text = `basename $file | sed 's/.f90//' | awk '{print "ALLOCATING MEMORY ==> ", $1, "ERR:" '$num'}' ` - echo $text - - sed -i ''$num's/ALLOCATING ARRAYS.*$/'"$text"' APOStroPHE/' $file - - end - sed -i "s/APOStroPHE/\'/g" $file - - end diff --git a/data_util/Makefile b/data_util/Makefile index e4d562c..fed4b7e 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -2,7 +2,7 @@ # Makefile for data_util library ############################################################################ # -include src_dir_path +include src_dir_path.mk include ../config.mk # $(DEP_FILE) is a .dep file generated by fort_depend.py @@ -26,8 +26,8 @@ test: depend: $(FFILES) - @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk/ -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + echo "Making dependencies ..." + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) diff --git a/data_util/ll_cat.f90 b/data_util/ll_cat.f90 index 26abc15..b07aecf 100644 --- a/data_util/ll_cat.f90 +++ b/data_util/ll_cat.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_CAT +! Subroutine FLL_CAT ! ! Date: 2016-10-10 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_CAT_M +MODULE FLL_CAT_M CONTAINS - SUBROUTINE LL_CAT(PNODE,IOUNIT,FPAR) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -74,22 +74,22 @@ SUBROUTINE LL_CAT(PNODE,IOUNIT,FPAR) PCHILD => PNODE%PCHILD IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' NODE HAS A PARENT, NAME IS ', PNODE%PPAR%LNAME - CALL LL_PRINT(PNODE, IOUNIT, POS, FPAR) + CALL FLL_PRINT(PNODE, IOUNIT, POS, FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL LL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_CAT + END SUBROUTINE FLL_CAT ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE LL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -109,12 +109,12 @@ RECURSIVE SUBROUTINE LL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) ! DO WHILE(ASSOCIATED(PCURR)) - CALL LL_PRINT(PCURR, IOUNIT, POS, FPAR) + CALL FLL_PRINT(PCURR, IOUNIT, POS, FPAR) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL LL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) END IF PCURR => PNEXT @@ -123,12 +123,12 @@ RECURSIVE SUBROUTINE LL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_CAT_RECURSIVE_NODE + END SUBROUTINE FLL_CAT_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE LL_PRINT(PNODE, IOUNIT, POS, FPAR) - USE LL_TYPE_M + SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -209,7 +209,7 @@ SUBROUTINE LL_PRINT(PNODE, IOUNIT, POS, FPAR) POS = POS - 1 RETURN !100 FORMAT('-',A,) - END SUBROUTINE LL_PRINT + END SUBROUTINE FLL_PRINT -END MODULE LL_CAT_M +END MODULE FLL_CAT_M diff --git a/data_util/ll_cp.f90 b/data_util/ll_cp.f90 index e6d8dda..584ebbb 100644 --- a/data_util/ll_cp.f90 +++ b/data_util/ll_cp.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_CP +! Subroutine FLL_CP ! ! Date: 2016-10-10 ! @@ -43,10 +43,10 @@ ! Description ! ! -MODULE LL_CP_M +MODULE FLL_CP_M CONTAINS - FUNCTION LL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) + FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! ! FUNCTIONS COPIES PHAT TO PWHERE. ! IF PWHERE IS NULL, PWHAT WILL @@ -54,10 +54,10 @@ FUNCTION LL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! ! INPUT PARAMETERS: ! - USE LL_TYPE_M - USE LL_MV_M - USE LL_DUPLICATE_M - USE LL_CAT_M + USE FLL_TYPE_M + USE FLL_MV_M + USE FLL_DUPLICATE_M + USE FLL_CAT_M IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT,PWHERE @@ -78,25 +78,25 @@ FUNCTION LL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! IF NOT SPECIFIED WHERE TO COPY ! JUST DUPLICATE NODE ! - PNEW => LL_DUPLICATE(PWHAT, FPAR) + PNEW => FLL_DUPLICATE(PWHAT, FPAR) ELSE ! ! DUPLICATE NODE AND MOVE IT ! TO PWHERE ! - PNEW => LL_CP_R(PWHAT,PWHERE,'C',FPAR) + PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) END IF RETURN - END FUNCTION LL_CP + END FUNCTION FLL_CP - FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) - USE LL_TYPE_M - USE LL_RM_M - USE LL_STICH_M - USE LL_DUPLICATE_M + USE FLL_TYPE_M + USE FLL_RM_M + USE FLL_STICH_M + USE FLL_DUPLICATE_M IMPLICIT NONE ! @@ -134,7 +134,7 @@ FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) PTPAR => PWHERE%PPAR IF(MODE == 'C')THEN - PNEW => LL_DUPLICATE(PWHAT, FPAR) + PNEW => FLL_DUPLICATE(PWHAT, FPAR) PSOURCETMP => PNEW ! ! IN CASE NODE IS NOT COPIED ANYWAY, IT IS ONLY DUPLICATED, RETURN @@ -153,7 +153,7 @@ FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL LL_STICH(PWHAT,FPAR) + IF(MODE == 'M') CALL FLL_STICH(PWHAT,FPAR) IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN ! @@ -188,11 +188,11 @@ FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN ! DELETE TARGET NODE ! - CALL LL_RM(PWHERE, FPAR) + CALL FLL_RM(PWHERE, FPAR) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL LL_STICH(PSOURCETMP,FPAR) + IF(MODE == 'M') CALL FLL_STICH(PSOURCETMP,FPAR) ! ! ADD A NEW NODE ! @@ -232,6 +232,6 @@ FUNCTION LL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .TRUE. RETURN - END FUNCTION LL_CP_R + END FUNCTION FLL_CP_R -END MODULE LL_CP_M +END MODULE FLL_CP_M diff --git a/data_util/ll_deattach.f90 b/data_util/ll_deattach.f90 index ef50e59..b46a298 100644 --- a/data_util/ll_deattach.f90 +++ b/data_util/ll_deattach.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_DEATTACH +! Subroutine FLL_DEATTACH ! ! Date: 2016-10-10 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_DEATTACH_M +MODULE FLL_DEATTACH_M CONTAINS - FUNCTION LL_DEATTACH(PWHAT,FPAR) RESULT(OK) - USE LL_TYPE_M - USE LL_STICH_M + FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) + USE FLL_TYPE_M + USE FLL_STICH_M IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT TYPE(FUNC_DATA_SET) :: FPAR @@ -63,7 +63,7 @@ FUNCTION LL_DEATTACH(PWHAT,FPAR) RESULT(OK) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - CALL LL_STICH(PWHAT,FPAR) + CALL FLL_STICH(PWHAT,FPAR) PWHAT%PPAR => NULL() PWHAT%PNEXT => NULL() PWHAT%PPREV => NULL() @@ -71,6 +71,6 @@ FUNCTION LL_DEATTACH(PWHAT,FPAR) RESULT(OK) FPAR%SUCCESS = .TRUE. OK = .TRUE. RETURN - END FUNCTION LL_DEATTACH + END FUNCTION FLL_DEATTACH -END MODULE LL_DEATTACH_M +END MODULE FLL_DEATTACH_M diff --git a/data_util/ll_duplicate.f90 b/data_util/ll_duplicate.f90 index aefa95e..18c1ee1 100644 --- a/data_util/ll_duplicate.f90 +++ b/data_util/ll_duplicate.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_duplicate +! Subroutine FLL_duplicate ! ! Date: 2016-10-10 ! @@ -43,14 +43,14 @@ ! Description ! ! -MODULE LL_DUPLICATE_M +MODULE FLL_DUPLICATE_M CONTAINS - FUNCTION LL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) + FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) - USE LL_TYPE_M - USE LL_MK_M - USE LL_MV_M + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M IMPLICIT NONE ! @@ -78,7 +78,7 @@ FUNCTION LL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM ! IF(ASSOCIATED(PCHILD))THEN - PNEW => LL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) + PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. @@ -86,7 +86,7 @@ FUNCTION LL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) RETURN END IF - CALL LL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' FPAR%SUCCESS = .FALSE. @@ -98,29 +98,29 @@ FUNCTION LL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! ! NODE IS A FILE NODE ! - PNEW => LL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF - CALL LL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) END IF FPAR%SUCCESS = .TRUE. RETURN - END FUNCTION LL_DUPLICATE + END FUNCTION FLL_DUPLICATE ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) + RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) - USE LL_TYPE_M - USE LL_MK_M - USE LL_MV_M + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -138,14 +138,14 @@ RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! IF(.NOT.ASSOCIATED(PCHILD))THEN - PNEW => LL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF - CALL LL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) - OK = LL_MV(PNEW, PDUPL, FPAR) + CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) + OK = FLL_MV(PNEW, PDUPL, FPAR) FPAR%SUCCESS = .TRUE. ELSE ! @@ -157,7 +157,7 @@ RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - PNEW => LL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) + PNEW => FLL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. @@ -169,7 +169,7 @@ RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! DO WHILE(ASSOCIATED(PCHILD)) - CALL LL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' PCHILD => PCHILD%PNEXT @@ -177,7 +177,7 @@ RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! ! ADD TO PDUPL LIST ! - OK = LL_MV(PNEW,PDUPL,FPAR) + OK = FLL_MV(PNEW,PDUPL,FPAR) PCURR => PNEXT END DO @@ -186,12 +186,12 @@ RECURSIVE SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_DUPLICATE_RECURSIVE_NODE + END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE LL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) - USE LL_TYPE_M + SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -401,7 +401,7 @@ SUBROUTINE LL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%L0 = PNODE%L0 PNEW%S = PNODE%S - END SUBROUTINE LL_COPPY_NODE_ARRAYS + END SUBROUTINE FLL_COPPY_NODE_ARRAYS -END MODULE LL_DUPLICATE_M +END MODULE FLL_DUPLICATE_M diff --git a/data_util/ll_funct_prt.f90 b/data_util/ll_funct_prt.f90 index 8b3143f..07b489d 100644 --- a/data_util/ll_funct_prt.f90 +++ b/data_util/ll_funct_prt.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_FUNC_PRT_M +! Subroutine FLL_FUNC_PRT_M ! ! Date: 2016-10-10 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_FUNC_PRT_M +MODULE FLL_FUNC_PRT_M CONTAINS FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: NTYPE @@ -61,7 +61,7 @@ END FUNCTION ERR_MSG FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) ! - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE INTEGER :: IOSTAT TYPE(FUNC_DATA_SET) :: FPAR @@ -83,4 +83,4 @@ FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) ! END FUNCTION TEST_IOSTAT -END MODULE LL_FUNC_PRT_M +END MODULE FLL_FUNC_PRT_M diff --git a/data_util/ll_locate.f90 b/data_util/ll_locate.f90 index ca51eaa..a58023f 100644 --- a/data_util/ll_locate.f90 +++ b/data_util/ll_locate.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_LOCATE +! Subroutine FLL_LOCATE ! ! Date: 2016-10-10 ! @@ -43,13 +43,13 @@ ! Description ! ! -MODULE LL_LOCATE_M +MODULE FLL_LOCATE_M CONTAINS - RECURSIVE FUNCTION LL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) + RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) - USE LL_TYPE_M - USE LL_FUNC_PRT_M + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M IMPLICIT NONE ! @@ -98,7 +98,7 @@ RECURSIVE FUNCTION LL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - PFIND => LL_LOCATE(PCHLD,NAME,1_LICOMPIL,LTYPE,RECURSE,FPAR) + PFIND => FLL_LOCATE(PCHLD,NAME,1_LICOMPIL,LTYPE,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN @@ -129,7 +129,7 @@ RECURSIVE FUNCTION LL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) RETURN - END FUNCTION LL_LOCATE + END FUNCTION FLL_LOCATE -END MODULE LL_LOCATE_M +END MODULE FLL_LOCATE_M diff --git a/data_util/ll_mk.f90 b/data_util/ll_mk.f90 index 78f6613..1a07d8f 100644 --- a/data_util/ll_mk.f90 +++ b/data_util/ll_mk.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_MK +! Subroutine FLL_MK ! ! Date: 2016-10-19 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_MK_M +MODULE FLL_MK_M CONTAINS - FUNCTION LL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) + FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE TYPE(FUNC_DATA_SET) :: FPAR @@ -183,9 +183,9 @@ FUNCTION LL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) END SELECT RETURN - END FUNCTION LL_MK + END FUNCTION FLL_MK -END MODULE LL_MK_M +END MODULE FLL_MK_M diff --git a/data_util/ll_mods.f90 b/data_util/ll_mods.f90 index 053e2bd..cf4d37f 100644 --- a/data_util/ll_mods.f90 +++ b/data_util/ll_mods.f90 @@ -1,20 +1,20 @@ -MODULE LL_MODS_M +MODULE FLL_MODS_M - USE LL_CAT_M - USE LL_CP_M - USE LL_DEATTACH_M - USE LL_DUPLICATE_M - USE LL_FUNC_PRT_M - USE LL_LOCATE_M - USE LL_MK_M - USE LL_MV_M - USE LL_NNODES_M - USE LL_READ_M - USE LL_RM_M - USE LL_STICH_M - USE LL_SWEEP_M - USE LL_TYPE_M - USE LL_WRITE_M + USE FLL_CAT_M + USE FLL_CP_M + USE FLL_DEATTACH_M + USE FLL_DUPLICATE_M + USE FLL_FUNC_PRT_M + USE FLL_LOCATE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_NNODES_M + USE FLL_READ_M + USE FLL_RM_M + USE FLL_STICH_M + USE FLL_SWEEP_M + USE FLL_TYPE_M + USE FLL_WRITE_M -END MODULE LL_MODS_M +END MODULE FLL_MODS_M diff --git a/data_util/ll_modules b/data_util/ll_modules index dcb1b1f..1a4506c 100644 --- a/data_util/ll_modules +++ b/data_util/ll_modules @@ -1,10 +1,10 @@ -USE LL_DUPLICATE_M -USE LL_RUNC_PRT_M -USE LL_LOCATE_M -USE LL_MK_M -USE LL_MVCP_M -USE LL_READ_M -USE LL_RM_M -USE LL_STICH_M -USE LL_TYPE_M -USE LL_WRITE_M +USE FLL_DUPLICATE_M +USE FLL_RUNC_PRT_M +USE FLL_LOCATE_M +USE FLL_MK_M +USE FLL_MVCP_M +USE FLL_READ_M +USE FLL_RM_M +USE FLL_STICH_M +USE FLL_TYPE_M +USE FLL_WRITE_M diff --git a/data_util/ll_mv.f90 b/data_util/ll_mv.f90 index e26ef0b..51a65e4 100644 --- a/data_util/ll_mv.f90 +++ b/data_util/ll_mv.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_MV +! Subroutine FLL_MV ! ! Date: 2016-10-10 ! @@ -43,28 +43,28 @@ ! Description ! ! -MODULE LL_MV_M +MODULE FLL_MV_M CONTAINS - FUNCTION LL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) - USE LL_TYPE_M + FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) + USE FLL_TYPE_M IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PSOURCETMP LOGICAL OK - PSOURCETMP => LL_MVCP(PWHAT,PWHERE,'M',FPAR) + PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) OK = FPAR%SUCCESS RETURN - END FUNCTION LL_MV + END FUNCTION FLL_MV - FUNCTION LL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) - USE LL_TYPE_M - USE LL_RM_M - USE LL_STICH_M + USE FLL_TYPE_M + USE FLL_RM_M + USE FLL_STICH_M IMPLICIT NONE ! @@ -111,7 +111,7 @@ FUNCTION LL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - CALL LL_STICH(PWHAT,FPAR) + CALL FLL_STICH(PWHAT,FPAR) IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN ! @@ -145,11 +145,11 @@ FUNCTION LL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN ! DELETE TARGET NODE ! - CALL LL_RM(PWHERE, FPAR) + CALL FLL_RM(PWHERE, FPAR) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - CALL LL_STICH(PSOURCETMP,FPAR) + CALL FLL_STICH(PSOURCETMP,FPAR) ! ! ADD A NEW NODE ! @@ -189,6 +189,6 @@ FUNCTION LL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .TRUE. RETURN - END FUNCTION LL_MVCP + END FUNCTION FLL_MVCP -END MODULE LL_MV_M +END MODULE FLL_MV_M diff --git a/data_util/ll_nnodes.f90 b/data_util/ll_nnodes.f90 index 439b2e7..9b895fa 100644 --- a/data_util/ll_nnodes.f90 +++ b/data_util/ll_nnodes.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_NNODES +! Subroutine FLL_NNODES ! ! Date: 2016-10-10 ! @@ -43,13 +43,13 @@ ! Description ! ! -MODULE LL_NNODES_M +MODULE FLL_NNODES_M CONTAINS - RECURSIVE FUNCTION LL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) + RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) - USE LL_TYPE_M - USE LL_FUNC_PRT_M + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M IMPLICIT NONE ! @@ -98,7 +98,7 @@ RECURSIVE FUNCTION LL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - NUMBER = NUMBER + LL_NNODES(PCHLD,NAME,LTYPE,RECURSE,FPAR) + NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN @@ -118,7 +118,7 @@ RECURSIVE FUNCTION LL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) END DO RETURN - END FUNCTION LL_NNODES + END FUNCTION FLL_NNODES -END MODULE LL_NNODES_M +END MODULE FLL_NNODES_M diff --git a/data_util/ll_read.f90 b/data_util/ll_read.f90 index 9ec0d7f..42ddad9 100644 --- a/data_util/ll_read.f90 +++ b/data_util/ll_read.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_READ +! Subroutine FLL_READ ! ! Date: 2016-10-10 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_READ_M +MODULE FLL_READ_M CONTAINS - FUNCTION LL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! @@ -122,15 +122,15 @@ FUNCTION LL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) RETURN - END FUNCTION LL_READ + END FUNCTION FLL_READ ! ! READS NODE ! RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) - USE LL_TYPE_M - USE LL_MK_M - USE LL_MV_M + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M IMPLICIT NONE @@ -164,9 +164,9 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) END IF IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - PNODE => LL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) ELSE - PNODE => LL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -184,7 +184,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! ! ATTACH TO PNODE ! - OK = LL_MV(PNEW,PNODE,FPAR) + OK = FLL_MV(PNEW,PNODE,FPAR) IF(.NOT.OK) STOP' ERROR MV' END DO @@ -209,8 +209,8 @@ END FUNCTION READ_NODE ! SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) - USE LL_TYPE_M - USE LL_FUNC_PRT_M + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M IMPLICIT NONE @@ -330,8 +330,8 @@ END SUBROUTINE READ_HEADER ! SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - USE LL_TYPE_M - USE LL_FUNC_PRT_M + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M IMPLICIT NONE @@ -440,8 +440,8 @@ END SUBROUTINE READ_DATA_ASCII ! SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - USE LL_TYPE_M - USE LL_FUNC_PRT_M + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M IMPLICIT NONE @@ -542,4 +542,4 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END SUBROUTINE READ_DATA_BIN -END MODULE LL_READ_M +END MODULE FLL_READ_M diff --git a/data_util/ll_rm.f90 b/data_util/ll_rm.f90 index 01d5d8c..02de994 100644 --- a/data_util/ll_rm.f90 +++ b/data_util/ll_rm.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_RM +! Subroutine FLL_RM ! ! Date: 2016-10-10 ! @@ -43,13 +43,13 @@ ! Description ! ! -MODULE LL_RM_M +MODULE FLL_RM_M CONTAINS - SUBROUTINE LL_RM(PNODE,FPAR) + SUBROUTINE FLL_RM(PNODE,FPAR) - USE LL_TYPE_M - USE LL_STICH_M + USE FLL_TYPE_M + USE FLL_STICH_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -74,13 +74,13 @@ SUBROUTINE LL_RM(PNODE,FPAR) ! ! IF NODE HAS CHILDREN, REMOVE ALL OF THEM ! - IF(ASSOCIATED(PCHILD))CALL LL_RM_RECURSIVE_NODE(PCHILD,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR) - CALL LL_DEALLOC_DATA(PNODE,FPAR) + CALL FLL_DEALLOC_DATA(PNODE,FPAR) ! ! STICH AND SUBSTRACT FROM PARENT ! - CALL LL_STICH(PNODE,FPAR) + CALL FLL_STICH(PNODE,FPAR) ! ! NULLIFY NODE ! @@ -91,13 +91,13 @@ SUBROUTINE LL_RM(PNODE,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_RM + END SUBROUTINE FLL_RM ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE LL_RM_RECURSIVE_NODE(PNODE,FPAR) + RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -117,12 +117,12 @@ RECURSIVE SUBROUTINE LL_RM_RECURSIVE_NODE(PNODE,FPAR) DO WHILE(ASSOCIATED(PCURR)) PNEXT => PCURR%PNEXT IF(ASSOCIATED(PCURR%PCHILD))THEN - CALL LL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR) + CALL FLL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR) END IF IF(TRIM(PCURR%LTYPE) /= 'LINK')THEN - CALL LL_DEALLOC_DATA(PCURR,FPAR) + CALL FLL_DEALLOC_DATA(PCURR,FPAR) IF(ASSOCIATED(PCURR%PLINK))THEN PNODE%PLINK%PCHILD => NULL(); @@ -151,12 +151,12 @@ RECURSIVE SUBROUTINE LL_RM_RECURSIVE_NODE(PNODE,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_RM_RECURSIVE_NODE + END SUBROUTINE FLL_RM_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE LL_DEALLOC_DATA(PNODE,FPAR) - USE LL_TYPE_M + SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -250,7 +250,7 @@ SUBROUTINE LL_DEALLOC_DATA(PNODE,FPAR) RETURN END IF - END SUBROUTINE LL_DEALLOC_DATA + END SUBROUTINE FLL_DEALLOC_DATA -END MODULE LL_RM_M +END MODULE FLL_RM_M diff --git a/data_util/ll_stich.f90 b/data_util/ll_stich.f90 index 3ce16ed..f6f2ac5 100644 --- a/data_util/ll_stich.f90 +++ b/data_util/ll_stich.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_MV +! Subroutine FLL_MV ! ! Date: 2016-10-10 ! @@ -43,12 +43,12 @@ ! Description ! ! -MODULE LL_STICH_M +MODULE FLL_STICH_M CONTAINS - SUBROUTINE LL_STICH(PNODE,FPAR) + SUBROUTINE FLL_STICH(PNODE,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! @@ -106,6 +106,6 @@ SUBROUTINE LL_STICH(PNODE,FPAR) END IF END IF - END SUBROUTINE LL_STICH + END SUBROUTINE FLL_STICH -END MODULE LL_STICH_M +END MODULE FLL_STICH_M diff --git a/data_util/ll_sweep.f90 b/data_util/ll_sweep.f90 index d91a2b0..33f3c1c 100644 --- a/data_util/ll_sweep.f90 +++ b/data_util/ll_sweep.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_SWEEP +! Subroutine FLL_SWEEP ! ! Date: 2016-10-10 ! @@ -43,13 +43,13 @@ ! Description ! ! -MODULE LL_SWEEP_M +MODULE FLL_SWEEP_M CONTAINS - FUNCTION LL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) + FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) - USE LL_TYPE_M - USE LL_LOCATE_M + USE FLL_TYPE_M + USE FLL_LOCATE_M IMPLICIT NONE ! @@ -95,7 +95,7 @@ FUNCTION LL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) RETURN - END FUNCTION LL_SWEEP + END FUNCTION FLL_SWEEP -END MODULE LL_SWEEP_M +END MODULE FLL_SWEEP_M diff --git a/data_util/ll_type.f90 b/data_util/ll_type.f90 index 16f5bf1..72acfcd 100644 --- a/data_util/ll_type.f90 +++ b/data_util/ll_type.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_TYPE_M +! Subroutine FLL_TYPE_M ! ! Date: 2016-10-10 ! @@ -40,7 +40,7 @@ ! Description ! ! -MODULE LL_TYPE_M +MODULE FLL_TYPE_M !#ifdef f2003 !use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & ! stdout=>output_unit, & @@ -106,4 +106,4 @@ MODULE LL_TYPE_M CHARACTER(LEN=ERR_PATH_LENGTH) :: ERRPATH END TYPE FUNC_DATA_SET -END MODULE LL_TYPE_M +END MODULE FLL_TYPE_M diff --git a/data_util/ll_write.f90 b/data_util/ll_write.f90 index 5ab81af..d5b0e48 100644 --- a/data_util/ll_write.f90 +++ b/data_util/ll_write.f90 @@ -19,7 +19,7 @@ ! ! -! Subroutine LL_WRITE +! Subroutine FLL_WRITE ! ! Date: 2016-10-10 ! @@ -43,13 +43,13 @@ ! Description ! ! -MODULE LL_WRITE_M +MODULE FLL_WRITE_M CONTAINS - FUNCTION LL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) + FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! @@ -105,7 +105,7 @@ FUNCTION LL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! ! WRITE LINKED LIST ! - CALL LL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) + CALL FLL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -118,13 +118,13 @@ FUNCTION LL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) OK = .TRUE. RETURN - END FUNCTION LL_WRITE + END FUNCTION FLL_WRITE - SUBROUTINE LL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) + SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE WRITES LIST @@ -149,27 +149,27 @@ SUBROUTINE LL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) END IF IF(FMT == 'A')THEN - CALL LL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + CALL FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ELSE - CALL LL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + CALL FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) END IF PCHILD => PNODE%PCHILD ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL LL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_WRITE_LIST + END SUBROUTINE FLL_WRITE_LIST ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE LL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) + RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE REMOVES NODE @@ -191,15 +191,15 @@ RECURSIVE SUBROUTINE LL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) DO WHILE(ASSOCIATED(PCURR)) IF(FMT == 'A')THEN - CALL LL_SAVE_NODE_A(PCURR, IOUNIT, FPAR) + CALL FLL_SAVE_NODE_A(PCURR, IOUNIT, FPAR) ELSE - CALL LL_SAVE_NODE_B(PCURR, IOUNIT, POS, FPAR) + CALL FLL_SAVE_NODE_B(PCURR, IOUNIT, POS, FPAR) END IF PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL LL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) END IF PCURR => PNEXT @@ -208,12 +208,12 @@ RECURSIVE SUBROUTINE LL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE LL_WRITE_RECURSIVE_NODE + END SUBROUTINE FLL_WRITE_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE LL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) - USE LL_TYPE_M + SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE SAVES NODE @@ -300,11 +300,11 @@ SUBROUTINE LL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) RETURN - END SUBROUTINE LL_SAVE_NODE_A + END SUBROUTINE FLL_SAVE_NODE_A - SUBROUTINE LL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) - USE LL_TYPE_M + USE FLL_TYPE_M IMPLICIT NONE ! ! SUBROUTINE SAVES NODE @@ -391,6 +391,6 @@ SUBROUTINE LL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) RETURN - END SUBROUTINE LL_SAVE_NODE_B + END SUBROUTINE FLL_SAVE_NODE_B -END MODULE LL_WRITE_M +END MODULE FLL_WRITE_M diff --git a/data_util/project.dep b/data_util/project.dep index 54bcc58..d7f1266 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,17 +1,23 @@ # This file is generated automatically. DO NOT EDIT! -ll_cat.o : \ - ll_type.o - -ll_cp.o : \ - ll_cat.o \ - ll_rm.o \ +ll_mods.o : \ ll_mv.o \ + ll_write.o \ + ll_cat.o \ + ll_mk.o \ ll_stich.o \ + ll_cp.o \ + ll_sweep.o \ + ll_nnodes.o \ + ll_funct_prt.o \ + ll_deattach.o \ + ll_rm.o \ + ll_locate.o \ + ll_read.o \ ll_duplicate.o \ ll_type.o -ll_mk.o : \ +ll_funct_prt.o : \ ll_type.o ll_mv.o : \ @@ -19,61 +25,55 @@ ll_mv.o : \ ll_stich.o \ ll_type.o -ll_nnodes.o : \ - ll_type.o \ - ll_funct_prt.o - -ll_rm.o : \ - ll_stich.o \ +ll_locate.o : \ + ll_funct_prt.o \ ll_type.o -ll_duplicate.o : \ - ll_mk.o \ - ll_type.o \ - ll_mv.o +ll_cat.o : \ + ll_type.o -ll_funct_prt.o : \ +ll_mk.o : \ ll_type.o -ll_mods.o : \ - ll_cat.o \ - ll_nnodes.o \ - ll_deattach.o \ - ll_funct_prt.o \ - ll_mk.o \ - ll_rm.o \ - ll_cp.o \ - ll_write.o \ - ll_locate.o \ +ll_cp.o : \ ll_mv.o \ + ll_cat.o \ ll_stich.o \ - ll_sweep.o \ - ll_duplicate.o \ + ll_rm.o \ ll_type.o \ - ll_read.o + ll_duplicate.o -ll_deattach.o : \ - ll_stich.o \ - ll_type.o - -ll_locate.o : \ +ll_sweep.o : \ ll_type.o \ - ll_funct_prt.o + ll_locate.o -ll_write.o : \ +ll_nnodes.o : \ + ll_funct_prt.o \ ll_type.o -ll_sweep.o : \ - ll_type.o \ - ll_locate.o +ll_deattach.o : \ + ll_stich.o \ + ll_type.o -ll_type.o : +ll_duplicate.o : \ + ll_mv.o \ + ll_mk.o \ + ll_type.o ll_stich.o : \ ll_type.o +ll_rm.o : \ + ll_stich.o \ + ll_type.o + ll_read.o : \ - ll_mk.o \ - ll_type.o \ + ll_mv.o \ ll_funct_prt.o \ - ll_mv.o + ll_mk.o \ + ll_type.o + +ll_write.o : \ + ll_type.o + +ll_type.o : diff --git a/data_util/src_dir_path b/data_util/src_dir_path deleted file mode 100644 index 927db3c..0000000 --- a/data_util/src_dir_path +++ /dev/null @@ -1 +0,0 @@ -srcdir=/home/jka/OSS_CFD/trunk/data_util diff --git a/data_util/src_dir_path.mk b/data_util/src_dir_path.mk new file mode 100644 index 0000000..b83f4b1 --- /dev/null +++ b/data_util/src_dir_path.mk @@ -0,0 +1 @@ +srcdir=$(PROJ_ROOT_PATH)/data_util diff --git a/fort_depend.py b/python_dep/fort_depend.py similarity index 90% rename from fort_depend.py rename to python_dep/fort_depend.py index c9730e4..604e854 100755 --- a/fort_depend.py +++ b/python_dep/fort_depend.py @@ -1,4 +1,15 @@ #!/usr/bin/python +# +# +# this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py +# +# the modified version used here can be found @https://github.com/libm3l/fort_depend.py +# +# this is a script which maked fortran project dependecies +# it is executed in each directory separately and creates a project.dep file with fortran dependencies +# if fortran source uses module from other directory the script will add the module too +# the project root directory is specified as an input parameter with an option -r +# import os import re import glob @@ -78,15 +89,7 @@ def get_source(ext=[".f90",".F90"]): fil.extend(filter(lambda x: x.endswith(i),tmp)) return fil -def get_all_files(path): - #l=[] - - #for filename in glob.iglob('/home/jka/OSS_CFD/trunk/**/*.f90', recursive=True): - #print(filename) - #l.append(filename) - - #return l - +def get_all_files(path): matches = [] for root, dirnames, filenames in os.walk(path): for filename in fnmatch.filter(filenames, '*.f90'): @@ -101,7 +104,8 @@ def check_if_there(use,file): if "module" in line.lower(): if use in line: return 1 - + + f.close() return 0 @@ -184,9 +188,9 @@ def get_depends(fob=[],m2f=[], ffiles=[]): if retval > 0: name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") - print ("\033[031m..... \033[039m adding it to dependency file, not checking its dependency further \033[032m") + print ("\033[031m..... \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") deps[i.file_name]=tmp diff --git a/rules.mk b/rules.mk index 33258c6..dbaf1ab 100644 --- a/rules.mk +++ b/rules.mk @@ -15,38 +15,18 @@ HANDLE_UPPER_CASE_MOD_NAMES = ! [ "$(UPPER_MODFILE_NAME)" ] || ! [[ $* = *_m ]] $(FC) -c $(FFLAGS) $(FMODDIRS:%=$(FCMODINCFLAG)%) $< -@$(HANDLE_UPPER_CASE_MOD_NAMES) -# Rule for building fixed-form fortran from srcdir directory -%.o %.mod: $(srcdir)/%.f - $(FC) -c $(FFFLAGS) $(FMODDIRS:%=$(FCMODINCFLAG)%) $< - -@$(HANDLE_UPPER_CASE_MOD_NAMES) - # Rule for building C from srcdir directory +# %.o: $(srcdir)/%.c $(CC) -c $(CFLAGS) $(CINCDIRS:%=-I%) $< -# Rule for creating a build directory, if it doesn't already exist. -# Also links the corresponding Makefile from the sourcedirectory if -# it doesn't already exist. Also copies depend.mk from sourcedirectory -# if it exists. +# Rule for creating a build directory +# %.mkdir: @[ -d $* ] || mkdir $* - @! [ -h $*/Makefile ] || rm -f $*/Makefile - @[ -f $*/Makefile ] || ln -s $(srcdir)/$*/Makefile $*/Makefile - @rm -f $*/local_config.mk - @echo srcdir=$(if $(filter .,$(srcdir)),.,$(srcdir)/$*) \ - > $*/local_config.mk - -%: $(srcdir)/%.bash - sed 's:^#!/bin/bash:#!'"$(SHELL):" $< > $@ - chmod 755 $@ - -%: $(srcdir)/%.py - cat $< > $@ - chmod 755 $@ - # # Rules for recursion into subdirectories for standard targets. -# +# %.all: %.mkdir @cd $* && $(MAKE) all diff --git a/src_dir_path b/src_dir_path deleted file mode 100644 index 847ef74..0000000 --- a/src_dir_path +++ /dev/null @@ -1 +0,0 @@ -srcdir=/home/jka/OSS_CFD/trunk/ diff --git a/src_dir_path.mk b/src_dir_path.mk new file mode 100644 index 0000000..51f57a5 --- /dev/null +++ b/src_dir_path.mk @@ -0,0 +1 @@ +srcdir=/home/jiraseka/LL/trunk diff --git a/test/Makefile b/test/Makefile index 9c4b6c8..8e02fdc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,15 +1,7 @@ -############################################################################ -# Makefile for ffalist -############################################################################ -# -# $HeadURL: https://costello.foi.se/svn/edge/branches/aeroelastics/programs/ffalist/Makefile $ -# $LastChangedDate: 2007-09-21 14:50:09 +0200 (Fri, 21 Sep 2007) $ -# $LastChangedBy: oskeno $ -# $LastChangedRevision: 1282 $ EXE = ll_test -include src_dir_path +include src_dir_path.mk include ../config.mk DEP_FILE=project.dep @@ -36,7 +28,7 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk/ -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) install: $(EXE).x $(EXE) $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) diff --git a/test/ll_test.f90 b/test/ll_test.f90 index 734af83..0a401f5 100644 --- a/test/ll_test.f90 +++ b/test/ll_test.f90 @@ -43,9 +43,9 @@ ! Description ! ! - PROGRAM LL_TEST + PROGRAM FLL_TEST - USE LL_MODS_M + USE FLL_MODS_M IMPLICIT NONE ! ! SUBROUTINE MOVES NODE @@ -65,65 +65,65 @@ PROGRAM LL_TEST ! ! read TEST file and store it in PNODE ! - PNODE => LL_READ('TEST',8,'A',FPAR) + PNODE => FLL_READ('TEST',8,'A',FPAR) ! ! print Pnode on screen ! - CALL LL_CAT(PNODE, 6, FPAR) + CALL FLL_CAT(PNODE, 6, FPAR) WRITE(*,*)'------------------------------------------------------1' ! ! read TEST1 file and store it in PNODE1 ! - PNODE1 => LL_READ('TEST1',8,'A',FPAR) + PNODE1 => FLL_READ('TEST1',8,'A',FPAR) ! ! print PNODE1 on screen ! - CALL LL_CAT(PNODE1, 6, FPAR) + CALL FLL_CAT(PNODE1, 6, FPAR) WRITE(*,*)'------------------------------------------------------2' ! ! save PNODE1 as binary and ascii file ! - OK = LL_WRITE(PNODE1,'File_2.txt',8,'B',FPAR) - OK = LL_WRITE(PNODE1,'File_1.txt',8,'A',FPAR) + OK = FLL_WRITE(PNODE1,'File_2.txt',8,'B',FPAR) + OK = FLL_WRITE(PNODE1,'File_1.txt',8,'A',FPAR) ! ! read bindary file and store it in PNODE2 ! then print it on screed and then delete it - PNODE2 => LL_READ('File_2.txt',8,'B',FPAR) - CALL LL_CAT(PNODE2, 6, FPAR) - CALL LL_RM(PNODE2,FPAR) + PNODE2 => FLL_READ('File_2.txt',8,'B',FPAR) + CALL FLL_CAT(PNODE2, 6, FPAR) + CALL FLL_RM(PNODE2,FPAR) WRITE(*,*)'------------------------------------------------------3' ! ! MAKE A NEW NODE AND MOVE ENTIRE PNODE INTO IT ! PRINT IT ON THE SCREEN ! - PNEW1 => LL_MK("newnone","DIR",0_LINT, 0_LINT,FPAR) - OK = LL_MV(PNODE, PNEW1, FPAR) - CALL LL_CAT(PNEW1, 6, FPAR) + PNEW1 => FLL_MK("newnone","DIR",0_LINT, 0_LINT,FPAR) + OK = FLL_MV(PNODE, PNEW1, FPAR) + CALL FLL_CAT(PNEW1, 6, FPAR) WRITE(*,*)'------------------------------------------------------4' ! ! COPY PNODE, BECASE THE TARGET IN COPY IS NULL ! THE PNEW IS GOING TO BE A DUPLICATE OF PNODE ! AND IS GOING TO BE A NEW NODE ! - PNEW => LL_CP(PNODE, NULL(), FPAR) - CALL LL_CAT(PNEW, 6, FPAR) + PNEW => FLL_CP(PNODE, NULL(), FPAR) + CALL FLL_CAT(PNEW, 6, FPAR) WRITE(*,*)'------------------------------------------------------5' ! ! REMOVE PNEW1 ! - CALL LL_RM(PNEW1,FPAR) + CALL FLL_RM(PNEW1,FPAR) ! ! COPY PNODE TO PNEW -! ON RETURN, THE LL_CP WILL GIVE BACK POINTER OF PNEW IN PNODE LIST +! ON RETURN, THE FLL_CP WILL GIVE BACK POINTER OF PNEW IN PNODE LIST ! - PNEW2 => LL_CP(PNEW, PNODE1, FPAR) - CALL LL_CAT(PNODE1, 6, FPAR) + PNEW2 => FLL_CP(PNEW, PNODE1, FPAR) + CALL FLL_CAT(PNODE1, 6, FPAR) WRITE(*,*)'------------------------------------------------------6' ! ! LOCATE 1st subdir IN PNODE1 AND PRINT IT ON THE SCREEN ! - PTMP => LL_LOCATE(PNODE1,'subdir',1_lint,'*',.false.,FPAR) - CALL LL_CAT(PTMP, 6, FPAR) + PTMP => FLL_LOCATE(PNODE1,'subdir',1_lint,'*',.false.,FPAR) + CALL FLL_CAT(PTMP, 6, FPAR) WRITE(*,*)'------------------------------------------------------7' ! ! CLEANUP ALL MEMORY @@ -135,8 +135,8 @@ PROGRAM LL_TEST ! PNODE2 WAS DELETED RIGHT AFTER BEING RETURN FROM READ ! PNEW2 IS NOT A NEW NODE, IT POINTS TO A COPY SO DOES NOT NEED TO BE FREED ! - CALL LL_RM(PNEW,FPAR) - CALL LL_RM(PNODE1,FPAR) + CALL FLL_RM(PNEW,FPAR) + CALL FLL_RM(PNODE1,FPAR) END PROGRAM diff --git a/test/src_dir_path b/test/src_dir_path deleted file mode 100644 index 0b3090b..0000000 --- a/test/src_dir_path +++ /dev/null @@ -1 +0,0 @@ -srcdir=/home/jka/OSS_CFD/trunk/test diff --git a/test/src_dir_path.mk b/test/src_dir_path.mk new file mode 100644 index 0000000..38f2584 --- /dev/null +++ b/test/src_dir_path.mk @@ -0,0 +1 @@ +srcdir=$(PROJ_ROOT_PATH)/test From 2ef6eaab302a379c53db353834f0672d599babb2 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 27 Oct 2016 20:47:27 -0600 Subject: [PATCH 009/325] rename all routines to fll_ --- accessories/ll_cat/Makefile | 44 +++++ accessories/ll_cat/ada.py | 10 ++ accessories/ll_cat/ll_cat.f90 | 82 ++++++++++ accessories/ll_cat/project.dep | 6 + config.log | 1 + config/compset.gfortran | 29 ++-- config/compset.gfortran_debug | 48 ++---- configure.py | 2 +- data_util/{ll_cat.f90 => fll_cat.f90} | 0 data_util/{ll_cp.f90 => fll_cp.f90} | 0 .../{ll_deattach.f90 => fll_deattach.f90} | 0 .../{ll_duplicate.f90 => fll_duplicate.f90} | 0 .../{ll_funct_prt.f90 => fll_funct_prt.f90} | 0 data_util/{ll_locate.f90 => fll_locate.f90} | 0 data_util/{ll_mk.f90 => fll_mk.f90} | 0 data_util/{ll_mods.f90 => fll_mods.f90} | 0 data_util/{ll_modules => fll_modules} | 0 data_util/{ll_mv.f90 => fll_mv.f90} | 0 data_util/{ll_nnodes.f90 => fll_nnodes.f90} | 0 data_util/{ll_read.f90 => fll_read.f90} | 0 data_util/{ll_rm.f90 => fll_rm.f90} | 0 data_util/{ll_stich.f90 => fll_stich.f90} | 0 data_util/{ll_sweep.f90 => fll_sweep.f90} | 0 data_util/{ll_type.f90 => fll_type.f90} | 0 data_util/{ll_write.f90 => fll_write.f90} | 0 data_util/project.dep | 154 +++++++++--------- data_util/reshape | 8 - test/Makefile | 4 +- test/{ll_test.f90 => fll_test.f90} | 0 test/project.dep | 4 +- 30 files changed, 249 insertions(+), 143 deletions(-) create mode 100644 accessories/ll_cat/Makefile create mode 100644 accessories/ll_cat/ada.py create mode 100644 accessories/ll_cat/ll_cat.f90 create mode 100644 accessories/ll_cat/project.dep create mode 100644 config.log rename data_util/{ll_cat.f90 => fll_cat.f90} (100%) rename data_util/{ll_cp.f90 => fll_cp.f90} (100%) rename data_util/{ll_deattach.f90 => fll_deattach.f90} (100%) rename data_util/{ll_duplicate.f90 => fll_duplicate.f90} (100%) rename data_util/{ll_funct_prt.f90 => fll_funct_prt.f90} (100%) rename data_util/{ll_locate.f90 => fll_locate.f90} (100%) rename data_util/{ll_mk.f90 => fll_mk.f90} (100%) rename data_util/{ll_mods.f90 => fll_mods.f90} (100%) rename data_util/{ll_modules => fll_modules} (100%) rename data_util/{ll_mv.f90 => fll_mv.f90} (100%) rename data_util/{ll_nnodes.f90 => fll_nnodes.f90} (100%) rename data_util/{ll_read.f90 => fll_read.f90} (100%) rename data_util/{ll_rm.f90 => fll_rm.f90} (100%) rename data_util/{ll_stich.f90 => fll_stich.f90} (100%) rename data_util/{ll_sweep.f90 => fll_sweep.f90} (100%) rename data_util/{ll_type.f90 => fll_type.f90} (100%) rename data_util/{ll_write.f90 => fll_write.f90} (100%) delete mode 100644 data_util/reshape rename test/{ll_test.f90 => fll_test.f90} (100%) diff --git a/accessories/ll_cat/Makefile b/accessories/ll_cat/Makefile new file mode 100644 index 0000000..c2524ac --- /dev/null +++ b/accessories/ll_cat/Makefile @@ -0,0 +1,44 @@ +############################################################################ +# Makefile for ffalist +############################################################################ +# +# $HeadURL: https://costello.foi.se/svn/edge/branches/aeroelastics/programs/ffalist/Makefile $ +# $LastChangedDate: 2007-09-21 14:50:09 +0200 (Fri, 21 Sep 2007) $ +# $LastChangedBy: oskeno $ +# $LastChangedRevision: 1282 $ + +EXE = ll_cut + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=project.dep +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x $(EXE) + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +install: $(EXE).x $(EXE) + $(INSTALL) $(EXE) $(prefix)/bin/$(EXE)$(POSTFIX) + $(INSTALL) $(EXE).x $(prefix)/bin/$(EXE)$(POSTFIX).x + +-include $(srcdir)/project.dep diff --git a/accessories/ll_cat/ada.py b/accessories/ll_cat/ada.py new file mode 100644 index 0000000..dd73512 --- /dev/null +++ b/accessories/ll_cat/ada.py @@ -0,0 +1,10 @@ + +import fnmatch +import os + +matches = [] +for root, dirnames, filenames in os.walk('/home/jka/OSS_CFD/trunk/accessories/ll_cat'): + for filename in fnmatch.filter(filenames, '*.f90'): + matches.append(os.path.join(root, filename)) + print(filename) + diff --git a/accessories/ll_cat/ll_cat.f90 b/accessories/ll_cat/ll_cat.f90 new file mode 100644 index 0000000..4be1b92 --- /dev/null +++ b/accessories/ll_cat/ll_cat.f90 @@ -0,0 +1,82 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine LL_MV +! +! Date: 2016-10-10 +! +! +! +! +! Description: duplicate +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM LL_TEST + + USE LL_TYPE_M + USE LL_READ_M + USE LL_RM_M + USE LL_MV_M + USE LL_CP_M + USE LL_MK_M +! INCLUDE '.././data_util/l_modules' + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE,PNEW,ptmp + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! LOCAL TYPES +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS + + PNODE => LL_READ('TEST',8,'A',FPAR)\ + + WRITE(*,*)' COPY' + PNEW => LL_CP(PNODE, NULL(), FPAR) + WRITE(*,*)' REMOVE' + CALL LL_RM(PNODE,FPAR) + WRITE(*,*)' REMOVE' + CALL LL_RM(PNEW,FPAR) + + +END PROGRAM diff --git a/accessories/ll_cat/project.dep b/accessories/ll_cat/project.dep new file mode 100644 index 0000000..2a694b3 --- /dev/null +++ b/accessories/ll_cat/project.dep @@ -0,0 +1,6 @@ +# This file is generated automatically. DO NOT EDIT! + +ll_cat.o : \ + ../../data_util/ll_rm.o \ + ../../data_util/ll_read.o \ + ../../data_util/ll_type.o diff --git a/config.log b/config.log new file mode 100644 index 0000000..c889954 --- /dev/null +++ b/config.log @@ -0,0 +1 @@ +exit_handler called diff --git a/config/compset.gfortran b/config/compset.gfortran index 4694c3f..873ddca 100644 --- a/config/compset.gfortran +++ b/config/compset.gfortran @@ -1,17 +1,12 @@ - -# Fortran compiler and flags -FC='gfortran' -FFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp' -FFFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp' -LDFLAGS='-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4' - -# C compiler -CC='gcc' -CFLAGS='-O2 -fopenmp' -C_LDFLAGS='-O2 -fopenmp' - -# MPI fortran compiler and flags. -# Set MPI_FC empty if you don't have/need MPI. -MPI_FC= -MPI_FFLAGS="$FFLAGS" -MPI_LDFLAGS="$LDFLAGS" +FC = gfortran +FCMODINCFLAG = -I +FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp -x f95-cpp-input +FFFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +UPPER_MODFILE_NAME = +LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 +CC = gcc +CFLAGS = -O2 -fopenmp +C_LDFLAGS = -O2 -fopenmp +MPI_FC = mpif90 +MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp diff --git a/config/compset.gfortran_debug b/config/compset.gfortran_debug index 513c8fd..4926b69 100644 --- a/config/compset.gfortran_debug +++ b/config/compset.gfortran_debug @@ -1,37 +1,13 @@ -# -*-sh-*- -# -# For GNU compiler collection (GCC) 4.0 -# -echo ' -!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!! -! -! Versions up to 4.1.0 DO NOT WORK with edge due to compiler bugs. -! Also the binary file format for unformatted I/O is -! not compatible with the format used by most other compilers. -! -! This configuration file works with gfortran 4.3.2 and newer -! Note: older gfortran versions should include -! flags "-static-libgfortran" or "-static" -! -! MAKE SURE YOU HAVE gfortran VERSION 4.1.1 OR NEWER -! -!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!! -' - -# Fortran compiler and flags -FC='gfortran' -FFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' -FFFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' -LDFLAGS='-g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra' - -# C compiler -CC='gcc' -CFLAGS='-g' -C_LDFLAGS='-g' - -# MPI fortran compiler and flags. -# Set MPI_FC empty if you don't have/need MPI. -MPI_FC= -MPI_FFLAGS="$FFLAGS" -MPI_LDFLAGS="$LDFLAGS" +FC = gfortran +FCMODINCFLAG = -I +FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +UPPER_MODFILE_NAME = +LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp +CC = gcc -fopenmp +CFLAGS = -g -fopenmp +C_LDFLAGS = -g -fopenmp +MPI_FC = mpif90 +MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp diff --git a/configure.py b/configure.py index a4524c3..5ecf32d 100755 --- a/configure.py +++ b/configure.py @@ -197,7 +197,7 @@ def mkconfigfile(path, cwd,version, bin_dir): fconfig.write("#\n") fconfig.write("#\n") - fconfig.write("Compiler settings\n") + fconfig.write("# Compiler settings\n") fconfig.write("#\n") with open(filename) as f: diff --git a/data_util/ll_cat.f90 b/data_util/fll_cat.f90 similarity index 100% rename from data_util/ll_cat.f90 rename to data_util/fll_cat.f90 diff --git a/data_util/ll_cp.f90 b/data_util/fll_cp.f90 similarity index 100% rename from data_util/ll_cp.f90 rename to data_util/fll_cp.f90 diff --git a/data_util/ll_deattach.f90 b/data_util/fll_deattach.f90 similarity index 100% rename from data_util/ll_deattach.f90 rename to data_util/fll_deattach.f90 diff --git a/data_util/ll_duplicate.f90 b/data_util/fll_duplicate.f90 similarity index 100% rename from data_util/ll_duplicate.f90 rename to data_util/fll_duplicate.f90 diff --git a/data_util/ll_funct_prt.f90 b/data_util/fll_funct_prt.f90 similarity index 100% rename from data_util/ll_funct_prt.f90 rename to data_util/fll_funct_prt.f90 diff --git a/data_util/ll_locate.f90 b/data_util/fll_locate.f90 similarity index 100% rename from data_util/ll_locate.f90 rename to data_util/fll_locate.f90 diff --git a/data_util/ll_mk.f90 b/data_util/fll_mk.f90 similarity index 100% rename from data_util/ll_mk.f90 rename to data_util/fll_mk.f90 diff --git a/data_util/ll_mods.f90 b/data_util/fll_mods.f90 similarity index 100% rename from data_util/ll_mods.f90 rename to data_util/fll_mods.f90 diff --git a/data_util/ll_modules b/data_util/fll_modules similarity index 100% rename from data_util/ll_modules rename to data_util/fll_modules diff --git a/data_util/ll_mv.f90 b/data_util/fll_mv.f90 similarity index 100% rename from data_util/ll_mv.f90 rename to data_util/fll_mv.f90 diff --git a/data_util/ll_nnodes.f90 b/data_util/fll_nnodes.f90 similarity index 100% rename from data_util/ll_nnodes.f90 rename to data_util/fll_nnodes.f90 diff --git a/data_util/ll_read.f90 b/data_util/fll_read.f90 similarity index 100% rename from data_util/ll_read.f90 rename to data_util/fll_read.f90 diff --git a/data_util/ll_rm.f90 b/data_util/fll_rm.f90 similarity index 100% rename from data_util/ll_rm.f90 rename to data_util/fll_rm.f90 diff --git a/data_util/ll_stich.f90 b/data_util/fll_stich.f90 similarity index 100% rename from data_util/ll_stich.f90 rename to data_util/fll_stich.f90 diff --git a/data_util/ll_sweep.f90 b/data_util/fll_sweep.f90 similarity index 100% rename from data_util/ll_sweep.f90 rename to data_util/fll_sweep.f90 diff --git a/data_util/ll_type.f90 b/data_util/fll_type.f90 similarity index 100% rename from data_util/ll_type.f90 rename to data_util/fll_type.f90 diff --git a/data_util/ll_write.f90 b/data_util/fll_write.f90 similarity index 100% rename from data_util/ll_write.f90 rename to data_util/fll_write.f90 diff --git a/data_util/project.dep b/data_util/project.dep index d7f1266..22bdff2 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,79 +1,79 @@ # This file is generated automatically. DO NOT EDIT! -ll_mods.o : \ - ll_mv.o \ - ll_write.o \ - ll_cat.o \ - ll_mk.o \ - ll_stich.o \ - ll_cp.o \ - ll_sweep.o \ - ll_nnodes.o \ - ll_funct_prt.o \ - ll_deattach.o \ - ll_rm.o \ - ll_locate.o \ - ll_read.o \ - ll_duplicate.o \ - ll_type.o - -ll_funct_prt.o : \ - ll_type.o - -ll_mv.o : \ - ll_rm.o \ - ll_stich.o \ - ll_type.o - -ll_locate.o : \ - ll_funct_prt.o \ - ll_type.o - -ll_cat.o : \ - ll_type.o - -ll_mk.o : \ - ll_type.o - -ll_cp.o : \ - ll_mv.o \ - ll_cat.o \ - ll_stich.o \ - ll_rm.o \ - ll_type.o \ - ll_duplicate.o - -ll_sweep.o : \ - ll_type.o \ - ll_locate.o - -ll_nnodes.o : \ - ll_funct_prt.o \ - ll_type.o - -ll_deattach.o : \ - ll_stich.o \ - ll_type.o - -ll_duplicate.o : \ - ll_mv.o \ - ll_mk.o \ - ll_type.o - -ll_stich.o : \ - ll_type.o - -ll_rm.o : \ - ll_stich.o \ - ll_type.o - -ll_read.o : \ - ll_mv.o \ - ll_funct_prt.o \ - ll_mk.o \ - ll_type.o - -ll_write.o : \ - ll_type.o - -ll_type.o : +fll_mk.o : \ + fll_type.o + +fll_read.o : \ + fll_mk.o \ + fll_funct_prt.o \ + fll_mv.o \ + fll_type.o + +fll_rm.o : \ + fll_stich.o \ + fll_type.o + +fll_stich.o : \ + fll_type.o + +fll_mv.o : \ + fll_stich.o \ + fll_rm.o \ + fll_type.o + +fll_duplicate.o : \ + fll_mk.o \ + fll_mv.o \ + fll_type.o + +fll_deattach.o : \ + fll_stich.o \ + fll_type.o + +fll_write.o : \ + fll_type.o + +fll_type.o : + +fll_nnodes.o : \ + fll_funct_prt.o \ + fll_type.o + +fll_cat.o : \ + fll_type.o + +fll_locate.o : \ + fll_funct_prt.o \ + fll_type.o + +fll_sweep.o : \ + fll_locate.o \ + fll_type.o + +fll_mods.o : \ + fll_cp.o \ + fll_funct_prt.o \ + fll_nnodes.o \ + fll_duplicate.o \ + fll_rm.o \ + fll_mk.o \ + fll_stich.o \ + fll_sweep.o \ + fll_write.o \ + fll_type.o \ + fll_locate.o \ + fll_deattach.o \ + fll_cat.o \ + fll_mv.o \ + fll_read.o + +fll_funct_prt.o : \ + fll_type.o + +fll_cp.o : \ + fll_rm.o \ + fll_duplicate.o \ + fll_stich.o \ + fll_type.o \ + fll_cat.o \ + fll_mv.o diff --git a/data_util/reshape b/data_util/reshape deleted file mode 100644 index c959b4a..0000000 --- a/data_util/reshape +++ /dev/null @@ -1,8 +0,0 @@ -program ptrtest - real, pointer :: a(:) - real, pointer :: b(:,:) - integer :: n = 10 - allocate(a(n**2)) - a = 42 - b (1:n, 1:n) => a -end program ptrtest diff --git a/test/Makefile b/test/Makefile index 8e02fdc..0806b66 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,5 +1,5 @@ -EXE = ll_test +EXE = fll_test include src_dir_path.mk include ../config.mk @@ -12,7 +12,7 @@ FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) OFILES=$(FFILES:%.f90=%.o) -XOFILES=$(wildcard $(FMODDIRS)/*.o) +XOFILES=$(wildcard ../data_util/*.o) ########################################################################### diff --git a/test/ll_test.f90 b/test/fll_test.f90 similarity index 100% rename from test/ll_test.f90 rename to test/fll_test.f90 diff --git a/test/project.dep b/test/project.dep index c835ccf..f2ae792 100644 --- a/test/project.dep +++ b/test/project.dep @@ -1,4 +1,4 @@ # This file is generated automatically. DO NOT EDIT! -ll_test.o : \ - ../data_util/ll_mods.o +fll_test.o : \ + ../data_util/fll_mods.o From 24b05990dc5dd85c428f6438f1c429ad9e592c9e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 27 Oct 2016 21:10:40 -0600 Subject: [PATCH 010/325] add init to Makefile --- INSTALLATION | 7 +++- Makefile | 5 +++ data_util/project.dep | 94 +++++++++++++++++++++---------------------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/INSTALLATION b/INSTALLATION index 4543159..4f571c9 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -38,8 +38,11 @@ gmake 3. DEVELOPERS: ==================================================== +1. Initialize -1. If modifying, adding removin or changing project in any way, developers +gmake init + +2. If modifying, adding removin or changing project in any way, developers have to update project dependencies: To update project dependencies, execute @@ -47,7 +50,7 @@ gmake depend in the project source directory or in each directory separately -2. Source can be compiled separately in each directory by +3. Source can be compiled separately in each directory by changing location to the directory and issuing command gmake diff --git a/Makefile b/Makefile index 8c3ac0f..7ea61d9 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,11 @@ all: $(SUBDIRS:%=%.all) include rules.mk + +init: + echo PROJ_ROOT_PATH=$(PWD) > config.mk + echo MAKEDEPEND="$(PROJ_ROOT_PATH)"/python_dep/fort_depend.py >> config.mk + data_util.all: test.all: data_util.all diff --git a/data_util/project.dep b/data_util/project.dep index 22bdff2..b593347 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,79 +1,79 @@ # This file is generated automatically. DO NOT EDIT! -fll_mk.o : \ +fll_rm.o : \ + fll_type.o \ + fll_stich.o + +fll_cat.o : \ fll_type.o fll_read.o : \ - fll_mk.o \ + fll_mv.o \ + fll_type.o \ fll_funct_prt.o \ + fll_mk.o + +fll_duplicate.o : \ fll_mv.o \ - fll_type.o + fll_type.o \ + fll_mk.o -fll_rm.o : \ +fll_cp.o : \ fll_stich.o \ - fll_type.o - -fll_stich.o : \ - fll_type.o + fll_mv.o \ + fll_cat.o \ + fll_type.o \ + fll_rm.o \ + fll_duplicate.o fll_mv.o : \ - fll_stich.o \ + fll_type.o \ fll_rm.o \ - fll_type.o - -fll_duplicate.o : \ - fll_mk.o \ - fll_mv.o \ - fll_type.o + fll_stich.o -fll_deattach.o : \ - fll_stich.o \ - fll_type.o - -fll_write.o : \ +fll_mk.o : \ fll_type.o -fll_type.o : - -fll_nnodes.o : \ - fll_funct_prt.o \ +fll_stich.o : \ fll_type.o -fll_cat.o : \ +fll_funct_prt.o : \ fll_type.o fll_locate.o : \ - fll_funct_prt.o \ - fll_type.o - -fll_sweep.o : \ - fll_locate.o \ - fll_type.o + fll_type.o \ + fll_funct_prt.o fll_mods.o : \ - fll_cp.o \ - fll_funct_prt.o \ fll_nnodes.o \ - fll_duplicate.o \ - fll_rm.o \ - fll_mk.o \ fll_stich.o \ + fll_mk.o \ + fll_cat.o \ + fll_funct_prt.o \ + fll_mv.o \ fll_sweep.o \ - fll_write.o \ + fll_cp.o \ fll_type.o \ fll_locate.o \ fll_deattach.o \ - fll_cat.o \ - fll_mv.o \ - fll_read.o + fll_read.o \ + fll_rm.o \ + fll_write.o \ + fll_duplicate.o -fll_funct_prt.o : \ +fll_sweep.o : \ + fll_type.o \ + fll_locate.o + +fll_write.o : \ fll_type.o -fll_cp.o : \ - fll_rm.o \ - fll_duplicate.o \ - fll_stich.o \ +fll_type.o : + +fll_nnodes.o : \ fll_type.o \ - fll_cat.o \ - fll_mv.o + fll_funct_prt.o + +fll_deattach.o : \ + fll_type.o \ + fll_stich.o From a4462284873b42f8a253459ab591e6b5ea6a9796 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Oct 2016 18:06:12 -0600 Subject: [PATCH 011/325] code cleanup, add fll_getndata function --- INSTALLATION | 2 +- Makefile | 11 +- config.log | 1 - config.mk | 4 - data_util/fll_getndata.f90 | 545 ++++++++++++++++++++++++++++++++ data_util/fll_locate.f90 | 6 +- data_util/fll_nnodes.f90 | 4 +- data_util/fll_sweep.f90 | 4 +- data_util/fll_type.f90 | 7 +- data_util/project.dep | 92 +++--- {test => examples}/Makefile | 2 +- {test => examples}/fll_test.f90 | 0 {test => examples}/project.dep | 0 examples/src_dir_path.mk | 1 + python_dep/fort_depend.py | 4 + rules.mk | 14 - src_dir_path.mk | 2 +- test/src_dir_path.mk | 1 - 18 files changed, 613 insertions(+), 87 deletions(-) delete mode 100644 config.log delete mode 100644 config.mk create mode 100644 data_util/fll_getndata.f90 rename {test => examples}/Makefile (97%) rename {test => examples}/fll_test.f90 (100%) rename {test => examples}/project.dep (100%) create mode 100644 examples/src_dir_path.mk delete mode 100644 test/src_dir_path.mk diff --git a/INSTALLATION b/INSTALLATION index 4f571c9..f39731f 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -12,7 +12,7 @@ Make a new directory where the compillation procees takes place In this directory execute configure file from FLL project source directory. For example, if the FLL source is in -/home/usr/fll_souce/master +/home/usr/fll_souce/fll-master and you want to compile and install everyting in diff --git a/Makefile b/Makefile index 7ea61d9..56bc6f7 100644 --- a/Makefile +++ b/Makefile @@ -5,11 +5,11 @@ # # include src_dir_path.mk -include config.mk +-include config.mk SUBDIRS= \ data_util\ -test\ +examples\ ########################################################################### @@ -17,11 +17,6 @@ all: $(SUBDIRS:%=%.all) @echo '************************************************' @echo '*' @echo '* FLL built successfully!' - @MAKE=$(MAKE) && \ - echo "* Type \"$${MAKE##*/} install\" to install FLL into directory $(bin_dir)" - @echo "* " - @MAKE=$(MAKE) && \ - echo "* $${MAKE##*/} bin_dir=/usr/local/bin" @echo '*' @echo '************************************************' @@ -30,7 +25,7 @@ include rules.mk init: echo PROJ_ROOT_PATH=$(PWD) > config.mk - echo MAKEDEPEND="$(PROJ_ROOT_PATH)"/python_dep/fort_depend.py >> config.mk + echo MAKEDEPEND=$(PWD)/python_dep/fort_depend.py >> config.mk data_util.all: test.all: data_util.all diff --git a/config.log b/config.log deleted file mode 100644 index c889954..0000000 --- a/config.log +++ /dev/null @@ -1 +0,0 @@ -exit_handler called diff --git a/config.mk b/config.mk deleted file mode 100644 index 1d282c9..0000000 --- a/config.mk +++ /dev/null @@ -1,4 +0,0 @@ - -PROJ_ROOT_PATH=/home/jka/OSS_CFD/trunk -MAKEDEPEND=$(PROJ_ROOT_PATH)/python_dep/fort_depend.py - diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 new file mode 100644 index 0000000..2ed8eec --- /dev/null +++ b/data_util/fll_getndata.f90 @@ -0,0 +1,545 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! FUNCTION FLL_GETNDATA +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints node +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_GETNDATA_M +CONTAINS +! +! SINGLE +! + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RSINGLE) :: R0 +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R0 = PNODE%R0 + RETURN + + END FUNCTION FLL_GETNDATA_R0 + + + + FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RSINGLE), POINTER :: R1(:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R1 => PNODE%R1 + RETURN + + END FUNCTION FLL_GETNDATA_R1 + + FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RSINGLE), POINTER :: R2(:,:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R2 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R2 => PNODE%R2 + RETURN + + END FUNCTION FLL_GETNDATA_R2 +! +! DOUBLE +! + FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RDOUBLE) :: R0 +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R0 = PNODE%D0 + RETURN + + END FUNCTION FLL_GETNDATA_D0 + + + + FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RDOUBLE), POINTER :: R1(:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R1 => PNODE%D1 + RETURN + + END FUNCTION FLL_GETNDATA_D1 + + FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + REAL(RDOUBLE), POINTER :: R2(:,:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + R2 => PNODE%D2 + RETURN + + END FUNCTION FLL_GETNDATA_D2 +! +! INTEGER +! + FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(SINT) :: I0 +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I0 = PNODE%I0 + RETURN + + END FUNCTION FLL_GETNDATA_I0 + + + + FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(SINT), POINTER :: I1(:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I1 => PNODE%I1 + RETURN + + END FUNCTION FLL_GETNDATA_I1 + + FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(SINT), POINTER :: I2(:,:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I2 => PNODE%I2 + RETURN + + END FUNCTION FLL_GETNDATA_I2 +! +! LONG INTEGER +! + FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(LINT) :: I0 +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I0 = PNODE%L0 + RETURN + + END FUNCTION FLL_GETNDATA_L0 + + + + FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(LINT), POINTER :: I1(:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I1 => PNODE%L1 + RETURN + + END FUNCTION FLL_GETNDATA_L1 + + FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + INTEGER(LINT), POINTER :: I2(:,:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + I2 => PNODE%L2 + RETURN + + END FUNCTION FLL_GETNDATA_L2 + +END MODULE FLL_GETNDATA_M diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index a58023f..b749d81 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -59,14 +59,14 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LICOMPIL) :: NUMBER + INTEGER(LINT) :: NUMBER LOGICAL :: RECURSE ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LICOMPIL) :: LOCNUM,I + INTEGER(LINT) :: LOCNUM,I ! ! BODY OF FUNCTION ! @@ -98,7 +98,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - PFIND => FLL_LOCATE(PCHLD,NAME,1_LICOMPIL,LTYPE,RECURSE,FPAR) + PFIND => FLL_LOCATE(PCHLD,NAME,1_LINT,LTYPE,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 9b895fa..8730fb1 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -59,14 +59,14 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LICOMPIL) :: NUMBER + INTEGER(LINT) :: NUMBER LOGICAL :: RECURSE ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LICOMPIL) :: I + INTEGER(LINT) :: I ! ! BODY OF FUNCTION ! diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 33f3c1c..6568461 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -59,14 +59,14 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LICOMPIL) :: NUMBER + INTEGER(LINT) :: NUMBER LOGICAL :: RECURSE ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LICOMPIL) :: LOCNUM,I + INTEGER(LINT) :: LOCNUM,I ! ! BODY OF FUNCTION ! diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 72acfcd..ac053e7 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -58,9 +58,6 @@ MODULE FLL_TYPE_M INTEGER, PARAMETER :: RDOUBLE = KIND(0.D0) INTEGER, PARAMETER :: SINT = SELECTED_INT_KIND(9) INTEGER, PARAMETER :: LINT = SELECTED_INT_KIND(16) - - INTEGER, PARAMETER :: LICOMPIL = LINT - INTEGER, PARAMETER :: SICOMPIL = SINT INTEGER, PARAMETER :: NAME_LENGTH = 16 INTEGER, PARAMETER :: TYPE_LENGTH = 4 @@ -74,8 +71,8 @@ MODULE FLL_TYPE_M TYPE DNODE CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list - INTEGER(LICOMPIL) :: NDIM = 0, NSIZE = 0 - INTEGER(LICOMPIL) :: POS = 0, LENGTH = 0 + INTEGER(LINT) :: NDIM = 0, NSIZE = 0 + INTEGER(LINT) :: POS = 0, LENGTH = 0 TYPE (DNODE), POINTER :: & PPAR =>NULL(),& ! Pointer to parent list diff --git a/data_util/project.dep b/data_util/project.dep index b593347..55c9945 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,79 +1,83 @@ # This file is generated automatically. DO NOT EDIT! -fll_rm.o : \ +fll_cp.o : \ fll_type.o \ - fll_stich.o - -fll_cat.o : \ - fll_type.o - -fll_read.o : \ + fll_cat.o \ fll_mv.o \ + fll_stich.o \ + fll_rm.o \ + fll_duplicate.o + +fll_sweep.o : \ fll_type.o \ - fll_funct_prt.o \ - fll_mk.o + fll_locate.o -fll_duplicate.o : \ - fll_mv.o \ +fll_locate.o : \ fll_type.o \ - fll_mk.o + fll_funct_prt.o -fll_cp.o : \ - fll_stich.o \ - fll_mv.o \ - fll_cat.o \ +fll_deattach.o : \ fll_type.o \ - fll_rm.o \ - fll_duplicate.o + fll_stich.o -fll_mv.o : \ +fll_rm.o : \ fll_type.o \ - fll_rm.o \ fll_stich.o -fll_mk.o : \ +fll_cat.o : \ fll_type.o -fll_stich.o : \ - fll_type.o +fll_duplicate.o : \ + fll_type.o \ + fll_mv.o \ + fll_mk.o -fll_funct_prt.o : \ +fll_write.o : \ fll_type.o -fll_locate.o : \ +fll_getndata.o : \ + fll_type.o \ + fll_locate.o + +fll_nnodes.o : \ fll_type.o \ fll_funct_prt.o +fll_mk.o : \ + fll_type.o + fll_mods.o : \ - fll_nnodes.o \ - fll_stich.o \ + fll_sweep.o \ + fll_read.o \ + fll_locate.o \ + fll_funct_prt.o \ fll_mk.o \ + fll_type.o \ fll_cat.o \ - fll_funct_prt.o \ fll_mv.o \ - fll_sweep.o \ - fll_cp.o \ - fll_type.o \ - fll_locate.o \ fll_deattach.o \ - fll_read.o \ + fll_stich.o \ + fll_nnodes.o \ fll_rm.o \ fll_write.o \ - fll_duplicate.o + fll_duplicate.o \ + fll_cp.o -fll_sweep.o : \ +fll_mv.o : \ fll_type.o \ - fll_locate.o + fll_rm.o \ + fll_stich.o -fll_write.o : \ +fll_read.o : \ + fll_type.o \ + fll_funct_prt.o \ + fll_mv.o \ + fll_mk.o + +fll_funct_prt.o : \ fll_type.o fll_type.o : -fll_nnodes.o : \ - fll_type.o \ - fll_funct_prt.o - -fll_deattach.o : \ - fll_type.o \ - fll_stich.o +fll_stich.o : \ + fll_type.o diff --git a/test/Makefile b/examples/Makefile similarity index 97% rename from test/Makefile rename to examples/Makefile index 0806b66..aeb8758 100644 --- a/test/Makefile +++ b/examples/Makefile @@ -16,7 +16,7 @@ XOFILES=$(wildcard ../data_util/*.o) ########################################################################### -all: $(EXE).x $(EXE) +all: $(EXE).x include ../rules.mk diff --git a/test/fll_test.f90 b/examples/fll_test.f90 similarity index 100% rename from test/fll_test.f90 rename to examples/fll_test.f90 diff --git a/test/project.dep b/examples/project.dep similarity index 100% rename from test/project.dep rename to examples/project.dep diff --git a/examples/src_dir_path.mk b/examples/src_dir_path.mk new file mode 100644 index 0000000..7c19767 --- /dev/null +++ b/examples/src_dir_path.mk @@ -0,0 +1 @@ +srcdir=$(PROJ_ROOT_PATH)/examples diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 604e854..3bf6197 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -26,6 +26,10 @@ def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build= path = check_path(path=path) cwd = check_path(path=cwd) + print(" ") + print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") + print(" ") + ff=get_all_files(path=path) l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) diff --git a/rules.mk b/rules.mk index dbaf1ab..88403bc 100644 --- a/rules.mk +++ b/rules.mk @@ -42,17 +42,3 @@ HANDLE_UPPER_CASE_MOD_NAMES = ! [ "$(UPPER_MODFILE_NAME)" ] || ! [[ $* = *_m ]] %.install: %.mkdir @cd $* && $(MAKE) install -%.html-doc: %.mkdir - @cd $* && $(MAKE) html-doc - -%.doc: %.mkdir - @cd $* && $(MAKE) doc - -%.chk: %.mkdir - @cd $* && $(MAKE) chk - -chk: - $(F95CHK) --dry-run $(FFILES:%=$(srcdir)/%) - -chk-fix: - $(F95CHK) $(FFILES:%=$(srcdir)/%) diff --git a/src_dir_path.mk b/src_dir_path.mk index 51f57a5..cb37019 100644 --- a/src_dir_path.mk +++ b/src_dir_path.mk @@ -1 +1 @@ -srcdir=/home/jiraseka/LL/trunk +srcdir=$(PROJ_ROOT_PATH) diff --git a/test/src_dir_path.mk b/test/src_dir_path.mk deleted file mode 100644 index 38f2584..0000000 --- a/test/src_dir_path.mk +++ /dev/null @@ -1 +0,0 @@ -srcdir=$(PROJ_ROOT_PATH)/test From 312b49150752c7c29ab0af2bf7c1696fd762d010 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Oct 2016 18:06:45 -0600 Subject: [PATCH 012/325] additional updates --- fort_depend.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index c9730e4..3bf6197 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,4 +1,15 @@ #!/usr/bin/python +# +# +# this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py +# +# the modified version used here can be found @https://github.com/libm3l/fort_depend.py +# +# this is a script which maked fortran project dependecies +# it is executed in each directory separately and creates a project.dep file with fortran dependencies +# if fortran source uses module from other directory the script will add the module too +# the project root directory is specified as an input parameter with an option -r +# import os import re import glob @@ -15,6 +26,10 @@ def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build= path = check_path(path=path) cwd = check_path(path=cwd) + print(" ") + print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") + print(" ") + ff=get_all_files(path=path) l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) @@ -78,15 +93,7 @@ def get_source(ext=[".f90",".F90"]): fil.extend(filter(lambda x: x.endswith(i),tmp)) return fil -def get_all_files(path): - #l=[] - - #for filename in glob.iglob('/home/jka/OSS_CFD/trunk/**/*.f90', recursive=True): - #print(filename) - #l.append(filename) - - #return l - +def get_all_files(path): matches = [] for root, dirnames, filenames in os.walk(path): for filename in fnmatch.filter(filenames, '*.f90'): @@ -101,7 +108,8 @@ def check_if_there(use,file): if "module" in line.lower(): if use in line: return 1 - + + f.close() return 0 @@ -184,9 +192,9 @@ def get_depends(fob=[],m2f=[], ffiles=[]): if retval > 0: name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any files in this directory") + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") - print ("\033[031m..... \033[039m adding it to dependency file, not checking its dependency further \033[032m") + print ("\033[031m..... \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") deps[i.file_name]=tmp From 70d4a80d862cd941fd2ed2777a15a4252dde71dd Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Oct 2016 18:39:10 -0600 Subject: [PATCH 013/325] FIX GETNDATA --- data_util/fll_cat.f90 | 7 ++- data_util/fll_getndata.f90 | 17 ++++---- data_util/fll_mods.f90 | 1 + data_util/fll_nnodes.f90 | 2 +- data_util/project.dep | 87 +++++++++++++++++++------------------- examples/fll_test.f90 | 31 +++++++++----- 6 files changed, 81 insertions(+), 64 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index b07aecf..7d3f645 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -46,7 +46,7 @@ MODULE FLL_CAT_M CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,FPAR) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) USE FLL_TYPE_M IMPLICIT NONE @@ -57,6 +57,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT INTEGER(LINT) :: POS + LOGICAL :: PARENT ! ! LOCAL TYPES ! @@ -73,7 +74,9 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,FPAR) END IF PCHILD => PNODE%PCHILD - IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' NODE HAS A PARENT, NAME IS ', PNODE%PPAR%LNAME + IF(PARENT) THEN + IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is ', PNODE%PPAR%LNAME + END IF CALL FLL_PRINT(PNODE, IOUNIT, POS, FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 2ed8eec..7bb6771 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -125,7 +125,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - R1 => PNODE%R1 + R1 => PFIND%R1 RETURN END FUNCTION FLL_GETNDATA_R1 @@ -165,7 +165,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - R2 => PNODE%R2 + R2 => PFIND%R2 RETURN END FUNCTION FLL_GETNDATA_R2 @@ -249,7 +249,8 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - R1 => PNODE%D1 + R1 => PFIND%D1 + RETURN END FUNCTION FLL_GETNDATA_D1 @@ -289,7 +290,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - R2 => PNODE%D2 + R2 => PFIND%D2 RETURN END FUNCTION FLL_GETNDATA_D2 @@ -373,7 +374,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - I1 => PNODE%I1 + I1 => PFIND%I1 RETURN END FUNCTION FLL_GETNDATA_I1 @@ -413,7 +414,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - I2 => PNODE%I2 + I2 => PFIND%I2 RETURN END FUNCTION FLL_GETNDATA_I2 @@ -497,7 +498,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - I1 => PNODE%L1 + I1 => PFIND%L1 RETURN END FUNCTION FLL_GETNDATA_L1 @@ -537,7 +538,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - I2 => PNODE%L2 + I2 => PFIND%L2 RETURN END FUNCTION FLL_GETNDATA_L2 diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index cf4d37f..99e24aa 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -16,5 +16,6 @@ MODULE FLL_MODS_M USE FLL_SWEEP_M USE FLL_TYPE_M USE FLL_WRITE_M + USE FLL_GETNDATA_M END MODULE FLL_MODS_M diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 8730fb1..1030834 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -26,7 +26,7 @@ ! ! ! -! Description: Finds node in a chain +! Description: calculates number of nodes ! ! ! Input parameters: diff --git a/data_util/project.dep b/data_util/project.dep index 55c9945..36c8f3d 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,83 +1,84 @@ # This file is generated automatically. DO NOT EDIT! -fll_cp.o : \ +fll_mv.o : \ fll_type.o \ - fll_cat.o \ - fll_mv.o \ fll_stich.o \ - fll_rm.o \ - fll_duplicate.o + fll_rm.o -fll_sweep.o : \ - fll_type.o \ - fll_locate.o +fll_mk.o : \ + fll_type.o + +fll_funct_prt.o : \ + fll_type.o fll_locate.o : \ fll_type.o \ fll_funct_prt.o -fll_deattach.o : \ +fll_getndata.o : \ fll_type.o \ - fll_stich.o + fll_locate.o -fll_rm.o : \ +fll_read.o : \ fll_type.o \ - fll_stich.o - -fll_cat.o : \ - fll_type.o + fll_mv.o \ + fll_mk.o \ + fll_funct_prt.o -fll_duplicate.o : \ +fll_cp.o : \ fll_type.o \ + fll_duplicate.o \ + fll_cat.o \ fll_mv.o \ - fll_mk.o + fll_stich.o \ + fll_rm.o -fll_write.o : \ +fll_cat.o : \ fll_type.o -fll_getndata.o : \ - fll_type.o \ - fll_locate.o - fll_nnodes.o : \ fll_type.o \ fll_funct_prt.o -fll_mk.o : \ +fll_type.o : + +fll_write.o : \ fll_type.o fll_mods.o : \ - fll_sweep.o \ - fll_read.o \ fll_locate.o \ fll_funct_prt.o \ - fll_mk.o \ + fll_nnodes.o \ fll_type.o \ + fll_duplicate.o \ + fll_read.o \ + fll_getndata.o \ + fll_cp.o \ + fll_mk.o \ + fll_sweep.o \ fll_cat.o \ fll_mv.o \ - fll_deattach.o \ fll_stich.o \ - fll_nnodes.o \ fll_rm.o \ - fll_write.o \ - fll_duplicate.o \ - fll_cp.o + fll_deattach.o \ + fll_write.o -fll_mv.o : \ +fll_stich.o : \ + fll_type.o + +fll_rm.o : \ fll_type.o \ - fll_rm.o \ fll_stich.o -fll_read.o : \ +fll_sweep.o : \ fll_type.o \ - fll_funct_prt.o \ - fll_mv.o \ - fll_mk.o - -fll_funct_prt.o : \ - fll_type.o + fll_locate.o -fll_type.o : +fll_deattach.o : \ + fll_type.o \ + fll_stich.o -fll_stich.o : \ - fll_type.o +fll_duplicate.o : \ + fll_type.o \ + fll_mv.o \ + fll_mk.o diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 0a401f5..fab17c5 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -61,7 +61,8 @@ PROGRAM FLL_TEST LOGICAL :: OK CHARACTER :: FMT_LOC INTEGER :: ISTAT - INTEGER(LINT) :: POS + INTEGER(LINT) :: POS,NNODES + REAL(RDOUBLE), POINTER :: PRESS(:) ! ! read TEST file and store it in PNODE ! @@ -69,7 +70,7 @@ PROGRAM FLL_TEST ! ! print Pnode on screen ! - CALL FLL_CAT(PNODE, 6, FPAR) + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------1' ! ! read TEST1 file and store it in PNODE1 @@ -78,7 +79,7 @@ PROGRAM FLL_TEST ! ! print PNODE1 on screen ! - CALL FLL_CAT(PNODE1, 6, FPAR) + CALL FLL_CAT(PNODE1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------2' ! ! save PNODE1 as binary and ascii file @@ -89,7 +90,7 @@ PROGRAM FLL_TEST ! read bindary file and store it in PNODE2 ! then print it on screed and then delete it PNODE2 => FLL_READ('File_2.txt',8,'B',FPAR) - CALL FLL_CAT(PNODE2, 6, FPAR) + CALL FLL_CAT(PNODE2, 6, .TRUE.,FPAR) CALL FLL_RM(PNODE2,FPAR) WRITE(*,*)'------------------------------------------------------3' ! @@ -98,7 +99,7 @@ PROGRAM FLL_TEST ! PNEW1 => FLL_MK("newnone","DIR",0_LINT, 0_LINT,FPAR) OK = FLL_MV(PNODE, PNEW1, FPAR) - CALL FLL_CAT(PNEW1, 6, FPAR) + CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------4' ! ! COPY PNODE, BECASE THE TARGET IN COPY IS NULL @@ -106,7 +107,7 @@ PROGRAM FLL_TEST ! AND IS GOING TO BE A NEW NODE ! PNEW => FLL_CP(PNODE, NULL(), FPAR) - CALL FLL_CAT(PNEW, 6, FPAR) + CALL FLL_CAT(PNEW, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------5' ! ! REMOVE PNEW1 @@ -117,15 +118,25 @@ PROGRAM FLL_TEST ! ON RETURN, THE FLL_CP WILL GIVE BACK POINTER OF PNEW IN PNODE LIST ! PNEW2 => FLL_CP(PNEW, PNODE1, FPAR) - CALL FLL_CAT(PNODE1, 6, FPAR) + CALL FLL_CAT(PNODE1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------6' ! -! LOCATE 1st subdir IN PNODE1 AND PRINT IT ON THE SCREEN +! find number 1st subdir IN PNODE1 +! + NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',.false.,FPAR) + write(*,*)' number of TEST1_Subdir subsets is ', NNODES +! +! find the first TEST1_Subdir in PNODE1 and print it on the screen ! - PTMP => FLL_LOCATE(PNODE1,'subdir',1_lint,'*',.false.,FPAR) - CALL FLL_CAT(PTMP, 6, FPAR) + PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',.false.,FPAR) + CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------7' ! +! find the values of pressure subset #1 and print them on screen +! + PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,'D',FPAR) + write(*,*)' Values of pressure are ',PRESS +! ! CLEANUP ALL MEMORY ! WRITE(*,*)' REMOVE ===========================' From 9be51c0e81323d29536d0c1f2bed9c48c930867a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Oct 2016 23:20:18 -0600 Subject: [PATCH 014/325] add getdnode data for string --- data_util/fll_getndata.f90 | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 7bb6771..1500b37 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -542,5 +542,48 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END FUNCTION FLL_GETNDATA_L2 + + + + + FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + CHARACTER(LEN=STRING_LENGHT) :: STRING +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + STRING = PNODE%S + RETURN + + END FUNCTION FLL_GETNDATA_L0 END MODULE FLL_GETNDATA_M From 9af0e639eb7eb4acc0de573729ccdddf73c41f9b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Oct 2016 23:20:51 -0600 Subject: [PATCH 015/325] add gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aee2e4c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.mk From 3d61e8ba0303e9721c0a217c862322846d47f126 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 30 Oct 2016 19:27:14 -0600 Subject: [PATCH 016/325] add power point presentation --- INSTALLATION | 2 ++ data_util/fll_getndata.f90 | 2 +- ...42\200\223 Fortran Linked List Library.pptx" | Bin 0 -> 54663 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 "fll \342\200\223 Fortran Linked List Library.pptx" diff --git a/INSTALLATION b/INSTALLATION index f39731f..f92d148 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -40,6 +40,8 @@ gmake ==================================================== 1. Initialize +in fll-master directory + gmake init 2. If modifying, adding removin or changing project in any way, developers diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 1500b37..1c366fe 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -584,6 +584,6 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) STRING = PNODE%S RETURN - END FUNCTION FLL_GETNDATA_L0 + END FUNCTION FLL_GETNDATA_S END MODULE FLL_GETNDATA_M diff --git "a/fll \342\200\223 Fortran Linked List Library.pptx" "b/fll \342\200\223 Fortran Linked List Library.pptx" new file mode 100644 index 0000000000000000000000000000000000000000..6a24606f56d1b240af83990859e1be3ee41a56ea GIT binary patch literal 54663 zcmeFZRa9Kjx-5(ZcXxMphv4qgxVyUt2=49{+#$FHcY?cXaCf&$vd{U)z5mJHFZXTl z+Yh}4-M|=MGiz4Os#+*WgMy&~fdfGT0Ra&K71@NKJpuy(U7`X3p#VXGXbIcdI-A%! z>#2Cyn>gvvyW3b3=7E7w<^X|weE#1`i$ABsCqvshJy%Kh*sYhSS5t97mxU z8*CEO)J_&|Q>LJ3gc6J5ma$6~u|asUJG@z1ba@~@mC2SY5{tPFc$8pF4l8IvfSZ}l zH!=U3oM=h7CE$YaVZ|r7UQUN3k2c)zE=rJ2{aF~@zpwR$H}=Jq(X79}y1HDIY0ee= z6>OvQGN%_b%2}>lQ!I0zW`>s#$EHL|<<6={sO174b0wCrW`z+=5X6> z=@<2x_RhGlfKF%QmsJahvaB%`xTwk$I;mlsI>0*ztybyi8u?u}SQJ9%PsGdO4gAmr z@|7ze5F>gZ<%RZ zx!>y8X?#AseWqS;#o}PtVjP;m2R~0?-aW*yknzBlz*hbi9Y2s*++V=7d&u?iQo6#& zOWzX*6890a2NDm}vmr&3b|}wz7^*5m_E}cfid~N4gh?(G`PL`SX!2aHigH`ata6qV zGwv~xXM8^v`};d6ki!45W0*fU=YoFh7{5L?1elK8 zbOFqGPx6R=+ixohvn$5b7!YYejX6~2aQ2oXT4wPO-n+>+h|Csqykf~f_$y|lZ~0Ez zKi=W^zzyNY)!yEj!O7af*u;t9AMp9}1^aKd{R5=PiFW87Mns4UoeR94Q}Q`Mk@O#- zgq&ggU2)ng`Wb=RsLyw%^_!dSdYzxu2-dd=brTmqRT%Y9JPHW)@#AP*(OZ4W}DGnI(zCnOwg5l;IAc~rvbX} zg|(^T)Yt`I&d!rHHAn=~wlmA-;vsh{;8^AV*C%D{r_0?|6zake|t^$ zFV_6Oy|Vciv;W&4WB$eL|Mp`3U(Eh*FKPe9?Em(f_Fv5YZz*cO%XsrT0|NoI!2$sh z06_x(c5MD()z~|lIDG^p2F@0Cw*Q~9`EWjgKQfY!ANbFHw52FoeHd3?Hz1x7$j+_O z%Tz<=QkX6b7}@VZYws#dY?R_h$9y|;@>LuL@q75z8(O}6akDruyj^3T!jG(M7)}dC zLHDC})+nbov&$H4#fqp%C`*h2#MXhTH)^i0)9U8LjWg7?{-}$q%CjDK9e26UTrq^G ztgkr}c%;y>(LDTOPQCu~moT7fhV*AM*1Y~mUHa6I(KL+|pZBrcfcM$?6&szd0D68c zg|lJwRdyGsjvQ9B=1jcajT6?pIm}LYA~6wEVo|0NW5`+XB-mL|Y9XZ)s|Qc^WqAYn z>0-uks$l+X6kULBVwqqDXeOYkOKK!X8%_A_<6q;Mn|b{ z?S6NmWuoRGBJNziuu}d8GNF_MB{0;`euf2t=NuFpIPNYX;NXL%u_8fWd>x^&TvANM zmLssem?(;ojF8l5B~XHeLOJx)IUJSORuGtj7l|jIf4!V!8$E*l&7SXevdTXGu;yhy zjw>IT-XE*+|G#8UQr2vj8Bqs+Cpmema;%&ighHzGCh4=1CG`lK;(hAiY%Z&ZPqTZr4O#us&*dm zRu^Wk2e%i?9r{;&_}@ogOxwRhJ8qz^VE4GmaprO()RbyE+|2t7WVD2jB!aES&E1J2 zrg6wX=WLG~EcqvQ*2D(BQxgQXVLOyDJ9(p$8({YlRc|Y^fj~R9KaM_6+>E&HlZHnv zb)JOo4!OL12X~oFs7`4yJ+75wZ zWNgOD(sw*8SUcB*!7rU4C*aj?k&*Kn&q&L74h^KFKE&=V*w8qkRPtvUBJj+MqbyFv zDmo0Uaz-i5P2p>hgdL1U`!}ZNF!E|78Amm#@W-`l{{$tw#sV0PkezGANS`TGgnu%~ z-%lDJV9n(T*Q_pO@*UEK^gE6CxVt#7Bca@5>k8&YlWX%tOY1FsJ0p-W=VBG}z3~ zx%tw=LV!w2i4TNVdh?YSRN<(Y`x!VkZyGdw;_H{sQMYRPKm{c?Uy(r-kimtc_!SR< z3(W+=#}x|XRXhbyKoxMwgyZ-Xr#RG}!@>wJ+%8!UUyBu(RKaz>`F55jymuIHp=ioKd+la@#grEP2oNUWP4)c) zUMI5eR7NgBH!Te`>+$;L%K(_z=)zKC$tr{wYZ6C^nqOuY3?$)PRl5t=ApCv(RhV)&_ zi(dkPiI0?J8NP}BEKvRS)4#EL^47!UIOvBC7407Xq0=y7GB1d%Ww}L`$V>i-8f|s;DG%1XG_cKz^H`#%=ji?>1ufpzzv@KzRpf&NBIqCgX zd@lF_RjBtM;uEpj=M^i&BGJi7E}tTNa6B`VT7?m#mNDB5Y87?DpNZJIP~2F`)GqG* zMU56}My$>^(?aKCEsuG8x@zZMTUuXRCF7AK3&%y+f_erDQzz=&WUHllH@!Vu65fQB zp7I{j-RqXbCS2cN-GV2iqEShtNuS~4Tr)-~o`19-N#K|{8xh6Db(atdqk>fM#C5bC zUwQ+(Rs@-e`~*AaUtStLgPc;91+@A-7E$6{!24QSuag*M)d%Qhjoa4EuN@}x%!yU4 zaxTAW@}ICZjkKS7=1-lT;JO|UcIsd$+0>_k>*Z#mCZWUgm)cGTT3GB1*)pZ=nJAU) zz?l=!&9l!*>DtOtBDd&NF1Q`ZGMF9k(P*BRw{Gv=B5XhLsP3c4L#GSv{qT`6AWG4L zASh}ca#;KPfy)1xIjbkAo|1gvmIUUX;P#K#&<0qs#b!eEuA23&zAH^4gaLyTBtnW+ z5S79~jo%+$T-Tqo(rQfkS|;@x@@CLkV03Ov38g40=%L}|&BbCCJ@_r5PLz5w6Kf>t zMD#X5Gcc7j+|gqr;>=cjPA;&bH{LLp^jK8dG{0`<{#?#^0Xkg2sa|I_!gT!57FUbe zh^i4niUrCkjG4;y!s^V(@&Yuch}d@4@|3e*Tdd!wZp4u&}OpU0A0W5j4egZ4=WAwNUPiq&ZvW8KRfc#*Gx6RUK0DTRMB;2wkvly(hbq!Nne;c!c;l$}}B2b!k%!9Kc|q-vdMb zH`TLMC+?{DaXL5u+$WOqX}$6))JM}em9D{=i9^2cLtM{*iC8Vmua5X->M8QUb6V@&WBMlxo`o^G!+@mh5B3K&+_)YUpqmbQHG6gZIOwFqhKoHWY-iJX$ge47#%npldy5z>6wBggc(89Cvxi|FcWY#*O~O0e#@U$#&>*B9!nFMQq3c!l|{O~KAKzhK!9@g7c_NYXm39JZzLh<* zyHmOBA&P)sb$4$!1=Yk7@=!6|NuASwdV0OaKwjnEK}}~afD3Wf{XEN~xTx>6gLdiq z`pI7fnbb2OM<+OQQF+!lS#Ik)&5L-VhGDbok%hmtFX(yp1?3vXiVvEBwEL!}U;rcg zE^@}M^cA14ypS@wphBFshT4sSsXN0HKPGMyPVaaQcL|61+}`7*V#8<4rn3BbgE}r; z=cnG@2!f81GLBX-dObZmon#jhSpM=kCAr92Y6l3BLeVJU($WSmPRexk8_wSKz?5$-Bjn)*T zWl!gLUT!Vmg3_8U1oKUomuV~=qixFRe@Y{Tws-6L)0(FI_b%Kdp#m^4b9>JgLw50M2YE;tvxh&H)GBI6+OM*gI z#`fg2tF^`EzFen2Qp-9;4~9>`Bz^~DqD&>(V;^a#oVu}^tQVAKG`Itmg4n^z4)03= z=wXZKB}7b!$=~(`ZdFBu`SB996USB%YUDLzmy8N2(+iRLuzCa3Gqg=EZ5I3}Dy;S49j^tWh_nF;5a$Sy9#})qT5x3Z4OA$B1Hv+Xl zueY{IU=x1^V!2+@N@1zuiBzCP9LMq#EXv_6#>GcB^2va0r&7h`_}#7aWKxXqB={n3 zVf6Ieg8!;*$;z{1-di6(m;vWtP!tMy$0$}|xpoyph*9=XILe0547DtNLwZWn%vrO> zWv^j7NF;}pdp*UwdTONC*x4ja)G2&cZ zv54{P9jKneJa*8sakpXHv`}hm_Y08XSJ`=8t`Z94G;s4sJR}ss z#hO1^D7kjz(adt$G1I2^S5PQTgs>ldfCBd8NV%t#UzWZo>fzmKhp&wL;n4g3o#fQUJFHW$G`CIw}Yu9zyULcj%ibRBds~*%swc zWL!JrENKAlu?>;mO1nx4E)I`slR@6aY~CKNHAlu8<6t7hoJYg3M_f^2R~TUeZZnl2 zDx-D9E_c4tg1I9aYpH-1rti}?$&h3$thzo)x+=7w){r7LI-`G z$(y^D$HmyFJ8H~})i70nTpa|uK@Y<$eH5MA4)Ir0=*W|js2q#6uHDo;cHKfc81#CI zY-!)oE&3Wmajn8p3@EjFQYnK_Oi)420#2yQPB7gJSS->zkLb5oEeREAqkPJ9wrCx?HF&5ck+e)NHI{@IDG_Pi@rcWN84^jt}v+>!Nh^oZ< zN8*T6B&Q4#l4Hlf{!GM=jk>V~g$&C;@^G>4dmrD=0tW#sHud5hu7ijmh+rU0ck3|G8jPVBzM2P7#|63?Uq=C{G?<8=6Ydn>R@<5 zmjjL8lrd&Y%b1|ZwZUuBA*C#K5Jv1ISV$uPySoVNl)+>}!}^NKYE$wlmGK$BP*_2X zocFSDPAynTFX2%+}@QmRxNRSq|lbEyyNGq@Tgfb*ZJS{}3jolld>fjrPy(K*v zj2-|vs`un|vU1Qvq{JGpO7nA^Bk}_r!BY+m0xyGkx~hU_xtXqH`{7)2ipO%Q{R>C( z;j8MTXa|>9Fdl9s&|@95SdP+g3gf~_+aHH#jX0_?$B101WS=;y#9XBN78jJJ9adg* z-w)cj*j+qVpvGB9fFv7j&cW8$63aC7FpJ{hO&BjRmitoDPC?I!^0h>UzPdXl<`)|M zk-!f_Of__V+Z|hz9SKQ@6<8g68S^4{AvnvOHK=|8sNtLAgr|5mT!qHsRW?9HR zfx3ltD}N7dIo6hfLbYmwbo(Uy3Pww)VTWj}LFGl0L+#+*llDc_?`j+fS=UN;8w>dZ zfo@K{KdAQgL^~Scbh`+;=LCdyQS*`~_s_~*hME$ko%tLE85BKRZaw?q%;x9vu!tk= z8b9}FBc04+b*MN1-w}`5(JFh&-N%Hb{Cv6Hrbt%|+0mBS5&&2zSWU4HVm|c9r}nZ9 z-`giW*d*JE$U>xUtOvglgs^|#2cr?O>fNL;KHipbP+CY?G9r4%6DU;#F-TaQhzBpU|CVBZU%79RWo`H#a! zE1a<2diw8v7uTfYF5GbGRE}vHsOCI^31_XuEH%}&#uAS7ly@5`@u#F&MT;`UO!~)$ zVZ6MgWF20eBc#@o>bY}_mK<70Ils7(Ecqfk=<#vfkkkiNdI|uXk$2|#_xHYUm-Gbc zX+Wm{*REj2BW?arqY>rNRGTAQv{x;Q1SWCex@eT%MpCu}hvK;(Q7q&tDyJMNCky3C zo1AlPLkcZQp@KhgiJD4>Z0P7ZMKouN-$y%}!k-l0KQc zhcjsnyxyF3+~3jqD5Tm|$(jkq4rljh0}~)m160{`Gkj-X2wGwgC*Hx=f~D`4Ka7#Q1mf-XwqU7RHCY`A(0KV ztFf*3$dS{y6}HblQ<^y|*`HfZgu#r036{iTv7C&^?%Oy&}_WKU-bh5=#uNfTV}*IlWwC_K%C16Mq9O)cEhf5mL!n?Jr9`Nj`g1% z&}#09#e+m%$S7HU@L3yNkmEYW9vD(tbVV9?A)+rU=g?e(la{gdbB$GikpYe2ZP}*M z4t3ic2w-?lc2aLrQPZrxVd)~w2=fD-Zs1;iQm}`y`wo3_J@d-|NLqFn6jd4y@G?b2 zL`EAo4r{{*oC_Zc%uzzg&48ddO1lXLFsofSyo;8yj99ua&gbD4cEA^O~uQ z4(}OEzV$ntm{;2>4y=tR^0g3OZ@;B8xaMvJFP{=C^YoWo+c7YX<)b7k$1K%P_L;|Y z>DmzrpiNq;M6w;w91l88GsibSR6PV1kJxi=MMYIt94+{3UMx^vgokm{B~yn>C8~~M zwvp|4PM<%F`~T^H{6MJ6qxyil(LZxQ{>aicz;9#!znHf{vH)0$O0*Ddl3Dc#z^Zxb z$Q-R)@!@v+N(#;twD+#t%QLS?4oj74f*;GCJnTR4>_6=D@Mjg{?yBIBi!zv>%z=u0 zieo})YTw-RM0Eu*28zIRqB3VtS3t@9*5>V0@gsO}XdJyL!mArrz$Jeu7E88fDIpws zB}F33u)6b!J)Ethu7oNk{nnF5iU~!KORv+oLk3ywAdOT*>Jutqx+5&RBa6|niun2-5gMVNGL1B165cN3JB_1W z7@%kapt_nx!R=DG8@$)v72avTG1M@{MfgF!CNya}l~~fI`&MG&b0AZC5!?V#`Ycl{*IuuKC+LFJO{ zf>GY&1r=+!!>hu>BOgkU5_^ z3KpOlFJu#>apu_$lglgs!1TiJ z>hNJuA0>#bjKt*0Z*l{9eS3s)Fzu3LE0nM>jd5z@fwr2*)TCnF;XX%*%V zaPj^#aQ%_BZGi6IMo7Eb(PwopOR^qvL=X`$5fBxLdJ)o0n!#h)ijP>}TcC(4*;{V$ z8@}F0ERd3j2u7sHU{!VM@r}dIdSdD)Yl3l4C5mQ4-m)tju{P6(t!ypY^cpcND1xhy zq)>`xC(3e`m#`f}5G^zFGcc#YQFb|845$ceFgnUzY^{-9drP~_Mhw{Zlu?ehU3gYz zfM?EYm`+P%?o0p2>XYd`)`m2@IGnUb zV%WD)U!%_h#RBU5Lwotw&h5r@I9UuDcqur2@76~eyW@Ptb;{F+FtM4l_!>!X+)jl{ z2;zxi{NH@!&K*R@mzqpP^i2_=c~xrYvthGZSVXJ!m*;ifp`WCvLYOnQCK5c%s4Y7VSx(jT=0T)wA+Q+ zaOPMA@u@$j2QIO(#Xtl;%s`CD#t^AAx1e% zMFYS2g|wm&-Ogk>vIBoFp--(e-PyuN;RXPr5ZZM?MCT8Lzc3)>XTm>w=gf{XuM-*G zXOJ}?K7y1^qJa>NiL5ji{k(G8J0Q28qhqmfgpu^LwB@sVlUJkGvba*Yz;hZfGk*5S zpl368Bx~w%v0qC|>2RTelmcbiFhga{l7%*>Z+(N;Bo?87IA12J%9YFSJm+cCS)*r% zi+Yay^v7*XM+?GFxT9fPNI*1Og+(x-fW@j%j|j2r=yMWp?fk2;vR+HevG!rCctiaY z6aT;E>VMmfzfF8>c8)(N6Z}9K*f*MOms&u3qltX7h-%@R@O$+ikf9=ju^x^*`IwGp zYIwoN?5B}(HOZOJMPT#XhT8W#6VKLTtgXXZJtH{?s0tMV+A!#vBcfy0J9$`jC{X;1 zla8l#6G2jKae0!jB7fl7H1{-wHDZ0jUAD+n_lzk?i_Ez7r1%XnkM)kdwr?NST5NFfOK8Z_;Z~(f+Pd5{ed9$S;KY z9xWob&bbH{ee{`I!=1!!F<5dr34WkDmKQei9gKtaiKcWy;k#wib|`6&kiM)oIOxw( zPe?f2C^I*}gaD=77YRbJqAm~MNG%*zT~O}0tMak+&?fNx-a!gXZ88$e!`nK_plb5I z8fZ=J(x57VSU7h@6u4{*ykGB0BHKg9;4;FZ5xZI3IBW-YgD42qS zk@&YDJdC#Ys6Sw_E9vi`t!aZ?J?}FR2Z4g5uR0hCPsYE~!j4uzCr6>XE34b#Ds@oL znYyW(m+hl%{E&t)i5aap5Z!ow4UluH-l)38IW?&C_N-Rp!E$xA>Rki0@*SLK!)ls+ zesNkecT3ydBI_)nM$XhO1!3;4aP?(Mb8B@jY@gHEc4PZ2>-l3`*-$kFmn|S>w2K`S>_kbZ=9`Qjt zoF9tsuW9t3_Hf%DH|4*rMrG+Ih{O*&MT3GA94+y~PLY#j9c;92s!u1sg!c;J!<4Tz zqVNM2ePNA_SadkKzRsE$f9#bJ!d&?iohN7`@= z@7~NfmhmE?Y64)gNXdkwzB@B7#i@^S5BiTLQ-xWNBE{cDH-_492p?eX;ny%n=?s<# zTX9S-593>C-+maos#8L~D<8EDM|z#e<=dMjs>2uf9IF~sDGtWJvWiID47Oyqxbcu& zFEvn;yXGn+y5wDXEXi-Qu#iKHjC(O_a*`QYzY?C>8%>=02fQns?T$^FGZaVX5|&}? z1BW5ov@i4(G*0-1Ynh*{>rSxJ3|AItF{c{Fx;KX=%kn=(J)=tN(zv>06l zK29wF-z;%kx{%j{J{gTkb})y=wp^99nriP-1IkBjc$FsnXpZhjrzG_lq)#(r~WCyQGt(emb zd`-pP3~L2rw|d~szXX=wNDan5*G~(T%F*;F1*X+n`<8Lsc}$uXt8zqJQWRS4fO^gA zrRE=X0d{rcC_WXU@KnKh*0yY&Z`S&LN4OIa4%$B?6}Q}~pcLJVZp$io(rRxV^ zzU|2vc}W(9- z!lzgZkn0hENs#pBljGMLU+xWj>~a}Mnqrij-%My4?0mZ#h;AFk{5J2?Hz=>o8o;eq9ajt}>+&=|au4iKxfd z>y|Y2=jsl~d7eMG%7q{(*W`Me(bnQsRCmgtt|*49mhTiFT*eI8x%6S3-fIl7S< zi3}V-T~?-%oLp^jK$2gHUpuhDpR@WV!jLmj&EZO6@^k_NYNP;0(Q0pmQMK!qj&;ku zangTu6fzdkptR)WD=H@jU0aax_gR7kL`G^5U*b8sS>3iaaZqRW{pf7p6e$yJoEqz| z(l{eN8yz80-o;`NH$LoY+5!eD;L*3Pb&aEd3_5ux)>~Gwy`RLX+QCu{W79J_oBK;P zzVIduKXV#Bdm8U0>n5sgYNCeFK^Xc;`ardouPvJqYMi;I9N507#7(_~PAbiPf9x#D z7FOpx#o~fXNRKP!ZKW!p#B}?*jp&5O!o|bK;|tIjuh#(!&dK!#U0;sTN8k3OAQ_X~ zUaRcu@O})TIs`R@2-RX71$E1Fx4dhW|3cB;1o?#29o3_R8mCHd(CHSG?Wc_LqFO*p1|58?&JzOQdYT5pX_oy-3GHN_~+L{V|Ql0FZUd1!fS65oS`n$8p`Ke zI|10`i9J|$SN4Q58W>ikY#f_;Md}7FJT6mBJCMI}IKFtZp1?&PQILes*DI=fn$Mf0 zDx85fWhWz{?F3cJZYTD8*7_vaHpU*gpZz@v#8dJNt@#kF?jP~^U-|h@>w6TSC%?jo z=$l=CuD@&HMQOV{DJUvfKM55U6`pKnd}4(%RztS}S6SqJza%%Ubf7R8Jd2U--QnBW zn&3@g7Ll0`Qvb8yK=e|OMToG(I4$)yul480W=dofrXMH`+-?p<&du}suqEOGXEtO3 zGeg!+*#K~1VrLD?Oa(0!Xl^Z?<*GR=F-x_$I;hygZAu@5AD1N0lhQlSV0!QZ=C;c{EwRo*>fJB$(JXUx(hOUvW zYa2Jv0Q%BbDy|BCk1SUn%<_{K0<}tE?h@OD?hqj$(Ak~$1$kX6ukWN(Do%&mY}ivd zN!tU9{aC-ucu7>Rw$SZr(_BBEp2O8T1-D1=kt{G*r!DgV{?k-5j(Dia^7lFe`4A^T zZKpj zsk8nH6r$z=jnaGv1IkAM?e68D^w9R2hSdz(cYVr>}O*^PJ--wz(lStT$X>IKFM_*4Y$pfL>UiV+Wq< z1XPcKKO!KtuL;bBwBoowu0trvqn~ATvNta0wv2mDP58Vw&tT);;=FQVvByVjGelh* z>{m1KT2uVY@pa}m*L%B4kjiu}4QA}qp6g9D>cISZ6=`X)GmEc~rj~#TxI(Ir*T5|L zWy%(Z*5_y4v?94`K^{V+!`TOzL9BdNE+Yzae2pr}AVwYFs>^}!D_pHt^Zsmw6ti~t z3jQ}1lUK*U>G)XW?f=aC_;XvwC_q~N!~5t^JNl?r&EosJC0vC6E`bnDA+ydj%**FcxB&j;STaclx^C6(2 zYNLlTA;~m2G#E2*|D<_5fE~z+!qZq=CC*|VOfAjo_(i(Hw7}LHW-^CrHk3>pM;Kjc zzYL2X0n$At$fsk}cb2?+iCL7~AImTar5DU0wuP>_v4NvKoWmyd6G!)xqEyJ&$Y_zX z!nu@Srq1{}d9j$A$-rZVx?Dlt5Kl6Rc;w;uO?RZZ9>91H$Y-YPS?TGt7}-NIec@|c zkbb=fhC4IsGsH^x!>dGe42Fa0UpJp@v?00>{5@4v9VfO}tvFLwp@M6@R9rd$*)&gM z#HBznA$r}d3nh$Rr7%0_*xFp@)JLi*1~oF|=p$oZ)Ortu9E80@hmgl&wnXZS=I>Az zm_ura6AI)wYWZNhtIZ~Ct6TcirRTI)Z1%axNn6MBp;#!29(6T{3n+VEpQB&CUT+3G}{hLXib-CO{+}<8%!x64nvbUnkrmRVE0`=Dw({t3pP4?cZYt-RYXVX z#dj+&1H4}9n*HkFvV(L1zs(Ss+Np2zdtZaD5%SnTJtlJc?(r1JE3+qTIJB^EP`4gg z8#PkWGQXZp!zK8F24XD$)i*FDVvQ@?=V`(02u_~p3&+jR-3j)-fb~p(*N0zuw)t3& zCBm28UF~eEqn%s2wYKwpVP(VO?%p#>cOIX0nc}%MYP z>l%WMF4kS=SrF7~W@P-cR1pxhhOTOoDP99;8a40ll}Imi_@0FXv?S%GbxONdnXN8S znM|bd&NwKU0DYZy5TRjC+vhlX(;EjaG{Ett^jB`c+TZWk-9{L4<@?ZW5dS1K`*W}E zN0;!wZHV8kCo*ef5F#YtI00%>dZd*7;aktJpg*mrO6psJr;yk9==RnE0R`5?PY}602;)GYcFkiREC3Q?nSR z;!$zVWIA+2{8;rREqD$#(yXt@tTw5lsf4crg?z?h45Gip%d23Ge8?&EB0FYgpfs-V$?G4Ur&M22jO7BGK&N z$F?|n`-$Xgoz>QkF?qHXt4&awQ9AmHfYMav;sRtyCA4bkl;#qB^UKop4m5ax^Z;lLR2`X6AnJfWc zvggU>MAZh7+e^aRq0~dom>LzwJTO3_I+7Z9a!lsQ(=tWwY!Fu{n0}DRJBQvLCS(xf z7?yxwzC1*paT7a9Q$8J-33h0a>I8?AOlWlSCw!*=@(78YM-v0V4~)^Ms6cA-{>u88q4zy52Hv@evhH^g?oyvpgG*o(kQ=kBJ3@F2c53m_iLflpA<*4I~ ziCOrKIu!G0ESNa!Q9d`Gr>A1R#cHQ>83C5p)oW$=u#HV+0hME>bsH;O2X^?cH(5sQ zOHf5UJD=$@j8?x)$C_qhf7GeiONPV8+2@a<(>58b#g7~Egufxy3$*G~&1s#U0u)UY z8ysPWpO&?6DpXRH^Cl>|sUOg}I|&+D**8S7vh^-!70(#{>iZ#lM($Jnz+2J>9RF6R z`a>|QYC3iw|6I&FyZ+sN_r8xHY=&J^lg)xfRjRe@@Eb+AWI!-5uw;Vl^LeX&>tUnw zaJ>aWqjA8NBiFumWXt(Dd*N3$mSh^P@M&9Q-~<&kZT{%InERP=2e5f04a8hh98s;` zz1=3e^}}4WPn+fzA;ze5Su?$yjm|%%3|pmG!n|Qjq<&q@@eTwL$saVJIwX?@G?QwJ z-MTvsxi_fW57VRSB+2|34m0rQ6tPXwUKz;X@5^8x&C6hXf{-X4iX0c+k}g00DDILk zoJV~-)wDJ((j7)lHwm1UBch78KZNGXR`!xmmbRBO%(=v|)V1|QpD82xfUjeBUfee6vSzU_I#5jpx>tVE7I;iz1rMA8vYIxCHL$>j<|EPA-(`Z7>NrX)Z2sfZ&+Cs_o04 zgc-OoJlpl3Pj49HqPh2H1lQB{+I@VP`T4VN=sO>I=}!?#4T$<%EtOQQUqx!8uw zf{v9`=RHg-=1^EPFJmo>B(ti5^DVv=2MDGYdU!*Mo6BN#J>`342`U+U4|}VIf7;ZJ zPLnjBPK915e#r_ej^6J0t6xFL3JQ|{q4e55bl~4`_{XlOSGDVsVW}A*ftUm5axnikz9P!G%7$ zs|VgaXSRU}e=}F3YPy*+qcdJUcMY)+43bKBZ5ouR^~I_b9;S@)uDa5Q89&eHtwRfgIZ4WG+!w`Ft*UrKC+xv}=Z z8N01j=tKce`I2Rytd{AMZlprKZ$O>F_dAM4@Y6eB90SEYv1OO#4EeP-MMN;=rF$6) zJL@Cn1xAPVVK`8i`aL9#2Hu_V!BC&(TC~UmVIq*&96pVcD%^^|ebc6{Pfww3JL-ZG zGc_bu_##O6`eNFVE{c+2%Oj%&y+Q8SN#7 z4wacy!s5qPe>(SFyOqI50etPuPQ8^bfl%R*E z29Fb!2#|@dnmL@R{>+oll-N_l9!dq3A>DY zoq1aQ!t81ViC_n&f0k&%rElb((c%xV6aF)vzp@LGTG|)08eBt?sZVS8UJ0%qep%JM`(+LR?^xJf+j~eJ!6ckjc&L^$BP6Ku&x$n+`3y7rB zsaq<1O?fvsSk^ByGi{Zk=YKaNcuErUffNOeNBi>dw8y{;^MSA;L?c^J>+!5hq2zeZ zH?m5Sx0w8Adg|?Y)HTaB4a|q)ixv|L^FWNlW~myhXCoNrA86ENJ=CM}Oj8ZX{a@OA z#y!$VBPTmZ%M+n9u%;4?U`EH{sg%`~Cu)jV+4KjpJH$&tzr|6-teMZsC?A;`zDkyt zVp}nEsK>AwGWF32fD|Ksc<7&6()Gd{vIBkb^iY*omr1!@NFIXOPl5b9T{b39r=mnj zS4dlRYTH)xrIYu)>U%*5+dw}o^dUayV$Eh2qhw{3mfNz;51T%o0UQeIjq{%6-jByI5|S{nzKop3!xL{E4i(MQL*btsUGG1B`fPkD{)PMT1ssO zs9#3woQ=8k)FC`b%Y7ie&b^EC9;Q9@zFEv_R1jY^-xR5s$1=C+eAdQ{vLg91yjklP z7(2@IO{jY$+c#dR-Tnif5ueg8ec=~@qHp*UhLuBx^3X7DxKUi>&Qu;UY-MkHavE(* zrELz}uT(2oOrUCbZyuO%@lc2{rGod<2|<+)oYz+0u6>Y-T8H7G6Dezy?54(UC*JHG zonB!iPth?Ly;Y&>GKG3JCteu24hUco#2}QNH!h21l`Fm1mO%yS9>tBkB3HHF>3zS5 zk-mt2LFxhf^$Kbc&V^j=EO%R;cdH21@5mNX(uuY+$uqRMuhYgnJw(zy(&3KMTpA+1 z7(5WFTvIK5K*!4ZDJGv^!?X_iN0Y=;u6y?u7amr|#H3W6>qX@XpDn;kd`+oIi6HUl zb-Qv3p`kK1~dZ!JL*pz!a8k;^;}(utW&9y z^jcP$Y?z1O9a^OSYl!uCJG#-Qf$3 z1HoVOq}qk;787Q_t-)CcsUnNQAy|3we%|0P8sO*B*^jT_RL@mqC?g<6+6q5ZDe++V z(SpCgjZ_m|mMB%}&aiBclXdsmhm%Q%M)_A|(&@Brz5TfJ_G0a)iBi7FV4BVpi=onM z>C{20NuG1I6bBN?We2&Sa4E0FL0z*n{TG=!lkp^)OrVrmj~!Q{$jY`f?>4N>`BuT> z&xE&pEbK`Zn3XNyplBqWq5;7f}I`Rd@zLu{MR)4lTkdbmMO3gQ{O26eqjNfbKKp^7EYNGIt8z zy2^U2#zgA0q!aJHfV}#z2Z(iZMVbn(4!En00(;V^MtEmhUnV{}9_Pw&5RH$Gl5 zv8!`uL5VY0t|lrTw&PR0sX4AvOCJ~6lKe0B-a0&vCrKL=GqWs<*+N^)%odZy%*b?x8m-p$_5JhR{Zb@$Dcx}>bmY&{j(m6>luM!dnX-@i4)lxKe) z-AMZ_(0!{QE(m>6`ONrJEN;>_%q>Qj0PtV^`_^O}$^s#;4H!p1#6#gzrbN+(!z8=1 znd6)T4`bCMX8c-DOca6|X!2k3+%z!u0MXfo zZ{Z53+duES`hvZu+wceBfAbefVXa)wIdm(#i}-rIKnbM=RL(RB)FB+K2pl$*pLX&a{)RJvXkLh;z_*6f1Xw%&5P1IWt$)h-RN)`O?1b9WBXSEGwYLJbO177KxSBrW=fCUu_O4my zEuH78ppV@iq^?3VoUWUB!Ln94w15R+a*H*zCDE6TbAM((qiNc&8RcplDOgx4%k}QEe8_<$aqKZ0!@1bx~x>9^=#m~hwFk&uFso~$;N&03GT{Qqz-jE~f7a{%K>e}4Oua^~+aw6vasqmjMC-vIUBF8)Far|NIk zJEABbT?(5$_8;Z!?eD$6NHJrkvl6uPC_H@zw7Vy2odNL4n#xC61vWFhlROe8Lv6Zo zG4Rqdk|Y5EfZeOp)7O0im#s5oRrvGrl=5rATdnIs2YiZIlCgpEi+AU**5s9n)L*`h z!uLF%vy`n7Ms>dJTP>Hl-ZNET#3K!(C`aF~wxQpFeN zr-xJl=?@+ENhZ(C@#71f<@u31n(DX%)U97U3FD%goHU~^=Z2zd_cN=FdaR^x_R8Ag zgSX=4UJ1Y5+$ijV9?Fl5U& z)9`L>@u^KgMjd?)ktOrP9@>VJuf@O3iqe#gVxg=wv906tCj9}4Y6gc%MxmwlCBjcg z>40{Xhf;33*|AYn$a3lQTx`^A!!7LdtPn?y&Uo1Wt2RdqRBZ$=DHLU;1~NWUxP6BS()O6Jmo zeg0XkG{DUEX+iN=tX<*YIE_iurKBr{R)AQ>sh?@)`Rp@^SB_|ge9b+)6Z4Ln`%!VP zo?7K+^v4kJJ!q5?N(FZOFhdfqytsFFq1vygD}yT#6OLVckQUyvx-9D>-f%9nQ1;T6 ze1m1;J7QOF)|gPJuzq__Z3`P&O6J9?kMwASM`|lS4}UBqnJjELI7kXxMN?0ysfUbj zTMj&e_vgi*5x?tajRi{$eXa|>wW~=mf7iX*?%cUK%AC#SEEK|<8&a}LhG8ByFyK_I zZjDBPPmq!YUf6ip&hr(Y;PrLSmgQ6dTVv17DFx|}g38md5zZ@aW za=4Nq%z#Zy?V1(oFnO^AQ&Q&coo}CGE=hUK-In-+3E+aqVa0`x6iIT|oI~XPkYI8s z?2Q!c@A^3-qdtnua1Ac{Eq?K`|DwJfRbs~!&#f_WiADyvhS?0@;)Jn!6E)=|GN))HErUwV738#I6&&WL4k9{hK_95!Cws9*xv#niUhEXr;!g0yNr z@8^TIsqA-8Kg&pLkDt&FptlplYNMZ}892?nMX^wwAlpRVCwfK24Y;K)-qG<$Nr#=fr(-M| z;v5rfv7T_oS7ys3UBJr|=HZRBs$9oOtS5My?y%;jYc`XO=O`90dOo}iT+mg1r_N_1 zU^GwjS%`!-Gcw#v-D|4Q(O+(Z9Pk@e^jWHEifHk%L=v@9>%9?>RA!+uOXz_5u?q&b zJID#1syN-6pIf}Oc+)|A$|cymf-G#FTIR@G7@l#`0fjQlk%*~yV$Y%$<>R;4`SLWk z$)t6_YoU#j*Fv1l(=O=kwOU+&t)Y2N5L$ag{{|;+}k7f`>e`9ykB{GZBCtZ+I7K z4;5Bt^#1J62mdt4gxXt|sdxju20*tAF7szu5+Muf;Jtx7Sp;bAS`uBb63NCrR(pCB z09&7Qb7TTbIUe$#vS#f&#_RsHWC%GKVTql^$BAR0gq<^Qto{-^Eg?+jUgt-JNf ztJbURz{EY+OD-t&fH2`qt9fc#LM-@v3ArLtaZ|WR z#+v|LANPgF@M-H?_!?3|UnOUTz#Yhq7MiSLE5&^WFw4YC-sx}{s+F>Tnwfm|Ryg%r zsoV{4_Pv?4e7;e9t^*F{k(7cHzl7Q#TfrKo`*3CL&?J>i!7_GKxI7QSbTXI3YnA;t zw7KbtM^R;>8+Es=NmJv5W;smc>E4tXZqn!EVghzzxi4(q*XAng4(q$l4pWib;DU2= z_34DtOmAw|jy+!Up37Kv-fdfu?aD+EXWdHfXIo}M_{)-{6*O~|tXk_lbF5m@S!PyE z;7ic{eyR<2vg>vlF30@8I#eq$EO0riDuZ#vkV z9$AP`aGINT=4`0;S`4>Q;B!J=>mZ+g9FLdrjJSs%Sgbqj=wU;B`ovoYfP+D{^EM~-xpxU9%oDMm$szmc1Q4oO_E~a}T zFvg2z%j=GoK8RfGx>LzW<{r_Bc7k45#| z`ry@i4@gUTzf?zVmOx%HX|hbQf9Z4`KAq*V4aVU-U=$e+m=;D%r;oRU>rhDJH(?fr zJA;;kKdxiSML+L+E8ufX!9MN>(|(O7>$5$UrdVVbR2(C0L#Ih?j{O}W_Zdn^$11Il z;p~Z0v2wJXXzpjr{+=~m!&Xso;OA9`d0)7|OsdhKu`#sz+V8mj5$qU)T>*^niTmoQ zU4WD_RCPPAYMu_!j4@HNwTnsHFD%x8fmeA=zwpyVX2nAjA;pW5e~5$t9uqONTF+zSeCqq7RAC)slrkt}

n?B~qI4q*~~g9UU0jA3#^0|32NA;mW<>k*1t*1v1!w!zR=(u$qP!pF4S5mR)6z0CCo6jG)#~sFnV{ z9295t#AC+0Hh_EVabPk*HKc|6VMRrW7e-CWMWa6oS6kOy5L;1UFuQ1I!EJ7lQCp!u ztCC=et=RaIShIYi;RWo(|K7bneSRO{1FiENz|5WhYBvAN##a7!BvrL1F`Msl@^W+8 zW@vKtz2GVR1*lPH%hqOW#8>L8yO(5K&ibQ15*@?Rr%OXan-7@|_V)IT6;vxIC6bdt z+Kw3RA=Me!pF^5IXSXH1X(gD0WQ4r0KW>%Hq zv{ZcZN^)Z3K~|lDA0aem$ePxbWMANSe{mc_PKX*9>nsn-_^}OLtYIKGN~xuy*7L9C zKohT~n&>VLtK_w7k3W<>nZNs5b*6dg;y1(lsV09?VQGGF)E6sSBzD*Pefh<1^2Q?& z2bwp?OZs9Uci&R9#+~k`fvU~Q2*G#Kqz&WtrBo?vz4~xh{zUCVeDZsdl;A*OP=*1D zD%cwvtQbHdfui4XIMK7?_pw(3vnX+Sb4TAq3N$rFImoTq;=BscMRL6X%%sN`ys3t; zUO#6TaLVnE!0#C`=;g4jx$KlQGVuH;O*v*czSpu;@ZXaOG-2$bk3*Vruh5Qrsvi@L z^3G{fW!@wh(w>gUvYwZj&!4v0k6pO(m}Oe?#8mYlo|`)#NL4MmH(`z`Grm%d2HVVBJW5dZ7GuT+=9{iO>18 zqo>#N+wZ3%S@;%nXn_8fhj*nTlaPhl3K;kK;I7xciM%=7W%EI_@p=^B37Hw^d$2mW5+P(e9K8n6mkA0^= zq{N2%ugBJ3mfO?R6YEu044)6=B`%m18)v;Y>uZTy4WOr27RsKUZzF5@_xz;RA$?OnCX}re&SOtzfTCq!l$8?QmQwr9 zL0l@9+;y$5u;!3r+tz-do<_ybBhPk%e8=dTFLjs#Jx7>Me_m<(71)RHX->H^(3NOD94K*fu1f_50fe26Cvd{WBaeeFok%E;U@w~ zgW1eI%yIdGFFsNN%~0l}F!AE#0U+`q5~lXi9Pe*Fny?x^`H=xcw@q4mmYVsNcG=r0 z<7!Fbu%}Y4QflJK@YHzOyUcsRFv|4H?$Xb+FulL*)lIqZA-*+Tr3RUCn|!O|RvI4k zoYpZGmzlF4w;=*iNCR@lw}Sjw8;yXjL;I#^P4y9{v98>9kR$IPRN{M&b?EL}G1!=^ zK2-vzte8pH;IA3;3lTH$ugi5hOb$@LYSX~L*q0vzr8OH!to1@M+e+p73qQQW8_uSo z{WHUq%Rk|r>VgBz&T0()G}^{0OF7eWhA8{N(pcwz*Re&LOs%r8845dWYL3dG8{axP zZu=#IxF^vA_dJ1ipHTgZED@Bpntq_5}59vMuD%z=6@$Y_7hf8?vZhe zEKM)O28UI#YFRZ=15ls-WvjL_};ji1>^f8=M4N|G(XrA-Tn@??*`JStUqDhgb!?qPUuXZnuGohAK zAA6Nt^H-z#h)K$R{Fs?6cRG56s5ZMvQm97`u5s z*`RD@SEhy&0unAvZT`^iqs$7vpu8 zkrYJV5iBFgx3Ya)HoyNvl&9Zl&p8N$A>6>)e+5JS+TJ-;l?E!67#qmbTqwutGhO94 zPHQF1Gk0VoZsJf))p+FF8HDLZsKx>3+3J!-~<|9E8`J zz^{k$HGs4%E)Ef2Y!B1?SMx6f)VqrOc3*{#YmcI>O94H$r7JBq=TAS-%QU8<)nvzN zCub7&$DmM`{cHnrfJ$Ylajuxb(66si0e)Z0fJ!CXcQ+cs!-;ih_!PIF1)|(1k}X+N zcAzkp^W8hXez4>UJt?w&bnJqyVk%t@tR_us<*se5zkks)3pUN#w<51I-$<$y?w-6<461Rioj1r!CooqOZp43^ZEzDKsw7Q*%%`M~3#gYT4=~&(4xfap{ z*!u-1e?yVp^xpQR^dxrR92blBd-18tuMfkD##q9}s-kNi5c=kWU^YP5{E7(yH;5Po zg)CW)4I%{(6}N-u_}LV^Ry!Oq(-9~myZsP~;7-zJ3f6?PU!2=4C;B**r~Fz_3%WC_ zz*XTA-_>{KOC{weOdbqN$Z(an6iooFxks*DPI<@==RXYZXULbKewe3hkhX}qF?#bI zv!Os#_)2_0rR0qcQGn8tLyUtQvfDK967^Da0(}cxc_La2Sw?v3FmCMF^zl;Zv6VZ- z>--h=gT@<_o6-#1+*ANEK!^om4T=3x+50xKFKwF5(->*f|)+a z;2s$Rv6&(QI5M+_+_1*kjum@>eHo;RKi}kUjnc7ssn^mt50s`AwD;f~yO#`X7};^wNLt7!#YU(-^9uoCcaNcK5wWwE)LB-OjS z{R)b$e-Xt$TWGC|4_2#MdnGR9wkD|`**nlhato1G)S5LBs(*b`w{{%z`sD?1Ig?+GbR6M<>o={p~L)_jLH90 z&B^uTSTLW^A`hb*`iSlJ9u3jNvP}8JJ+M%{Wk2uyR+r#T_%xQ?lqzl*S6KV!CUrlo zI0`471{>1aa5#azwWX?1gS2p?(4B^U&Db&7n5P3v?JJZ+#X7xs2U<&FpivkCSRKtV#V^uvDh3YnB&t0^^S)nqB+~%=jQ@ z%yNb5kj2C-p>#tdXK8W~_TVHu;Y5nn*!lKsq`D?#rq-LZxr7Rc;C!|&JBytXsl8dPB93T7tGlfJvWwF z4wX8#F8b*7k%+%z?lsnQi9*~;(qgF&<4qaX+V7lCtqWgT3frus=aEUUJ#8^GGwutv zNCvSg0e$!=gr3eAnrK}_n*B??cOK3C;UO|Ld6&6+QrjXibQ@bBHm8G!4S-;5fkxLp zf-0afO32gG71c1Djk6o?X=7&WOyr7W7|UjDSEPEVswufYoJgbHAG}=;rDO6gh={Q2 zHiQ7;p8PE}k#H=X{`Ib7^uxQfZBzMyTKQDl2~cp`vcRKQ7}XbcZKV1eZ^)}@{6sCg zeBfE+#R>Mn&hSb#E~2l6EnRIcWSq|Xc(UAZUo?q{*bXPc697My-FD*%rKGG~?dH{# zbZTDVcpD81ZD%><3l9$KF$5koN7(8|PwPO;xEJhuC5xI;5GQT;{zDO#$+73D2luoK z;-H=YmMfZ87xde%z1AA4(X_YU%9jV9$rmDpQEj+A!#>=e>+z91vTTky~p+o34_qbIf{e*>aM{N%mYAzO(?`#kEB(ep?0}7c1xu)JAONo#D zhUE5d$RJn-4i*3n*3akA{?o9p)*hgiT4gi(TiC;d>hzm4$L4wQ`P1pg!pO>QZh(Dp z2EVnoY=VOipx^R;H=HQuPjk5g5lb2{#Q9$#mcN`3fQFMl%3UX6wF^*@$_FZgg&vwAv7ZPWECrTaJLPOLr3wqF>$996Clttk&k(O(FZS+#BLky>nsQj z!e(C{*TN?Skx{in;;w^R9AL9}UIlH=dA!oZ*X>qz()d(~-vwObNp8hzTSc_?@MCVp}XLP)>R4o~7 zB!XI*;0amY@B-%&bB4lPH?+&3J5D#T40nHvaALGXd95xnTHttK%5?oTH-d`)1M%J5 zjV?^~lO5KQt zQGOXrIh+|b%faJ{gMjwl6%#Ko%$q(<*9TbwNz)Vh=u|sv@4}2LAa6$9bV{^NgV|_y z0z6y&p-F+= z!_=@_+YckX&jYF10W^p2zPVW7gI-^ui*)2hq-Y3FppyesYW>8#~pn$tdqy`bH~h97s}G z|C0APte5Jkgx1nDCjcvvgGP7`knD?*9UAA?iiVD4po-DBqz$C7DA@k}MC{+wl;gCq z(rrWQZJO#H{9F1YE+4o}GAk`n?ECVWBkjkzkhJF={y!SHJ{vFzgFuwgj`pty?%#4% z{Lrx8WyN@7nC5{wZX%Jl!HY+r&x40&uq0Iz}dZm9D*hQvY~m|0<|e#zBvsF&C$K zLZfg(Xyf&MB(zX^tmpgBk#82CJIyU&t+tt^w@F)V)~CurOS-uw=4yjooa+Pm@TM<^jjRL`%^;gh5V zS8i~bs+W2)wk`BnUAX&duOhojq!NP-vd#MeX5Zwei@K?nS~7$b;=Z|cBfz^frs73^ z!7YbV7<_Y%#aA|LI3=|I9G|cc%dV%Ra!spdO|)KimNN}xqw~<)TG_B}@x)llg{ob% z#$osJKU6q}H>Z_;Azwsls(}M3bO1TAHoye={s6MLGWZ1~W#el(n9mVmAF$Z-r-)1N zr`Tbz1Z7(s{H10X`>9op{*=1L&roWCi)Z0>;yuBBJB#smLVx}D`V3m}4PWj1McCVD zv%%InF3MWj!;BthK;i~ZB5yjrp|=f-13)8*>aG!(*h90`0~T@SH<*ka?;M_Qd?2?A zR~;RLDa&@^+c+%hHHc?Uw;7~y({&&b4f?d3-l+Tymn(ciUgNW(Wp356j?}_=|N5h| zqm3-7Mkj$iWGUWe6z|26=~!?Ef6z?iC0&hjKn^}!1)smIY^;XhDv~EC7qHlfskb$n zd4kZ(V`T#isqv88-T+D^xCuW=JNjXe%q|_xT_8p}J`zPB0okDxjrJ}WDHmU(`dfVR zxzKbNFBO3M6FrpbJu26i&u-Ab0OMEacGPJNYUEjWbr98Uhpz?K`&RmMuOyLD7N%hw z&lGM;wu9O>{crxHqaT+eL9fy~J;4u~6hD=dU<-2hRs&)dcI?+^*`Au|IgO6%JtK2)|FnTHTgAap8#k&ESIi+6=yWDAH&m z>_40qA?jsFY|>$Ef$9dk;iOf`*ZFZX7Jc#2*{7a}?bHl%?Vxe9IJ-|9kGOPmriX)z zYA*tQ4`#r4#bdC;QOOn2+cS;pjUJ3Kd^Qv@JQux*=49=+hD}K+g2kjhhualqHbc;p zg83%-Lxjl<4t!!MBb}C!s_dXG>p(;ACWl;0QT3?2_(drI8Ia-GyYMDh87pXhEXP|~ zd)=Z%f)@g#mC3pO`VUhs9L3;Fp8;`=Ik5I$p_jj$2g{YEtbrlC>)40*5Ka|`7Ek_5 zzJ_WdzRX{b_dp_q2L#FD$jt!Os6+ts==gX?@lctxe15ErkUdlOjE4Jd5y_ zV(QeD_fQj!6pZ@vk+b>E&e6_+G_2?wUKY_oni!r!Oo zwWUTVDrv%4tYg`85YQi06TrA6$mD1aahD(Qs zp8DCY5y3u%J52+E0O;N&63HTA8tRLi*cGfwTATYT zc-%Q9B3|SxI}YxQsFyQrUeYawv$bnE_`ICT1(r&kvt)F4kHqvZ)(Svs&lUEsT_b}? zANys_?a2HH0An5y4!+%*=}{%sc$iN{gS(&%2}v6b0w>n$lA32f8BxsQiMCIkwXZ_z z@Ri4#$w##(e?VM>FXY9fDwcbdoFkj;8|WPg@;Vn*tG1mLVRUS7;R}P7zzDFjw>i#% zD6X}()84dZ?_3kt7})8CNdVQv`JQotxwk&*=8wuDM{m-35JZ5HLP%3su#aayy%K95 z%Km&$B3T4G$Bsw^fVuWo6C{6fi^ClJaNe$Yh8{M@Pzq%>fiZeTz z&>BbtLlGpnoWnt$D)t<%$?+9(Gdm!v+q_W8&0X0YCJ{KQv~BQ$ScSigu7+Z31rU%} z^+>I3$hJQKeM;TL&DN4qu9CjD1NTW!PBy(g$Opp`*<6PJpFl;+23>a+)WhviigPIt zRj@T&)0ghcA!M1LsXC6fqaYJ824(#dqLw?_qx!&a@80ajOd12 zk>N(MG0E~x1*epok;V#M&h7LZY%Io}`T=e2zf~kHt(55?+ZU?Ej!!+q`{ketjjjE$ zSZ<7%0No3FVX2>>BMU#*`J9=%{~3f-h}lDBrmhypzv1V0;h(sm%AJf z?bT?>klpOUL+0slBFcyC08cFIE zK)M$tqL=AR02S4%gU(?q%sWi&IAkkeJ}GHS&I{cV^aa^YA_u0`@-45c@|Q<-YB1@undr{(h_b0 zPg@fANq_=CtdFv&ckWp2)gjPdfaM5%l9Zn zayWkh7{HGN0%1_XNrtiMkvIoyxGNJq%P$>DDUxF{sj?QddeD@U9~>!O#FK8g68NN2 zqEdbv73s*)uDDtL*ru%@&uZqUPY(O-nUi&lQ9I+Zy&T+eW~VwvSJP94YAI6(W>}*B zo*Q4#-QYLy(}4@2*URn@;KF2BnXB0to<0z-;DxO|X&!4!`O}nWYPLuyb$6MRcUqAU zA0bklVNzsaUC&Oq*-EaVrno*=FP{`ZN^~UNx;7_pFHH40cT0LR3Cho#Lc!LYOOa}@ zGI>qc!HZHJM?3JSSQS>&A?u#4{eqCV{3z8AeJzA9tJ; z$A5EYD+49?@PVsz_hTEq#=_? zZ*4t@&?{SdA1yO-8ZrW;pWy>$A>`q5(vOjiC~U$jEK@d}ye-om+cmB}S22>VoGS$P zpIrg^O)M$vfy#i3?C#weQ{$EUdql%Bk}d&am^{lQ58{w@UyH2BAhUf)>0MK0<=CTQ z1txjFKTsRMr%g+_Qm^8gOi2Gsjc(6Ek$`o_&`FkT`??paAka{?;7pm(2TaVqi%5vo1s zYkCQnqlJnh^ncg%J~ju8jtwvy)U%UGX-d~IzvqW47)X4nN3O?;u&~elCF2|7NIVoH zu0rOLpy+szvgWEZqPt3Dw8ke>J4ex?b?<^3x!gLAX4^|Z@>|Z16QSXxTvoPSOfa~3 zJi52Lp~Gw66KyF4Db6lGI7{}GxrX}4;D(W3IieqjA<^gAm1l%%PgCG(M zS%?#|`vl$kf}8$b;juP|hyVczFNN*gp&H>gYti|c!{iKU)j}RF=38V0R{#O|PUxpt z<3a5NQjTL}5uuG?H?1CQ7||>r@|+84&DASPot2AJ z2tiDv zSQGkStn9UyZQhgj5V%MMxJbunrBj^iMhH98vAsjwe5c&_`M6lB+C`_-o8r|Bm;0j- z0BJqZTs4vMh908Kq2&XX`(jvjNGFYh!|<2q^S__ZPBy!KzC2HXSSV|+$hyU3pQsln zHEx&CcE{St_6>)GghR5!MU3=5L<9o&Qkmf>6;0kDqai}LqB!DB5WC3Fs3GmLGZgpC z#>ZMUL&KZL7kq=&60>ouMwPPM_`k9iVQ9dO9;=gXUSI8s7Qp_rsG8OI{))C6Y%$0; zee6twEkQ5h^o3B_?5cQC+{CY@DVSUJA6q65$Up`rfOw?};eUWv{^p^p`d{!$Ws(u; z2LE*dRrLtHdC^6La8-yLiPUUVCJDb+*;~d>iQohylMWekgLUlK+@N5l1KZ)5GC+D- z4ohsk(;S(FVaXT@oiB!VP^Zh}#c4&_NZ~TqxL{Xoa zVqyZ0#6|r>x6)$q$OS~~d|w+WdW-UHWnTA!enQYTW9`G2P*sB!_O_?%jHjP1`H-oX z`pWU5O+;~w}cZn<*0GH&p*1mrF zlaljWpP=4B6xDTu%6Y&Br~NGJSrqk&VZU}5zm;J)ToIj}Hl09+nwm{JQ$;nsR5R68 zO{_S#=N(0BVI#9isik8r38cq@lUPs8F&S(@d|Bz)VN_RoptKA(ckf*}!Mf~Jn-^Z- zeBjQghCc{N&?VG9Xhw5sfBYraN6gqKgm|4Wl*##+U~oC}&z z7A@hv&vmOQM@)hN#zVFRE}pSr6A`+D8D^G>$2d0-OQ>VSt%ap-QwSabCt4J#hvE?{ ziJAwXA$l6lhdNiO*n< zA|k(^4rc-nnL6WIIq`TqF|z1ob9J}|cIXEve#BFz8o|1m87Ia_9HVOnrqH!zm`~ka zP$X*Ixn6jiG%;*HGs(Xu9;kf_FI04yMK-qPhApz@MSQ8`Lz>M`9?(lL%x=?Y2#{l` z7>VGmBx})0mAd9u2HOn(*<9$qM+En1>#63RNy{`TP2xopu`bDgX z=}k@4tz}D7NSs5@cx?hP4){jqU)~je?Nqe%YBxx$3ilS+7Ts0`tHiB9d?wpwpIGM( zkp@G0wq})bKQG4~xMG*Bvtxd<44WY$z=~T6duXaHOZ0zKYtWn%v>!-*F5J4SJiUkb z5YOM5SJ{Y(u&QVu+uS`JGSmEq{f{8d))L+&E|8lm`4b2T#(yX;j;2OdMht)b{##(2nrt{88%7uQGk*UX ze)JjchuRL}{gTYeDFtzx#E5)WtVzN`LTaSZ)_>zG2C)`hP zc=!v~@Yy#$jJ608fY@E(+dY&_IB1mN!1fs@%{#l&w&XG?a+1bFb9d4^wL?0L+`QIV zgDcmPL$^-ADcup2gB<*5rE(kf59lvmTM5=QkPeEr#k(#ir_($m;&06Wtc~ zczBOl+1`llV3^W2;C!DTX$Z}KTtnyS&!jw6@W0f$It>2{ReRI$gPG z3Gv%9IR=&-P<|P85vhI$`7^N8d|CO>L|>z_;F8yf6jrV$5X^*syvP(xC={Nk#~`SO zAPPOzRWU`Le!zMizXkCr-J54Yfxwpw#(X7^Y7Z|r19^+MPjSYHH%SE_@%ninx=M!| z9C-40+`gX9FqlLWX7fBR=ei;q*Hk_pzc9SN-z#1M>Mpc-o<^e%INu+#d0)-|3}^f~ z;5uG!x6uc(I$k$V*?inJ-5v;0PLISgsL*WFu+7qn9BgACrsEsmcNu+u01l152IG!9 z(H`cABiu%EkWKrYkk0wLq?Ti_ZY?Z(`d4&yWS{JlmZ?D?E zuz38a39`|c!q#a~9Z<(V95ZP97H`edC(B3-tuHf8plXygb|gYdt%P4t|I;vqqP7KR zvU>oblvP*hr=N&@On1rW!a~uIr(VbLo&@_Ad8(R)#uZcJBi=|jvkDd70!c_J75kPM zU=>}c;EH7h!BEn^GJ{I=1i7!~gS5D*e=6B0EVK#*S0q@LI(WUAnrhR7{ia&EWD%vk zXK=<3|Goz}(QlhX0`de!f?W~kfnx6IOcQ1Ry1A1*O$LftC|J7n?`Z0uC>RA#cHpC& zOfVJvwa>$(KULg&qn@;flrKQVrSjO405toOjRo1yIMLmN6DAzLoL#kB3!<55QDVT0 zeWZ_mGtxvLl7&lYRUYRX0Q<^s`^7;E8GJ-#&HPS+-6jNkbQR8530cdC38pCV8aycw|*`6b4V?Z0$KY**fN-+5@uJ@|*M-Unk=ZMP&g zZdxe0cWxFVzNK*;0th9GLdYtf29`*lxP|t^n;0cKuP7+!qL-5e(^N`0p;Z%W-O&}x zY`oFIt8d5sjXmeh9G@p7i)QeY+XcF`jvywyjHVIP{bz_SS2JgXpg+@811uo49hNGY zEd=DQ(yV2=)=TQ!-8&8%+|P0V9?h2x8E$TL>t(KI??CkUpLQ@HP5oa7F-Wor#y~01 zHRsO>Tx&oKZ4Bh>ZEPKYD~XepzO|m2CB3<=k;%u>#}){Rq^N`_2q-8hh%WF4Z4a0m$SaPaVmNN6aCNT^8g@F-X)sOT7&n3xF2 z*f>}iIA|D{7=Qi=C^+yl5RkBtkgynt@Q4`y%g0AI2r3Ln3@8XVC3g1#5aR6=p8UnDp)aVBxT^ad1D8Q&3V-e_>`}Wn<^y6cQE@6%&_` zR8&${QT?H&ZeVC+Y+`C=?%?R;?BeR??jH~s6dV#778jq8n3SB7nwFcFUr<<7TvA$F zSKrXs)ZEhA+t)uZI5a#mIy*PNun1UMUfJH+-TS?NaCmflb$xStcmMGC^!!JzKXU%( z@i)Q#Z*rjmD!HE@+fJ=S4sl<^?Z_ zMcP2*LIhT*LBSFB@pK*9gq!tsYsS4oGv@T6w9pDm(QU+AzFUiXR=No0?|0hA%$+u! zFrCYQN5$S1-a0#iNP;?^jhf1_qTI46GGa`Fx{R7}w~^Jw+JMjNxk~xDl~Z!L&4rH> zTg5*$v#`_q(|)?Y$TSAcjg!IqwFM9uvp(gc2pa|wMR8P04Qw_f_sPO)q#}oqEPUco z*px`61&tp`lM3{0Vq1S()}Q=!4#)X9V$F0uUP9!UlD$HMCoJsd>7DnLyK#P1HhCb; zU7NggV+@{SoROKtDNcsZxdL|$-hijpwIF);pl|W=Zln2~cJ8dcO{$=_Iqhhi0(aSk z%(@bs=39&^X^be7)UwjM>H{>lN9G%5@YV+i-k~<%EKh>?d&9IgN7V%wS4 z7+f5?L|tUk#pWr*S94ynN0#kqg35H0q7M)&DI>zAss=)O_Rbmm7+vY#_~Y=eW%V|e z^r{^2%TpFkO%u^+JX5l{%^t{+@8ApEY9Aml14UtuCy_2^3QOtidn4Fiv2KVc@r3gX zvKhFl^LIZ3_%0vr{Vw0zEFyR$Kmz5 zZqK%8`p_Yt#!-vGhUpc#VQZRCt|)N!>S_71*BChzu`)Fn_h5$>=Fy-U;QE#zZ%MR| zIO@4{!PqCEH&+!QufN#0ULFYx`vl&yLNqw9Hps4#zt2d9csgbxv~R7E-PAXXiGdBs zJ@|SJoW?3ub9LGh#_Mi&!%{_=xw3zG)J}meMaFYHZc}PYY*0W#NlTS-PRTT*g>Yzy zM7czSDW*b>Rqt$g0;Abkbt&l7gYA@hTJd-%|2LZEXB*fU)-`*4zEVB&1Y=5cWoY}2 zH9N-pwPq}J?o4h(0u5jxf1|M0-^hzdwkHw}wUMk~s8PCD5J>u2Uo78}w1`G?IO(do z)Mcu|!nS5=yR2L*FWZboVM>^_Y+USGh3;4q)=U3u8bNI-xOLJGQVV;2KI^@7EtD;r zjV(14wEy`^9|9pLe?{go-RxB!H(cN0Kk3~-)HEZnSwF~}5yy0nmB^?sZgS<#dn2gV zLZ1mnqn&)={lee_8Lj45h#_K z#I5IF59^;Qv4Mr@-1AP&>%>13-d{Q6+;BJJ-FV(s#1mBn9{d#d4(#iw^|)_so`9eE zqwkj~og!s#7UCDR&r0E@kUs+amtRIt{4O_y`Y5MZ>MlQ|4`%GQovsg4TpKMIDB;7G z1$|uTvIg&hEL1UM@)a`P=69c3q)^Hp=cY~Vk|0uNNe^l=bLR_qRkO->?RQ?F7?Un4I-2WMP1ENC4mS+rU(3M ztYCCtVQ2&O`^7ry^pvN*7nebvdqU* z{vmW+{VY|Rrypesg@Y}A)YuLtO&b|0h@J$8g0=O_9F{tHh@#{fBKn)@&(_kzV+Yde z2NRY={Zc4m1TzZKe+YBAGZQ#Owh_vAb39KnI+N%4?Bn!pm0H~=+&NjL6RHU8?0)x{ z%~#z!cu*x^Qfd3Jx@9=z!c#PB$iAkbMQUl&&zU(cpKtQ0cQi#m_%>#-mVV^NRvCvK znr+CIwc`}QdsB^j&2ffoJ>?IBwLVCeamNw}Mk>w76LW8s#Avo-HIUD4OqAn3EVn-= z93(I>z>@UMIak{E$_r20`laQ}%a=}@!qk@UHmc)8o|ETItoA0K?)8yK8C&?(Z0+ft zHeyYwoHlG|IHC(>H&bPPblUh{MuH}PVh0K_IR2_T|i zD|~&{x{QU6Z2h_TFQMrJcCKtE9=2rq%waLB(!-P(My2qbG$L_Rw`f**LbfE~Jk)Yi zG)lB$8f!R}{<#?iF&)Wl>TqqV7x>&d#8P5j>xRWL=Hl0LIV1cp@!gDBT!#$2y>C(PzY@D zqfI_(XHzTeTtM)VMosBk_1%i-R_c=mH-}8`*ts$iU+f+f(1PeDjg*XUyKlB{@Rh&% zE$X{du|_%atw4S*jxv|&kaQ~R%>?b% z9Rt4&Tau=$HMOg(b?^{dqg#|`t7^Pu10Lss$bRx;wNcSJxAlJ0a(Kn=kFP7V^WEgL zvXc8Y)8`55E%LRAmPdjF+uG87J`#?n9~-AYjpO zzxLzx=5-$qMAF(N-4A7BLT**7??)+&hI`xc2so^@BMg4fTZUXWbhFJVoq_Rnjgm|# z_UdwKO!X^RR>F6#Z&D5CEqh!kUVXOckMDO0X8l78rdeN^YeoINK7-V5^L$9E2RBUw z^@RYVbK6h@qQ$pqRI_3W zK19Eq{5A4xtA1)bUR`~spi$9CUF-d`D)FnYuB z@@l2(`Itn57nMQ-BFgE6VTl_nH@6HCv{O9P9*r1TZ-pz)rP09m>E=e zcP08X3E2AacwCuQEvb2CR9s3K*(B~TcBA-hg<1xG`WNORqaRfZ27JvbLY1lr`cGza zE#up&B5Syf1@3L}k}d7u^};1(Yt}x*f$i~iZ~Ra)7Z+-w5)*J-kz%9;aaO|>T8t6v zlfh4Rcnu8}V2gfqtIO5K86(4%T3W*WhI*r_bZORp-QwYdHcv~3WvJ8&ue~m2hFg!g z56MnUD5Sp1=<)eBwa{r5D&B`{VadT+f*d~ARy)gPT}OylX-l$_ zUq^nvitUOWcY|nZlrM2mj#LC#YO&{ryi8&%H{W&@7uG{?t&z6C+CpnJ{fUCUEm_U~ zXsU^bONVBw3NV(v&ADrlmDrf>8L&!gDyGodU&%S*e;;zjc&)s<`7-0`2qM}eYtxDL zw8S+>s}BX~tck1T&_E9MhvVmDHKwW5CV1))My;Z9VFl*ZeLN<$p=Z+rV8W+@*p@$#gzLv=GsQa^sKm&GZ?=8D=R3o$5ozj zAd|pk+$XAewK(un_^a{~rcY)L4wq?(CRLkxKnS;8kbF;EQ+(wHVDY}yVeU+;)y1F5 z8ifs)=P6T%&@7!Hw}s+`eO6`igOA_%E9xka~ z@>FnEAi{7)9=4Z+MyEW4 zWmmlnSi?;!@LU<=!Qmf+Bcqfe6@ErI=;dI@$*2isr{2S7`@i!@?hdOdVPTVja6mxl z2jCDOlTn0bFtGf=4lMovD?EEKsogBW?t5!I+#a?zVd_woCSJlirZu9Q%RP2sn1iC& z*Bs#Y%AgX8wcOdtsUjmaz7lq@aFyvst_lcb!dcwcW7ZRdS| zZo^m0mzx;ENMZ!lR%sdh6AcV+7}WO`ZLfx%B%Dc|%p=xMW@gh?BdD!7O*k0)Vd%Wt z?Az;}#Vk`bimjIMEag2xKel%yx814-NDTA!hwfaHn@S-GXr5LS6ECXXExJr3FHpRB zy)W$D3kn@yR|@S9E0Bi}(pW9E$Ff6SMC_Q4n01KeX=4N6$!;DA5f>64xfZF;dxxh? zUQ`Y0dFXoPCvQiIj-tw!a-ICL`x9zi9D|Rgm`2~!15Wmo&LRg*6q}3;i5%Y(Ti%4w zb2PFLZzUrIi8O((^u=ZIgmbU;?drJ8jg_ILHt&Wbii9OHAsq8-Ld%qt=d%!e%?s>e-u?GhoD7!1Eh3zb^}%7h_#=uHMP$rIrZ;%A7U&yF@bbJ# zML%y6JrlJWPGHl}=oWdiGpU@p&RxY=C@O5QdA-zoz|ZZjWz6J)w?uX^2Gz?k3a+Xl z*{7rtN}cc;m_xghuGBa_#z?GvXi0h%1EM7x*OhMCgsk-E6LG~|eDRQLbRv|*Z|ff9 zx3lC6T@J{%u^jItb8^F=aCKL|GVVR-t9)zyHcm?M`Bl)Ci8H` z!Ewydvg}R~K7nV&M25Jds;6@vnf5|YrbU7SPMWjxwGdmmlq!kmw`Z5W-@Q3%TTPg* zhw$!?VGj60`)KMJ&cLH&sBrFmhSajgthb*-EakEEy#!hvH9ibh=WMfc`duxN1VlgF zxOHOfEBAoo#g)MEVq(xqjDMGkjU60*w~Qeb8-wj7=-YxNUMCVV7;i^FV0Tn2noBl^ie0r<*rPWyz;I zNOog2VEN}D4Jz6v)>y>L*<5mGBFkV9kFCkCGz;mfHA|*++N_cs_yzm{>GJ#gH!GW)`&T^I}}y7feXuDbb~rTn}%(xuXGPzwohUbv7zMaCSHbw_{qA>YeRk zMZpzTddz!almX=0iryH8&@rzQ?vYP2@C6Y=(X-31&LlE055FeS7UXu;bsbIfcwNWk zNhQPLA^7qV`^!pP9X;Qa!RDMer^UzdT@E}Zb?+ha`g+wL7J2L*cn^~Tn;DusFdV( zh(D1<+BuQ!Qi&PfNHloKPu#P7Iff2yu@j83lIW$C(^fu5xP0C{Vm3|sww;~7X8J~A ztckPbGR{vA)^qanlHW6QaSbLxn|kt4#9}2d~K227dOQf8JM8()ZFp zEyEz7tk11HB%wH~#mYu*I-qZ)zNsF51y9AIX#y+m`iGSSp6M4FSw!{5Kkjw3@J>5v zIN?CAFTAm8_2-#sq3j}=yW>iV^$tNnB3VF0#NN+NddAPh2BSmDWSA_9e<^H&q+Bt? z%nrIB(0RQb&YwCI{iKSdK*+id(@`V#7CfMAFkR*XCk)!|u4s(|_6}C&DU!X4MTg14 zD5ox7iapyOe8TtZ{cjN!Ts|SoO#y!Lb|B$|_ZF9ydq*3{wBslne&tbcyOi=bE_71M zL{MkPDL3uxZnw>x!E?Ps$(;|K(N5i}k_y+`kRX=zHfOUB&@{3}<)%+`OFnQY{ zn>63sjNT>B!X@=>ZFvUPrtM~sFT|bYmQxfZ#dkX~-NQsIu)Jy^IG& zuQ>5hG~fm?pg{kva0hWBfa0PTj_-JFJ%|$kj_e4#4%GGi94Qx9mFvJhe3{z?syt@5O}4F3Do7_bAzE|&IoM-F1Bvo&M^FayefKK(v3i7dS|e_*H> zRIO5Yu)+QScq6|B=r_>W`^qxif!6KCO8%oys0^KFnoCRog9(@o4>B^(qhaigdQ?V# zv}fRNgJuZK&%g6nBFi?*VFp@+dUvqUJb)ksdiEfK3&^Befgj0A7=ult40w4Tbtwqr=(6$9Zshsy1kV6C*p$8d05@;BE6D(?f zoYUZNC;%9+Lt|7-3JqgV_fQ$M>RutmKwCV3@pVv+b24Zcd(#0bLsf^8rXFC_9qLmI zc{Gf@848s#P1Not0kj48(C}DSJj~d$hNuYCgyKk5F;zK?Kr01mE@UKP;pSlk+73lc zJc~p?H4Y=t_9tqpO(cRu=P&~8&_GShheR;y?L+)?|8-vk=0CqW+MpjzzMy{`^3k?^ zKlyhWJ!IiBI1c$QPR-G10mEaV|2O?1W^^3%(T?4Ip@CU;Uy-_V9P-hA%F$#w5-G}>Uy4b_*nYBjXG)!R3why=kGYQ)(AD4A`&Nj@9#LYW(76g84~yD z!QXLc4IOF}CL}H?rlejaMb2PCd5^6xnGzC7whb0jZ2`tLln zz6$CMPbALo#ouv%-nCIR4)u~4lJ_|24-fUq*dGGm_3f3zcLR`w4{1l<6hIXNbq5*= zDKGyc#)184)as~Pp~&jim4B)q*ce5vj=CX-tj=8hpH4WqJ% Date: Sun, 30 Oct 2016 21:21:53 -0600 Subject: [PATCH 017/325] fix ll_cat function --- data_util/fll_cat.f90 | 73 ++++++++++++++++++++++++++---------------- data_util/fll_read.f90 | 2 +- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 7d3f645..b63107c 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -64,8 +64,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) ! ! BODY OF SUBROUTINE ! - - POS = 0 + POS = 1 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' CAT - null node ' @@ -106,6 +105,7 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) ! ! IF NODE HAS CHILDREN ! + POS = POS + 1 PCURR => PNODE ! ! IF CHILDREN, PRINT THEM TOO @@ -123,6 +123,8 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) PCURR => PNEXT END DO + POS = POS - 1 + FPAR%SUCCESS = .TRUE. RETURN @@ -142,53 +144,62 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) INTEGER :: IOUNIT INTEGER(LINT) :: POS,I,J,NDIM,NSIZE LOGICAL :: SAVED + CHARACTER*2048 :: TEXT + CHARACTER(2*POS) SPACE SAVED = .FALSE. NDIM = 3 NSIZE = 3 - - POS = POS + 1 + SPACE(:) = ' ' ! -! 1D ARRAYS +! HEADERS ! IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN -! WRITE(IOUNIT, *, FORMAT = 100)PNODE%LTYPE, PNODE%LNAME, PNODE%NDIM - WRITE(IOUNIT, *)TRIM(PNODE%LTYPE),' ', TRIM(PNODE%LNAME),' ', PNODE%NDIM + WRITE(TEXT,*)"-",TRIM(PNODE%LTYPE),"-",SPACE,TRIM(PNODE%LNAME),' ', PNODE%NDIM + WRITE(IOUNIT, *)TRIM(TEXT) ELSE -! WRITE(IOUNIT, *, FORMAT = 110)PNODE%LTYPE, PNODE%LNAME, PNODE%NDIM, PNODE%NSIZE - WRITE(IOUNIT, *)TRIM(PNODE%LTYPE),' ', TRIM(PNODE%LNAME),' ', PNODE%NDIM, PNODE%NSIZE + WRITE(TEXT,*)"-",TRIM(PNODE%LTYPE),"- ",SPACE,TRIM(PNODE%LNAME),' ', PNODE%NDIM + WRITE(IOUNIT, *)TRIM(TEXT) END IF ! ! 1 D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - WRITE(IOUNIT, *)(PNODE%R1(I), I = 1,NDIM) + WRITE(TEXT,*)" ",SPACE,(PNODE%R1(I), I = 1,MAX(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN - WRITE(IOUNIT, *)(PNODE%D1(I), I = 1,NDIM) + WRITE(TEXT,*)" ",SPACE,(PNODE%D1(I), I = 1,MAX(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN - WRITE(IOUNIT, *)(PNODE%I1(I), I = 1,NDIM) + WRITE(TEXT,*)" ",SPACE,(PNODE%I1(I), I = 1,MAX(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN - WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) + WRITE(TEXT,*)" ",SPACE,(PNODE%L1(I), I = 1,MAX(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ! ! 2D ARRAYS ! ELSE IF(ASSOCIATED(PNODE%R2))THEN - WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + WRITE(TEXT,*)" ",SPACE,((PNODE%R2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN - WRITE(IOUNIT, *)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(TEXT,*)" ",SPACE,((PNODE%D2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN - WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(TEXT,*)" ",SPACE,((PNODE%I2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN - WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + WRITE(TEXT,*)" ",SPACE,((PNODE%L2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT) + SAVED = .TRUE. END IF ! ! CHECK IF NODE IS CONSTANT @@ -196,23 +207,29 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) IF(.NOT.SAVED)THEN SELECT CASE(PNODE%LTYPE) CASE('R') - WRITE(IOUNIT, *)PNODE%R0 + WRITE(TEXT,*)" ",SPACE,PNODE%R0 + WRITE(IOUNIT, *)TRIM(TEXT) CASE('D') - WRITE(IOUNIT, *)PNODE%D0 - CASE('I') - WRITE(IOUNIT, *)PNODE%I0 + WRITE(TEXT,*)" ",SPACE,PNODE%D0 + WRITE(IOUNIT, *)TRIM(TEXT) + CASE('I') + WRITE(TEXT,*)" ",SPACE,PNODE%I0 + WRITE(IOUNIT, *)TRIM(TEXT) CASE('L') - WRITE(IOUNIT, *)PNODE%L0 + WRITE(TEXT,*)" ",SPACE,PNODE%L0 + WRITE(IOUNIT, *)TRIM(TEXT) + CASE('S') + WRITE(TEXT,*)" ",SPACE,PNODE%S + WRITE(IOUNIT, *)TRIM(TEXT) CASE DEFAULT END SELECT END IF - - POS = POS - 1 + RETURN -!100 FORMAT('-',A,) - END SUBROUTINE FLL_PRINT + + END SUBROUTINE FLL_PRINT END MODULE FLL_CAT_M diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 42ddad9..182bb3c 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -251,7 +251,7 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) IIND =IIND + 1 IF(IIND > 254)RETURN END DO - NAME = TRIM_LINE(ISTART:IIND) + NAME = TRIM_LINE(ISTART:IIND) DO WHILE(TRIM_LINE(IIND:IIND) == ' ') IIND =IIND + 1 From fb54473fd69431c32978168ce36b3bc29ba86da7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 30 Oct 2016 21:22:23 -0600 Subject: [PATCH 018/325] add to examples --- examples/TEST | 15 +++++++++++++++ examples/TEST1 | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 examples/TEST create mode 100644 examples/TEST1 diff --git a/examples/TEST b/examples/TEST new file mode 100644 index 0000000..582ef92 --- /dev/null +++ b/examples/TEST @@ -0,0 +1,15 @@ +TEST_DIR DIR 3 + TEST_Subdir DIR 3 + pressure D 10 1 + 1 2 3 4 5 6 7 8 9 10 + density D 5 1 + 3 4 5 6 7 + TEST_Subdir_Subdir DIR 1 + index L 4 1 + 1 2 3 4 + TEST_Subdir DIR 1 + volumes D 10 1 + 4 3 2 1 5 6 7 8 9 1 + TEST_Subdir DIR 1 + times D 1 1 + 1 diff --git a/examples/TEST1 b/examples/TEST1 new file mode 100644 index 0000000..b27c5db --- /dev/null +++ b/examples/TEST1 @@ -0,0 +1,17 @@ +TEST1_DIR DIR 3 + TEST1_Subdir DIR 3 + pressure D 10 1 + 1 2 3 4 5 6 7 8 9 10 + density D 5 1 + 3 4 5 6 7 + TEST1_Subdir_Subdir DIR 1 + index L 4 1 + 1 2 3 4 + TEST1_Subdir DIR 1 + volumes D 10 1 + 4 3 2 1 5 6 7 8 9 1 + TEST1_Subdir DIR 2 + times D 1 1 + 1 + some_name S 1 1 + Text-name From 17f12d8f1ef9d107ab8a7a1331d607d50d2249d4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 30 Oct 2016 21:28:04 -0600 Subject: [PATCH 019/325] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9e32f96..446799e 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ # fll is a fortran linked list library + +The library creates, modifies, removes, saves and read from file a multi-level linked list. + +[![Analytics](https://ga-beacon.appspot.com/UA-86532469-1/libm3l/fll)](https://github.com/igrigorik/ga-beacon) From 5604dab2511f099e8887691068c1ab14634d4a5e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Nov 2016 19:05:02 -0600 Subject: [PATCH 020/325] bug fixes --- data_util/fll_cat.f90 | 154 ++++++---- data_util/fll_duplicate.f90 | 44 ++- data_util/fll_getndata.f90 | 111 +++++-- data_util/fll_locate.f90 | 38 ++- data_util/fll_mk.f90 | 23 +- data_util/fll_mods.f90 | 2 + data_util/fll_read.f90 | 41 ++- data_util/fll_read_ffa.f90 | 590 ++++++++++++++++++++++++++++++++++++ data_util/fll_type.f90 | 12 +- data_util/fll_write.f90 | 39 ++- data_util/fll_write_ffa.f90 | 435 ++++++++++++++++++++++++++ data_util/project.dep | 113 +++---- examples/fll_test.f90 | 19 +- 13 files changed, 1451 insertions(+), 170 deletions(-) create mode 100644 data_util/fll_read_ffa.f90 create mode 100644 data_util/fll_write_ffa.f90 diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index b63107c..f1cae60 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -144,88 +144,122 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) INTEGER :: IOUNIT INTEGER(LINT) :: POS,I,J,NDIM,NSIZE LOGICAL :: SAVED - CHARACTER*2048 :: TEXT - CHARACTER(2*POS) SPACE + CHARACTER*2048 :: TEXT,TEXT1 + CHARACTER*72 :: NDSTR,NSSTR + CHARACTER(3*POS) SPACE SAVED = .FALSE. - NDIM = 3 - NSIZE = 3 + NDIM = PNODE%NDIM + NSIZE = PNODE%NSIZE SPACE(:) = ' ' ! ! HEADERS ! - IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN - WRITE(TEXT,*)"-",TRIM(PNODE%LTYPE),"-",SPACE,TRIM(PNODE%LNAME),' ', PNODE%NDIM - WRITE(IOUNIT, *)TRIM(TEXT) + WRITE(NDSTR,'(I10)')PNODE%NDIM + WRITE(NSSTR,'(I10)')PNODE%NSIZE + + IF(TRIM(PNODE%LTYPE) == 'DIR')THEN + WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),' ',SPACE,TRIM(PNODE%LNAME) + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN + WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),' ',SPACE,TRIM(PNODE%LNAME) + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN ELSE - WRITE(TEXT,*)"-",TRIM(PNODE%LTYPE),"- ",SPACE,TRIM(PNODE%LNAME),' ', PNODE%NDIM - WRITE(IOUNIT, *)TRIM(TEXT) + WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'x',TRIM(ADJUSTL(NSSTR)),' ',SPACE,TRIM(PNODE%LNAME) END IF ! ! 1 D ARRAYS ! - IF(ASSOCIATED(PNODE%R1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%R1(I), I = 1,MAX(NDIM,3_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%D1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%D1(I), I = 1,MAX(NDIM,3_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%I1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%I1(I), I = 1,MAX(NDIM,3_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%L1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%L1(I), I = 1,MAX(NDIM,3_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. + IF(ASSOCIATED(PNODE%R1))THEN + WRITE(TEXT,*)" ",SPACE,(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + WRITE(TEXT,*)" ",(PNODE%D1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + WRITE(TEXT,*)" ",SPACE,(PNODE%I1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + WRITE(TEXT,*)" ",SPACE,(PNODE%L1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S1))THEN + WRITE(TEXT,*)" ",SPACE,(PNODE%S1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. ! ! 2D ARRAYS ! - ELSE IF(ASSOCIATED(PNODE%R2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%R2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%D2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%D2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%I2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%I2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - ELSE IF(ASSOCIATED(PNODE%L2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%L2(I,J), J = 1,MAX(NSIZE,2_LINT)), I=1,MAX(NDIM,2_LINT)) - WRITE(IOUNIT, *)TRIM(TEXT) - SAVED = .TRUE. - END IF + ELSE IF(ASSOCIATED(PNODE%R2))THEN + WRITE(TEXT,*)" ",SPACE,((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + WRITE(TEXT,*)" ",SPACE,((PNODE%D2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + WRITE(TEXT,*)" ",SPACE,((PNODE%I2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + WRITE(TEXT,*)" ",SPACE,((PNODE%L2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S2))THEN + WRITE(TEXT,*)" ",SPACE,((PNODE%S2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + SAVED = .TRUE. + END IF ! ! CHECK IF NODE IS CONSTANT ! - IF(.NOT.SAVED)THEN - SELECT CASE(PNODE%LTYPE) - CASE('R') - WRITE(TEXT,*)" ",SPACE,PNODE%R0 - WRITE(IOUNIT, *)TRIM(TEXT) - CASE('D') - WRITE(TEXT,*)" ",SPACE,PNODE%D0 - WRITE(IOUNIT, *)TRIM(TEXT) - CASE('I') - WRITE(TEXT,*)" ",SPACE,PNODE%I0 - WRITE(IOUNIT, *)TRIM(TEXT) - CASE('L') - WRITE(TEXT,*)" ",SPACE,PNODE%L0 - WRITE(IOUNIT, *)TRIM(TEXT) - CASE('S') - WRITE(TEXT,*)" ",SPACE,PNODE%S - WRITE(IOUNIT, *)TRIM(TEXT) + IF(.NOT.SAVED)THEN + IF(NDIM /= 0 .AND. NSIZE /= 0)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(TEXT,*)" ",SPACE,PNODE%R0 + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + CASE('D') + WRITE(TEXT,*)" ",SPACE,PNODE%D0 + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + CASE('I') + WRITE(TEXT,*)" ",SPACE,PNODE%I0 + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + CASE('L') + WRITE(TEXT,*)" ",SPACE,PNODE%L0 + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + CASE('S') + WRITE(TEXT,*)" ",SPACE,PNODE%S + WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) + CASE DEFAULT + + END SELECT + ELSE + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT, *)TRIM(TEXT1) + CASE('D') + WRITE(IOUNIT, *)TRIM(TEXT1) + CASE('I') + WRITE(IOUNIT, *)TRIM(TEXT1) + CASE('L') + WRITE(IOUNIT, *)TRIM(TEXT1) + CASE('S') + WRITE(IOUNIT, *)TRIM(TEXT1) CASE DEFAULT - + END SELECT + END IF + END IF RETURN diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 18c1ee1..0f8ecb9 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -301,7 +301,27 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) RETURN END IF - END IF + END IF + + IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%S1))THEN + NNDIM = SIZE(PNEW%S1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%S1 = PNODE%S1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF ! ! 2D ARRAYS ! @@ -392,6 +412,28 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) RETURN END IF END IF + + IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%L2))THEN + NNDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW%S2 = PNODE%S2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF ! ! SCALARS AND STATICALLY DEFINED ARRAYS ! diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 1c366fe..82babd2 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -74,7 +74,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -116,7 +116,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -156,7 +156,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -198,7 +198,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -240,7 +240,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -281,7 +281,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -323,7 +323,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -365,7 +365,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -405,7 +405,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -447,7 +447,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -489,7 +489,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -529,7 +529,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -543,10 +543,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - - - - FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) USE FLL_TYPE_M USE FLL_LOCATE_M @@ -572,7 +569,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -586,4 +583,84 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S +FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + STRING = PNODE%S + RETURN + + END FUNCTION FLL_GETNDATA_S1 + + FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + + USE FLL_TYPE_M + USE FLL_LOCATE_M + + IMPLICIT NONE +! +! FUNCTION FIND NODES WITH SPECIFIED NAME +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PFIND + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER + LOGICAL :: RECURSE + CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:,:) +! +! LOCAL TYPES +! + IF(.NOT.ASSOCIATED(PNODE))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + STOP + RETURN + END IF + + PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + + IF(.NOT.ASSOCIATED(PFIND))THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + STOP + RETURN + END IF + + STRING = PNODE%S + RETURN + + END FUNCTION FLL_GETNDATA_S2 + END MODULE FLL_GETNDATA_M diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index b749d81..df01322 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -46,7 +46,7 @@ MODULE FLL_LOCATE_M CONTAINS - RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND) + RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESULT(PFIND) USE FLL_TYPE_M USE FLL_FUNC_PRT_M @@ -59,14 +59,14 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LINT) :: NUMBER + INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LINT) :: LOCNUM,I + INTEGER(LINT) :: LOCNUM,I, NDIM, NSIZE ! ! BODY OF FUNCTION ! @@ -98,7 +98,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - PFIND => FLL_LOCATE(PCHLD,NAME,1_LINT,LTYPE,RECURSE,FPAR) + PFIND => FLL_LOCATE(PCHLD,NAME,1_LINT,LTYPE,DATADIM,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN @@ -110,9 +110,39 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,RECURSE,FPAR) RESULT(PFIND IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(PCURR%LNAME) == '*') .AND. & (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN + NDIM = PCURR%NDIM + NSIZE = PCURR%NSIZE + IF(LOCNUM == NUMBER)THEN + SELECT CASE(DATADIM) + CASE(0) + IF(NDIM == 1 .AND. NSIZE == 1)THEN + PFIND => PCURR + FPAR%SUCCESS = .TRUE. + RETURN + ELSE + LOCNUM = LOCNUM -1 + END IF + CASE(1) + IF(NDIM > 1 .OR. NSIZE > 1)THEN + PFIND => PCURR + FPAR%SUCCESS = .TRUE. + RETURN + ELSE + LOCNUM = LOCNUM -1 + END IF + CASE(2) + IF(NDIM > 1 .AND. NSIZE > 1)THEN + PFIND => PCURR + FPAR%SUCCESS = .TRUE. + RETURN + ELSE + LOCNUM = LOCNUM -1 + END IF + CASE DEFAULT PFIND => PCURR RETURN + END SELECT ELSE LOCNUM = LOCNUM + 1 END IF diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index 1a07d8f..fba1599 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -82,6 +82,9 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:82 ' PNEW%LNAME = TRIM(NAME) PNEW%LTYPE = LTYPE + PNEW%NDIM = 0 + PNEW%NSIZE = 0 + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN PNEW%NDIM = 0 PNEW%NSIZE = 0 @@ -98,8 +101,10 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) PNEW%PLINK => NULL() IF(NDIM < 1 .OR. NSIZE < 1)THEN - WRITE(*,*)' WRONG DIMENSIONS ' - STOP + WRITE(FPAR%MESG,'(A,A,I5,I5)')' Wrong dimensions for node ',TRIM(NAME), NDIM, NSIZE +! WRITE(*,*)' MK WRONG DIMENSIONS ',TRIM(NAME), NDIM, NSIZE +! STOP + RETURN END IF ! ! ALLOCATE ARRAYS @@ -173,6 +178,20 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) CASE('S') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + ALLOCATE(PNEW%S1(NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:156 ' + END IF + ELSE + IF(NSIZE == 1)THEN + ALLOCATE(PNEW%S1(NDIM), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:161 ' + ELSE + ALLOCATE(PNEW%S2(NDIM,NSIZE), STAT=ISTAT) + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:164 ' + END IF + END IF CASE('C') diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 99e24aa..5862602 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -11,11 +11,13 @@ MODULE FLL_MODS_M USE FLL_MV_M USE FLL_NNODES_M USE FLL_READ_M + USE FLL_READ_FFA_M USE FLL_RM_M USE FLL_STICH_M USE FLL_SWEEP_M USE FLL_TYPE_M USE FLL_WRITE_M + USE FLL_WRITE_FFA_M USE FLL_GETNDATA_M END MODULE FLL_MODS_M diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 182bb3c..420a7f1 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -150,12 +150,6 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H) -! write(*,*)name -! write(*,*)ltype -! write(*,*)ndim -! write(*,*)nsize -! write(*,*)FPAR_H%SUCCESS - IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' FPAR%SUCCESS = .FALSE. @@ -299,12 +293,6 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) IF(IIND > 254)RETURN END DO READ(TRIM_LINE(ISTART:IIND),'(I30)',IOSTAT=IOSTAT) NSIZE - - DO WHILE(TRIM_LINE(IIND:IIND) == ' ') - IIND =IIND + 1 - IF(IIND > 254)RETURN - END DO - ISTART = IIND FPAR%SUCCESS = .TRUE. RETURN @@ -413,8 +401,21 @@ SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END IF + CASE('S') - READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF CASE('C') @@ -524,7 +525,19 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('S') - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%S + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF CASE('C') diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 new file mode 100644 index 0000000..51890dc --- /dev/null +++ b/data_util/fll_read_ffa.f90 @@ -0,0 +1,590 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine FLL_READ_FFA +! +! Date: 2016-10-10 +! +! +! +! +! Description: reads a ffa file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_READ_FFA_M +CONTAINS + + FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + + USE FLL_TYPE_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! LOCAL TYPES +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS + + + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! DETERMINE RORMAT' +! + SELECT CASE(FMT) + CASE('A','a') + FMT_LOC = 'A' + CASE('B','b') + FMT_LOC = 'B' + CASE('U','u','*') + FMT_LOC = 'U' + CASE DEFAULT + WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END SELECT +! +! OPEN THE FILE +! + SELECT CASE(FMT_LOC) + CASE('B') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + CASE('A') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& + IOSTAT=ISTAT, ACTION = 'READ') + END SELECT + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! READ INITIAL NODE +! + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,FPAR) + + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + END IF + + RETURN + + END FUNCTION FLL_READ_FFA +! +! READS NODE +! + RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) + + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + + IMPLICIT NONE + + INTEGER(LINT), INTENT(OUT) :: POS + TYPE(DNODE), POINTER :: PNODE,PNEW + CHARACTER :: FMT + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + + INTEGER(LINT) :: NLINK + + TYPE(FUNC_DATA_SET) :: FPAR_H + CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + INTEGER(LINT) :: NDIM, NSIZE,NNODES + LOGICAL :: OK,EXTRALINE +! +! READ HEADER +! + CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR_H) + + IF(.NOT.FPAR_H%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' Read - error reading header ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + ELSE + PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) + END IF + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + + IF(EXTRALINE)THEN + PNODE%NLINK = NLINK + write(*,*)'reading extra line for node ',PNODE%LNAME + READ(IOUNIT,*)PNODE%S + end if + DO NNODES = 1,NDIM + PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) + IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' +! +! ATTACH TO PNODE +! + OK = FLL_MV(PNEW,PNODE,FPAR) + IF(.NOT.OK) STOP' ERROR MV' + + END DO + ELSE +! +! READ DATA +! + SELECT CASE(FMT) + CASE('A') + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CASE('B') + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END SELECT + + END IF + + RETURN + + END FUNCTION READ_NODE_FFA +! +! READ HEADER OR EACH NODE +! + SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR) + + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE + + INTEGER(LINT) :: POS + CHARACTER :: FMT + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + + CHARACTER(*) :: LTYPE + CHARACTER(*) :: NAME + INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT + CHARACTER*255 :: TEXT_LINE,TRIM_LINE + INTEGER :: IOSTAT + LOGICAL :: OK,EXTRALINE + + EXTRALINE = .FALSE. + + + SELECT CASE(FMT) + CASE('A') + TEXT_LINE(1:1) = '*' + DO WHILE(TEXT_LINE(1:1)=='*') ! IGNORE COMMENT TEXT_LINE + READ(IOUNIT,'(A256)',IOSTAT=IOSTAT) TEXT_LINE + OK = TEST_IOSTAT(IOSTAT,FPAR) + IF(.NOT.OK) RETURN + END DO + + TRIM_LINE = TRIM(TEXT_LINE) +! +! GET NAME +! + IIND = 1 + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND + + DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + NAME = TRIM(TRIM_LINE(ISTART:IIND-1)) + IIND = IIND + 1 + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET TYPE +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + LTYPE = TRIM(TRIM_LINE(ISTART:IIND-1)) + IIND = IIND + 1 + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET NSIZE +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + + READ(TRIM_LINE(ISTART:IIND-1),'(I30)',IOSTAT=IOSTAT) NSIZE + IIND = IIND + 1 + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET NDIM +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + READ(TRIM_LINE(ISTART:IIND-1),'(I30)',IOSTAT=IOSTAT) NDIM + IIND = IIND + 1 + + DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + ISTART = IIND +! +! GET NLINK +! + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ' ) + IIND =IIND + 1 + IF(IIND > 254)RETURN + END DO + + READ(TRIM_LINE(ISTART:IIND-1),'(I30)',IOSTAT=IOSTAT) NLINK +! +! SWTICH FORMAT SPECIFIC DATA TO CURRENT DATA +! + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + TMPINT = NDIM + NDIM = NLINK + NLINK = TMPINT + ELSE IF(TRIM(LTYPE) == 'L')THEN + LTYPE ='S' + IF(NLINK > 0)THEN + EXTRALINE = .TRUE. + LTYPE = 'DIR' + NDIM = NLINK + END IF + + ELSE IF(TRIM(LTYPE) == 'J')THEN + LTYPE ='L' + END IF + + + FPAR%SUCCESS = .TRUE. + RETURN + + CASE('B') + NSIZE = 0 + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,nsize + FPAR%SUCCESS = .TRUE. + RETURN + END SELECT + + WRITE(FPAR%MESG,'(A)')' Read - reading header error ' + FPAR%SUCCESS = .FALSE. + RETURN + + WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' + FPAR%SUCCESS = .FALSE. + RETURN + + END SUBROUTINE READ_HEADER_FFA +! +! READ DATA +! + SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT + INTEGER(LINT) :: NDIM,NSIZE + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL DECLARATION +! + INTEGER(LINT) :: I,J + INTEGER :: IOSTAT + LOGICAL :: OK +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%R0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%D0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%I0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%L0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('S') +! READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + OK = TEST_IOSTAT(IOSTAT,FPAR) + + RETURN + + END SUBROUTINE READ_DATA_FFA_ASCII + + + + +! +! READ DATA +! + SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT + INTEGER(LINT) :: NDIM,NSIZE + CHARACTER(*) :: LTYPE + TYPE(FUNC_DATA_SET) :: FPAR +! +! LOCAL DECLARATION +! + INTEGER(LINT) :: I,J + INTEGER :: IOSTAT + LOGICAL :: OK +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%R0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%D0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%I0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%L0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + END IF + END IF + + + CASE('S') + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%S + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + OK = TEST_IOSTAT(IOSTAT,FPAR) + + RETURN + + END SUBROUTINE READ_DATA_FFA_BIN + +END MODULE FLL_READ_FFA_M diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index ac053e7..1ec1356 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -64,14 +64,14 @@ MODULE FLL_TYPE_M INTEGER, PARAMETER :: ERR_MSG_LENGTH = 256 INTEGER, PARAMETER :: ERR_PATH_LENGTH = 1024 INTEGER, PARAMETER :: FILE_NAME_LENGTH = 1024 - INTEGER, PARAMETER :: STRING_LENGHT = 24 + INTEGER, PARAMETER :: STRING_LENGHT = 72 ! ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! TYPE DNODE CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list - INTEGER(LINT) :: NDIM = 0, NSIZE = 0 + INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 INTEGER(LINT) :: POS = 0, LENGTH = 0 TYPE (DNODE), POINTER :: & @@ -85,15 +85,17 @@ MODULE FLL_TYPE_M REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) =>NULL() INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) =>NULL() INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) =>NULL() + CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S1(:)=>NULL() + CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() REAL(RSINGLE) :: R0 REAL(RDOUBLE) :: D0 INTEGER(SINT) :: I0 INTEGER(LINT) :: L0 - + CHARACTER(LEN=STRING_LENGHT) :: S CHARACTER :: C - CHARACTER(LEN=STRING_LENGHT) :: S - CHARACTER, POINTER :: S1(:) + + END TYPE DNODE diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index d5b0e48..b168bf2 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -253,6 +253,12 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) + DO I = 1,NDIM + WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + END DO + SAVED = .TRUE. ! ! 2D ARRAYS ! @@ -269,13 +275,21 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ELSE IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT, *)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - WRITE(IOUNIT, *)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + WRITE(IOUNIT, *)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) + DO I = 1,NDIM + WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", J = 1,NSIZE) + END DO +! WRITE(IOUNIT, *)(("'",PNODE%S2(I,J),"' ", J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. END IF ! ! CHECK IF NODE IS CONSTANT @@ -291,7 +305,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) CASE('L') WRITE(IOUNIT, *)PNODE%L0 CASE('S') - WRITE(IOUNIT,*)PNODE%S + WRITE(IOUNIT,*)"'",PNODE%S,"'" CASE DEFAULT @@ -320,11 +334,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ! ! 1D ARRAYS ! -! IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN -! WRITE(IOUNIT)TRIM(PNODE%LNAME),TRIM(PNODE%LTYPE), PNODE%NDIM -! ELSE WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE -! END IF ! ! 1 D ARRAYS ! @@ -344,6 +354,10 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%S1(I), I = 1,NDIM) + SAVED = .TRUE. ! ! 2D ARRAYS ! @@ -360,12 +374,17 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%S2(I,J), J = 1,NSIZE), I=1,NDIM) SAVED = .TRUE. END IF ! diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 new file mode 100644 index 0000000..141ca00 --- /dev/null +++ b/data_util/fll_write_ffa.f90 @@ -0,0 +1,435 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine FLL_WRITE_FFA +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints node +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_WRITE_FFA_M +CONTAINS + + + FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) + + USE FLL_TYPE_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT + LOGICAL OK +! +! LOCAL TYPES +! + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS +! +! DETERMINE RORMAT' +! + SELECT CASE(FMT) + CASE('A','a') ! ASCII FORMAT + FMT_LOC = 'A' + CASE('B','b') ! BINARY FORMAT + FMT_LOC = 'B' + CASE('U','u','*')! UNKNOWN - UNSPECIFIED FORMAT + FMT_LOC = 'U' + CASE DEFAULT + WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + OK = .FALSE. + RETURN + END SELECT +! +! OPEN THE FILE +! + SELECT CASE(FMT_LOC) + CASE('B') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + CASE('A') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& + IOSTAT=ISTAT,ACTION='WRITE') + END SELECT + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Write - error opening file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF +! +! WRITE LINKED LIST +! + CALL FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) + + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF + + OK = .TRUE. + RETURN + + END FUNCTION FLL_WRITE_FFA + + + + SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) + + USE FLL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE WRITES LIST +! + TYPE(DNODE), POINTER :: PNODE,PCHILD + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT + INTEGER(LINT) :: POS +! +! LOCAL TYPES +! +! +! BODY OF SUBROUTINE +! + POS = 0 + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' CAT - null node ' + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + IF(FMT == 'A')THEN + CALL FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + ELSE + CALL FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + END IF + + PCHILD => PNODE%PCHILD +! +! IF NODE HAS CHILDREN PRINT THEM TOO +! + IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_FFA_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + + FPAR%SUCCESS = .TRUE. + + RETURN + END SUBROUTINE FLL_WRITE_FFA_LIST +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) + + USE FLL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE REMOVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: POS + + TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! IF NODE HAS CHILDREN +! + PCURR => PNODE +! +! IF CHILDREN, PRINT THEM TOO +! + DO WHILE(ASSOCIATED(PCURR)) + + IF(FMT == 'A')THEN + CALL FLL_SAVE_NODE_A(PCURR, IOUNIT, FPAR) + ELSE + CALL FLL_SAVE_NODE_B(PCURR, IOUNIT, POS, FPAR) + END IF + + PNEXT => PCURR%PNEXT + PCHILD => PCURR%PCHILD + IF(ASSOCIATED(PCHILD))THEN + CALL FLL_WRITE_FFA_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + END IF + + PCURR => PNEXT + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE +! +! FREE MEMORY FOR NODE +! + SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + USE FLL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE SAVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: IOUNIT + INTEGER(LINT) :: I,J,NDIM,NSIZE + LOGICAL :: SAVED + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + + SAVED = .FALSE. +! +! 1D ARRAYS +! + LTYPE = PNODE%LTYPE + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN + IF(PNODE%NLINK > 0)THEN + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',L, 1, 1,',PNODE%NDIM + WRITE(IOUNIT, *)"'",PNODE%S,"'" + ELSE + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',N, 0, 0,',PNODE%NDIM + END IF + ELSE + IF(TRIM(LTYPE) == 'S') THEN + LTYPE ='L' + ELSE IF(TRIM(LTYPE) == 'L') THEN + LTYPE ='J' + END IF + + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',', TRIM(LTYPE),',', PNODE%NSIZE, ',',PNODE%NDIM,',',0 + END IF +! +! 1 D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%R1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%D1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%I1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) + WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) + DO I = 1,NDIM + WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + END DO + SAVED = .TRUE. +! +! 2D ARRAYS +! + ELSE IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) + DO I=1,NDIM + WRITE(IOUNIT, *)(PNODE%R2(I,J), J = 1,NSIZE) + END DO + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) + DO I=1,NDIM + WRITE(IOUNIT, *)(PNODE%D2(I,J), J = 1,NSIZE) + END DO + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) + DO I=1,NDIM + WRITE(IOUNIT, *)(PNODE%I2(I,J), J = 1,NSIZE) + END DO + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) + DO I=1,NDIM + WRITE(IOUNIT, *)(PNODE%L2(I,J), J = 1,NSIZE) + END DO + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) + DO I = 1,NDIM + WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", J = 1,NSIZE) + END DO + SAVED = .TRUE. + END IF +! +! CHECK IF NODE IS CONSTANT +! + IF(.NOT.SAVED)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT, *)PNODE%R0 + CASE('D') + WRITE(IOUNIT, *)PNODE%D0 + CASE('I') + WRITE(IOUNIT, *)PNODE%I0 + CASE('L') + WRITE(IOUNIT, *)PNODE%L0 + CASE('S') + WRITE(IOUNIT,*)"'",PNODE%S,"'" + + CASE DEFAULT + + END SELECT + END IF + + + RETURN + END SUBROUTINE FLL_SAVE_NODE_A + + SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + + USE FLL_TYPE_M + IMPLICIT NONE +! +! SUBROUTINE SAVES NODE +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: IOUNIT + INTEGER(LINT) :: I,J,NDIM,NSIZE,POS + LOGICAL :: SAVED + + SAVED = .FALSE. +! +! 1D ARRAYS +! + WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE +! +! 1 D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%R1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%D1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I1))THEN + NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%I1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) + WRITE(IOUNIT)(PNODE%S1(I), I = 1,NDIM) + SAVED = .TRUE. +! +! 2D ARRAYS +! + ELSE IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + ELSE IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) + WRITE(IOUNIT)((PNODE%S2(I,J), J = 1,NSIZE), I=1,NDIM) + SAVED = .TRUE. + END IF +! +! CHECK IF NODE IS CONSTANT +! + IF(.NOT.SAVED)THEN + SELECT CASE(PNODE%LTYPE) + CASE('R') + WRITE(IOUNIT)PNODE%R0 + CASE('D') + WRITE(IOUNIT)PNODE%D0 + CASE('I') + WRITE(IOUNIT)PNODE%I0 + CASE('L') + WRITE(IOUNIT)PNODE%L0 + CASE('S') + WRITE(IOUNIT)PNODE%S + + CASE DEFAULT + + END SELECT + END IF + + + RETURN + END SUBROUTINE FLL_SAVE_NODE_B + +END MODULE FLL_WRITE_FFA_M diff --git a/data_util/project.dep b/data_util/project.dep index 36c8f3d..03e4b99 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,84 +1,95 @@ # This file is generated automatically. DO NOT EDIT! -fll_mv.o : \ - fll_type.o \ - fll_stich.o \ - fll_rm.o - -fll_mk.o : \ - fll_type.o - -fll_funct_prt.o : \ +fll_write_ffa.o : \ fll_type.o fll_locate.o : \ - fll_type.o \ - fll_funct_prt.o + fll_funct_prt.o \ + fll_type.o -fll_getndata.o : \ - fll_type.o \ - fll_locate.o +fll_mk.o : \ + fll_type.o -fll_read.o : \ - fll_type.o \ - fll_mv.o \ - fll_mk.o \ - fll_funct_prt.o +fll_write.o : \ + fll_type.o -fll_cp.o : \ - fll_type.o \ - fll_duplicate.o \ - fll_cat.o \ - fll_mv.o \ +fll_mv.o : \ fll_stich.o \ - fll_rm.o - -fll_cat.o : \ + fll_rm.o \ fll_type.o fll_nnodes.o : \ - fll_type.o \ - fll_funct_prt.o - -fll_type.o : - -fll_write.o : \ + fll_funct_prt.o \ fll_type.o fll_mods.o : \ + fll_sweep.o \ + fll_duplicate.o \ + fll_write_ffa.o \ fll_locate.o \ + fll_read_ffa.o \ fll_funct_prt.o \ - fll_nnodes.o \ + fll_mv.o \ fll_type.o \ - fll_duplicate.o \ - fll_read.o \ + fll_write.o \ fll_getndata.o \ - fll_cp.o \ - fll_mk.o \ - fll_sweep.o \ - fll_cat.o \ - fll_mv.o \ + fll_deattach.o \ + fll_nnodes.o \ fll_stich.o \ + fll_cp.o \ fll_rm.o \ - fll_deattach.o \ - fll_write.o + fll_cat.o \ + fll_read.o \ + fll_mk.o + +fll_funct_prt.o : \ + fll_type.o fll_stich.o : \ fll_type.o -fll_rm.o : \ +fll_read_ffa.o : \ + fll_funct_prt.o \ + fll_mv.o \ fll_type.o \ - fll_stich.o + fll_mk.o -fll_sweep.o : \ - fll_type.o \ - fll_locate.o +fll_getndata.o : \ + fll_locate.o \ + fll_type.o -fll_deattach.o : \ +fll_read.o : \ + fll_funct_prt.o \ + fll_mv.o \ fll_type.o \ - fll_stich.o + fll_mk.o fll_duplicate.o : \ - fll_type.o \ fll_mv.o \ + fll_type.o \ fll_mk.o + +fll_sweep.o : \ + fll_locate.o \ + fll_type.o + +fll_deattach.o : \ + fll_stich.o \ + fll_type.o + +fll_type.o : + +fll_cp.o : \ + fll_duplicate.o \ + fll_mv.o \ + fll_type.o \ + fll_stich.o \ + fll_rm.o \ + fll_cat.o + +fll_cat.o : \ + fll_type.o + +fll_rm.o : \ + fll_stich.o \ + fll_type.o diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index fab17c5..b1de397 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -51,7 +51,7 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2 + TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2,PFFA TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT @@ -67,11 +67,18 @@ PROGRAM FLL_TEST ! read TEST file and store it in PNODE ! PNODE => FLL_READ('TEST',8,'A',FPAR) + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) + WRITE(*,*) + WRITE(*,*)'------------------------------------------------------1' + + PFFA => FLL_READ_FFA('case1.ainp',8,'A',FPAR) ! -! print Pnode on screen +! print Pnode on screen ! - CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) +! CALL FLL_CAT(PFFA, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------1' + OK = FLL_WRITE_FFA(PFFA,'File_1.txt',8,'A',FPAR) +stop ! ! read TEST1 file and store it in PNODE1 ! @@ -81,8 +88,8 @@ PROGRAM FLL_TEST ! CALL FLL_CAT(PNODE1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------2' -! -! save PNODE1 as binary and ascii file + +!! save PNODE1 as binary and ascii file ! OK = FLL_WRITE(PNODE1,'File_2.txt',8,'B',FPAR) OK = FLL_WRITE(PNODE1,'File_1.txt',8,'A',FPAR) @@ -128,7 +135,7 @@ PROGRAM FLL_TEST ! ! find the first TEST1_Subdir in PNODE1 and print it on the screen ! - PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',.false.,FPAR) + PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',-1_LINT,.false.,FPAR) CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------7' ! From a50e2fb0a2f0bbc50e9e98cbe25c4920011e4ade Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Nov 2016 21:54:48 -0600 Subject: [PATCH 021/325] fix reading FFA format --- data_util/fll_mk.f90 | 2 +- data_util/fll_read_ffa.f90 | 61 +++++++++++++++++++--------------- data_util/fll_type.f90 | 3 +- data_util/fll_write.f90 | 12 ++++--- data_util/fll_write_ffa.f90 | 66 +++++++++++++++++++++---------------- examples/fll_test.f90 | 11 +------ 6 files changed, 83 insertions(+), 72 deletions(-) diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index fba1599..c68202b 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -64,7 +64,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) ! Body ! IF(LEN_TRIM(LTYPE)<1.OR.LEN_TRIM(LTYPE)>TYPE_LENGTH) THEN - WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) + WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) RETURN END IF diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 51890dc..902c1a2 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -144,13 +144,13 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR_H CHARACTER(LEN=NAME_LENGTH) :: NAME - CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE,FTYPE INTEGER(LINT) :: NDIM, NSIZE,NNODES LOGICAL :: OK,EXTRALINE ! ! READ HEADER ! - CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR_H) + CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' @@ -169,17 +169,23 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' FPAR%SUCCESS = .FALSE. PNODE => NULL() + STOP RETURN END IF + PNODE%FTYPE = FTYPE IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN IF(EXTRALINE)THEN PNODE%NLINK = NLINK - write(*,*)'reading extra line for node ',PNODE%LNAME - READ(IOUNIT,*)PNODE%S - end if + SELECT CASE(PNODE%FTYPE) + CASE('L','S') + READ(IOUNIT,*)PNODE%S + CASE('I') + READ(IOUNIT,*)PNODE%I0 + END SELECT + END IF DO NNODES = 1,NDIM PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' @@ -209,7 +215,7 @@ END FUNCTION READ_NODE_FFA ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR) + SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR) USE FLL_TYPE_M USE FLL_FUNC_PRT_M @@ -221,7 +227,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE, TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - CHARACTER(*) :: LTYPE + CHARACTER(*) :: LTYPE,FTYPE CHARACTER(*) :: NAME INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT CHARACTER*255 :: TEXT_LINE,TRIM_LINE @@ -229,7 +235,6 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE, LOGICAL :: OK,EXTRALINE EXTRALINE = .FALSE. - SELECT CASE(FMT) CASE('A') @@ -271,6 +276,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE, IF(IIND > 254)RETURN END DO LTYPE = TRIM(TRIM_LINE(ISTART:IIND-1)) + FTYPE = TRIM(TRIM_LINE(ISTART:IIND-1)) IIND = IIND + 1 DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') @@ -322,21 +328,21 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,NLINK,EXTRALINE, ! SWTICH FORMAT SPECIFIC DATA TO CURRENT DATA ! IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - TMPINT = NDIM NDIM = NLINK - NLINK = TMPINT - ELSE IF(TRIM(LTYPE) == 'L')THEN - LTYPE ='S' - IF(NLINK > 0)THEN - EXTRALINE = .TRUE. - LTYPE = 'DIR' - NDIM = NLINK - END IF - - ELSE IF(TRIM(LTYPE) == 'J')THEN - LTYPE ='L' + ELSE + + IF(TRIM(LTYPE) == 'L')THEN + LTYPE ='S' + ELSE IF(TRIM(LTYPE) == 'J')THEN + LTYPE ='L' + END IF + + IF(NLINK > 0 )THEN + EXTRALINE = .TRUE. + LTYPE = 'DIR' + NDIM = NLINK + END IF END IF - FPAR%SUCCESS = .TRUE. RETURN @@ -381,6 +387,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! ! BODY ! + IF(NDIM*NSIZE == 0)RETURN SELECT CASE(LTYPE) CASE('R') IF(NDIM == 1)THEN @@ -393,7 +400,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%R2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -408,7 +415,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%D2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -424,7 +431,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%I2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -440,7 +447,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%L2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -457,7 +464,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%S2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -467,7 +474,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) RETURN CASE DEFAULT - WRITE(*,*)' WRONG TYPE' + WRITE(*,*)' WRONG TYPE ', pnode%lname, pnode%ltype END SELECT diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 1ec1356..be76360 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -71,6 +71,7 @@ MODULE FLL_TYPE_M TYPE DNODE CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list + CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 INTEGER(LINT) :: POS = 0, LENGTH = 0 @@ -92,7 +93,7 @@ MODULE FLL_TYPE_M REAL(RDOUBLE) :: D0 INTEGER(SINT) :: I0 INTEGER(LINT) :: L0 - CHARACTER(LEN=STRING_LENGHT) :: S + CHARACTER(LEN=STRING_LENGHT) :: S CHARACTER :: C diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index b168bf2..d5d2144 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -356,7 +356,9 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%S1(I), I = 1,NDIM) + DO I = 1,NDIM + WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + END DO SAVED = .TRUE. ! ! 2D ARRAYS @@ -384,8 +386,10 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%S2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + DO J=1,NSIZE + WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) + END DO + SAVED = .TRUE. END IF ! ! CHECK IF NODE IS CONSTANT @@ -401,7 +405,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) CASE('L') WRITE(IOUNIT)PNODE%L0 CASE('S') - WRITE(IOUNIT)PNODE%S + WRITE(IOUNIT)"'",PNODE%S,"'" CASE DEFAULT diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 141ca00..0b589ee 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -225,6 +225,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED CHARACTER(LEN=TYPE_LENGTH) :: LTYPE + CHARACTER * 16 :: SHTEXT SAVED = .FALSE. ! @@ -233,18 +234,23 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) LTYPE = PNODE%LTYPE IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN IF(PNODE%NLINK > 0)THEN - WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',L, 1, 1,',PNODE%NDIM - WRITE(IOUNIT, *)"'",PNODE%S,"'" + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),",",TRIM(PNODE%FTYPE),' ,1, 1,',PNODE%NDIM + LTYPE = PNODE%FTYPE ELSE WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',N, 0, 0,',PNODE%NDIM END IF ELSE IF(TRIM(LTYPE) == 'S') THEN - LTYPE ='L' + IF(LTYPE == 'S')THEN + LTYPE = 'S' + ELSE + LTYPE ='L' + END IF ELSE IF(TRIM(LTYPE) == 'L') THEN LTYPE ='J' END IF - + LTYPE = PNODE%FTYPE + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',', TRIM(LTYPE),',', PNODE%NSIZE, ',',PNODE%NDIM,',',0 END IF ! @@ -278,36 +284,36 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ELSE IF(ASSOCIATED(PNODE%R2))THEN NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) - DO I=1,NDIM - WRITE(IOUNIT, *)(PNODE%R2(I,J), J = 1,NSIZE) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%R2(I,J), I = 1,NDIM) END DO - SAVED = .TRUE. + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) - DO I=1,NDIM - WRITE(IOUNIT, *)(PNODE%D2(I,J), J = 1,NSIZE) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%D2(I,J), I = 1,NDIM) END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - DO I=1,NDIM - WRITE(IOUNIT, *)(PNODE%I2(I,J), J = 1,NSIZE) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%I2(I,J), I = 1,NDIM) END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - DO I=1,NDIM - WRITE(IOUNIT, *)(PNODE%L2(I,J), J = 1,NSIZE) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%L2(I,J), I = 1,NDIM) END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) - DO I = 1,NDIM - WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", J = 1,NSIZE) + DO J=1,NSIZE + WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) END DO SAVED = .TRUE. END IF @@ -315,21 +321,23 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ! CHECK IF NODE IS CONSTANT ! IF(.NOT.SAVED)THEN - SELECT CASE(PNODE%LTYPE) - CASE('R') - WRITE(IOUNIT, *)PNODE%R0 - CASE('D') - WRITE(IOUNIT, *)PNODE%D0 - CASE('I') - WRITE(IOUNIT, *)PNODE%I0 - CASE('L') - WRITE(IOUNIT, *)PNODE%L0 - CASE('S') - WRITE(IOUNIT,*)"'",PNODE%S,"'" + IF(PNODE%NSIZE*PNODE%NDIM /= 0 .OR. PNODE%NLINK >0)THEN + SELECT CASE(LTYPE) + CASE('R') + WRITE(IOUNIT,*)PNODE%R0 + CASE('D') + WRITE(IOUNIT,*)PNODE%D0 + CASE('I') + WRITE(IOUNIT,*)PNODE%I0 + CASE('J') + WRITE(IOUNIT,*)PNODE%L0 + CASE('S','L') + WRITE(IOUNIT,*)"'",PNODE%S,"'" - CASE DEFAULT + CASE DEFAULT - END SELECT + END SELECT + END IF END IF @@ -384,7 +392,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%R2))THEN NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)((PNODE%R2(I,J), I = 1,NSIZE), I=1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index b1de397..0303d67 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -51,7 +51,7 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2,PFFA + TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2 TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT @@ -70,15 +70,6 @@ PROGRAM FLL_TEST CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) WRITE(*,*) WRITE(*,*)'------------------------------------------------------1' - - PFFA => FLL_READ_FFA('case1.ainp',8,'A',FPAR) -! -! print Pnode on screen -! -! CALL FLL_CAT(PFFA, 6, .TRUE.,FPAR) - WRITE(*,*)'------------------------------------------------------1' - OK = FLL_WRITE_FFA(PFFA,'File_1.txt',8,'A',FPAR) -stop ! ! read TEST1 file and store it in PNODE1 ! From 7b76410d340f0311d511ddd059b5f70af3e423b9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 11:22:44 -0600 Subject: [PATCH 022/325] correct error for bindary W os S types --- data_util/fll_cat.f90 | 6 +-- data_util/fll_write.f90 | 11 ++--- data_util/project.dep | 106 ++++++++++++++++++++-------------------- examples/TEST1 | 4 +- 4 files changed, 63 insertions(+), 64 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index f1cae60..d84755b 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -190,7 +190,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%S1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)" ",SPACE,(TRIM(PNODE%S1(I)), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ! @@ -213,7 +213,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%S2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",SPACE,((TRIM(PNODE%S2(I,J)), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. END IF @@ -236,7 +236,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(TEXT,*)" ",SPACE,PNODE%L0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('S') - WRITE(TEXT,*)" ",SPACE,PNODE%S + WRITE(TEXT,*)" ",SPACE,TRIM(PNODE%S) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE DEFAULT diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index d5d2144..e9eeeb0 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -256,7 +256,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) DO I = 1,NDIM - WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + WRITE(IOUNIT, *)"'",TRIM(PNODE%S1(I)),"'" END DO SAVED = .TRUE. ! @@ -286,9 +286,8 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) DO I = 1,NDIM - WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", J = 1,NSIZE) + WRITE(IOUNIT, *)("'",TRIM(PNODE%S2(I,J)),"' ", J = 1,NSIZE) END DO -! WRITE(IOUNIT, *)(("'",PNODE%S2(I,J),"' ", J = 1,NSIZE), I=1,NDIM) SAVED = .TRUE. END IF ! @@ -305,7 +304,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) CASE('L') WRITE(IOUNIT, *)PNODE%L0 CASE('S') - WRITE(IOUNIT,*)"'",PNODE%S,"'" + WRITE(IOUNIT,*)"'",TRIM(PNODE%S),"'" CASE DEFAULT @@ -357,7 +356,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) DO I = 1,NDIM - WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + WRITE(IOUNIT)"'",PNODE%S1(I),"'" END DO SAVED = .TRUE. ! @@ -387,7 +386,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) DO J=1,NSIZE - WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) + WRITE(IOUNIT)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) END DO SAVED = .TRUE. END IF diff --git a/data_util/project.dep b/data_util/project.dep index 03e4b99..97f37d5 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,95 +1,95 @@ # This file is generated automatically. DO NOT EDIT! -fll_write_ffa.o : \ +fll_deattach.o : \ + fll_stich.o \ fll_type.o -fll_locate.o : \ +fll_nnodes.o : \ fll_funct_prt.o \ fll_type.o -fll_mk.o : \ +fll_stich.o : \ fll_type.o -fll_write.o : \ +fll_funct_prt.o : \ fll_type.o -fll_mv.o : \ - fll_stich.o \ - fll_rm.o \ +fll_sweep.o : \ + fll_locate.o \ fll_type.o -fll_nnodes.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_type.o -fll_mods.o : \ - fll_sweep.o \ - fll_duplicate.o \ - fll_write_ffa.o \ - fll_locate.o \ - fll_read_ffa.o \ - fll_funct_prt.o \ +fll_cp.o : \ fll_mv.o \ - fll_type.o \ - fll_write.o \ - fll_getndata.o \ - fll_deattach.o \ - fll_nnodes.o \ - fll_stich.o \ - fll_cp.o \ - fll_rm.o \ fll_cat.o \ - fll_read.o \ - fll_mk.o - -fll_funct_prt.o : \ + fll_duplicate.o \ + fll_rm.o \ + fll_stich.o \ fll_type.o -fll_stich.o : \ +fll_locate.o : \ + fll_funct_prt.o \ fll_type.o -fll_read_ffa.o : \ - fll_funct_prt.o \ +fll_duplicate.o : \ fll_mv.o \ - fll_type.o \ - fll_mk.o - -fll_getndata.o : \ - fll_locate.o \ + fll_mk.o \ fll_type.o -fll_read.o : \ - fll_funct_prt.o \ +fll_mods.o : \ fll_mv.o \ + fll_deattach.o \ + fll_cat.o \ + fll_duplicate.o \ + fll_write.o \ + fll_locate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_write_ffa.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_cp.o \ + fll_mk.o \ fll_type.o \ - fll_mk.o + fll_nnodes.o \ + fll_read.o \ + fll_getndata.o \ + fll_read_ffa.o -fll_duplicate.o : \ - fll_mv.o \ - fll_type.o \ - fll_mk.o +fll_rm.o : \ + fll_stich.o \ + fll_type.o -fll_sweep.o : \ +fll_getndata.o : \ fll_locate.o \ fll_type.o -fll_deattach.o : \ +fll_mv.o : \ fll_stich.o \ + fll_rm.o \ fll_type.o -fll_type.o : +fll_write.o : \ + fll_type.o -fll_cp.o : \ - fll_duplicate.o \ +fll_mk.o : \ + fll_type.o + +fll_read.o : \ fll_mv.o \ - fll_type.o \ - fll_stich.o \ - fll_rm.o \ - fll_cat.o + fll_funct_prt.o \ + fll_mk.o \ + fll_type.o fll_cat.o : \ fll_type.o -fll_rm.o : \ - fll_stich.o \ +fll_write_ffa.o : \ fll_type.o + +fll_type.o : diff --git a/examples/TEST1 b/examples/TEST1 index b27c5db..e914c25 100644 --- a/examples/TEST1 +++ b/examples/TEST1 @@ -13,5 +13,5 @@ TEST1_DIR DIR 3 TEST1_Subdir DIR 2 times D 1 1 1 - some_name S 1 1 - Text-name + some_name S 2 1 + ' Text-name ' 'My name' From 9f785b3e06e5673142784b5daf2c1f5d78f81516 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 12:51:58 -0600 Subject: [PATCH 023/325] improve NSUB reading from format --- data_util/fll_read_ffa.f90 | 147 ++++++++++++++++++++++++++++--------- data_util/fll_type.f90 | 1 + 2 files changed, 112 insertions(+), 36 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 902c1a2..332d4c1 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -139,8 +139,8 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - - INTEGER(LINT) :: NLINK + INTEGER(LINT) :: NSUB + CHARACTER(LEN=NAME_LENGTH) :: T TYPE(FUNC_DATA_SET) :: FPAR_H CHARACTER(LEN=NAME_LENGTH) :: NAME @@ -150,7 +150,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! ! READ HEADER ! - CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR_H) + CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,EXTRALINE,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' @@ -160,7 +160,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) END IF IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) ELSE PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) END IF @@ -178,14 +178,17 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN IF(EXTRALINE)THEN - PNODE%NLINK = NLINK - SELECT CASE(PNODE%FTYPE) - CASE('L','S') - READ(IOUNIT,*)PNODE%S - CASE('I') - READ(IOUNIT,*)PNODE%I0 + PNODE%NLINK = NSUB + SELECT CASE(FMT) + CASE('A') +! CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,1_LINT,1_LINT,FPAR_H) + CASE('B') +! CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,1_LINT,1_LINT,FPAR_H) END SELECT END IF + DO NNODES = 1,NDIM PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' @@ -202,9 +205,9 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! SELECT CASE(FMT) CASE('A') - CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) CASE('B') - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) END SELECT END IF @@ -231,6 +234,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR CHARACTER(*) :: NAME INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT CHARACTER*255 :: TEXT_LINE,TRIM_LINE + CHARACTER*32 :: VER INTEGER :: IOSTAT LOGICAL :: OK,EXTRALINE @@ -349,7 +353,37 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR CASE('B') NSIZE = 0 - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,nsize + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,NSIZE,NLINK + IF(TRIM(NAME) == 'FFA-format-v2')THEN +! +! DISREGARD, THIS IS JUST INFO ABOUT VERSION +! CONSIDER HAVING VERSION ONLY AT THE BEGINING OF THE FILE +! + REWIND(IOUNIT) + READ(IOUNIT,IOSTAT=IOSTAT)VER + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,NSIZE,NLINK + END IF + FTYPE = LTYPE + +write(*,*)' Header ',NAME,LTYPE,NDIM,NSIZE,NLINK + + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN + NDIM = NLINK + ELSE + + IF(TRIM(LTYPE) == 'L')THEN + LTYPE ='S' + ELSE IF(TRIM(LTYPE) == 'J')THEN + LTYPE ='L' + END IF + + IF(NLINK > 0 )THEN + EXTRALINE = .TRUE. + LTYPE = 'DIR' + NDIM = NLINK + END IF + END IF + FPAR%SUCCESS = .TRUE. RETURN END SELECT @@ -436,7 +470,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END IF - CASE('L') + CASE('J') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) @@ -452,8 +486,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END IF - CASE('S') -! READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + CASE('S','L') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) @@ -499,8 +532,9 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT - INTEGER(LINT) :: NDIM,NSIZE + INTEGER(LINT) :: NDIM,NSIZE,NINTEG CHARACTER(*) :: LTYPE + CHARACTER(LEN=NAME_LENGTH) :: T TYPE(FUNC_DATA_SET) :: FPAR ! ! LOCAL DECLARATION @@ -515,30 +549,31 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NSIZE) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%R0 + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%R0 + write(*,*)PNODE%R0 END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) END IF END IF CASE('D') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%D1(I),I=1,NSIZE) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%D0 + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%D0 END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%D1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) END IF END IF @@ -546,37 +581,77 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('I') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%I1(I),I=1,NSIZE) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%I0 + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%I0 END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%I1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) END IF END IF - CASE('L') + CASE('J') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%L1(I),I=1,NSIZE) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%L0 + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%L0 END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%L1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) END IF END IF - CASE('S') - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%S + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + DO I=1,NSIZE + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = T + END DO + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%T + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = T + END DO + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + DO J=1,NSIZE + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S2(I,J) = T + END DO + END DO + END IF + END IF + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%S1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%S + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%S1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%S2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF CASE('C') diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index be76360..f1ac86e 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -94,6 +94,7 @@ MODULE FLL_TYPE_M INTEGER(SINT) :: I0 INTEGER(LINT) :: L0 CHARACTER(LEN=STRING_LENGHT) :: S + CHARACTER(LEN=NAME_LENGTH) :: T CHARACTER :: C From 8b1d9936a1226ee1d048d1a8a2900e49e634d2d8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 14:19:11 -0600 Subject: [PATCH 024/325] finish reading format bindary files --- data_util/fll_cat.f90 | 4 ++-- data_util/fll_read_ffa.f90 | 45 ++++++++++++++++++++++--------------- data_util/fll_type.f90 | 2 ++ data_util/fll_write_ffa.f90 | 4 ++-- examples/fll_test.f90 | 14 +++++++++++- 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index d84755b..fa379a3 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -160,11 +160,11 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(NSSTR,'(I10)')PNODE%NSIZE IF(TRIM(PNODE%LTYPE) == 'DIR')THEN - WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),' ',SPACE,TRIM(PNODE%LNAME) + WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'\ ',SPACE,TRIM(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN - WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),' ',SPACE,TRIM(PNODE%LNAME) + WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'\ ',SPACE,TRIM(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 332d4c1..ff3d1c4 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -145,12 +145,12 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR_H CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: LTYPE,FTYPE - INTEGER(LINT) :: NDIM, NSIZE,NNODES + INTEGER(LINT) :: NDIM, NSIZE,NNODES,NDIMO,NSIZEO LOGICAL :: OK,EXTRALINE ! ! READ HEADER ! - CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,EXTRALINE,FPAR_H) + CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,NDIMO,NSIZEO,EXTRALINE,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' @@ -181,11 +181,9 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) PNODE%NLINK = NSUB SELECT CASE(FMT) CASE('A') -! CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) - CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,1_LINT,1_LINT,FPAR_H) + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) CASE('B') -! CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,1_LINT,1_LINT,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) END SELECT END IF @@ -218,7 +216,7 @@ END FUNCTION READ_NODE_FFA ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTRALINE,FPAR) + SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIMO,NSIZEO,EXTRALINE,FPAR) USE FLL_TYPE_M USE FLL_FUNC_PRT_M @@ -232,7 +230,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR CHARACTER(*) :: LTYPE,FTYPE CHARACTER(*) :: NAME - INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT + INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT,NDIMO,NSIZEO CHARACTER*255 :: TEXT_LINE,TRIM_LINE CHARACTER*32 :: VER INTEGER :: IOSTAT @@ -319,6 +317,9 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR IF(IIND > 254)RETURN END DO ISTART = IIND + + NSIZEO = NSIZE + NDIMO = NDIM ! ! GET NLINK ! @@ -350,10 +351,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR FPAR%SUCCESS = .TRUE. RETURN - +! +! binary +! CASE('B') NSIZE = 0 - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,NSIZE,NLINK + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK IF(TRIM(NAME) == 'FFA-format-v2')THEN ! ! DISREGARD, THIS IS JUST INFO ABOUT VERSION @@ -361,11 +364,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,EXTR ! REWIND(IOUNIT) READ(IOUNIT,IOSTAT=IOSTAT)VER - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,NSIZE,NLINK + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK END IF - FTYPE = LTYPE -write(*,*)' Header ',NAME,LTYPE,NDIM,NSIZE,NLINK + FTYPE = LTYPE + NSIZEO = NSIZE + NDIMO = NDIM IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN NDIM = NLINK @@ -545,6 +549,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! ! BODY ! + IF(NDIM*NSIZE == 0)RETURN SELECT CASE(LTYPE) CASE('R') IF(NDIM == 1)THEN @@ -558,7 +563,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%R2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -573,7 +578,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%D1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%D2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -589,7 +594,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%I1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%I2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -605,7 +610,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE == 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%L1(I),I=1,NDIM) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%L2(I,J),I=1,NDIM),J=1,NSIZE) END IF END IF @@ -615,16 +620,19 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) READ(IOUNIT,IOSTAT=IOSTAT)NINTEG DO I=1,NSIZE READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' PNODE%S1(I) = T END DO ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%T + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,T + PNODE%S = T END IF ELSE IF(NSIZE == 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG DO I=1,NDIM READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' PNODE%S1(I) = T END DO ELSE @@ -632,6 +640,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) DO J=1,NSIZE DO I=1,NDIM READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S2(I,J) = ' ' PNODE%S2(I,J) = T END DO END DO diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index f1ac86e..9123b76 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -65,6 +65,8 @@ MODULE FLL_TYPE_M INTEGER, PARAMETER :: ERR_PATH_LENGTH = 1024 INTEGER, PARAMETER :: FILE_NAME_LENGTH = 1024 INTEGER, PARAMETER :: STRING_LENGHT = 72 + + INTEGER, PARAMETER :: MAX_SUB = 32000 ! ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 0b589ee..e26ccd3 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -275,7 +275,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) DO I = 1,NDIM - WRITE(IOUNIT, *)"'",PNODE%S1(I),"'" + WRITE(IOUNIT, *)"'",TRIM(PNODE%S1(I)),"'" END DO SAVED = .TRUE. ! @@ -313,7 +313,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) DO J=1,NSIZE - WRITE(IOUNIT, *)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) + WRITE(IOUNIT, *)("'",TRIM(PNODE%S2(I,J)),"' ", I = 1,NDIM) END DO SAVED = .TRUE. END IF diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 0303d67..27662d7 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -51,7 +51,7 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2 + TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2,PFFA TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT @@ -63,6 +63,18 @@ PROGRAM FLL_TEST INTEGER :: ISTAT INTEGER(LINT) :: POS,NNODES REAL(RDOUBLE), POINTER :: PRESS(:) + +! +! read TEST file and store it in PNODE +! +! PFFA => FLL_READ_FFA('case1.ainp',8,'A',FPAR) + PFFA => FLL_READ_FFA('case1.binp',8,'B',FPAR) + CALL FLL_CAT(PFFA, 6, .TRUE.,FPAR) + WRITE(*,*) + WRITE(*,*)'------------------------------------------------------1' + OK = FLL_WRITE_FFA(PFFA,'File_1.txt',8,'A',FPAR) + +stop ! ! read TEST file and store it in PNODE ! From 353a65d14982decc4173e43b72ef67120413cec1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 14:44:13 -0600 Subject: [PATCH 025/325] add F to arrays in format --- data_util/fll_read_ffa.f90 | 6 ++++++ data_util/fll_write_ffa.f90 | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index ff3d1c4..0920ae8 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -357,6 +357,8 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM CASE('B') NSIZE = 0 READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK + WRITE(*,*)' 1st read ',NAME,LTYPE,NSIZE, NLINK + IF(TRIM(NAME) == 'FFA-format-v2')THEN ! ! DISREGARD, THIS IS JUST INFO ABOUT VERSION @@ -367,10 +369,14 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK END IF + LTYPE(2:4) = ' ' + FTYPE = LTYPE NSIZEO = NSIZE NDIMO = NDIM + WRITE(*,*)NAME,LTYPE,NSIZE, NLINK + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN NDIM = NLINK ELSE diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index e26ccd3..5e14b84 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -250,7 +250,14 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) LTYPE ='J' END IF LTYPE = PNODE%FTYPE - + + IF( (PNODE%NSIZE * PNODE%NDIM > 1) )THEN + SELECT CASE(LTYPE) + CASE('D','R','I','J') + LTYPE(2:2) = 'F' + END SELECT + END IF + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',', TRIM(LTYPE),',', PNODE%NSIZE, ',',PNODE%NDIM,',',0 END IF ! From cb714e7728c63efb4cff5f9de71d1c2d0a6581ca Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 15:16:59 -0600 Subject: [PATCH 026/325] tmp commit to write --- data_util/fll_write_ffa.f90 | 101 +++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 5e14b84..65a54b9 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -364,34 +364,65 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) INTEGER :: IOUNIT INTEGER(LINT) :: I,J,NDIM,NSIZE,POS LOGICAL :: SAVED + CHARACTER(LEN=TYPE_LENGTH) :: LTYPE SAVED = .FALSE. ! ! 1D ARRAYS ! - WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE + LTYPE = PNODE%LTYPE + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN + IF(PNODE%NLINK > 0)THEN + WRITE(IOUNIT)PNODE%LNAME,PNODE%FTYPE,' ,1, 1,',PNODE%NDIM + LTYPE = PNODE%FTYPE + ELSE + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',N, 0, 0,',PNODE%NDIM + END IF + ELSE + IF(TRIM(LTYPE) == 'S') THEN + IF(LTYPE == 'S')THEN + LTYPE = 'S' + ELSE + LTYPE ='L' + END IF + ELSE IF(TRIM(LTYPE) == 'L') THEN + LTYPE ='J' + END IF + LTYPE = PNODE%FTYPE + + IF( (PNODE%NSIZE * PNODE%NDIM > 1) )THEN + SELECT CASE(LTYPE) + CASE('D','R','I','J') + LTYPE(2:2) = 'F' + END SELECT + END IF + + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',', TRIM(LTYPE),',', PNODE%NSIZE, ',',PNODE%NDIM,',',0 + END IF ! ! 1 D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%R1(I), I = 1,NDIM) + WRITE(IOUNIT, *)(PNODE%R1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%D1(I), I = 1,NDIM) + WRITE(IOUNIT, *)(PNODE%D1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%I1(I), I = 1,NDIM) + WRITE(IOUNIT, *)(PNODE%I1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) + WRITE(IOUNIT, *)(PNODE%L1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%S1(I), I = 1,NDIM) + DO I = 1,NDIM + WRITE(IOUNIT, *)"'",TRIM(PNODE%S1(I)),"'" + END DO SAVED = .TRUE. ! ! 2D ARRAYS @@ -399,48 +430,60 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%R2))THEN NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), I = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%R2(I,J), I = 1,NDIM) + END DO + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%D2(I,J), I = 1,NDIM) + END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%I2(I,J), I = 1,NDIM) + END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + DO J=1,NSIZE + WRITE(IOUNIT, *)(PNODE%L2(I,J), I = 1,NDIM) + END DO + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%S2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + DO J=1,NSIZE + WRITE(IOUNIT, *)("'",TRIM(PNODE%S2(I,J)),"' ", I = 1,NDIM) + END DO + SAVED = .TRUE. END IF ! ! CHECK IF NODE IS CONSTANT ! IF(.NOT.SAVED)THEN - SELECT CASE(PNODE%LTYPE) - CASE('R') - WRITE(IOUNIT)PNODE%R0 - CASE('D') - WRITE(IOUNIT)PNODE%D0 - CASE('I') - WRITE(IOUNIT)PNODE%I0 - CASE('L') - WRITE(IOUNIT)PNODE%L0 - CASE('S') - WRITE(IOUNIT)PNODE%S - - CASE DEFAULT - - END SELECT + IF(PNODE%NSIZE*PNODE%NDIM /= 0 .OR. PNODE%NLINK >0)THEN + SELECT CASE(LTYPE) + CASE('R') + WRITE(IOUNIT,*)PNODE%R0 + CASE('D') + WRITE(IOUNIT,*)PNODE%D0 + CASE('I') + WRITE(IOUNIT,*)PNODE%I0 + CASE('J') + WRITE(IOUNIT,*)PNODE%L0 + CASE('L') + WRITE(IOUNIT)PNODE%S + CASE('S') + WRITE(IOUNIT)PNODE%S(1:NAME_LENGTH) + CASE DEFAULT + END SELECT + END IF END IF From 7e74980d2bac9c2214900b037ede1df79047d053 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 22:26:38 -0600 Subject: [PATCH 027/325] finish format reading --- data_util/fll_read_ffa.f90 | 1 - data_util/fll_write_ffa.f90 | 123 ++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 34 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index ff3d1c4..a6224d2 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -557,7 +557,6 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NSIZE) ELSE READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%R0 - write(*,*)PNODE%R0 END IF ELSE IF(NSIZE == 1)THEN diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index e26ccd3..b4d1503 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -61,6 +61,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) INTEGER :: IOUNIT CHARACTER :: FMT LOGICAL OK + CHARACTER(32) :: FFVERSION='FFA-format-v2' ! ! LOCAL TYPES ! @@ -91,6 +92,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& ACCESS='STREAM',IOSTAT=ISTAT) + WRITE(IOUNIT)FFVERSION CASE('A') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& IOSTAT=ISTAT,ACTION='WRITE') @@ -225,7 +227,6 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED CHARACTER(LEN=TYPE_LENGTH) :: LTYPE - CHARACTER * 16 :: SHTEXT SAVED = .FALSE. ! @@ -238,6 +239,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) LTYPE = PNODE%FTYPE ELSE WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',N, 0, 0,',PNODE%NDIM + RETURN END IF ELSE IF(TRIM(LTYPE) == 'S') THEN @@ -358,33 +360,64 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) INTEGER(LINT) :: I,J,NDIM,NSIZE,POS LOGICAL :: SAVED + CHARACTER(LEN=TYPE_LENGTH) :: NTYPE ='N', LTYPE + CHARACTER(LEN=NAME_LENGTH) :: SHTEXT + SAVED = .FALSE. -! -! 1D ARRAYS -! - WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE + LTYPE = PNODE%LTYPE + + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN + IF(PNODE%NLINK > 0)THEN + WRITE(IOUNIT)PNODE%LNAME,PNODE%FTYPE,1_LINT,1_LINT,PNODE%NDIM + LTYPE = PNODE%FTYPE + ELSE + WRITE(IOUNIT)PNODE%LNAME,NTYPE,0_LINT,0_LINT,PNODE%NDIM + RETURN + END IF + ELSE + IF(TRIM(LTYPE) == 'S') THEN + IF(LTYPE == 'S')THEN + LTYPE = 'S' + ELSE + LTYPE ='L' + END IF + ELSE IF(TRIM(LTYPE) == 'L') THEN + LTYPE ='J' + END IF + LTYPE = PNODE%FTYPE + + WRITE(IOUNIT)PNODE%LNAME,LTYPE,PNODE%NSIZE, PNODE%NDIM,0_LINT + END IF ! ! 1 D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%R1(I), I = 1,NDIM) + WRITE(IOUNIT)NDIM,(PNODE%R1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%D1(I), I = 1,NDIM) + WRITE(IOUNIT)NDIM,(PNODE%D1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%I1(I), I = 1,NDIM) + WRITE(IOUNIT)NDIM,(PNODE%I1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) + WRITE(IOUNIT)NDIM,(PNODE%L1(I), I = 1,NDIM) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%S1(I), I = 1,NDIM) + IF(PNODE%FTYPE == 'L')THEN + WRITE(IOUNIT)NDIM*STRING_LENGHT,(PNODE%S1(I),I=1,NDIM) + ELSE + WRITE(IOUNIT)NDIM*NAME_LENGTH + DO I = 1,NDIM + SHTEXT = PNODE%S1(I) + WRITE(IOUNIT)SHTEXT + END DO + END IF SAVED = .TRUE. ! ! 2D ARRAYS @@ -392,48 +425,72 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%R2))THEN NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), I = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + WRITE(IOUNIT)NDIM*NSIZE + DO J=1,NSIZE + WRITE(IOUNIT)(PNODE%R2(I,J), I = 1,NDIM) + END DO + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)NDIM*NSIZE + DO J=1,NSIZE + WRITE(IOUNIT)(PNODE%D2(I,J), I = 1,NDIM) + END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)NDIM*NSIZE + DO J=1,NSIZE + WRITE(IOUNIT)(PNODE%I2(I,J), I = 1,NDIM) + END DO SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + WRITE(IOUNIT)NDIM*NSIZE + DO J=1,NSIZE + WRITE(IOUNIT)(PNODE%L2(I,J), I = 1,NDIM) + END DO + SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%S2(I,J), J = 1,NSIZE), I=1,NDIM) - SAVED = .TRUE. + + IF(PNODE%FTYPE == 'L')THEN + WRITE(IOUNIT)NDIM*NSIZE*STRING_LENGHT,((PNODE%S2(I,J), I = 1,NDIM),J=1,NSIZE) + ELSE + WRITE(IOUNIT)NDIM*NSIZE*NAME_LENGTH + DO J=1,NSIZE + DO I=1,NDIM + SHTEXT = PNODE%S2(I,J) + WRITE(IOUNIT)SHTEXT + END DO + END DO + ENDIF + SAVED = .TRUE. END IF ! ! CHECK IF NODE IS CONSTANT ! IF(.NOT.SAVED)THEN - SELECT CASE(PNODE%LTYPE) - CASE('R') - WRITE(IOUNIT)PNODE%R0 - CASE('D') - WRITE(IOUNIT)PNODE%D0 - CASE('I') - WRITE(IOUNIT)PNODE%I0 - CASE('L') - WRITE(IOUNIT)PNODE%L0 - CASE('S') - WRITE(IOUNIT)PNODE%S - - CASE DEFAULT - - END SELECT + IF(PNODE%NSIZE*PNODE%NDIM /= 0 .OR. PNODE%NLINK >0)THEN + SELECT CASE(LTYPE) + CASE('R') + WRITE(IOUNIT)1_LINT,PNODE%R0 + CASE('D') + WRITE(IOUNIT)1_LINT,PNODE%D0 + CASE('I') + WRITE(IOUNIT)1_LINT,PNODE%I0 + CASE('J') + WRITE(IOUNIT)1_LINT,PNODE%L0 + CASE('L') + WRITE(IOUNIT)1_LINT*STRING_LENGHT,PNODE%S + CASE('S') + WRITE(IOUNIT)1_LINT*NAME_LENGTH,PNODE%S(1:NAME_LENGTH) + END SELECT + END IF END IF From 0d149bfff0198c6c12e12336d84d88852f0d6b57 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 22:58:18 -0600 Subject: [PATCH 028/325] fix binary read --- data_util/fll_read_ffa.f90 | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index a6224d2..b25244b 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -246,7 +246,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM OK = TEST_IOSTAT(IOSTAT,FPAR) IF(.NOT.OK) RETURN END DO - + TRIM_LINE = TRIM(TEXT_LINE) ! ! GET NAME @@ -366,7 +366,8 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM READ(IOUNIT,IOSTAT=IOSTAT)VER READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK END IF - + + LTYPE(2:) = ' ' FTYPE = LTYPE NSIZEO = NSIZE NDIMO = NDIM @@ -375,9 +376,9 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM NDIM = NLINK ELSE - IF(TRIM(LTYPE) == 'L')THEN + IF(TRIM(LTYPE(1:1)) == 'L')THEN LTYPE ='S' - ELSE IF(TRIM(LTYPE) == 'J')THEN + ELSE IF(TRIM(LTYPE(1:1)) == 'J')THEN LTYPE ='L' END IF @@ -426,7 +427,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! BODY ! IF(NDIM*NSIZE == 0)RETURN - SELECT CASE(LTYPE) + SELECT CASE(LTYPE(1:1)) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN @@ -550,7 +551,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! BODY ! IF(NDIM*NSIZE == 0)RETURN - SELECT CASE(LTYPE) + SELECT CASE(LTYPE(1:1)) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN From a2ba59db52982d588119d9c3efd6bafd6a3ac9cb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Nov 2016 23:14:43 -0600 Subject: [PATCH 029/325] fix reading ascii format --- data_util/fll_read_ffa.f90 | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index b25244b..4a00a9f 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -230,7 +230,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM CHARACTER(*) :: LTYPE,FTYPE CHARACTER(*) :: NAME - INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT,NDIMO,NSIZEO + INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT,NDIMO,NSIZEO,I CHARACTER*255 :: TEXT_LINE,TRIM_LINE CHARACTER*32 :: VER INTEGER :: IOSTAT @@ -248,6 +248,10 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM END DO TRIM_LINE = TRIM(TEXT_LINE) + + DO I=1,255 + IF(TRIM_LINE(I:I) == ',') TRIM_LINE(I:I) =' ' + END DO ! ! GET NAME ! @@ -258,12 +262,11 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM END DO ISTART = IIND - DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ' ) IIND =IIND + 1 IF(IIND > 254)RETURN END DO - NAME = TRIM(TRIM_LINE(ISTART:IIND-1)) - IIND = IIND + 1 + NAME = TRIM(TRIM_LINE(ISTART:IIND)) DO WHILE(TRIM_LINE(IIND:IIND) == ' ') IIND =IIND + 1 @@ -273,15 +276,15 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! ! GET TYPE ! - DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ' ) IIND =IIND + 1 IF(IIND > 254)RETURN END DO - LTYPE = TRIM(TRIM_LINE(ISTART:IIND-1)) - FTYPE = TRIM(TRIM_LINE(ISTART:IIND-1)) - IIND = IIND + 1 + LTYPE = TRIM(TRIM_LINE(ISTART:IIND)) + LTYPE(2:) = ' ' + FTYPE = LTYPE - DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') IIND =IIND + 1 IF(IIND > 254)RETURN END DO @@ -289,15 +292,14 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! ! GET NSIZE ! - DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ' ) IIND =IIND + 1 IF(IIND > 254)RETURN END DO READ(TRIM_LINE(ISTART:IIND-1),'(I30)',IOSTAT=IOSTAT) NSIZE - IIND = IIND + 1 - DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') IIND =IIND + 1 IF(IIND > 254)RETURN END DO @@ -305,14 +307,14 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! ! GET NDIM ! - DO WHILE(TRIM_LINE(IIND:IIND) /= ',' ) + DO WHILE(TRIM_LINE(IIND:IIND) /= ' ' ) IIND =IIND + 1 IF(IIND > 254)RETURN END DO READ(TRIM_LINE(ISTART:IIND-1),'(I30)',IOSTAT=IOSTAT) NDIM IIND = IIND + 1 - DO WHILE(TRIM_LINE(IIND:IIND) == ' ' .OR. TRIM_LINE(IIND:IIND) == ',') + DO WHILE(TRIM_LINE(IIND:IIND) == ' ') IIND =IIND + 1 IF(IIND > 254)RETURN END DO From f53f9cdd629aefa8e69ce50eaa26a810428ad91d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 08:17:49 -0600 Subject: [PATCH 030/325] format routines to std format --- data_util/fll_cp.f90 | 84 ++++++++++++++++++----------- data_util/fll_type.f90 | 116 ++++++++++++++++++++++++----------------- 2 files changed, 124 insertions(+), 76 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 584ebbb..8938999 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -22,48 +22,54 @@ ! Subroutine FLL_CP ! ! Date: 2016-10-10 -! -! ! ! -! Description: moves or copies node +MODULE FLL_CP_M ! +! Description: Contains function fll_cp ! -! Input parameters: ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Return value: -! -! ! -! Modifications: -! Date Version Patch number CLA +! External Modules used ! -! -! Description -! -! -MODULE FLL_CP_M + CONTAINS - FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! -! FUNCTIONS COPIES PHAT TO PWHERE. -! IF PWHERE IS NULL, PWHAT WILL +! Description: Module copies PWHAT pointer to PWHERE pointer +! If PWHERE pointer == NULL, PWHAT is a duplicate +! of PWHAT with PWHAT%Ppar == NULL ! -! -! INPUT PARAMETERS: -! +! External Modules used +! USE FLL_TYPE_M USE FLL_MV_M USE FLL_DUPLICATE_M USE FLL_CAT_M - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In pointer which is to be copied +! PWHERE In pointer which is to be copied +! PNEW Out pointer to new copy of PWHAT +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW - +! +! initialize PNEW pointer and check that PWHAT is not NULL +! NULLIFY(PNEW) IF(.NOT.ASSOCIATED(PWHAT))THEN @@ -81,7 +87,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) PNEW => FLL_DUPLICATE(PWHAT, FPAR) ELSE ! -! DUPLICATE NODE AND MOVE IT +! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) @@ -92,16 +98,32 @@ END FUNCTION FLL_CP FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) - +! +! Description: Module copies PWHAT pointer to PWHERE pointer +! If PWHERE pointer == NULL, PWHAT is a duplicate +! of PWHAT with PWHAT%Ppar == NULL +! +! External Modules used +! USE FLL_TYPE_M USE FLL_RM_M USE FLL_STICH_M USE FLL_DUPLICATE_M - - IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In pointer which is to be copied +! PWHERE In pointer which is to be copied +! MODE In if C - copy mode, if M - move mode +! PSOURCETMP Out pointer to new copy of PWHAT +! FPAR In/Out structure containing function specific data ! +! Arguments declaration +! + IMPLICIT NONE + TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE @@ -114,7 +136,9 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! BODY OF SUBROUTINE ! PSOURCETMP => NULL() - +! +! check that node is not null +! FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' @@ -122,7 +146,9 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. RETURN END IF - +! +! check that pwhere is associated +! IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' FPAR%SUCCESS = .FALSE. diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 9123b76..7fba26f 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -20,38 +20,60 @@ ! ! Subroutine FLL_TYPE_M -! -! Date: 2016-10-10 -! -! Description: Definition of the data set type for linked list ! ! -! Input parameters: -! +MODULE FLL_TYPE_M +! +! Description: efinition of the data set type for linked list and other related data ! -! Return value: -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Modifications: -! Date Version Patch number CLA ! +! External Modules used ! -! Description + ! +! define std I/O desriptors + +#ifdef f2008 +use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & + stdout=>output_unit, & + stderr=>error_unit +#else +#define stdin 5 +#define stdout 6 +#define stderr 0 +#endif + ! -MODULE FLL_TYPE_M -!#ifdef f2003 -!use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & -! stdout=>output_unit, & -! stderr=>error_unit -!#else -!#define stdin 5 -!#define stdout 6 -!#define stderr 0 -!#endif -! -! MODULE SPECIFIC VARIABLES +! Declarations +! +! Arguments description +! Name Function +! PWHAT pointer which is to be copied +! PWHERE pointer which is to be copied +! PNEW pointer to new copy of PWHAT +! FPAR structure containing function specific data +! +! RSINGLE ! real kind +! RDOUBLE ! double kind +! SINT ! integer kind +! LINT ! long integer kind +! +! NAME_LENGTH length of string for names +! TYPE_LENGTH length of string for type +! ERR_MSG_LENGTH length of string for error message +! ERR_PATH_LENGTH length of string for path of in err message +! FILE_NAME_LENGTH length of string for file names +! STRING_LENGHT length of long string + +! MAX_SUB maximum number of subsets in each node +! +! Arguments declaration ! IMPLICIT NONE INTEGER, PARAMETER :: RSINGLE = SELECTED_REAL_KIND(P=6,R=37) @@ -71,7 +93,7 @@ MODULE FLL_TYPE_M ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! TYPE DNODE - CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list + CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 @@ -79,34 +101,34 @@ MODULE FLL_TYPE_M TYPE (DNODE), POINTER :: & PPAR =>NULL(),& ! Pointer to parent list - PCHILD =>NULL(),& ! Pointer to first child list - PNEXT =>NULL(),& ! Pointer to next list - PPREV =>NULL(),& ! Pointer to previous list - PLINK =>NULL() ! Pointer to link target + PCHILD =>NULL(),& ! Pointer to first child list + PNEXT =>NULL(),& ! Pointer to next list + PPREV =>NULL(),& ! Pointer to previous list + PLINK =>NULL() ! Pointer to link target - REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) =>NULL() - REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) =>NULL() - INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) =>NULL() - INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) =>NULL() - CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S1(:)=>NULL() - CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() + REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) =>NULL() ! real arrays + REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) =>NULL() ! double arrays + INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) =>NULL() ! integer arrays + INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) =>NULL() ! long integer arrays + CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S1(:)=>NULL() ! 1D array of strings + CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() ! 2D array of strings - REAL(RSINGLE) :: R0 - REAL(RDOUBLE) :: D0 - INTEGER(SINT) :: I0 - INTEGER(LINT) :: L0 - CHARACTER(LEN=STRING_LENGHT) :: S - CHARACTER(LEN=NAME_LENGTH) :: T - CHARACTER :: C - - + REAL(RSINGLE) :: R0 ! real + REAL(RDOUBLE) :: D0 ! double + INTEGER(SINT) :: I0 ! integer + INTEGER(LINT) :: L0 ! long integer + CHARACTER(LEN=STRING_LENGHT) :: S ! string + CHARACTER(LEN=NAME_LENGTH) :: T ! short string + CHARACTER :: C ! character END TYPE DNODE - +! +! type used for diagnostic data set passed to subroutines and functions +! TYPE FUNC_DATA_SET - LOGICAL :: SUCCESS, ERRMSG - CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG - CHARACTER(LEN=ERR_PATH_LENGTH) :: ERRPATH + LOGICAL :: SUCCESS ! if .TRUE.=success, .FALSE. = fail + CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG ! error message + CHARACTER(LEN=ERR_PATH_LENGTH) :: ERRPATH ! path END TYPE FUNC_DATA_SET END MODULE FLL_TYPE_M From a073f6af3a6f07216115cbf9b3ea8cd14c235927 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 08:18:01 -0600 Subject: [PATCH 031/325] add template for formating subroutines --- template_v1.f90 | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 template_v1.f90 diff --git a/template_v1.f90 b/template_v1.f90 new file mode 100644 index 0000000..c4ec892 --- /dev/null +++ b/template_v1.f90 @@ -0,0 +1,65 @@ +! +! Header for svn +! +MODULE Convection +! +! Description: +! +! +! History: +! Version Date Comment +! ------- -------- ------- +! 1.1 24/03/16 Update of ... +! +! + +! External Modules used + USE FFAType + USE FFAData + +! Declarations + IMPLICIT NONE + PRIVATE + PUBLIC ConvectionMean + +CONTAINS + + SUBROUTINE ConvectionMean(pglob,preg,nnodes) + +! Description: Computes convective mean flow +! Fluxes computed and added to residuals +! + +! Declarations + IMPLICIT NONE + +! Arguments description +! Name In/Out Function +! pglob In/Out Pointer to all data +! preg In/Out Pointer to region data +! nnodes In Number of nodes + +! Arguments declaration + TYPE(DATA_SET), POINTER :: pglob + TYPE(DATA_SET), POINTER :: pdom + INTEGER, INTENT(IN) :: nnodes + +! Local variables declaration + INTEGER ndim,ncol,iupwin,irot,nsc,nedges + REAL :: gom1 + +! +! Global data +! + iupwin = Get_Child_I0(pglob,'IUPWIN') + +!... + + END SUBROUTINE ConvectionMean + + SUBROUTINE ConvectionTurbulence(pglob,preg,nnodes) +!... + +END MODULE Convection + +END MODULE GCONEU_M From a891531b6302154339837954f529f9712962adf4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 08:58:45 -0600 Subject: [PATCH 032/325] next round of fuctions to be formated to template --- data_util/fll_cat.f90 | 114 +++++--- data_util/fll_cp.f90 | 5 - data_util/fll_deattach.f90 | 54 ++-- data_util/fll_duplicate.f90 | 97 +++++-- data_util/fll_getndata.f90 | 517 +++++++++++++++++++++++++++++------- 5 files changed, 606 insertions(+), 181 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index fa379a3..fb04e3d 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -15,54 +15,56 @@ ! along with this program. If not, see . ! ! contact: libm3l@gmail.com -! -! - ! ! Subroutine FLL_CAT ! -! Date: 2016-10-10 -! -! -! ! -! Description: prints linked list -! +MODULE FLL_CAT_M ! -! Input parameters: -! +! Description: Contains function fll_cp ! -! Return value: ! -! -! -! Modifications: -! Date Version Patch number CLA -! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Description ! +! External Modules used ! -MODULE FLL_CAT_M CONTAINS SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) - +! +! Description: Module prints the short content of PNODE to IOUNIT +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer to be printed +! IOUNIR In pointer which is to be copied +! PARENT In parameter, if .TRUE. write information about PNODE parent node +! FPAR In/Out structure containing function specific data ! - TYPE(DNODE), POINTER :: PNODE,PCHILD +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - INTEGER(LINT) :: POS LOGICAL :: PARENT ! -! LOCAL TYPES +! Local types ! -! -! BODY OF SUBROUTINE + TYPE(DNODE), POINTER :: PCHILD + INTEGER(LINT) :: POS +! +! body of subroutine ! POS = 1 FPAR%SUCCESS = .FALSE. @@ -87,22 +89,37 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) RETURN END SUBROUTINE FLL_CAT ! -! DELETE CHID WITH ALL ITS CHILDREN +! print node recursively ! RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) - +! +! Description: Module prints the short content of PNODE to IOUNIT +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE -! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer to be printed +! IOUNIR In pointer which is to be copied +! PARENT In parameter, if .TRUE. write information about PNODE parent node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS - - TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD INTEGER :: IOUNIT ! +! Local variables +! + TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD +! ! IF NODE HAS CHILDREN ! POS = POS + 1 @@ -133,16 +150,34 @@ END SUBROUTINE FLL_CAT_RECURSIVE_NODE ! FREE MEMORY FOR NODE ! SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) +! +! Description: print content of PNODE +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer to be printed +! IOUNIR In pointer which is to be copied +! PARENT In parameter, if .TRUE. write information about PNODE parent node +! FPAR In/Out structure containing function specific data +! POS In level in linked list +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT - INTEGER(LINT) :: POS,I,J,NDIM,NSIZE + INTEGER(LINT) :: POS +! +! Local variables +! + INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED CHARACTER*2048 :: TEXT,TEXT1 CHARACTER*72 :: NDSTR,NSSTR @@ -154,7 +189,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) NSIZE = PNODE%NSIZE SPACE(:) = ' ' ! -! HEADERS +! print headers ! WRITE(NDSTR,'(I10)')PNODE%NDIM WRITE(NSSTR,'(I10)')PNODE%NSIZE @@ -171,7 +206,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'x',TRIM(ADJUSTL(NSSTR)),' ',SPACE,TRIM(PNODE%LNAME) END IF ! -! 1 D ARRAYS +! print 1D arrays ! IF(ASSOCIATED(PNODE%R1))THEN WRITE(TEXT,*)" ",SPACE,(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) @@ -194,7 +229,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ! -! 2D ARRAYS +! print 2D arrays ! ELSE IF(ASSOCIATED(PNODE%R2))THEN WRITE(TEXT,*)" ",SPACE,((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) @@ -218,7 +253,8 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) SAVED = .TRUE. END IF ! -! CHECK IF NODE IS CONSTANT +! if not 1D or 2D arrays, print constants +! only for nodes which contain something ! IF(.NOT.SAVED)THEN IF(NDIM /= 0 .AND. NSIZE /= 0)THEN diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 8938999..d509e6a 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -15,14 +15,9 @@ ! along with this program. If not, see . ! ! contact: libm3l@gmail.com -! -! - ! ! Subroutine FLL_CP ! -! Date: 2016-10-10 -! ! MODULE FLL_CP_M ! diff --git a/data_util/fll_deattach.f90 b/data_util/fll_deattach.f90 index b46a298..16d3f0a 100644 --- a/data_util/fll_deattach.f90 +++ b/data_util/fll_deattach.f90 @@ -15,45 +15,60 @@ ! along with this program. If not, see . ! ! contact: libm3l@gmail.com -! ! - ! ! Subroutine FLL_DEATTACH ! -! Date: 2016-10-10 -! -! -! ! -! Description: DEATTACHES NODE FROM THE LIST +MODULE FLL_DEATTACH_M ! +! Description: Deattach node from the list ! -! Input parameters: ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Return value: -! -! ! -! Modifications: -! Date Version Patch number CLA +! External Modules used + +CONTAINS + FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) ! +! Description: Deattach PWHAT node from the list +! upon return, PWHAT parent is set to NULL and +! the nodes is moved outside the list it is currently in ! -! Description +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -MODULE FLL_DEATTACH_M -CONTAINS +! External Modules used - FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) USE FLL_TYPE_M USE FLL_STICH_M +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In node to deattach from the list +! OK In return parameter, of .TRUE. - success, if .FALSE. - fail +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT TYPE(FUNC_DATA_SET) :: FPAR LOGICAL:: OK - +! +! check that PWAT is not null node +! OK = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Deattach - null node ' @@ -64,6 +79,9 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! CALL FLL_STICH(PWHAT,FPAR) +! +! set PWHAT pointers +! PWHAT%PPAR => NULL() PWHAT%PNEXT => NULL() PWHAT%PPREV => NULL() diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 0f8ecb9..131ea71 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -17,54 +17,64 @@ ! contact: libm3l@gmail.com ! ! - ! -! Subroutine FLL_duplicate ! -! Date: 2016-10-10 -! -! +MODULE FLL_DUPLICATE_M ! +! Description: Contains duplicates node ! -! Description: duplicates node with its children ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Input parameters: -! ! -! Return value: -! -! +! External Modules used ! -! Modifications: -! Date Version Patch number CLA +CONTAINS + FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! +! Description: Contains duplicates node to PNEW mode +! the parent, previous and next pointers of PNEW node are NULL ! -! Description +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -MODULE FLL_DUPLICATE_M -CONTAINS - - FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) - +! External Modules used +! USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M IMPLICIT NONE ! -! SUBROUTINE DUPLICATE NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! PNEW Out duplicate node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL TYPES +! Local declarations ! TYPE(DNODE), POINTER :: PCHILD ! ! BODY OF SUBROUTINE ! +! +! check the node is not null +! PNEW => NULL() FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN @@ -117,17 +127,31 @@ END FUNCTION FLL_DUPLICATE ! DELETE CHID WITH ALL ITS CHILDREN ! RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) - +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PDUPL Out duplicate of PNODE +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PDUPL TYPE(FUNC_DATA_SET) :: FPAR - +! +! Local declarations +! TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD LOGICAL :: OK ! @@ -188,19 +212,36 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE ! -! FREE MEMORY FOR NODE +! ! SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) +! +! Description: duplicated data of the node +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! PNEW Out duplicate of PNODE data +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - +! +! Local declarations +! INTEGER(LINT) :: NDIM, NSIZE, NNDIM, NNSIZE - +! +! check node types +! IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 82babd2..2fe48f5 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -17,55 +17,63 @@ ! contact: libm3l@gmail.com ! ! - -! -! FUNCTION FLL_GETNDATA -! -! Date: 2016-10-10 -! -! -! +MODULE FLL_GETNDATA_M ! -! Description: prints node -! +! Description: returns data of the node ! -! Input parameters: -! -! -! Return value: -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Modifications: -! Date Version Patch number CLA ! +! External Modules used ! -! Description +CONTAINS + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) ! +! Description: returns single real data of the node ! -MODULE FLL_GETNDATA_M -CONTAINS +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! SINGLE ! - FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) - +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R0 Out returns value of real scalar +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RSINGLE) :: R0 ! -! LOCAL TYPES +! Local declarations +! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE +! +! check for null nodes ! IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -91,24 +99,47 @@ END FUNCTION FLL_GETNDATA_R0 FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R1 Out returns pointer to real array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RSINGLE), POINTER :: R1(:) ! -! LOCAL TYPES +! Local declarations ! + LOGICAL :: RECURSE + TYPE(DNODE), POINTER :: PFIND + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' @@ -131,24 +162,48 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_R1 FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R2 Out returns pointer to real array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RSINGLE), POINTER :: R2(:,:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R2 - Null node ' @@ -173,24 +228,49 @@ END FUNCTION FLL_GETNDATA_R2 ! DOUBLE ! FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R1 Out returns double number +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RDOUBLE) :: R0 ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' @@ -215,24 +295,49 @@ END FUNCTION FLL_GETNDATA_D0 FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R1 Out returns pointer to double array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RDOUBLE), POINTER :: R1(:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' @@ -256,24 +361,49 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_D1 FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! R1 Out returns pointer to double array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE REAL(RDOUBLE), POINTER :: R2(:,:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' @@ -298,24 +428,48 @@ END FUNCTION FLL_GETNDATA_D2 ! INTEGER ! FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I0 Out returns integer value +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(SINT) :: I0 ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' @@ -340,24 +494,48 @@ END FUNCTION FLL_GETNDATA_I0 FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I1 Out returns pointer to integer array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(SINT), POINTER :: I1(:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' @@ -380,24 +558,48 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_I1 FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I2 Out returns pointer to integer array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(SINT), POINTER :: I2(:,:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' @@ -422,24 +624,48 @@ END FUNCTION FLL_GETNDATA_I2 ! LONG INTEGER ! FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I0 Out returns long integer value +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(LINT) :: I0 ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' @@ -470,18 +696,31 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I1 Out returns pointer to long integer array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(LINT), POINTER :: I1(:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' @@ -504,24 +743,48 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_L1 FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! I2 Out returns pointer to long integer array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE INTEGER(LINT), POINTER :: I2(:,:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' @@ -544,24 +807,48 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! STRING Out returns string +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE CHARACTER(LEN=STRING_LENGHT) :: STRING ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' @@ -584,24 +871,48 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! STRING Out returns pointer to string array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' @@ -624,24 +935,48 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S1 FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) - +! +! Description: returns single real data of the node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! Arguments description +! Name In/Out Function +! PNODE In pointer to data set +! NAME In name of pointer +! NUMBER Out number of pointer if more pointers of the same type are present +! LTYPE Out type of pointer +! FPAR In/Out structure containing function specific data +! STRING Out returns pointer to string array +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER - LOGICAL :: RECURSE CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:,:) ! -! LOCAL TYPES +! local declarations ! + TYPE(DNODE), POINTER :: PFIND + LOGICAL :: RECURSE + + IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' From 211e50acd77f62440a3c8ef5e0493ec52cd1dd34 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 09:19:25 -0600 Subject: [PATCH 033/325] Next round of format updates --- data_util/fll_funct_prt.f90 | 42 ++++++++++++------------- data_util/fll_locate.f90 | 61 +++++++++++++++++-------------------- data_util/fll_mk.f90 | 50 +++++++++++++----------------- data_util/fll_modules | 10 ------ 4 files changed, 71 insertions(+), 92 deletions(-) delete mode 100644 data_util/fll_modules diff --git a/data_util/fll_funct_prt.f90 b/data_util/fll_funct_prt.f90 index 07b489d..392b274 100644 --- a/data_util/fll_funct_prt.f90 +++ b/data_util/fll_funct_prt.f90 @@ -17,39 +17,39 @@ ! contact: libm3l@gmail.com ! ! - +MODULE FLL_FUNC_PRT_M ! -! Subroutine FLL_FUNC_PRT_M +! Description: Contains prototypes of some functions ! -! Date: 2016-10-10 -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -! Description: Finds node in a chain -! +! External Modules used ! -! Input parameters: -! +CONTAINS + + FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) ! -! Return value: -! -! +! Description: writes to a err message string ! -! Modifications: -! Date Version Patch number CLA +! External Modules used +! + USE FLL_TYPE_M + IMPLICIT NONE ! +! Declarations ! -! Description +! Arguments description +! Name In/Out Function +! NAME In name of node +! NTYPE In type of node ! +! Arguments declaration ! -MODULE FLL_FUNC_PRT_M -CONTAINS - - FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) - - USE FLL_TYPE_M - IMPLICIT NONE CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: NTYPE diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index df01322..2f0d13a 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -17,43 +17,42 @@ ! contact: libm3l@gmail.com ! ! - -! -! Subroutine FLL_LOCATE -! -! Date: 2016-10-10 -! -! -! -! -! Description: Finds node in a chain -! -! -! Input parameters: -! -! -! Return value: -! -! -! -! Modifications: -! Date Version Patch number CLA -! +MODULE FLL_LOCATE_M ! -! Description +! Description: locate node ! +! External Modules used ! -MODULE FLL_LOCATE_M CONTAINS RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESULT(PFIND) - +! +! Description: function finds node identified by name, type, position in list, dimensions of data it contains +! serach can be done recursively +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer where find node +! NAME In name of node +! NUMBER In position of node in list +! LTYPE In type of node - can be * +! DATADIM In dimensions of data the node should contain +! can be 0 - scalar), 1 -1D array, 2 -2D array +! any other number (prefer -1) - do not care about dimensions +! RECURSE In search recursively +! PFIND Out return pointer to located node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE,PFIND @@ -62,21 +61,17 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE ! -! LOCAL TYPES +! Local declarations ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD INTEGER(LINT) :: LOCNUM,I, NDIM, NSIZE ! -! BODY OF FUNCTION +! remove empty spaces ! NULLIFY(PFIND) - I = 1 - DO WHILE(LTYPE(I:I) == ' ') - I = I + 1 - END DO - TLTYPE = TRIM(LTYPE(I:)) + TLTYPE = ADJUSTL(TRIM(LTYPE(I:))) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index c68202b..2c93ce6 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -17,46 +17,43 @@ ! contact: libm3l@gmail.com ! ! - -! -! Subroutine FLL_MK -! -! Date: 2016-10-19 -! -! +MODULE FLL_MK_M ! +! Description: creates node ! -! Description: make nodes +! External Modules used ! +CONTAINS + FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) ! -! Input parameters: -! +! Description: function creates node specified by name, type and dimensions ! -! Return value: +! External Modules used ! -! -! -! Modifications: -! Date Version Patch number CLA + USE FLL_TYPE_M + + IMPLICIT NONE ! +! Declarations ! -! Description +! Arguments description +! Name In/Out Function +! NAME In name of node +! LTYPE In type of node - can be * +! NDIM, NSIZE In node dimensions +! PNEW Out return pointer to newly created node +! FPAR In/Out structure containing function specific data ! +! Arguments declaration ! -MODULE FLL_MK_M -CONTAINS - - FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) - - USE FLL_TYPE_M - - IMPLICIT NONE TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NDIM, NSIZE - +! +! Local declarations +! INTEGER :: ISTAT PNEW => NULL() @@ -204,7 +201,4 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) RETURN END FUNCTION FLL_MK - - - END MODULE FLL_MK_M diff --git a/data_util/fll_modules b/data_util/fll_modules deleted file mode 100644 index 1a4506c..0000000 --- a/data_util/fll_modules +++ /dev/null @@ -1,10 +0,0 @@ -USE FLL_DUPLICATE_M -USE FLL_RUNC_PRT_M -USE FLL_LOCATE_M -USE FLL_MK_M -USE FLL_MVCP_M -USE FLL_READ_M -USE FLL_RM_M -USE FLL_STICH_M -USE FLL_TYPE_M -USE FLL_WRITE_M From 50825aacf32663a997b7ca9e4cd3a1ddf08df5d1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 09:33:51 -0600 Subject: [PATCH 034/325] next round of comments --- data_util/fll_cp.f90 | 6 ++++ data_util/fll_mods.f90 | 37 +++++++++++++++++-- data_util/fll_mv.f90 | 75 +++++++++++++++++++++++++------------- data_util/fll_nnodes.f90 | 77 ++++++++++++++++++++++++---------------- examples/fll_test.f90 | 2 +- 5 files changed, 139 insertions(+), 58 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index d509e6a..7f9cb0f 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -40,6 +40,12 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! If PWHERE pointer == NULL, PWHAT is a duplicate ! of PWHAT with PWHAT%Ppar == NULL ! +! if PWHERE is DIR on N type, PWHAT is added +! to it as a new sub-data set +! +! if PWHERE is a data type of nodes +! PWHAT overwrites it +! ! External Modules used ! USE FLL_TYPE_M diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 5862602..0e88474 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -1,6 +1,39 @@ - +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! MODULE FLL_MODS_M - +! +! Description: Contains list of modules of data_util fll library +! each function/subroutine using fll data utilities +! should then use statement +! USE FLL_MODS_M +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_CAT_M USE FLL_CP_M USE FLL_DEATTACH_M diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 51a65e4..ef003c9 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -16,43 +16,53 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_MV_M ! - -! -! Subroutine FLL_MV +! Description: Contains function fll_mv ! -! Date: 2016-10-10 -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -! Description: moves or copies node -! -! -! Input parameters: -! +! External Modules used ! -! Return value: -! -! +CONTAINS + FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) ! -! Modifications: -! Date Version Patch number CLA +! Description: Module moves PWHAT pointer to PWHERE pointer ! +! if PWHERE is DIR on N type, PWHAT is added +! to it as a new sub-data set ! -! Description +! if PWHERE is a data type of nodes +! PWHAT overwrites it ! +! External Modules used ! -MODULE FLL_MV_M -CONTAINS - - FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) USE FLL_TYPE_M IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In pointer which is to be copied +! PWHERE In pointer which is to be copied +! FPAR In/Out structure containing function specific data +! OK Out if .TRUE. succes, of .FALSE. fail +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PWHAT,PWHERE - TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PSOURCETMP + TYPE(FUNC_DATA_SET) :: FPAR LOGICAL OK +! +! Local declarations +! + TYPE(DNODE), POINTER :: PSOURCETMP PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) OK = FPAR%SUCCESS @@ -61,7 +71,14 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) END FUNCTION FLL_MV FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) - +! +! Description: Module moves or copies PWHAT pointer to PWHERE pointer +! depending on MODE values (C or M) +! If PWHERE pointer == NULL, PWHAT is a duplicate +! of PWHAT with PWHAT%Ppar == NULL +! +! External Modules used +! USE FLL_TYPE_M USE FLL_RM_M USE FLL_STICH_M @@ -74,8 +91,18 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE ! -! LOCAL TYPES +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In pointer which is to be copied +! PWHERE In pointer which is to be copied +! MODE In if C - copy mode, if M - move mode +! PSOURCETMP Out pointer to new copy of PWHAT +! FPAR In/Out structure containing function specific data ! +! Arguments declaration +! TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& PLAST, PSOURCETMP,PCHILD,PNEW ! diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 1030834..0622849 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -17,56 +17,59 @@ ! contact: libm3l@gmail.com ! ! - -! -! Subroutine FLL_NNODES -! -! Date: 2016-10-10 -! -! -! -! -! Description: calculates number of nodes -! +MODULE FLL_NNODES_M ! -! Input parameters: -! +! Description: Contains function fll_nnodes ! -! Return value: -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Modifications: -! Date Version Patch number CLA ! +! External Modules used ! -! Description +CONTAINS + RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMBER) ! +! Description: function returns number of nodes specified by +! name, type and dimensions of data +! if data dimensions not specified as 0,1 or 2, +! do not care about data dimensions ! -MODULE FLL_NNODES_M -CONTAINS - - RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) - +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE ! -! FUNCTION FIND NODES WITH SPECIFIED NAME +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer where to search +! NAME In name of pointer +! LTYPE Out type of pointer +! DATADIM Out dimensions of data set of pointer +! RECURSE Out serach recursively +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(FUNC_DATA_SET) :: FPAR - TYPE(DNODE), POINTER :: PNODE,PFIND + TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LINT) :: NUMBER + INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE ! -! LOCAL TYPES +! local declarations ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE - TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LINT) :: I + TYPE(DNODE), POINTER :: PCURR, PCHLD, PFIND + INTEGER(LINT) :: I,NDIM,NSIZE ! ! BODY OF FUNCTION ! @@ -98,7 +101,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,RECURSE,FPAR) + NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,DATADIM,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN @@ -110,7 +113,19 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(NUMBER) IF( TRIM(PCURR%LNAME) == TRIM(NAME) .AND. & (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN - NUMBER = NUMBER + 1 + NDIM = PCURR%NDIM + NSIZE = PCURR%NSIZE + + SELECT CASE(DATADIM) + CASE(0) + IF(NDIM == 1 .AND. NSIZE == 1)NUMBER = NUMBER + 1 + CASE(1) + IF(NDIM > 1 .OR. NSIZE > 1)NUMBER = NUMBER + 1 + CASE(2) + IF(NDIM > 1 .AND. NSIZE > 1)NUMBER = NUMBER + 1 + CASE DEFAULT + NUMBER = NUMBER + 1 + END SELECT END IF PCURR => PCURR%PNEXT diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 27662d7..2618c3a 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -133,7 +133,7 @@ PROGRAM FLL_TEST ! ! find number 1st subdir IN PNODE1 ! - NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',.false.,FPAR) + NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',-1_lint,.false.,FPAR) write(*,*)' number of TEST1_Subdir subsets is ', NNODES ! ! find the first TEST1_Subdir in PNODE1 and print it on the screen From 416221274f55772ca1251ba0d70d82354a66d21d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 09:52:33 -0600 Subject: [PATCH 035/325] Next round of formatin routines --- data_util/fll_rm.f90 | 103 ++++++++++++++++++++++++++++------------ data_util/fll_stich.f90 | 47 +++++++++--------- data_util/fll_sweep.f90 | 51 +++++++++++--------- 3 files changed, 124 insertions(+), 77 deletions(-) diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index 02de994..a831475 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -16,48 +16,50 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_RM_M ! - -! -! Subroutine FLL_RM +! Description: Contains function fll_rm ! -! Date: 2016-10-10 -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -! Description: removes node and all its children -! +! External Modules used ! -! Input parameters: -! -! -! Return value: -! -! +CONTAINS + SUBROUTINE FLL_RM(PNODE,FPAR) ! -! Modifications: -! Date Version Patch number CLA +! Description: function removes PNODE ! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Description ! +! External Modules used ! -MODULE FLL_RM_M -CONTAINS - - SUBROUTINE FLL_RM(PNODE,FPAR) - USE FLL_TYPE_M USE FLL_STICH_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be removed +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PCHILD TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL TYPES +! Local declarations ! INTEGER :: ISTAT ! @@ -96,15 +98,36 @@ END SUBROUTINE FLL_RM ! DELETE CHID WITH ALL ITS CHILDREN ! RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) +! +! Description: recursive function removes PNODE +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE -! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be removed +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE - TYPE(FUNC_DATA_SET) :: FPAR - + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! TYPE(DNODE), POINTER :: PCURR, PNEXT INTEGER :: ISTAT ! @@ -156,14 +179,35 @@ END SUBROUTINE FLL_RM_RECURSIVE_NODE ! FREE MEMORY FOR NODE ! SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) +! +! Description: function deallocates data from associated with PNODE +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be removed +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - +! +! local declarations +! INTEGER :: ISTAT ! ! 1D ARRAYS @@ -251,6 +295,5 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) END IF END SUBROUTINE FLL_DEALLOC_DATA - END MODULE FLL_RM_M diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index f6f2ac5..a908010 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -16,48 +16,47 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_STICH_M ! - -! -! Subroutine FLL_MV +! Description: Contains function fll_stich ! -! Date: 2016-10-10 ! -! -! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Description: stiches list ! +! External Modules used ! -! Input parameters: -! -! -! Return value: -! -! -! -! Modifications: -! Date Version Patch number CLA -! +CONTAINS + SUBROUTINE FLL_STICH(PNODE,FPAR) ! -! Description +! Description: subroutine stiches list after PNODE +! is taken away ! +! External Modules used ! -MODULE FLL_STICH_M -CONTAINS - - SUBROUTINE FLL_STICH(PNODE,FPAR) USE FLL_TYPE_M IMPLICIT NONE ! -! STICHES THE LIST AFTER REMOVING NODES +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be take away from the list +! the list has to be stiched in place where the +! node PNODE will be missing +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL TYPES +! Local declarations ! TYPE(DNODE), POINTER :: PNEXT=>NULL(), PPREV=>NULL(),PPAR=>NULL() ! diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 6568461..483c279 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -16,45 +16,50 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_SWEEP_M ! - -! -! Subroutine FLL_SWEEP -! -! Date: 2016-10-10 -! -! -! +! Description: Contains function fll_sweek ! -! Description: sweep through list ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Input parameters: -! ! -! Return value: -! -! +! External Modules used ! -! Modifications: -! Date Version Patch number CLA +CONTAINS + FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) ! +! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! -! Description +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -MODULE FLL_SWEEP_M -CONTAINS - - FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) - +! External Modules used +! USE FLL_TYPE_M USE FLL_LOCATE_M IMPLICIT NONE ! -! FUNCTION FIND ALL NODES WITH SPECIFIED NAME OR TYPE +! Description: Module copies PWHAT pointer to PWHERE pointer +! If PWHERE pointer == NULL, PWHAT is a duplicate +! of PWHAT with PWHAT%Ppar == NULL +! +! if PWHERE is DIR on N type, PWHAT is added +! to it as a new sub-data set ! +! if PWHERE is a data type of nodes +! PWHAT overwrites it +! +! External Modules used +! TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME From 32fd0596dfbd8d9610005be5c0fa3d4be2084448 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 10:32:33 -0600 Subject: [PATCH 036/325] update RW to current source code structure --- data_util/fll_read.f90 | 186 ++++++++++++++++++++++++++++++++++------ data_util/fll_sweep.f90 | 4 +- data_util/fll_write.f90 | 173 ++++++++++++++++++++++++++++--------- 3 files changed, 296 insertions(+), 67 deletions(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 420a7f1..105422b 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -44,15 +44,47 @@ ! ! MODULE FLL_READ_M +! +! Description: Contains functions reading FLL native format file, ASCII and BINARY +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! CONTAINS FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) - +! +! Description: main function opening, reading and closing file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M - IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary, * not specified +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! CHARACTER(*) :: FILE TYPE(DNODE), POINTER :: PNODE @@ -60,7 +92,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER :: FMT ! -! LOCAL TYPES +! Local declarations ! LOGICAL :: OK CHARACTER :: FMT_LOC @@ -76,7 +108,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) RETURN END IF ! -! DETERMINE RORMAT' +! DETERMINE RORMAT ! SELECT CASE(FMT) CASE('A','a') @@ -127,19 +159,45 @@ END FUNCTION FLL_READ ! READS NODE ! RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) - +! +! Description: Function reads a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! POS In/Out Position in bindary file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! INTEGER(LINT), INTENT(OUT) :: POS - TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(DNODE), POINTER :: PNODE CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - +! +! Local declarations +! + TYPE(DNODE), POINTER :: PNEW TYPE(FUNC_DATA_SET) :: FPAR_H CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: LTYPE @@ -202,25 +260,56 @@ END FUNCTION READ_NODE ! READ HEADER OR EACH NODE ! SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) - +! +! Description: Reads header of each node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! NAME In name of node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! POS In/Out Position in bindary file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! INTEGER(LINT) :: POS CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT - + INTEGER :: IOUNIT CHARACTER(*) :: LTYPE CHARACTER(*) :: NAME - INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND + INTEGER(LINT) :: NDIM, NSIZE +! +! Local declarations +! + INTEGER(LINT) :: ISTART,IIND CHARACTER*255 :: TEXT_LINE,TRIM_LINE INTEGER :: IOSTAT LOGICAL :: OK - - +! +! body of function +! SELECT CASE(FMT) CASE('A') TEXT_LINE(1:1) = '*' @@ -317,19 +406,44 @@ END SUBROUTINE READ_HEADER ! READ DATA ! SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - +! +! Description: Reads data contatined in node Pnode - ASCII file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! IOUNIT In Number of unit +! NAME In name of node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE CHARACTER(LEN=TYPE_LENGTH) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL DECLARATION +! Local declarations ! INTEGER(LINT) :: I,J INTEGER :: IOSTAT @@ -432,27 +546,47 @@ SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) RETURN END SUBROUTINE READ_DATA_ASCII - - - - ! ! READ DATA ! SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - +! +! Description: Function reads data contained in Pnode, bindary file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! IOUNIT In Number of unit +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE CHARACTER(*) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL DECLARATION +! Local declarations ! INTEGER(LINT) :: I,J INTEGER :: IOSTAT diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 483c279..8974e8b 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -88,9 +88,9 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) FPAR%SUCCESS = .FALSE. RETURN END IF - +! ! DO WHILE(PNODE) - +! PCURR => PNODE%PCHILD IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN WRITE(*,*)' NODE NOT DIR NODE' diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index e9eeeb0..0a0d6b4 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -17,43 +17,48 @@ ! contact: libm3l@gmail.com ! ! - -! -! Subroutine FLL_WRITE -! -! Date: 2016-10-10 -! -! +MODULE FLL_WRITE_M ! +! Description: Contains functions writing FLL native format file, ASCII and BINARY ! -! Description: prints node ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Input parameters: -! ! -! Return value: -! -! +! External Modules used ! -! Modifications: -! Date Version Patch number CLA +CONTAINS + FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! +! Description: main function opening, writing and closing file ! -! Description +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -MODULE FLL_WRITE_M -CONTAINS - - - FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) - +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary, * not specified +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! CHARACTER(*) :: FILE TYPE(DNODE), POINTER :: PNODE @@ -62,7 +67,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CHARACTER :: FMT LOGICAL OK ! -! LOCAL TYPES +! local declarations ! CHARACTER :: FMT_LOC INTEGER :: ISTAT @@ -123,20 +128,41 @@ END FUNCTION FLL_WRITE SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) +! +! Description: Function writes a list +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE WRITES LIST +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PCHILD TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT - INTEGER(LINT) :: POS -! -! LOCAL TYPES ! +! Local declarations +! + INTEGER(LINT) :: POS ! ! BODY OF SUBROUTINE ! @@ -168,19 +194,42 @@ END SUBROUTINE FLL_WRITE_LIST ! DELETE CHID WITH ALL ITS CHILDREN ! RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) - +! +! Description: Function writes a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! POS In/Out position in binary file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT TYPE(FUNC_DATA_SET) :: FPAR - INTEGER(LINT) :: POS - + INTEGER(LINT) :: POS + CHARACTER :: FMT +! +! Local declarations +! TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD - INTEGER :: IOUNIT - CHARACTER :: FMT ! ! IF NODE HAS CHILDREN ! @@ -213,15 +262,37 @@ END SUBROUTINE FLL_WRITE_RECURSIVE_NODE ! FREE MEMORY FOR NODE ! SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) +! +! Description: Writes node and its data to an ASCII file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE SAVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FPAR In/Out structure containing function specific data ! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT +! +! Local declarations +! INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED @@ -316,17 +387,41 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) END SUBROUTINE FLL_SAVE_NODE_A SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) +! +! Description: Writes node and its data to an ASCII file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE SAVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! POS In/Out position in binary file +! FPAR In/Out structure containing function specific data ! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT - INTEGER(LINT) :: I,J,NDIM,NSIZE,POS + INTEGER(LINT) :: POS +! +! Local declarations +! + INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED SAVED = .FALSE. From da229088d2341633318898626790a2f5fe7b6611 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 10:44:50 -0600 Subject: [PATCH 037/325] finish source code formating --- data_util/fll_read_ffa.f90 | 209 +++++++++++++++++++++++++++--------- data_util/fll_write.f90 | 2 +- data_util/fll_write_ffa.f90 | 175 +++++++++++++++++++++++------- 3 files changed, 295 insertions(+), 91 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 5de0dfb..20bdcb9 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -16,43 +16,48 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_READ_FFA_M ! - -! -! Subroutine FLL_READ_FFA +! Description: Contains functions reading FFA native format file, ASCII and BINARY ! -! Date: 2016-10-10 -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -! Description: reads a ffa file +! External Modules used ! +CONTAINS + FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! -! Input parameters: -! +! Description: main function opening, reading and closing file ! -! Return value: -! ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Modifications: -! Date Version Patch number CLA -! -! -! Description ! -! -MODULE FLL_READ_FFA_M -CONTAINS - - FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) - +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary, * not specified +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! CHARACTER(*) :: FILE TYPE(DNODE), POINTER :: PNODE @@ -60,7 +65,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER :: FMT ! -! LOCAL TYPES +! Local declarations ! LOGICAL :: OK CHARACTER :: FMT_LOC @@ -127,26 +132,52 @@ END FUNCTION FLL_READ_FFA ! READS NODE ! RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) - +! +! Description: Function reads a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! POS In/Out Position in binary file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! INTEGER(LINT), INTENT(OUT) :: POS - TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(DNODE), POINTER :: PNODE CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - INTEGER(LINT) :: NSUB - CHARACTER(LEN=NAME_LENGTH) :: T - +! +! Local declarations +! + TYPE(DNODE), POINTER :: PNEW TYPE(FUNC_DATA_SET) :: FPAR_H CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: LTYPE,FTYPE INTEGER(LINT) :: NDIM, NSIZE,NNODES,NDIMO,NSIZEO LOGICAL :: OK,EXTRALINE + INTEGER(LINT) :: NSUB + CHARACTER(LEN=NAME_LENGTH) :: T ! ! READ HEADER ! @@ -217,24 +248,59 @@ END FUNCTION READ_NODE_FFA ! READ HEADER OR EACH NODE ! SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIMO,NSIZEO,EXTRALINE,FPAR) - +! +! Description: Reads header of each node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! NAME In name of node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! NLINK In = NSUB in FFA format +! NDIM0 In original value of NDIM from FFA format +! NSIZE0 In original value of NSIZE from FFA format +! EXTRALINE In/Out If node node N but has NSUB > 0 read extra line +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! INTEGER(LINT) :: POS CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - - CHARACTER(*) :: LTYPE,FTYPE - CHARACTER(*) :: NAME - INTEGER(LINT) :: NDIM, NSIZE,ISTART,IIND,NLINK,TMPINT,NDIMO,NSIZEO,I + LOGICAL :: EXTRALINE + INTEGER(LINT) :: NDIM, NSIZE,NLINK,NDIMO,NSIZEO + CHARACTER(*) :: LTYPE + CHARACTER(*) :: NAME +! +! Local declarations +! + CHARACTER(*) :: FTYPE + INTEGER(LINT) :: ISTART,IIND,TMPINT,I CHARACTER*255 :: TEXT_LINE,TRIM_LINE CHARACTER*32 :: VER INTEGER :: IOSTAT - LOGICAL :: OK,EXTRALINE + LOGICAL :: OK EXTRALINE = .FALSE. @@ -412,19 +478,44 @@ END SUBROUTINE READ_HEADER_FFA ! READ DATA ! SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - +! +! Description: Reads data contatined in node Pnode - ASCII file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! IOUNIT In Number of unit +! NAME In name of node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE CHARACTER(LEN=TYPE_LENGTH) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL DECLARATION +! Local declarations ! INTEGER(LINT) :: I,J INTEGER :: IOSTAT @@ -527,29 +618,49 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) RETURN END SUBROUTINE READ_DATA_FFA_ASCII - - - - + + + + SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! -! READ DATA +! Description: Function reads data contained in Pnode, binary file ! - SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) - +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M USE FLL_FUNC_PRT_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! IOUNIT In Number of unit +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE,NINTEG CHARACTER(*) :: LTYPE - CHARACTER(LEN=NAME_LENGTH) :: T TYPE(FUNC_DATA_SET) :: FPAR ! -! LOCAL DECLARATION +! Local declarations ! + CHARACTER(LEN=NAME_LENGTH) :: T INTEGER(LINT) :: I,J INTEGER :: IOSTAT LOGICAL :: OK diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 0a0d6b4..28ae809 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -388,7 +388,7 @@ END SUBROUTINE FLL_SAVE_NODE_A SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ! -! Description: Writes node and its data to an ASCII file +! Description: Writes node and its data to a binary file ! ! ! History: diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index a31589a..9f80e50 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -16,44 +16,47 @@ ! ! contact: libm3l@gmail.com ! +MODULE FLL_WRITE_FFA_M ! - -! -! Subroutine FLL_WRITE_FFA -! -! Date: 2016-10-10 -! -! -! +! Description: Contains functions writing FFA native format file, ASCII and BINARY ! -! Description: prints node ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Input parameters: -! ! -! Return value: -! -! +! External Modules used ! -! Modifications: -! Date Version Patch number CLA +CONTAINS + FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! +! Description: main function opening, writing and closing file ! -! Description +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! -MODULE FLL_WRITE_FFA_M -CONTAINS - - - FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) - +! External Modules used +! USE FLL_TYPE_M - IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary, * not specified +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! CHARACTER(*) :: FILE TYPE(DNODE), POINTER :: PNODE @@ -63,7 +66,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) LOGICAL OK CHARACTER(32) :: FFVERSION='FFA-format-v2' ! -! LOCAL TYPES +! Local declarations ! CHARACTER :: FMT_LOC INTEGER :: ISTAT @@ -125,20 +128,41 @@ END FUNCTION FLL_WRITE_FFA SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) - +! +! Description: Function writes a list +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE WRITES LIST +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! - TYPE(DNODE), POINTER :: PNODE,PCHILD + TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT - INTEGER(LINT) :: POS ! -! LOCAL TYPES +! Local declarations ! + TYPE(DNODE), POINTER :: PCHILD + INTEGER(LINT) :: POS ! ! BODY OF SUBROUTINE ! @@ -170,20 +194,44 @@ END SUBROUTINE FLL_WRITE_FFA_LIST ! DELETE CHID WITH ALL ITS CHILDREN ! RECURSIVE SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) - +! +! Description: Function writes a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE REMOVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! POS In/Out position in binary file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS - - TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD INTEGER :: IOUNIT CHARACTER :: FMT ! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR, PNEXT, PCHILD + +! ! IF NODE HAS CHILDREN ! PCURR => PNODE @@ -215,15 +263,37 @@ END SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE ! FREE MEMORY FOR NODE ! SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) +! +! Description: Writes node and its data to an ASCII file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE SAVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT +! +! Local declarations +! INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED CHARACTER(LEN=TYPE_LENGTH) :: LTYPE @@ -354,17 +424,40 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) END SUBROUTINE FLL_SAVE_NODE_A SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) - +! +! Description: Writes node and its data to a binary file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M IMPLICIT NONE ! -! SUBROUTINE SAVES NODE +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! POS In/Out position in binary file +! FPAR In/Out structure containing function specific data ! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT - INTEGER(LINT) :: I,J,NDIM,NSIZE,POS + INTEGER(LINT) :: POS +! +! Local declarations +! + INTEGER(LINT) :: I,J,NDIM,NSIZE LOGICAL :: SAVED CHARACTER(LEN=TYPE_LENGTH) :: NTYPE ='N', LTYPE From e894456fce48cbc82303516241966b7075e149de Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 10:55:28 -0600 Subject: [PATCH 038/325] Finish source code formating --- INSTALLATION | 24 +++++++ Makefile | 28 +++++++- accessories/ll_cat/Makefile | 44 ------------- accessories/ll_cat/ada.py | 10 --- accessories/ll_cat/ll_cat.f90 | 82 ------------------------ accessories/ll_cat/project.dep | 6 -- data_util/Makefile | 32 ++++++++- data_util/fll_type.f90 | 12 ++-- data_util/project.dep | 8 +-- examples/Makefile | 30 +++++++++ template_v1.f90 => template_v1.Sourcef90 | 0 11 files changed, 119 insertions(+), 157 deletions(-) delete mode 100644 accessories/ll_cat/Makefile delete mode 100644 accessories/ll_cat/ada.py delete mode 100644 accessories/ll_cat/ll_cat.f90 delete mode 100644 accessories/ll_cat/project.dep rename template_v1.f90 => template_v1.Sourcef90 (100%) diff --git a/INSTALLATION b/INSTALLATION index f92d148..3c41336 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -1,3 +1,27 @@ +* +* Copyright (C) 2016 Adam Jirasek +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +* +* contact: libm3l@gmail.com +* +* +* +* Description: Installation instruction +* +* + **************************************************** To install FLL you would need to: diff --git a/Makefile b/Makefile index 56bc6f7..8bd948f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,30 @@ # -# Makefile -# Do not edit this file +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation # # # diff --git a/accessories/ll_cat/Makefile b/accessories/ll_cat/Makefile deleted file mode 100644 index c2524ac..0000000 --- a/accessories/ll_cat/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -############################################################################ -# Makefile for ffalist -############################################################################ -# -# $HeadURL: https://costello.foi.se/svn/edge/branches/aeroelastics/programs/ffalist/Makefile $ -# $LastChangedDate: 2007-09-21 14:50:09 +0200 (Fri, 21 Sep 2007) $ -# $LastChangedBy: oskeno $ -# $LastChangedRevision: 1282 $ - -EXE = ll_cut - -include src_dir_path.mk -include ../../config.mk - -DEP_FILE=project.dep -FMODDIRS= ../../data_util - -FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) - - -OFILES=$(FFILES:%.f90=%.o) -XOFILES=$(wildcard ../../data_util/*.o) - -########################################################################### - -all: $(EXE).x $(EXE) - -include ../../rules.mk - -$(EXE).x: $(OFILES) $(XOFILES) - $(FC) $(LDFLAGS) -o $@ $^ - -clean: - rm -f *.x *.o *.mod $(EXE) - -depend: $(FFILES) - @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r /home/jka/OSS_CFD/trunk -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) - -install: $(EXE).x $(EXE) - $(INSTALL) $(EXE) $(prefix)/bin/$(EXE)$(POSTFIX) - $(INSTALL) $(EXE).x $(prefix)/bin/$(EXE)$(POSTFIX).x - --include $(srcdir)/project.dep diff --git a/accessories/ll_cat/ada.py b/accessories/ll_cat/ada.py deleted file mode 100644 index dd73512..0000000 --- a/accessories/ll_cat/ada.py +++ /dev/null @@ -1,10 +0,0 @@ - -import fnmatch -import os - -matches = [] -for root, dirnames, filenames in os.walk('/home/jka/OSS_CFD/trunk/accessories/ll_cat'): - for filename in fnmatch.filter(filenames, '*.f90'): - matches.append(os.path.join(root, filename)) - print(filename) - diff --git a/accessories/ll_cat/ll_cat.f90 b/accessories/ll_cat/ll_cat.f90 deleted file mode 100644 index 4be1b92..0000000 --- a/accessories/ll_cat/ll_cat.f90 +++ /dev/null @@ -1,82 +0,0 @@ -! -! Copyright (C) 2016 Adam Jirasek -! -! This program is free software: you can redistribute it and/or modify -! it under the terms of the GNU Lesser General Public License as published by -! the Free Software Foundation, either version 3 of the License, or -! (at your option) any later version. -! -! This program is distributed in the hope that it will be useful, -! but WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -! GNU Lesser General Public License for more details. -! -! You should have received a copy of the GNU Lesser General Public License -! along with this program. If not, see . -! -! contact: libm3l@gmail.com -! -! - -! -! Subroutine LL_MV -! -! Date: 2016-10-10 -! -! -! -! -! Description: duplicate -! -! -! Input parameters: -! -! -! Return value: -! -! -! -! Modifications: -! Date Version Patch number CLA -! -! -! Description -! -! - PROGRAM LL_TEST - - USE LL_TYPE_M - USE LL_READ_M - USE LL_RM_M - USE LL_MV_M - USE LL_CP_M - USE LL_MK_M -! INCLUDE '.././data_util/l_modules' - IMPLICIT NONE -! -! SUBROUTINE MOVES NODE -! - CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,ptmp - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT - CHARACTER :: FMT -! -! LOCAL TYPES -! - LOGICAL :: OK - CHARACTER :: FMT_LOC - INTEGER :: ISTAT - INTEGER(LINT) :: POS - - PNODE => LL_READ('TEST',8,'A',FPAR)\ - - WRITE(*,*)' COPY' - PNEW => LL_CP(PNODE, NULL(), FPAR) - WRITE(*,*)' REMOVE' - CALL LL_RM(PNODE,FPAR) - WRITE(*,*)' REMOVE' - CALL LL_RM(PNEW,FPAR) - - -END PROGRAM diff --git a/accessories/ll_cat/project.dep b/accessories/ll_cat/project.dep deleted file mode 100644 index 2a694b3..0000000 --- a/accessories/ll_cat/project.dep +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated automatically. DO NOT EDIT! - -ll_cat.o : \ - ../../data_util/ll_rm.o \ - ../../data_util/ll_read.o \ - ../../data_util/ll_type.o diff --git a/data_util/Makefile b/data_util/Makefile index fed4b7e..061c2a5 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -1,6 +1,32 @@ -############################################################################ -# Makefile for data_util library -############################################################################ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# # include src_dir_path.mk include ../config.mk diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 7fba26f..1f91553 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -39,15 +39,15 @@ MODULE FLL_TYPE_M ! ! define std I/O desriptors -#ifdef f2008 -use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & - stdout=>output_unit, & - stderr=>error_unit -#else +!#ifdef f2008 +!use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & +! stdout=>output_unit, & +! stderr=>error_unit +!#else #define stdin 5 #define stdout 6 #define stderr 0 -#endif +!#endif ! ! Declarations diff --git a/data_util/project.dep b/data_util/project.dep index 97f37d5..60bf35a 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -18,10 +18,8 @@ fll_sweep.o : \ fll_locate.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mk.o \ fll_type.o fll_cp.o : \ @@ -32,8 +30,10 @@ fll_cp.o : \ fll_stich.o \ fll_type.o -fll_locate.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_type.o fll_duplicate.o : \ diff --git a/examples/Makefile b/examples/Makefile index aeb8758..8bdd180 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,3 +1,33 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# EXE = fll_test diff --git a/template_v1.f90 b/template_v1.Sourcef90 similarity index 100% rename from template_v1.f90 rename to template_v1.Sourcef90 From 6b1a5e35511c6b6644d37c6b74bf64e66be98a91 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 12:33:14 -0600 Subject: [PATCH 039/325] update documentation --- ...2\200\223 Fortran Linked List Library.pptx" | Bin 54663 -> 0 bytes "fll\342\200\223FortranLinkedListLibrary.pdf" | Bin 0 -> 431111 bytes "fll\342\200\223FortranLinkedListLibrary.pptx" | Bin 0 -> 77083 bytes 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 "fll \342\200\223 Fortran Linked List Library.pptx" create mode 100644 "fll\342\200\223FortranLinkedListLibrary.pdf" create mode 100644 "fll\342\200\223FortranLinkedListLibrary.pptx" diff --git "a/fll \342\200\223 Fortran Linked List Library.pptx" "b/fll \342\200\223 Fortran Linked List Library.pptx" deleted file mode 100644 index 6a24606f56d1b240af83990859e1be3ee41a56ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54663 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

Rl%->jFNnL}3}9LrpL4wIdVZluCY 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�TEBC`jB2NKn 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 literal 0 HcmV?d00001 diff --git "a/fll\342\200\223FortranLinkedListLibrary.pptx" "b/fll\342\200\223FortranLinkedListLibrary.pptx" new file mode 100644 index 0000000000000000000000000000000000000000..1a2bf23c4a09174afb4d217c91089f1853ebe7ba GIT binary patch literal 77083 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 literal 0 HcmV?d00001 From 78054dbe25418216a80b74085352391cfbd1f180 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 15:03:20 -0600 Subject: [PATCH 040/325] correct some bugs --- data_util/fll_getndata.f90 | 58 ++++++++++---------- data_util/fll_locate.f90 | 2 +- examples/fll_test.f90 | 106 +++++++++++++++++++++++-------------- 3 files changed, 94 insertions(+), 72 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 2fe48f5..0bf5172 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -78,7 +78,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R0 - Null node ' - STOP + RETURN END IF @@ -87,7 +87,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -143,7 +143,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' - STOP + RETURN END IF @@ -152,7 +152,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -207,7 +207,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R2 - Null node ' - STOP + RETURN END IF @@ -216,7 +216,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -274,7 +274,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' - STOP + RETURN END IF @@ -283,7 +283,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -337,11 +337,9 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) TYPE(DNODE), POINTER :: PFIND LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' - STOP RETURN END IF @@ -350,7 +348,6 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP RETURN END IF @@ -407,7 +404,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' - STOP + RETURN END IF @@ -416,7 +413,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -473,7 +470,6 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' - STOP RETURN END IF @@ -482,7 +478,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -539,7 +535,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' - STOP + RETURN END IF @@ -548,7 +544,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -603,7 +599,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' - STOP + RETURN END IF @@ -612,7 +608,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -669,7 +665,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - STOP + RETURN END IF @@ -678,7 +674,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -724,7 +720,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' - STOP + RETURN END IF @@ -733,7 +729,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -788,7 +784,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' - STOP + RETURN END IF @@ -797,7 +793,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -852,7 +848,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - STOP + RETURN END IF @@ -861,7 +857,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -916,7 +912,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - STOP + RETURN END IF @@ -925,7 +921,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF @@ -980,7 +976,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - STOP + RETURN END IF @@ -989,7 +985,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - STOP + RETURN END IF diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 2f0d13a..2e803fa 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -71,7 +71,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU ! NULLIFY(PFIND) - TLTYPE = ADJUSTL(TRIM(LTYPE(I:))) + TLTYPE = ADJUSTL(TRIM(LTYPE(1:))) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 2618c3a..b580e05 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -51,9 +51,9 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,PNODE2,PNEW1,PNODE1,PTMP,PNEW2,PFFA + TYPE(DNODE), POINTER :: PNODE,PNEW,PNEW1,PNODE1,PTMP,PNEW2 TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT + INTEGER :: IOUNIT,I CHARACTER :: FMT ! ! LOCAL TYPES @@ -62,55 +62,89 @@ PROGRAM FLL_TEST CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS,NNODES - REAL(RDOUBLE), POINTER :: PRESS(:) + REAL(RDOUBLE), POINTER :: PRESS(:),HUMID(:) ! ! read TEST file and store it in PNODE +! file is an ASCII file ! -! PFFA => FLL_READ_FFA('case1.ainp',8,'A',FPAR) - PFFA => FLL_READ_FFA('case1.binp',8,'B',FPAR) - CALL FLL_CAT(PFFA, 6, .TRUE.,FPAR) - WRITE(*,*) - WRITE(*,*)'------------------------------------------------------1' - OK = FLL_WRITE_FFA(PFFA,'File_1.txt',8,'A',FPAR) - -stop + PNODE => FLL_READ('TEST',8,'A',FPAR) ! -! read TEST file and store it in PNODE +! print node on the screen ! - PNODE => FLL_READ('TEST',8,'A',FPAR) CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) WRITE(*,*) WRITE(*,*)'------------------------------------------------------1' ! -! read TEST1 file and store it in PNODE1 +! read TEST1 ASCII file and store it in PNODE1 ! PNODE1 => FLL_READ('TEST1',8,'A',FPAR) ! ! print PNODE1 on screen ! CALL FLL_CAT(PNODE1, 6, .TRUE.,FPAR) + WRITE(*,*) WRITE(*,*)'------------------------------------------------------2' - -!! save PNODE1 as binary and ascii file +! +! save PNODE1 as binary and ascii file ! OK = FLL_WRITE(PNODE1,'File_2.txt',8,'B',FPAR) OK = FLL_WRITE(PNODE1,'File_1.txt',8,'A',FPAR) -! -! read bindary file and store it in PNODE2 -! then print it on screed and then delete it - PNODE2 => FLL_READ('File_2.txt',8,'B',FPAR) - CALL FLL_CAT(PNODE2, 6, .TRUE.,FPAR) - CALL FLL_RM(PNODE2,FPAR) + WRITE(*,*)'------------------------------------------------------3' ! -! MAKE A NEW NODE AND MOVE ENTIRE PNODE INTO IT +! MAKE A NEW NODE CALLED new_node AND MOVE ENTIRE PNODE INTO IT +! THE NODE IS GOING TO CONTAIN OTHER NODESM, IT IS A DIR TYPE OF NODE ! PRINT IT ON THE SCREEN ! - PNEW1 => FLL_MK("newnone","DIR",0_LINT, 0_LINT,FPAR) - OK = FLL_MV(PNODE, PNEW1, FPAR) + PNEW1 => FLL_MK("new_node","DIR",0_LINT, 0_LINT,FPAR) +! +! create a data node and add it to a PNEW1 +! the node will be called Humidity, will contain doubles, array of 10 +! + PTMP => FLL_MK('Humidity','D', 10_LINT, 1_LINT, FPAR) + OK = FLL_MV(PTMP, PNEW1, FPAR) + CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) +! +! ACCESS DATA OF NODE Humidity +! +! can be done as +! 1. HUMID => PTMP%D1 +! 2. Locating the node in PNEW1 + + HUMID => FLL_GETNDATA_D1(PNEW1,'Humidity',1_LINT,'D',FPAR) + + IF(.NOT.ASSOCIATED(HUMID))THEN + STOP' DID NOT FIND HUMID' + ELSE +! +! with this array you can work as with a normal array +! +! find dimensions +! 1. NDIM = PTMP%NDIM +! 2. SIZE FUNCTION +! + WRITE(*,*) + WRITE(*,*)'SIZE OF ARRAY IS ',SIZE(HUMID) + WRITE(*,*) + END IF +! +! fill it with some data +! + DO I=1,10 + HUMID(I) = 3.1415926*I + END DO +! +! add PNODE to PNEW1 +! now the node contains Humidity and entire PNODE +! + OK = FLL_MV(PNODE, PNEW1, FPAR) CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------4' +! +! SOME ADDITIONAL OPERATIONS +! + ! ! COPY PNODE, BECASE THE TARGET IN COPY IS NULL ! THE PNEW IS GOING TO BE A DUPLICATE OF PNODE @@ -120,21 +154,12 @@ PROGRAM FLL_TEST CALL FLL_CAT(PNEW, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------5' ! -! REMOVE PNEW1 -! - CALL FLL_RM(PNEW1,FPAR) -! -! COPY PNODE TO PNEW -! ON RETURN, THE FLL_CP WILL GIVE BACK POINTER OF PNEW IN PNODE LIST -! - PNEW2 => FLL_CP(PNEW, PNODE1, FPAR) - CALL FLL_CAT(PNODE1, 6, .TRUE.,FPAR) - WRITE(*,*)'------------------------------------------------------6' -! ! find number 1st subdir IN PNODE1 ! NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',-1_lint,.false.,FPAR) - write(*,*)' number of TEST1_Subdir subsets is ', NNODES + WRITE(*,*) + WRITE(*,*)' number of TEST1_Subdir subsets is ', NNODES + WRITE(*,*) ! ! find the first TEST1_Subdir in PNODE1 and print it on the screen ! @@ -142,7 +167,7 @@ PROGRAM FLL_TEST CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------7' ! -! find the values of pressure subset #1 and print them on screen +! find the values of pressure subset #1 and print the data on screen ! PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,'D',FPAR) write(*,*)' Values of pressure are ',PRESS @@ -151,13 +176,14 @@ PROGRAM FLL_TEST ! WRITE(*,*)' REMOVE ===========================' ! -! WE HAVE TO REMOVE PNODE1 AND PNEW WHICH WAS CREATED ON LINE 107 +! WE HAVE TO REMOVE PNODE1 AND PNEW WHICH WAS CREATED ON LINE 153 ! PNODE WAS DELETED AS PART OF PNEW1 WHERE IT WAS MOVED -! PNODE2 WAS DELETED RIGHT AFTER BEING RETURN FROM READ + ! PNEW2 IS NOT A NEW NODE, IT POINTS TO A COPY SO DOES NOT NEED TO BE FREED ! CALL FLL_RM(PNEW,FPAR) CALL FLL_RM(PNODE1,FPAR) + CALL FLL_RM(PNODE,FPAR) END PROGRAM From 2e663c1b672c593712fee4410e0e788e7eb11e80 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 15:19:48 -0600 Subject: [PATCH 041/325] add subroutine to example --- examples/fll_test.f90 | 41 ++------------ examples/fll_test_subr.f90 | 107 +++++++++++++++++++++++++++++++++++++ examples/project.dep | 6 ++- 3 files changed, 115 insertions(+), 39 deletions(-) create mode 100644 examples/fll_test_subr.f90 diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index b580e05..22ec033 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -46,6 +46,7 @@ PROGRAM FLL_TEST USE FLL_MODS_M + USE FLL_TEST_SUBR_N IMPLICIT NONE ! ! SUBROUTINE MOVES NODE @@ -141,47 +142,11 @@ PROGRAM FLL_TEST OK = FLL_MV(PNODE, PNEW1, FPAR) CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------4' -! -! SOME ADDITIONAL OPERATIONS -! -! -! COPY PNODE, BECASE THE TARGET IN COPY IS NULL -! THE PNEW IS GOING TO BE A DUPLICATE OF PNODE -! AND IS GOING TO BE A NEW NODE -! - PNEW => FLL_CP(PNODE, NULL(), FPAR) - CALL FLL_CAT(PNEW, 6, .TRUE.,FPAR) - WRITE(*,*)'------------------------------------------------------5' -! -! find number 1st subdir IN PNODE1 -! - NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',-1_lint,.false.,FPAR) - WRITE(*,*) - WRITE(*,*)' number of TEST1_Subdir subsets is ', NNODES - WRITE(*,*) -! -! find the first TEST1_Subdir in PNODE1 and print it on the screen -! - PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',-1_LINT,.false.,FPAR) - CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) - WRITE(*,*)'------------------------------------------------------7' -! -! find the values of pressure subset #1 and print the data on screen -! - PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,'D',FPAR) - write(*,*)' Values of pressure are ',PRESS -! -! CLEANUP ALL MEMORY -! - WRITE(*,*)' REMOVE ===========================' -! -! WE HAVE TO REMOVE PNODE1 AND PNEW WHICH WAS CREATED ON LINE 153 -! PNODE WAS DELETED AS PART OF PNEW1 WHERE IT WAS MOVED + CALL FLL_TEST_SUBR(PNODE,PNODE1) -! PNEW2 IS NOT A NEW NODE, IT POINTS TO A COPY SO DOES NOT NEED TO BE FREED + WRITE(*,*)'---BACK FROM SUBROUTINE --------------8' ! - CALL FLL_RM(PNEW,FPAR) CALL FLL_RM(PNODE1,FPAR) CALL FLL_RM(PNODE,FPAR) diff --git a/examples/fll_test_subr.f90 b/examples/fll_test_subr.f90 new file mode 100644 index 0000000..a7d5925 --- /dev/null +++ b/examples/fll_test_subr.f90 @@ -0,0 +1,107 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: duplicate +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_TEST_SUBR_N +CONTAINS + + SUBROUTINE FLL_TEST_SUBR(PNODE,PNODE1) + + USE FLL_MODS_M + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE,PNEW,PNEW1,PNODE1,PTMP,PNEW2 + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT,I + CHARACTER :: FMT +! +! LOCAL TYPES +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS,NNODES + REAL(RDOUBLE), POINTER :: PRESS(:),HUMID(:) +! +! SOME ADDITIONAL OPERATIONS +! + +! +! COPY PNODE, BECASE THE TARGET IN COPY IS NULL +! THE PNEW IS GOING TO BE A DUPLICATE OF PNODE +! AND IS GOING TO BE A NEW NODE +! + PNEW => FLL_CP(PNODE, NULL(), FPAR) + CALL FLL_CAT(PNEW, 6, .TRUE.,FPAR) + WRITE(*,*)'------------------------------------------------------5' +! +! find number 1st subdir IN PNODE1 +! + NNODES = FLL_NNODES(PNODE1,'TEST1_Subdir','*',-1_lint,.false.,FPAR) + WRITE(*,*) + WRITE(*,*)' number of TEST1_Subdir subsets is ', NNODES + WRITE(*,*) +! +! find the first TEST1_Subdir in PNODE1 and print it on the screen +! + PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',-1_LINT,.false.,FPAR) + CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) + WRITE(*,*)'------------------------------------------------------7' +! +! find the values of pressure subset #1 and print the data on screen +! + PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,'D',FPAR) + write(*,*)' Values of pressure are ',PRESS +! +! PNEW WAS CREATED HERE, IT DOES NOT BELONG TO ANY NODE (WAS NOT MOVED TO ANY NODE) +! HAS TO BE REMOVED HERE +! + CALL FLL_RM(PNEW,FPAR) + + + END SUBROUTINE FLL_TEST_SUBR +END MODULE FLL_TEST_SUBR_N diff --git a/examples/project.dep b/examples/project.dep index f2ae792..ceeaf1d 100644 --- a/examples/project.dep +++ b/examples/project.dep @@ -1,4 +1,8 @@ # This file is generated automatically. DO NOT EDIT! -fll_test.o : \ +fll_test_subr.o : \ ../data_util/fll_mods.o + +fll_test.o : \ + ../data_util/fll_mods.o \ + fll_test_subr.o From dc29fe80f183bdb06ff5f281010d9d998bb29b93 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 18:42:19 -0600 Subject: [PATCH 042/325] Update README.md --- README.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 446799e..d5d78cd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,35 @@ # fll is a fortran linked list library -The library creates, modifies, removes, saves and read from file a multi-level linked list. +The library enables operations with linked list. +For more information see attached ppt or pdf file in the project root directory + +1. CONFIGURATION +==================================================== + +Make a new directory. +In this directory execute configure script from FLL project source directory. +For example, if the FLL source is in + +/home/usr/fll_souce/fll-master + +and you want to compile and install everyting in + +/home/usr/fll_exec + +directory, then do: + +mkdir /home/usr/fll_exec +cd /home/usr/fll_exec +/home/usr/fll_souce/master/configure.py + + + +2. COMPILATION: +==================================================== + +To compile, type + +gmake + [![Analytics](https://ga-beacon.appspot.com/UA-86532469-1/libm3l/fll)](https://github.com/igrigorik/ga-beacon) From 49d339c9229595e591cc963d4fb5af8dcb2076ee Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 18:55:44 -0600 Subject: [PATCH 043/325] remmove unused variables --- data_util/fll_read_ffa.f90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 20bdcb9..e1626d9 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -177,7 +177,6 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) INTEGER(LINT) :: NDIM, NSIZE,NNODES,NDIMO,NSIZEO LOGICAL :: OK,EXTRALINE INTEGER(LINT) :: NSUB - CHARACTER(LEN=NAME_LENGTH) :: T ! ! READ HEADER ! @@ -296,7 +295,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! Local declarations ! CHARACTER(*) :: FTYPE - INTEGER(LINT) :: ISTART,IIND,TMPINT,I + INTEGER(LINT) :: ISTART,IIND,I CHARACTER*255 :: TEXT_LINE,TRIM_LINE CHARACTER*32 :: VER INTEGER :: IOSTAT @@ -753,7 +752,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) PNODE%S1(I) = T END DO ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG DO J=1,NSIZE DO I=1,NDIM READ(IOUNIT,IOSTAT=IOSTAT)T From 5bb45c80e5fd3f172d9fdb0ff7e1eb4ce385d46d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 19:53:39 -0600 Subject: [PATCH 044/325] bug fix - moved and copied nodes did not updated their PPAR pointer --- data_util/fll_mv.f90 | 17 ++++++++++++----- data_util/fll_rm.f90 | 28 ++++++++++++++++++++++++---- data_util/fll_stich.f90 | 6 ++++-- examples/fll_test.f90 | 24 ++++++++++++++++++------ 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index ef003c9..3144d0b 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -132,7 +132,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! GET TYPE OF TARGET NODE ! DISTINGUISH BETWEEN DIR, OTHER TYPES ! - SELECT CASE(PWHERE%LTYPE) + SELECT CASE( TRIM(PWHERE%LTYPE)) CASE('N','DIR') ! @@ -145,10 +145,11 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DIR IS EMPTY ! PWHERE%PCHILD => PSOURCETMP + PWHERE%NDIM = 1 + PSOURCETMP%PPAR => PWHERE PSOURCETMP%PPREV => NULL() PSOURCETMP%PNEXT => NULL() - PWHERE%NDIM = 1 ELSE ! @@ -160,10 +161,12 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) PCHILD => PCHILD%PNEXT END DO - PLAST%PNEXT => PSOURCETMP + PLAST%PNEXT => PSOURCETMP + PWHERE%NDIM = PWHERE%NDIM + 1 + PSOURCETMP%PPREV => PLAST PSOURCETMP%PNEXT => NULL() - PWHERE%NDIM = PWHERE%NDIM + 1 + PSOURCETMP%PPAR => PWHERE END IF @@ -185,8 +188,11 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! PWHERE WAS THE FIRST NODE IN THE LIST ! PTPAR%PCHILD => PSOURCETMP + PTPAR%NDIM = PTPAR%NDIM + 1 + PSOURCETMP%PPAR => PTPAR PSOURCETMP%PPREV => NULL() + PSOURCETMP%PPAR => PWHERE PTPAR%NDIM = PTPAR%NDIM + 1 IF(ASSOCIATED(PTNEXT))THEN @@ -201,7 +207,8 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! PTPREV%PNEXT => PSOURCETMP PSOURCETMP%PPREV => PTPREV - + PSOURCETMP%PPAR => PWHERE + IF(ASSOCIATED(PTNEXT))THEN PSOURCETMP%PNEXT => PTNEXT ELSE diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index a831475..cba394f 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -74,16 +74,16 @@ SUBROUTINE FLL_RM(PNODE,FPAR) PCHILD => PNODE%PCHILD ! +! STICH AND SUBSTRACT FROM PARENT +! + CALL FLL_STICH(PNODE,FPAR) +! ! IF NODE HAS CHILDREN, REMOVE ALL OF THEM ! IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR) CALL FLL_DEALLOC_DATA(PNODE,FPAR) ! -! STICH AND SUBSTRACT FROM PARENT -! - CALL FLL_STICH(PNODE,FPAR) -! ! NULLIFY NODE ! DEALLOCATE(PNODE, STAT=ISTAT) @@ -251,6 +251,16 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) FPAR%SUCCESS = .TRUE. RETURN END IF + + IF(ASSOCIATED(PNODE%S1))THEN + DEALLOCATE(PNODE%S1, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:204 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF ! ! 2D ARRAYS ! @@ -293,6 +303,16 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) FPAR%SUCCESS = .TRUE. RETURN END IF + + IF(ASSOCIATED(PNODE%S2))THEN + DEALLOCATE(PNODE%S2, STAT=ISTAT) + IF(ISTAT /= 0)THEN + STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:246 ' + FPAR%SUCCESS = .FALSE. + END IF + FPAR%SUCCESS = .TRUE. + RETURN + END IF END SUBROUTINE FLL_DEALLOC_DATA diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index a908010..0951ffe 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -62,7 +62,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) ! ! BODY OF SUBROUTINE ! - IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN + IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Stich - null node ' FPAR%SUCCESS = .FALSE. RETURN @@ -70,7 +70,9 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) PNEXT => PNODE%PNEXT PPREV => PNODE%PPREV - PPAR => PNODE%PPAR + PPAR => PNODE%PPAR + + IF(.NOT.ASSOCIATED(PNEXT) .AND. .NOT.ASSOCIATED(PPREV) .AND. .NOT.ASSOCIATED(PPAR)) RETURN IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 22ec033..da1ebc6 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -105,7 +105,6 @@ PROGRAM FLL_TEST ! PTMP => FLL_MK('Humidity','D', 10_LINT, 1_LINT, FPAR) OK = FLL_MV(PTMP, PNEW1, FPAR) - CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) ! ! ACCESS DATA OF NODE Humidity ! @@ -135,20 +134,33 @@ PROGRAM FLL_TEST DO I=1,10 HUMID(I) = 3.1415926*I END DO -! -! add PNODE to PNEW1 -! now the node contains Humidity and entire PNODE -! + CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) + +! ! +! ! add PNODE to PNEW1 +! ! now the node contains Humidity and entire PNODE +! ! OK = FLL_MV(PNODE, PNEW1, FPAR) + + WRITE(*,*)'------------------------------------------------------4-1' + CALL FLL_CAT(pnode, 6, .TRUE.,FPAR) + WRITE(*,*)'------------------------------------------------------4-2' + + CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------4' - +! CALL FLL_TEST_SUBR(PNODE,PNODE1) WRITE(*,*)'---BACK FROM SUBROUTINE --------------8' ! CALL FLL_RM(PNODE1,FPAR) CALL FLL_RM(PNODE,FPAR) + + CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) + + + CALL FLL_RM(PNEW1,FPAR) END PROGRAM From 7ec36b30fb92fd669e716c5400a4dde93f08200f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 3 Nov 2016 19:55:17 -0600 Subject: [PATCH 045/325] minor updates in INSTALLATION --- INSTALLATION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALLATION b/INSTALLATION index 3c41336..b54132e 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -32,8 +32,8 @@ To install FLL you would need to: 1. CONFIGURATION ==================================================== -Make a new directory where the compillation procees takes place -In this directory execute configure file from FLL project source directory. +Make a new directory. +In this directory execute configure script from FLL project source directory. For example, if the FLL source is in /home/usr/fll_souce/fll-master From 113c176e071dbe80eb48407c6dda9e7b33b7d2a5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 4 Nov 2016 13:38:21 -0600 Subject: [PATCH 046/325] add compiler specification options --- INSTALLATION | 14 +++++++++++++- README.md | 13 ++++++++++++- configure.py | 21 ++++++++++++++++----- python_dep/fort_depend.py | 2 ++ 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/INSTALLATION b/INSTALLATION index b54132e..fec62ef 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -46,7 +46,19 @@ directory, then do: mkdir /home/usr/fll_exec cd /home/usr/fll_exec -/home/usr/fll_souce/master/configure.py +/home/usr/fll_souce/master/configure.py -c compiler + +where compiler specifies fortran compile options + +avalable are: + + gfortran + gfortran_debug + x86_64 + x86_64_debug + +x86_64 are settings for Intel fortran compiler + NOTE: The configure script should be always located in the diff --git a/README.md b/README.md index d5d78cd..c2a0625 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,18 @@ directory, then do: mkdir /home/usr/fll_exec cd /home/usr/fll_exec -/home/usr/fll_souce/master/configure.py +/home/usr/fll_souce/master/configure.py -c compiler + +where compiler specifies fortran compile options + +avalable are: + + gfortran + gfortran_debug + x86_64 + x86_64_debug + +x86_64 are settings for Intel fortran compiler diff --git a/configure.py b/configure.py index 5ecf32d..daa6bbb 100755 --- a/configure.py +++ b/configure.py @@ -15,7 +15,7 @@ #Definitions -def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): # # definition of parameters # @@ -52,14 +52,14 @@ def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): print(" ") print("\033[031mDIAG:\033[039m creating configure file \033[032m \033[039m") print(" ") - ok = mkconfigfile(path=path, cwd=cwd,version='gfortran', bin_dir=cwd) + ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=cwd) # # create structure and link necessary files # print(" ") print("\033[031mDIAG:\033[039m Recreating project tree structure and linking files \033[032m \033[039m .....") print("\033[031mDIAG:\033[039m Project root directory .... \033[032m \033[039m .....") - ok=prepare_root_dir(root_path=path, cwd=cwd, linkfiles=linkfiles) + ok=prepare_compiler(root_path=path, cwd=cwd, linkfiles=linkfiles) print(" ") print("\033[031mDIAG:\033[039m Subdirectories .... \033[032m \033[039m") ok=mkdir_structure(root_path=path, cwd=cwd, exclude=exclude, linkfiles=linkfiles) @@ -95,7 +95,7 @@ def get_all_dirs(path,exclude): return matchesf -def prepare_root_dir(root_path,cwd, linkfiles): +def prepare_compiler(root_path,cwd, linkfiles): # # list all dirs in project except directories specified in exclude # @@ -254,6 +254,7 @@ def print_header(): parser.add_argument('-o','--output',nargs=1,help='Output file') parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') + parser.add_argument('-c','--compiler',nargs=1,help='Compiler configuration') # Parse the command line arguments args = parser.parse_args() @@ -269,4 +270,14 @@ def print_header(): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' - run(verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + compiler = args.compiler[0] if args.compiler else None + + if not compiler: + print ("\033[031mError: \033[039m missing compiler settings, specify option -c \033[032m") + print ("\033[031m \033[039m available options are: \033[032m gfotran") + print ("\033[031m \033[039m available options are: \033[032m gfotran_debug") + print ("\033[031m \033[039m available options are: \033[032m x86_64") + print ("\033[031m \033[039m available options are: \033[032m x86_64_debug") + sys.exit() + + run(comp=compiler,verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 3bf6197..e938078 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -248,6 +248,7 @@ def __init__(self): parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') + parser.add_argument('-c','--compiler',nargs=1,help='Compiler configuration file') # Parse the command line arguments args = parser.parse_args() @@ -263,6 +264,7 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' root_dir = args.root_dir[0] if args.root_dir else None + compiler = args.compiler[0] if args.root_dir else None if not root_dir: print ("\033[031mError: \033[039m missing path to project root directory \033[032m") From cc9ab2d14180d33bfd69c59880403d18ee614faa Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 4 Nov 2016 14:00:48 -0600 Subject: [PATCH 047/325] add check of available compiler options --- configure.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/configure.py b/configure.py index daa6bbb..b31ef77 100755 --- a/configure.py +++ b/configure.py @@ -180,6 +180,16 @@ def check_path(path): def mkconfigfile(path, cwd,version, bin_dir): filename = path+'/config/compset.'+version + + if not(os.path.exists(filename)): + print ("\033[031mError: \033[039m \033[031m"+version+"\033[039m verion of compiler is not available") + print ("\033[031m \033[039m available options are: \033[032m gfotran\033[039m") + print ("\033[031m \033[039m \033[032m gfotran_debug\033[039m") + print ("\033[031m \033[039m \033[032m x86_64\033[039m") + print ("\033[031m \033[039m \033[032m x86_64_debug\033[039m") + sys.exit() + + exec_dir=bin_dir+"/bin/" confname = 'config.mk' @@ -273,11 +283,11 @@ def print_header(): compiler = args.compiler[0] if args.compiler else None if not compiler: - print ("\033[031mError: \033[039m missing compiler settings, specify option -c \033[032m") - print ("\033[031m \033[039m available options are: \033[032m gfotran") - print ("\033[031m \033[039m available options are: \033[032m gfotran_debug") - print ("\033[031m \033[039m available options are: \033[032m x86_64") - print ("\033[031m \033[039m available options are: \033[032m x86_64_debug") + print ("\033[031mError: \033[039m missing compiler settings, specify option \033[031m-c \033[032m") + print ("\033[031m \033[039m available options are: \033[032m gfotran\033[039m") + print ("\033[031m \033[039m \033[032m gfotran_debug\033[039m") + print ("\033[031m \033[039m \033[032m x86_64\033[039m") + print ("\033[031m \033[039m \033[032m x86_64_debug\033[039m") sys.exit() run(comp=compiler,verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From 8ce46cc2923cdfd1bddfad5a0f69bd13cd1684a5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 4 Nov 2016 20:49:42 -0600 Subject: [PATCH 048/325] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c2a0625..3e7e1a1 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,9 @@ and you want to compile and install everyting in directory, then do: mkdir /home/usr/fll_exec + cd /home/usr/fll_exec + /home/usr/fll_souce/master/configure.py -c compiler where compiler specifies fortran compile options From 7cc3922255b651e95d88b5cfc08ed17b1b4b4136 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 09:09:05 -0600 Subject: [PATCH 049/325] fix python dependency script --- python_dep/fort_depend.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index e938078..3bf6197 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -248,7 +248,6 @@ def __init__(self): parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') - parser.add_argument('-c','--compiler',nargs=1,help='Compiler configuration file') # Parse the command line arguments args = parser.parse_args() @@ -264,7 +263,6 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' root_dir = args.root_dir[0] if args.root_dir else None - compiler = args.compiler[0] if args.root_dir else None if not root_dir: print ("\033[031mError: \033[039m missing path to project root directory \033[032m") From 288bb6581878315ed739d1d17235802bae0c93fc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 09:09:25 -0600 Subject: [PATCH 050/325] add mising headers to routines --- data_util/fll_locate.f90 | 6 ++++++ data_util/fll_mk.f90 | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 2e803fa..7dbe209 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -21,6 +21,12 @@ MODULE FLL_LOCATE_M ! ! Description: locate node ! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! ! External Modules used ! CONTAINS diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index 2c93ce6..9a4a522 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -20,6 +20,11 @@ MODULE FLL_MK_M ! ! Description: creates node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! ! External Modules used ! From ba5e26d7e4d77eb7eeeb509a35f5d5e403844480 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 09:09:35 -0600 Subject: [PATCH 051/325] add mkdir routine --- data_util/fll_mkdir.f90 | 71 +++++++++++++++++++++ data_util/project.dep | 132 +++++++++++++++++++++------------------- examples/project.dep | 8 +-- 3 files changed, 143 insertions(+), 68 deletions(-) create mode 100644 data_util/fll_mkdir.f90 diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 new file mode 100644 index 0000000..c124bbd --- /dev/null +++ b/data_util/fll_mkdir.f90 @@ -0,0 +1,71 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MKDIR_M +! +! Description: creates node +! +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MKDIR(NAME,FPAR) RESULT(PNEW) +! +! Description: function creates node type of DIR +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! NAME In name of node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNEW + CHARACTER(*) :: NAME +! Local declarations +! + INTEGER :: ISTAT + + PNEW => NULL() +! +! Body +! + PNEW => FLL_MK(NAME,"DIR",0_LINT, 0_LINT,FPAR) + + RETURN + END FUNCTION FLL_MKDIR + +END MODULE FLL_MKDIR_M diff --git a/data_util/project.dep b/data_util/project.dep index 60bf35a..de37cb7 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,95 +1,99 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ - fll_type.o - -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_type.o - -fll_stich.o : \ - fll_type.o - -fll_funct_prt.o : \ - fll_type.o +fll_getndata.o : \ + fll_type.o \ + fll_locate.o -fll_sweep.o : \ - fll_locate.o \ - fll_type.o +fll_type.o : -fll_locate.o : \ - fll_funct_prt.o \ - fll_type.o +fll_mkdir.o : \ + fll_type.o \ + fll_mk.o fll_cp.o : \ - fll_mv.o \ - fll_cat.o \ fll_duplicate.o \ + fll_type.o \ fll_rm.o \ - fll_stich.o \ + fll_cat.o \ + fll_mv.o \ + fll_stich.o + +fll_mk.o : \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ +fll_write_ffa.o : \ + fll_type.o + +fll_write.o : \ fll_type.o fll_duplicate.o : \ - fll_mv.o \ + fll_type.o \ fll_mk.o \ - fll_type.o + fll_mv.o -fll_mods.o : \ - fll_mv.o \ - fll_deattach.o \ - fll_cat.o \ - fll_duplicate.o \ - fll_write.o \ - fll_locate.o \ - fll_sweep.o \ - fll_rm.o \ - fll_write_ffa.o \ - fll_funct_prt.o \ - fll_stich.o \ - fll_cp.o \ +fll_rm.o : \ + fll_type.o \ + fll_stich.o + +fll_nnodes.o : \ + fll_type.o \ + fll_funct_prt.o + +fll_read.o : \ + fll_type.o \ fll_mk.o \ + fll_funct_prt.o \ + fll_mv.o + +fll_read_ffa.o : \ fll_type.o \ - fll_nnodes.o \ - fll_read.o \ - fll_getndata.o \ - fll_read_ffa.o + fll_mk.o \ + fll_funct_prt.o \ + fll_mv.o -fll_rm.o : \ - fll_stich.o \ - fll_type.o +fll_sweep.o : \ + fll_type.o \ + fll_locate.o -fll_getndata.o : \ - fll_locate.o \ +fll_funct_prt.o : \ fll_type.o fll_mv.o : \ - fll_stich.o \ + fll_type.o \ fll_rm.o \ - fll_type.o + fll_stich.o -fll_write.o : \ - fll_type.o - -fll_mk.o : \ - fll_type.o - -fll_read.o : \ +fll_mods.o : \ + fll_write.o \ + fll_getndata.o \ + fll_duplicate.o \ + fll_deattach.o \ + fll_cp.o \ + fll_read.o \ + fll_rm.o \ + fll_mk.o \ + fll_sweep.o \ + fll_cat.o \ + fll_type.o \ + fll_locate.o \ + fll_write_ffa.o \ + fll_nnodes.o \ fll_mv.o \ + fll_read_ffa.o \ fll_funct_prt.o \ - fll_mk.o \ - fll_type.o + fll_stich.o + +fll_deattach.o : \ + fll_type.o \ + fll_stich.o + +fll_locate.o : \ + fll_type.o \ + fll_funct_prt.o fll_cat.o : \ fll_type.o -fll_write_ffa.o : \ +fll_stich.o : \ fll_type.o - -fll_type.o : diff --git a/examples/project.dep b/examples/project.dep index ceeaf1d..1f57af6 100644 --- a/examples/project.dep +++ b/examples/project.dep @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! -fll_test_subr.o : \ +fll_test.o : \ + fll_test_subr.o \ ../data_util/fll_mods.o -fll_test.o : \ - ../data_util/fll_mods.o \ - fll_test_subr.o +fll_test_subr.o : \ + ../data_util/fll_mods.o From fafbd812fb1fda683e39bf0f561bfdca1267731c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 10:53:12 -0600 Subject: [PATCH 052/325] fix python dependency script --- python_dep/fort_depend.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index e938078..3bf6197 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -248,7 +248,6 @@ def __init__(self): parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') - parser.add_argument('-c','--compiler',nargs=1,help='Compiler configuration file') # Parse the command line arguments args = parser.parse_args() @@ -264,7 +263,6 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' root_dir = args.root_dir[0] if args.root_dir else None - compiler = args.compiler[0] if args.root_dir else None if not root_dir: print ("\033[031mError: \033[039m missing path to project root directory \033[032m") From 145d731fe3ca2b6e4e2a0f44957f017a22f6924a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 10:53:38 -0600 Subject: [PATCH 053/325] update file headers --- data_util/fll_locate.f90 | 7 +++++++ data_util/fll_mk.f90 | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 2e803fa..c4de7c3 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -21,6 +21,13 @@ MODULE FLL_LOCATE_M ! ! Description: locate node ! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! ! External Modules used ! CONTAINS diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index 2c93ce6..f20761c 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -21,6 +21,13 @@ MODULE FLL_MK_M ! ! Description: creates node ! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! ! External Modules used ! CONTAINS From 90ed5f217e45ee2cfd1b5f7c03c3bb3af5e74b3b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 10:53:57 -0600 Subject: [PATCH 054/325] add mkdir function --- data_util/fll_mkdir.f90 | 71 +++++++++++++++++++++++++ data_util/fll_mods.f90 | 1 + data_util/fll_read_ffa.f90 | 5 +- data_util/project.dep | 105 +++++++++++++++++++------------------ 4 files changed, 128 insertions(+), 54 deletions(-) create mode 100644 data_util/fll_mkdir.f90 diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 new file mode 100644 index 0000000..0eef875 --- /dev/null +++ b/data_util/fll_mkdir.f90 @@ -0,0 +1,71 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MKDIR_M +! +! Description: creates node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MKDIR(NAME,FPAR) RESULT(PNEW) +! +! Description: function creates node specified by name, type and dimensions +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! NAME In name of node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNEW + CHARACTER(LEN=*) :: NAME +! +! Local declarations +! + INTEGER :: ISTAT + + PNEW => NULL() +! +! Body +! + PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR) + + RETURN + END FUNCTION FLL_MKDIR + +END MODULE FLL_MKDIR_M diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 0e88474..df6afbe 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -41,6 +41,7 @@ MODULE FLL_MODS_M USE FLL_FUNC_PRT_M USE FLL_LOCATE_M USE FLL_MK_M + USE FLL_MKDIR_M USE FLL_MV_M USE FLL_NNODES_M USE FLL_READ_M diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index e1626d9..167cbef 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -424,7 +424,6 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM CASE('B') NSIZE = 0 READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK - WRITE(*,*)' 1st read ',NAME,LTYPE,NSIZE, NLINK IF(TRIM(NAME) == 'FFA-format-v2')THEN ! @@ -440,9 +439,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM FTYPE = LTYPE NSIZEO = NSIZE NDIMO = NDIM - - WRITE(*,*)NAME,LTYPE,NSIZE, NLINK - + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN NDIM = NLINK ELSE diff --git a/data_util/project.dep b/data_util/project.dep index 60bf35a..08ae864 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,95 +1,100 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ +fll_mk.o : \ fll_type.o -fll_nnodes.o : \ - fll_funct_prt.o \ +fll_funct_prt.o : \ fll_type.o -fll_stich.o : \ +fll_read.o : \ + fll_mk.o \ + fll_funct_prt.o \ + fll_mv.o \ fll_type.o -fll_funct_prt.o : \ +fll_write.o : \ fll_type.o -fll_sweep.o : \ - fll_locate.o \ +fll_stich.o : \ fll_type.o -fll_locate.o : \ - fll_funct_prt.o \ +fll_rm.o : \ + fll_stich.o \ fll_type.o -fll_cp.o : \ - fll_mv.o \ - fll_cat.o \ - fll_duplicate.o \ - fll_rm.o \ +fll_deattach.o : \ fll_stich.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ +fll_mkdir.o : \ fll_mk.o \ fll_type.o -fll_duplicate.o : \ +fll_cp.o : \ + fll_stich.o \ + fll_duplicate.o \ fll_mv.o \ + fll_type.o \ + fll_rm.o \ + fll_cat.o + +fll_duplicate.o : \ fll_mk.o \ + fll_mv.o \ fll_type.o -fll_mods.o : \ - fll_mv.o \ - fll_deattach.o \ - fll_cat.o \ - fll_duplicate.o \ - fll_write.o \ - fll_locate.o \ - fll_sweep.o \ - fll_rm.o \ - fll_write_ffa.o \ - fll_funct_prt.o \ - fll_stich.o \ - fll_cp.o \ +fll_read_ffa.o : \ fll_mk.o \ - fll_type.o \ - fll_nnodes.o \ - fll_read.o \ - fll_getndata.o \ - fll_read_ffa.o - -fll_rm.o : \ - fll_stich.o \ + fll_funct_prt.o \ + fll_mv.o \ fll_type.o fll_getndata.o : \ fll_locate.o \ fll_type.o -fll_mv.o : \ - fll_stich.o \ - fll_rm.o \ +fll_sweep.o : \ + fll_locate.o \ fll_type.o -fll_write.o : \ +fll_type.o : + +fll_write_ffa.o : \ fll_type.o -fll_mk.o : \ +fll_cat.o : \ fll_type.o -fll_read.o : \ +fll_mods.o : \ + fll_sweep.o \ + fll_locate.o \ + fll_write.o \ + fll_deattach.o \ + fll_nnodes.o \ + fll_stich.o \ + fll_read.o \ + fll_duplicate.o \ + fll_write_ffa.o \ fll_mv.o \ + fll_type.o \ fll_funct_prt.o \ fll_mk.o \ - fll_type.o + fll_rm.o \ + fll_mkdir.o \ + fll_cat.o \ + fll_getndata.o \ + fll_cp.o \ + fll_read_ffa.o -fll_cat.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_type.o -fll_write_ffa.o : \ +fll_locate.o : \ + fll_funct_prt.o \ fll_type.o -fll_type.o : +fll_mv.o : \ + fll_rm.o \ + fll_stich.o \ + fll_type.o From 5b51384fd72443b78efe14385684166c542da780 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 18:54:25 -0600 Subject: [PATCH 055/325] added FLL_OUT function --- data_util/fll_cat.f90 | 2 + data_util/fll_cp.f90 | 5 ++ data_util/fll_deattach.f90 | 2 + data_util/fll_duplicate.f90 | 30 ++++++++ data_util/fll_funct_prt.f90 | 29 +++++++- data_util/fll_getndata.f90 | 74 ++++++++++++------- data_util/fll_locate.f90 | 3 + data_util/fll_mk.f90 | 9 ++- data_util/fll_mods.f90 | 1 + data_util/fll_mv.f90 | 6 +- data_util/fll_nnodes.f90 | 2 + data_util/fll_out.f90 | 123 +++++++++++++++++++++++++++++++ data_util/fll_read.f90 | 12 +++ data_util/fll_read_ffa.f90 | 13 +++- data_util/fll_rm.f90 | 3 + data_util/fll_stich.f90 | 3 + data_util/fll_sweep.f90 | 2 + data_util/fll_type.f90 | 17 ++++- data_util/fll_write.f90 | 15 +++- data_util/fll_write_ffa.f90 | 13 +++- data_util/project.dep | 141 +++++++++++++++++++++--------------- examples/project.dep | 4 +- 22 files changed, 405 insertions(+), 104 deletions(-) create mode 100644 data_util/fll_out.f90 diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index fb04e3d..564e23b 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -41,6 +41,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M IMPLICIT NONE ! ! Declarations @@ -71,6 +72,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' CAT - null node ' FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 7f9cb0f..570a83a 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -52,6 +52,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) USE FLL_MV_M USE FLL_DUPLICATE_M USE FLL_CAT_M + USE FLL_OUT_M ! ! Declarations ! @@ -76,6 +77,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -110,6 +112,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) USE FLL_RM_M USE FLL_STICH_M USE FLL_DUPLICATE_M + USE FLL_OUT_M ! ! Declarations ! @@ -144,6 +147,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -152,6 +156,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_deattach.f90 b/data_util/fll_deattach.f90 index 16d3f0a..57d7ceb 100644 --- a/data_util/fll_deattach.f90 +++ b/data_util/fll_deattach.f90 @@ -51,6 +51,7 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) USE FLL_TYPE_M USE FLL_STICH_M + USE FLL_OUT_M ! ! Declarations ! @@ -72,6 +73,7 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) OK = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Deattach - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 131ea71..594b9b2 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -50,6 +50,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -79,6 +80,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -99,6 +101,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN @@ -111,6 +114,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN @@ -135,6 +139,8 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -184,6 +190,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) PNEW => FLL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN @@ -221,6 +228,8 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -245,6 +254,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF ! @@ -269,6 +279,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -276,6 +287,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R1 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -290,6 +302,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -297,6 +310,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D1 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -312,12 +326,14 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I1 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -332,6 +348,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -339,6 +356,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L1 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -353,6 +371,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -360,6 +379,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S1 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF @@ -377,6 +397,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -384,6 +405,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R2 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF @@ -399,6 +421,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -406,6 +429,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D2 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF @@ -421,6 +445,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -428,6 +453,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I2 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF @@ -443,6 +469,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -450,6 +477,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L2 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF @@ -465,6 +493,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -472,6 +501,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S2 array not allocated',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) RETURN END IF END IF diff --git a/data_util/fll_funct_prt.f90 b/data_util/fll_funct_prt.f90 index 392b274..aa88bb0 100644 --- a/data_util/fll_funct_prt.f90 +++ b/data_util/fll_funct_prt.f90 @@ -36,6 +36,18 @@ FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) ! ! Description: writes to a err message string ! +! +! Description: Writes some standard err message +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! ! External Modules used ! USE FLL_TYPE_M @@ -60,8 +72,21 @@ FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) END FUNCTION ERR_MSG FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) -! +! +! Description: tests IOSTAT return parameter from R/W functions +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE INTEGER :: IOSTAT TYPE(FUNC_DATA_SET) :: FPAR @@ -70,9 +95,11 @@ FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) OK = .FALSE. IF (IOSTAT > 0) THEN WRITE(FPAR%MESG,'(A)')' Read - error readig node data' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. ELSE IF (IOSTAT < 0) THEN WRITE(FPAR%MESG,'(A)')' Read - EOF reached' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. ELSE FPAR%SUCCESS = .TRUE. diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 0bf5172..fbfcf0f 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -46,6 +46,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -78,7 +79,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -87,7 +88,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -113,7 +114,8 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) ! USE FLL_TYPE_M USE FLL_LOCATE_M - + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -143,7 +145,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -152,7 +154,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -177,6 +179,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -216,7 +219,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -243,6 +246,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -274,7 +278,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -283,7 +287,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -310,6 +314,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -340,6 +345,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -348,6 +354,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -373,6 +380,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -404,7 +412,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -413,7 +421,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -440,6 +448,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -470,6 +479,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -478,7 +488,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -504,6 +514,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -535,7 +546,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -544,7 +555,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -568,6 +579,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -599,7 +611,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -608,7 +620,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -634,6 +646,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -665,7 +678,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -674,7 +687,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -689,7 +702,8 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) USE FLL_TYPE_M USE FLL_LOCATE_M - + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -720,7 +734,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -729,7 +743,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -753,6 +767,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -784,7 +799,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -793,7 +808,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -817,6 +832,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -848,7 +864,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -857,7 +873,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -881,6 +897,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -912,7 +929,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -921,7 +938,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -945,6 +962,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -976,7 +994,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -985,7 +1003,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' - + CALL FLL_OUT('ALL',FPAR) RETURN END IF diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index c4de7c3..f4792a3 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -41,6 +41,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -82,6 +83,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -159,6 +161,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU PFIND => NULL() FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) + CALL FLL_OUT('ALL',FPAR) RETURN END FUNCTION FLL_LOCATE diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index db1b701..a691aa1 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -43,6 +43,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -74,16 +75,19 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) ! IF(LEN_TRIM(LTYPE)<1.OR.LEN_TRIM(LTYPE)>TYPE_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) + CALL FLL_OUT('ALL',FPAR) RETURN END IF IF(LEN_TRIM(NAME)>NAME_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong name: ',TRIM(NAME) + CALL FLL_OUT('ALL',FPAR) RETURN END IF IF(.NOT.ANY(LTYPE(1:1)==(/'C','S','I','L','R','D','N'/))) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) + CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -111,9 +115,8 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM < 1 .OR. NSIZE < 1)THEN WRITE(FPAR%MESG,'(A,A,I5,I5)')' Wrong dimensions for node ',TRIM(NAME), NDIM, NSIZE -! WRITE(*,*)' MK WRONG DIMENSIONS ',TRIM(NAME), NDIM, NSIZE -! STOP - RETURN + CALL FLL_OUT('ALL',FPAR) + RETURN END IF ! ! ALLOCATE ARRAYS diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index df6afbe..8db6667 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -53,5 +53,6 @@ MODULE FLL_MODS_M USE FLL_WRITE_M USE FLL_WRITE_FFA_M USE FLL_GETNDATA_M + USE FLL_OUT_M END MODULE FLL_MODS_M diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 3144d0b..790f7fe 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -43,6 +43,7 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) ! External Modules used ! USE FLL_TYPE_M + IMPLICIT NONE ! ! Declarations @@ -82,7 +83,8 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) USE FLL_TYPE_M USE FLL_RM_M USE FLL_STICH_M - + USE FLL_OUT_M + IMPLICIT NONE ! ! SUBROUTINE MOVES NODE @@ -113,12 +115,14 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 0622849..ea7d9c6 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -42,6 +42,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -84,6 +85,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_out.f90 b/data_util/fll_out.f90 new file mode 100644 index 0000000..ccefd11 --- /dev/null +++ b/data_util/fll_out.f90 @@ -0,0 +1,123 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! Subroutine FLL_OUT +! +! +MODULE FLL_OUT_M + IMPLICIT NONE +! +! Description: Contains subroutine FLL_OUT +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + +CONTAINS + SUBROUTINE FLL_OUT(ACTION,FPAR) +! +! Description: Contains subroutine pritning errmessage from FPAR structure +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + + USE FLL_TYPE_M +! +! Declarations +! +! Arguments description +! Name In/Out Function +! ACTION In determines what to do +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + IMPLICIT NONE +! +! ARGUMENTS: +! + CHARACTER(*) :: ACTION + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=72) :: STRMES ='LOGFILE' +! +! Local declarations +! +! +! Select here to print +! + SELECT CASE(ACTION) + + CASE('OPEN') + OPEN(UNIT=IOLOGFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') + + CASE('OPEN_STAT') + OPEN(UNIT=IOSTATFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') + WRITE(IOSTATFILE,'(A)')'Process running ...' + CLOSE(IOSTATFILE) + + CASE('CLOSE') + CLOSE(IOLOGFILE) + + CASE('CLOSE_STAT') + OPEN(UNIT=IOSTATFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') + WRITE(IOSTATFILE,'(A)')'Finished' + CLOSE(IOSTATFILE) + + CASE('LOG') + WRITE(IOLOGFILE,'(A)')FPAR%MESG + FLUSH(IOLOGFILE) + + CASE('OUT') + WRITE(STDOUT,'(A)')FPAR%MESG + FLUSH(STDOUT) + + CASE('ALL') + WRITE(IOLOGFILE,'(A)')FPAR%MESG + FLUSH(IOLOGFILE) + WRITE(STDOUT,'(A)')FPAR%MESG + FLUSH(STDOUT) + + CASE DEFAULT + WRITE(STDOUT,*)& + 'Error: wrong action in fll_out, action: "'//ACTION//'" not defined.' + WRITE(STDOUT,*)FPAR%MESG + FLUSH(STDOUT) + WRITE(IOLOGFILE,*)& + 'Error: wrong action in fll_out, action: "'//ACTION//'" not defined.' + WRITE(IOLOGFILE,*)FPAR%MESG + FLUSH(IOLOGFILE) + + END SELECT + + RETURN +!-------------------------------------END OF FLL_OUT ------------------- + END SUBROUTINE FLL_OUT +END MODULE FLL_OUT_M diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 105422b..a3a4e0a 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -72,6 +72,8 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -103,6 +105,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -119,6 +122,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -137,6 +141,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -149,6 +154,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -174,6 +180,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -210,6 +217,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -223,6 +231,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -274,6 +283,7 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -394,10 +404,12 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) END SELECT WRITE(FPAR%MESG,'(A)')' Read - reading header error ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 167cbef..24aa436 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -44,6 +44,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -76,6 +77,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -92,6 +94,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -110,6 +113,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -122,6 +126,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -147,7 +152,8 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M - + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -184,6 +190,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -197,6 +204,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() STOP @@ -260,6 +268,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -462,10 +471,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM END SELECT WRITE(FPAR%MESG,'(A)')' Read - reading header error ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index cba394f..0b017ff 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -45,6 +45,8 @@ SUBROUTINE FLL_RM(PNODE,FPAR) ! USE FLL_TYPE_M USE FLL_STICH_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -68,6 +70,7 @@ SUBROUTINE FLL_RM(PNODE,FPAR) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' RM - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index 0951ffe..0013e3d 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -39,6 +39,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) ! USE FLL_TYPE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -64,6 +65,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Stich - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -76,6 +78,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 8974e8b..373b631 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -45,6 +45,7 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) ! USE FLL_TYPE_M USE FLL_LOCATE_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -85,6 +86,7 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 1f91553..9f1fee5 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -44,9 +44,13 @@ MODULE FLL_TYPE_M ! stdout=>output_unit, & ! stderr=>error_unit !#else -#define stdin 5 -#define stdout 6 -#define stderr 0 + +! #define STDIN 5 +! #define STDOUT 6 +! #define STDERR 0 +! #define IOSTAT=55 +! #define IOLOG=99 + !#endif ! @@ -76,6 +80,13 @@ MODULE FLL_TYPE_M ! Arguments declaration ! IMPLICIT NONE + + INTEGER, PARAMETER :: STDIN =5 + INTEGER, PARAMETER :: STDOUT=6 + INTEGER, PARAMETER :: STDERR=0 + INTEGER, PARAMETER :: IOSTATFILE=55 + INTEGER, PARAMETER :: IOLOGFILE=99 + INTEGER, PARAMETER :: RSINGLE = SELECTED_REAL_KIND(P=6,R=37) INTEGER, PARAMETER :: RDOUBLE = KIND(0.D0) INTEGER, PARAMETER :: SINT = SELECTED_INT_KIND(9) diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 28ae809..33a554e 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -45,7 +45,8 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! External Modules used ! USE FLL_TYPE_M - + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -83,7 +84,8 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CASE('U','u','*')! UNKNOWN - UNSPECIFIED FORMAT FMT_LOC = 'U' CASE DEFAULT - WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) + WRITE(FPAR%MESG,'(A,A)')' Write_ffaunknown format',TRIM(FMT) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. @@ -102,7 +104,8 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) END SELECT IF(ISTAT/=0) THEN - WRITE(FPAR%MESG,'(A,A)')' Write - error opening file ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Write_ffaerror opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -115,6 +118,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -142,6 +146,8 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) ! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -169,7 +175,8 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) POS = 0 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' CAT - null node ' + WRITE(FPAR%MESG,'(A)')' Write_ffa - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 9f80e50..870868c 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -44,6 +44,8 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -83,6 +85,8 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) + CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. @@ -103,6 +107,8 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write - error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -115,6 +121,8 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -141,6 +149,8 @@ SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) ! External Modules used ! USE FLL_TYPE_M + USE FLL_OUT_M + IMPLICIT NONE ! ! Declarations @@ -169,7 +179,8 @@ SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) POS = 0 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' CAT - null node ' + WRITE(FPAR%MESG,'(A)')' Write - null node ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/project.dep b/data_util/project.dep index 08ae864..bf8d118 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,100 +1,121 @@ # This file is generated automatically. DO NOT EDIT! +fll_mods.o : \ + fll_nnodes.o \ + fll_type.o \ + fll_getndata.o \ + fll_duplicate.o \ + fll_mv.o \ + fll_write.o \ + fll_read_ffa.o \ + fll_mk.o \ + fll_deattach.o \ + fll_cp.o \ + fll_out.o \ + fll_cat.o \ + fll_funct_prt.o \ + fll_mkdir.o \ + fll_locate.o \ + fll_stich.o \ + fll_sweep.o \ + fll_write_ffa.o \ + fll_rm.o \ + fll_read.o + fll_mk.o : \ + fll_out.o \ fll_type.o -fll_funct_prt.o : \ +fll_sweep.o : \ + fll_locate.o \ + fll_out.o \ fll_type.o -fll_read.o : \ - fll_mk.o \ - fll_funct_prt.o \ - fll_mv.o \ - fll_type.o +fll_mv.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o \ + fll_rm.o -fll_write.o : \ +fll_funct_prt.o : \ + fll_out.o \ fll_type.o -fll_stich.o : \ +fll_cat.o : \ + fll_out.o \ fll_type.o fll_rm.o : \ fll_stich.o \ + fll_out.o \ fll_type.o -fll_deattach.o : \ - fll_stich.o \ - fll_type.o +fll_nnodes.o : \ + fll_out.o \ + fll_type.o \ + fll_funct_prt.o -fll_mkdir.o : \ - fll_mk.o \ +fll_locate.o : \ + fll_out.o \ + fll_type.o \ + fll_funct_prt.o + +fll_getndata.o : \ + fll_locate.o \ + fll_out.o \ fll_type.o -fll_cp.o : \ - fll_stich.o \ - fll_duplicate.o \ +fll_duplicate.o : \ fll_mv.o \ fll_type.o \ - fll_rm.o \ - fll_cat.o + fll_out.o \ + fll_mk.o -fll_duplicate.o : \ - fll_mk.o \ - fll_mv.o \ +fll_write_ffa.o : \ + fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mk.o \ - fll_funct_prt.o \ - fll_mv.o \ +fll_write.o : \ + fll_out.o \ fll_type.o -fll_getndata.o : \ - fll_locate.o \ +fll_stich.o : \ + fll_out.o \ fll_type.o -fll_sweep.o : \ - fll_locate.o \ +fll_deattach.o : \ + fll_stich.o \ + fll_out.o \ fll_type.o -fll_type.o : +fll_read_ffa.o : \ + fll_out.o \ + fll_type.o \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o -fll_write_ffa.o : \ - fll_type.o +fll_type.o : -fll_cat.o : \ +fll_out.o : \ fll_type.o -fll_mods.o : \ - fll_sweep.o \ - fll_locate.o \ - fll_write.o \ - fll_deattach.o \ - fll_nnodes.o \ - fll_stich.o \ - fll_read.o \ +fll_cp.o : \ + fll_type.o \ fll_duplicate.o \ - fll_write_ffa.o \ fll_mv.o \ - fll_type.o \ - fll_funct_prt.o \ - fll_mk.o \ - fll_rm.o \ - fll_mkdir.o \ + fll_out.o \ fll_cat.o \ - fll_getndata.o \ - fll_cp.o \ - fll_read_ffa.o - -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_type.o + fll_stich.o \ + fll_rm.o -fll_locate.o : \ +fll_read.o : \ + fll_out.o \ + fll_type.o \ + fll_mv.o \ fll_funct_prt.o \ - fll_type.o + fll_mk.o -fll_mv.o : \ - fll_rm.o \ - fll_stich.o \ - fll_type.o +fll_mkdir.o : \ + fll_type.o \ + fll_mk.o diff --git a/examples/project.dep b/examples/project.dep index 1f57af6..f48062d 100644 --- a/examples/project.dep +++ b/examples/project.dep @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! fll_test.o : \ - fll_test_subr.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_test_subr.o fll_test_subr.o : \ ../data_util/fll_mods.o From cad8e0da5cdf45bad3ec599e6fc87c1263241651 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 5 Nov 2016 19:14:55 -0600 Subject: [PATCH 056/325] fix ERR statements --- data_util/fll_mk.f90 | 32 ++++++++++++++++---------------- data_util/fll_rm.f90 | 26 +++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index a691aa1..0b17c13 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -92,7 +92,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) END IF ALLOCATE(PNEW, STAT = ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:82 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:95 ' PNEW%LNAME = TRIM(NAME) PNEW%LTYPE = LTYPE PNEW%NDIM = 0 @@ -126,15 +126,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%R1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:106 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:129 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%R1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:111 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:134 ' ELSE ALLOCATE(PNEW%R2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:114 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:137 ' END IF END IF @@ -142,15 +142,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%D1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:122 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:145 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%D1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:127 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:150 ' ELSE ALLOCATE(PNEW%D2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:130 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:153 ' END IF END IF @@ -159,15 +159,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%I1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:139 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:162 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%I1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:144 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:167 ' ELSE ALLOCATE(PNEW%I2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:147 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:170 ' END IF END IF @@ -176,15 +176,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%L1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:156 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:179 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%L1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:161 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:184 ' ELSE ALLOCATE(PNEW%L2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:164 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:187 ' END IF END IF @@ -193,15 +193,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%S1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:156 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:196 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%S1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:161 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:201 ' ELSE ALLOCATE(PNEW%S2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> ll_mk ERR:164 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:204 ' END IF END IF diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index 0b017ff..91d0aaf 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -90,7 +90,7 @@ SUBROUTINE FLL_RM(PNODE,FPAR) ! NULLIFY NODE ! DEALLOCATE(PNODE, STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:88 ' + IF(ISTAT /= 0)STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:93 ' NULLIFY(PNODE) FPAR%SUCCESS = .TRUE. @@ -155,7 +155,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) END IF DEALLOCATE(PCURR, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> ll_rm ERR:132 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:158 ' NULLIFY(PCURR) FPAR%SUCCESS = .TRUE. ELSE @@ -165,7 +165,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) PCURR%PCHILD%PLINK => NULL() PCURR%PCHILD => NULL() DEALLOCATE(PCURR, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> ll_rm ERR:142 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:168 ' NULLIFY(PCURR) FPAR%SUCCESS = .TRUE. END IF @@ -218,7 +218,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%R1))THEN DEALLOCATE(PNODE%R1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:174 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:221 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -228,7 +228,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%D1))THEN DEALLOCATE(PNODE%D1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:184 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:231 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -238,7 +238,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%I1))THEN DEALLOCATE(PNODE%I1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:194 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:241 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -248,7 +248,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%L1))THEN DEALLOCATE(PNODE%L1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:204 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:251 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -258,7 +258,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%S1))THEN DEALLOCATE(PNODE%S1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:204 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:261 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -270,7 +270,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%R2))THEN DEALLOCATE(PNODE%R2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:216 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:273 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -280,7 +280,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%D2))THEN DEALLOCATE(PNODE%D2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:226 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:283 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -290,7 +290,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%I2))THEN DEALLOCATE(PNODE%I2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:236 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:293 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -300,7 +300,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%L2))THEN DEALLOCATE(PNODE%L2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:246 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:303 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -310,7 +310,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) IF(ASSOCIATED(PNODE%S2))THEN DEALLOCATE(PNODE%S2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> ll_rm ERR:246 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:313 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. From c3311caf00ef4b34d421ff445c78eee19336f6af Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 6 Nov 2016 15:10:11 -0700 Subject: [PATCH 057/325] code cleanup --- data_util/fll_getndata.f90 | 28 +--------------------------- data_util/fll_locate.f90 | 2 +- data_util/fll_mkdir.f90 | 4 +--- data_util/fll_mv.f90 | 2 +- data_util/fll_nnodes.f90 | 2 +- data_util/fll_sweep.f90 | 3 +-- data_util/fll_type.f90 | 19 +++++++++---------- 7 files changed, 15 insertions(+), 45 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index fbfcf0f..f8b7364 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -71,9 +71,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) ! ! Local declarations ! - TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE -! + TYPE(DNODE), POINTER :: PFIND! ! check for null nodes ! IF(.NOT.ASSOCIATED(PNODE))THEN @@ -139,7 +137,6 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) ! ! Local declarations ! - LOGICAL :: RECURSE TYPE(DNODE), POINTER :: PFIND IF(.NOT.ASSOCIATED(PNODE))THEN @@ -205,7 +202,6 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -272,8 +268,6 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -340,7 +334,6 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -406,8 +399,6 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -474,7 +465,6 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -540,8 +530,6 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -605,8 +593,6 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -672,8 +658,6 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -728,8 +712,6 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -793,8 +775,6 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -858,8 +838,6 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -923,8 +901,6 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -988,8 +964,6 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - LOGICAL :: RECURSE - IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index f4792a3..422df40 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -73,7 +73,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LINT) :: LOCNUM,I, NDIM, NSIZE + INTEGER(LINT) :: LOCNUM,NDIM, NSIZE ! ! remove empty spaces ! diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 index 0eef875..774440d 100644 --- a/data_util/fll_mkdir.f90 +++ b/data_util/fll_mkdir.f90 @@ -56,9 +56,7 @@ FUNCTION FLL_MKDIR(NAME,FPAR) RESULT(PNEW) CHARACTER(LEN=*) :: NAME ! ! Local declarations -! - INTEGER :: ISTAT - +! PNEW => NULL() ! ! Body diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 790f7fe..f3f14b0 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -106,7 +106,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! Arguments declaration ! TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& - PLAST, PSOURCETMP,PCHILD,PNEW + PLAST, PSOURCETMP,PCHILD ! ! BODY OF SUBROUTINE ! diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index ea7d9c6..a2447d8 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -115,7 +115,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB IF( TRIM(PCURR%LNAME) == TRIM(NAME) .AND. & (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN - NDIM = PCURR%NDIM + NDIM = PCURR%NDIM NSIZE = PCURR%NSIZE SELECT CASE(DATADIM) diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 373b631..32f9cbc 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -65,14 +65,13 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - INTEGER(LINT) :: NUMBER LOGICAL :: RECURSE ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD - INTEGER(LINT) :: LOCNUM,I + INTEGER(LINT) :: I ! ! BODY OF FUNCTION ! diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 9f1fee5..8a19094 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -104,7 +104,7 @@ MODULE FLL_TYPE_M ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! TYPE DNODE - CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list + CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 @@ -124,21 +124,20 @@ MODULE FLL_TYPE_M CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S1(:)=>NULL() ! 1D array of strings CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() ! 2D array of strings - REAL(RSINGLE) :: R0 ! real - REAL(RDOUBLE) :: D0 ! double - INTEGER(SINT) :: I0 ! integer - INTEGER(LINT) :: L0 ! long integer - CHARACTER(LEN=STRING_LENGHT) :: S ! string - CHARACTER(LEN=NAME_LENGTH) :: T ! short string - CHARACTER :: C ! character + REAL(RSINGLE) :: R0 ! real + REAL(RDOUBLE) :: D0 ! double + INTEGER(SINT) :: I0 ! integer + INTEGER(LINT) :: L0 ! long integer + CHARACTER(LEN=STRING_LENGHT) :: S ! string + CHARACTER :: C ! character END TYPE DNODE ! ! type used for diagnostic data set passed to subroutines and functions ! TYPE FUNC_DATA_SET - LOGICAL :: SUCCESS ! if .TRUE.=success, .FALSE. = fail - CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG ! error message + LOGICAL :: SUCCESS ! if .TRUE.=success, .FALSE. = fail + CHARACTER(LEN=ERR_MSG_LENGTH) :: MESG ! error message CHARACTER(LEN=ERR_PATH_LENGTH) :: ERRPATH ! path END TYPE FUNC_DATA_SET From a71206175e8ad15ccaecfbd0aa8cf2592fab4b6d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 6 Nov 2016 15:52:38 -0700 Subject: [PATCH 058/325] add fll_match_pattern --- data_util/fll_mods.f90 | 1 + data_util/fll_sweep.f90 | 30 +++----- data_util/project.dep | 161 +++++++++++++++++++++------------------- 3 files changed, 95 insertions(+), 97 deletions(-) diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 8db6667..52b3728 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -54,5 +54,6 @@ MODULE FLL_MODS_M USE FLL_WRITE_FFA_M USE FLL_GETNDATA_M USE FLL_OUT_M + USE FLL_MATCH_PATTERN_M END MODULE FLL_MODS_M diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 32f9cbc..0b82ac6 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -18,7 +18,7 @@ ! MODULE FLL_SWEEP_M ! -! Description: Contains function fll_sweek +! Description: Contains function fll_sweep and match_pattern ! ! ! History: @@ -30,7 +30,7 @@ MODULE FLL_SWEEP_M ! External Modules used ! CONTAINS - FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) + SUBROUTINE FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,RECURSE,FPAR) ! ! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! @@ -44,20 +44,12 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) ! External Modules used ! USE FLL_TYPE_M - USE FLL_LOCATE_M USE FLL_OUT_M + USE FLL_MATCH_PATTERN_M IMPLICIT NONE ! -! Description: Module copies PWHAT pointer to PWHERE pointer -! If PWHERE pointer == NULL, PWHAT is a duplicate -! of PWHAT with PWHAT%Ppar == NULL -! -! if PWHERE is DIR on N type, PWHAT is added -! to it as a new sub-data set -! -! if PWHERE is a data type of nodes -! PWHAT overwrites it +! Description: Sweeps through the list returning nodes matching patern ! ! External Modules used ! @@ -74,8 +66,7 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) INTEGER(LINT) :: I ! ! BODY OF FUNCTION -! - NULLIFY(PFIND) +! I = 1 DO WHILE(LTYPE(I:I) == ' ') I = I + 1 @@ -84,24 +75,25 @@ FUNCTION FLL_SWEEP(PNODE,NAME,LTYPE,RECURSE,FPAR) RESULT(PFIND) TLTYPE = TRIM(LTYPE(I:)) IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) + WRITE(FPAR%MESG,'(A,A)')'Sweep - Null node: ',TRIM(NAME) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF -! -! DO WHILE(PNODE) ! PCURR => PNODE%PCHILD IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN WRITE(*,*)' NODE NOT DIR NODE' RETURN END IF -! END DO +! +! start loop +! + IF(.NOT.ASSOCIATED(PFIND))PFIND => PNODE%PCHILD RETURN - END FUNCTION FLL_SWEEP + END SUBROUTINE FLL_SWEEP END MODULE FLL_SWEEP_M diff --git a/data_util/project.dep b/data_util/project.dep index bf8d118..d51ec2b 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,121 +1,126 @@ # This file is generated automatically. DO NOT EDIT! -fll_mods.o : \ - fll_nnodes.o \ - fll_type.o \ - fll_getndata.o \ - fll_duplicate.o \ - fll_mv.o \ - fll_write.o \ - fll_read_ffa.o \ - fll_mk.o \ - fll_deattach.o \ - fll_cp.o \ - fll_out.o \ - fll_cat.o \ - fll_funct_prt.o \ - fll_mkdir.o \ - fll_locate.o \ +fll_deattach.o : \ fll_stich.o \ - fll_sweep.o \ - fll_write_ffa.o \ - fll_rm.o \ - fll_read.o - -fll_mk.o : \ - fll_out.o \ - fll_type.o - -fll_sweep.o : \ - fll_locate.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_mv.o : \ - fll_stich.o \ - fll_out.o \ +fll_mkdir.o : \ fll_type.o \ - fll_rm.o + fll_mk.o -fll_funct_prt.o : \ - fll_out.o \ - fll_type.o +fll_read.o : \ + fll_funct_prt.o \ + fll_mv.o \ + fll_type.o \ + fll_mk.o \ + fll_out.o -fll_cat.o : \ - fll_out.o \ - fll_type.o +fll_duplicate.o : \ + fll_mv.o \ + fll_type.o \ + fll_mk.o \ + fll_out.o -fll_rm.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o +fll_type.o : -fll_nnodes.o : \ +fll_locate.o : \ fll_out.o \ fll_type.o \ fll_funct_prt.o -fll_locate.o : \ - fll_out.o \ +fll_rm.o : \ + fll_stich.o \ fll_type.o \ - fll_funct_prt.o + fll_out.o fll_getndata.o : \ fll_locate.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_duplicate.o : \ - fll_mv.o \ +fll_write.o : \ fll_type.o \ + fll_out.o + +fll_nnodes.o : \ fll_out.o \ - fll_mk.o + fll_type.o \ + fll_funct_prt.o fll_write_ffa.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_write.o : \ - fll_out.o \ - fll_type.o +fll_sweep.o : \ + fll_type.o \ + fll_match_pattern.o \ + fll_out.o fll_stich.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_deattach.o : \ +fll_cp.o : \ fll_stich.o \ + fll_duplicate.o \ + fll_rm.o \ fll_out.o \ - fll_type.o + fll_cat.o \ + fll_type.o \ + fll_mv.o -fll_read_ffa.o : \ +fll_mods.o : \ + fll_cp.o \ + fll_nnodes.o \ + fll_stich.o \ + fll_sweep.o \ + fll_duplicate.o \ + fll_rm.o \ fll_out.o \ + fll_write.o \ + fll_cat.o \ + fll_getndata.o \ + fll_match_pattern.o \ + fll_read_ffa.o \ + fll_mkdir.o \ fll_type.o \ - fll_mv.o \ + fll_write_ffa.o \ fll_funct_prt.o \ + fll_mv.o \ + fll_locate.o \ + fll_read.o \ + fll_deattach.o \ fll_mk.o -fll_type.o : +fll_funct_prt.o : \ + fll_type.o \ + fll_out.o + +fll_read_ffa.o : \ + fll_funct_prt.o \ + fll_mv.o \ + fll_type.o \ + fll_mk.o \ + fll_out.o fll_out.o : \ fll_type.o -fll_cp.o : \ +fll_cat.o : \ fll_type.o \ - fll_duplicate.o \ - fll_mv.o \ - fll_out.o \ - fll_cat.o \ - fll_stich.o \ - fll_rm.o + fll_out.o -fll_read.o : \ - fll_out.o \ +fll_match_pattern.o : \ fll_type.o \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o + fll_out.o -fll_mkdir.o : \ +fll_mk.o : \ fll_type.o \ - fll_mk.o + fll_out.o + +fll_mv.o : \ + fll_stich.o \ + fll_type.o \ + fll_rm.o \ + fll_out.o From d5916384cc8d618b6083382f4532774a937e23cb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 6 Nov 2016 15:52:58 -0700 Subject: [PATCH 059/325] add missing fll_match_pattern function --- data_util/fll_match_pattern.f90 | 120 ++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 data_util/fll_match_pattern.f90 diff --git a/data_util/fll_match_pattern.f90 b/data_util/fll_match_pattern.f90 new file mode 100644 index 0000000..5ed3783 --- /dev/null +++ b/data_util/fll_match_pattern.f90 @@ -0,0 +1,120 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +MODULE FLL_MATCH_PATTERN_M +! +! Description: Contains function fll_match_pattern +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_MATCH_PATTERN(PNODE, NAME, TYPE, DIM, FPAR) RESULT(OK) +! +! Description: matches pattern +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer where find node +! NAME In name of node +! LTYPE In type of node - can be * +! DIM In dimensions of data the node should contain +! can be 0 - scalar), 1 -1D array, 2 -2D array +! any other number (prefer -1) - do not care about dimensions +! OK Out return value +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE + CHARACTER(LEN=*) :: NAME + CHARACTER(LEN=*) :: TYPE + INTEGER(LINT) :: DIM + + LOGICAL OK +! +! Local declarations +! + INTEGER(LINT) :: NLOCD + + OK = .FALSE. + + IF(TRIM(PNODE%LNAME) == TRIM(NAME) .OR. TRIM(NAME) == '*')THEN + OK = .TRUE. + ELSE + OK = .FALSE. + RETURN + END IF + + IF(TRIM(PNODE%LTYPE) == TRIM(TYPE) .OR. TRIM(TYPE) == '*')THEN + OK = .TRUE. + ELSE + OK = .FALSE. + RETURN + END IF + + IF(DIM < 0 .OR. DIM > 2)THEN + OK = .TRUE. + RETURN + END IF + + IF(PNODE%NDIM > 1 .AND. PNODE%NSIZE > 1) THEN + NLOCD = 2 + ELSE IF (PNODE%NDIM > 1 .OR. PNODE%NSIZE > 1) THEN + NLOCD = 1 + ELSE + NLOCD = 0 + END IF + + IF(NLOCD == DIM )THEN + OK = .TRUE. + ELSE + OK = .FALSE. + RETURN + END IF + + RETURN + + END FUNCTION FLL_MATCH_PATTERN + + +END MODULE FLL_MATCH_PATTERN_M From 057d6c66dcde20ee00ad1ba7a829cea917f846ac Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 6 Nov 2016 17:35:42 -0700 Subject: [PATCH 060/325] Make calls to fll_getndata and fll_locate consistent --- data_util/fll_getndata.f90 | 60 +++++++++++++++---------------- data_util/fll_locate.f90 | 4 +-- data_util/fll_match_pattern.f90 | 1 - data_util/fll_sweep.f90 | 64 ++++++++++++++++++++++++++------- examples/fll_test.f90 | 22 +++++++++--- examples/fll_test_subr.f90 | 4 +-- 6 files changed, 103 insertions(+), 52 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index f8b7364..1d00e1c 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNDATA_M ! External Modules used ! CONTAINS - FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -81,7 +81,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -97,7 +97,7 @@ END FUNCTION FLL_GETNDATA_R0 - FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -146,7 +146,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -160,7 +160,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_R1 - FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_R2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -210,7 +210,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -226,7 +226,7 @@ END FUNCTION FLL_GETNDATA_R2 ! ! DOUBLE ! - FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_D0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -276,7 +276,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -292,7 +292,7 @@ END FUNCTION FLL_GETNDATA_D0 - FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -342,7 +342,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -357,7 +357,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_D1 - FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_D2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -407,7 +407,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -423,7 +423,7 @@ END FUNCTION FLL_GETNDATA_D2 ! ! INTEGER ! - FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_I0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -473,7 +473,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -489,7 +489,7 @@ END FUNCTION FLL_GETNDATA_I0 - FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) ! ! Description: returns single real data of the node ! @@ -538,7 +538,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -552,7 +552,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_I1 - FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_I2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -601,7 +601,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -617,7 +617,7 @@ END FUNCTION FLL_GETNDATA_I2 ! ! LONG INTEGER ! - FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_L0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -666,7 +666,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -682,7 +682,7 @@ END FUNCTION FLL_GETNDATA_L0 - FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) USE FLL_TYPE_M USE FLL_LOCATE_M @@ -720,7 +720,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -734,7 +734,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_L1 - FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -783,7 +783,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -797,7 +797,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -846,7 +846,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,0_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -860,7 +860,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S -FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) +FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -909,7 +909,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,1_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -923,7 +923,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S1 - FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -972,7 +972,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,LTYPE,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,2_LINT,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 422df40..6db1d93 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -32,7 +32,7 @@ MODULE FLL_LOCATE_M ! CONTAINS - RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESULT(PFIND) + RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PFIND) ! ! Description: function finds node identified by name, type, position in list, dimensions of data it contains ! serach can be done recursively @@ -102,7 +102,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,NUMBER,LTYPE,DATADIM,RECURSE,FPAR) RESU ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - PFIND => FLL_LOCATE(PCHLD,NAME,1_LINT,LTYPE,DATADIM,RECURSE,FPAR) + PFIND => FLL_LOCATE(PCHLD,NAME,LTYPE,DATADIM,1_LINT,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN diff --git a/data_util/fll_match_pattern.f90 b/data_util/fll_match_pattern.f90 index 5ed3783..767b69d 100644 --- a/data_util/fll_match_pattern.f90 +++ b/data_util/fll_match_pattern.f90 @@ -77,7 +77,6 @@ FUNCTION FLL_MATCH_PATTERN(PNODE, NAME, TYPE, DIM, FPAR) RESULT(OK) INTEGER(LINT) :: NLOCD OK = .FALSE. - IF(TRIM(PNODE%LNAME) == TRIM(NAME) .OR. TRIM(NAME) == '*')THEN OK = .TRUE. ELSE diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 0b82ac6..3f77c16 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -30,7 +30,7 @@ MODULE FLL_SWEEP_M ! External Modules used ! CONTAINS - SUBROUTINE FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,RECURSE,FPAR) + RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR) RESULT(OK) ! ! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! @@ -49,24 +49,41 @@ SUBROUTINE FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,RECURSE,FPAR) IMPLICIT NONE ! -! Description: Sweeps through the list returning nodes matching patern +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer where find node +! NAME In name of node +! NUMBER In position of node in list +! LTYPE In type of node - can be * +! DIM In dimensions of data the node should contain +! can be 0 - scalar), 1 -1D array, 2 -2D array +! any other number (prefer -1) - do not care about dimensions +! RECURSE In search recursively +! PFIND Out return pointer to located node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! -! External Modules used -! TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE LOGICAL :: RECURSE + INTEGER(LINT) :: DIM + LOGICAL OK ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE - TYPE(DNODE), POINTER :: PCURR, PCHLD INTEGER(LINT) :: I + TYPE(DNODE), POINTER :: PNEXT ! ! BODY OF FUNCTION ! + OK =.FALSE. + I = 1 DO WHILE(LTYPE(I:I) == ' ') I = I + 1 @@ -80,20 +97,41 @@ SUBROUTINE FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,RECURSE,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF -! - PCURR => PNODE%PCHILD - IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN - WRITE(*,*)' NODE NOT DIR NODE' - RETURN - END IF ! ! start loop ! - IF(.NOT.ASSOCIATED(PFIND))PFIND => PNODE%PCHILD + IF(.NOT.ASSOCIATED(PFIND))THEN + IF(ASSOCIATED(PNODE%PCHILD))THEN + PFIND => PNODE%PCHILD + ELSE + PFIND => PNODE + END IF + ELSE + PFIND => PFIND%PNEXT + END IF + + DO WHILE(ASSOCIATED(PFIND)) +! IF(RECURSE .AND. ASSOCIATED(PFIND%PCHILD))THEN +! PFIND => PFIND%PCHILD +! IF(FLL_SWEEP(PFIND,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR,.TRUE., PPAR))THEN +! OK = .TRUE. +! RETURN +! END IF +! PFIND => PNEXT +! END IF + + IF(FLL_MATCH_PATTERN(PFIND,NAME,LTYPE,DIM,FPAR))THEN + OK =.TRUE. + RETURN + END IF + + PFIND => PFIND%PNEXT + + END DO RETURN - END SUBROUTINE FLL_SWEEP + END FUNCTION FLL_SWEEP END MODULE FLL_SWEEP_M diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index da1ebc6..4a5b6bc 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -52,7 +52,7 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,PNEW,PNEW1,PNODE1,PTMP,PNEW2 + TYPE(DNODE), POINTER :: PNODE,PNEW,PNEW1,PNODE1,PTMP,PNEW2,PFIND TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,I CHARACTER :: FMT @@ -112,7 +112,7 @@ PROGRAM FLL_TEST ! 1. HUMID => PTMP%D1 ! 2. Locating the node in PNEW1 - HUMID => FLL_GETNDATA_D1(PNEW1,'Humidity',1_LINT,'D',FPAR) + HUMID => FLL_GETNDATA_D1(PNEW1,'Humidity','D',1_LINT,FPAR) IF(.NOT.ASSOCIATED(HUMID))THEN STOP' DID NOT FIND HUMID' @@ -153,12 +153,26 @@ PROGRAM FLL_TEST CALL FLL_TEST_SUBR(PNODE,PNODE1) WRITE(*,*)'---BACK FROM SUBROUTINE --------------8' + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) + WRITE(*,*)'---BACK FROM SUBROUTINE --------------9' + +! + PFIND => NULL() +! +! SWEEP IN THE FIRST SUBDIR TEST_Subdir AND PRINT ALL ITEMS WHICH ARE CONTAIN THERE ! + PTMP => FLL_LOCATE(PNODE,'TEST_Subdir','*',-1_LINT,1_LINT,.FALSE. ,FPAR) + DO WHILE(FLL_SWEEP(PTMP, PFIND,'*', '*', -1_LINT, .TRUE., FPAR)) + WRITE(*,*)PFIND%LNAME + END DO + CALL FLL_RM(PNODE1,FPAR) CALL FLL_RM(PNODE,FPAR) - CALL FLL_CAT(PNEW1, 6, .TRUE.,FPAR) - + CALL FLL_CAT(PNEW1, 6, .FALSE.,FPAR) + WRITE(*,*)'---BACK FROM SUBROUTINE --------------9' + + CALL FLL_RM(PNEW1,FPAR) diff --git a/examples/fll_test_subr.f90 b/examples/fll_test_subr.f90 index a7d5925..76ad474 100644 --- a/examples/fll_test_subr.f90 +++ b/examples/fll_test_subr.f90 @@ -88,13 +88,13 @@ SUBROUTINE FLL_TEST_SUBR(PNODE,PNODE1) ! ! find the first TEST1_Subdir in PNODE1 and print it on the screen ! - PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir',1_lint,'*',-1_LINT,.false.,FPAR) + PTMP => FLL_LOCATE(PNODE1,'TEST1_Subdir','*',-1_LINT,1_LINT,.false.,FPAR) CALL FLL_CAT(PTMP, 6, .TRUE.,FPAR) WRITE(*,*)'------------------------------------------------------7' ! ! find the values of pressure subset #1 and print the data on screen ! - PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,'D',FPAR) + PRESS => FLL_GETNDATA_D1(PTMP,'pressure','D',1_LINT,FPAR) write(*,*)' Values of pressure are ',PRESS ! ! PNEW WAS CREATED HERE, IT DOES NOT BELONG TO ANY NODE (WAS NOT MOVED TO ANY NODE) From 5ec219f85afc131cd1686f7594911bfcc46d9fb5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 6 Nov 2016 18:50:20 -0700 Subject: [PATCH 061/325] code cleanup --- data_util/fll_cat.f90 | 6 ++++-- data_util/fll_sweep.f90 | 13 +------------ examples/fll_test.f90 | 8 +++----- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 564e23b..259f320 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -75,10 +75,12 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) CALL FLL_OUT('ALL',FPAR) RETURN END IF - + + WRITE(*,*) PCHILD => PNODE%PCHILD IF(PARENT) THEN - IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is ', PNODE%PPAR%LNAME + IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is: ', PNODE%PPAR%LNAME + WRITE(*,*) END IF CALL FLL_PRINT(PNODE, IOUNIT, POS, FPAR) ! diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 3f77c16..4f4f06d 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -30,7 +30,7 @@ MODULE FLL_SWEEP_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR) RESULT(OK) + RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR) RESULT(OK) ! ! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! @@ -60,7 +60,6 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR) RESULT(OK ! DIM In dimensions of data the node should contain ! can be 0 - scalar), 1 -1D array, 2 -2D array ! any other number (prefer -1) - do not care about dimensions -! RECURSE In search recursively ! PFIND Out return pointer to located node ! FPAR In/Out structure containing function specific data ! @@ -70,7 +69,6 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR) RESULT(OK TYPE(DNODE), POINTER :: PNODE,PFIND CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE - LOGICAL :: RECURSE INTEGER(LINT) :: DIM LOGICAL OK ! @@ -111,15 +109,6 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR) RESULT(OK END IF DO WHILE(ASSOCIATED(PFIND)) - -! IF(RECURSE .AND. ASSOCIATED(PFIND%PCHILD))THEN -! PFIND => PFIND%PCHILD -! IF(FLL_SWEEP(PFIND,PFIND,NAME,LTYPE,DIM,RECURSE,FPAR,.TRUE., PPAR))THEN -! OK = .TRUE. -! RETURN -! END IF -! PFIND => PNEXT -! END IF IF(FLL_MATCH_PATTERN(PFIND,NAME,LTYPE,DIM,FPAR))THEN OK =.TRUE. diff --git a/examples/fll_test.f90 b/examples/fll_test.f90 index 4a5b6bc..654fb6c 100644 --- a/examples/fll_test.f90 +++ b/examples/fll_test.f90 @@ -159,11 +159,11 @@ PROGRAM FLL_TEST ! PFIND => NULL() ! -! SWEEP IN THE FIRST SUBDIR TEST_Subdir AND PRINT ALL ITEMS WHICH ARE CONTAIN THERE +! SWEEP IN THE FIRST SUBDIR TEST_Subdir AND PRINT ALL ITEMS WHICH ARE CONTAINED THERE ! PTMP => FLL_LOCATE(PNODE,'TEST_Subdir','*',-1_LINT,1_LINT,.FALSE. ,FPAR) - DO WHILE(FLL_SWEEP(PTMP, PFIND,'*', '*', -1_LINT, .TRUE., FPAR)) - WRITE(*,*)PFIND%LNAME + DO WHILE(FLL_SWEEP(PTMP, PFIND,'*', '*', -1_LINT, FPAR)) + WRITE(*,*)'Name of node is ',PFIND%LNAME END DO CALL FLL_RM(PNODE1,FPAR) @@ -172,8 +172,6 @@ PROGRAM FLL_TEST CALL FLL_CAT(PNEW1, 6, .FALSE.,FPAR) WRITE(*,*)'---BACK FROM SUBROUTINE --------------9' - - CALL FLL_RM(PNEW1,FPAR) From 6ba40f887838d08b74efb71ffbdf041fa8effc67 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 10:13:17 -0700 Subject: [PATCH 062/325] update configure file if file which is to be linked does not exist, do not link it --- configure.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.py b/configure.py index b31ef77..1e5bd94 100755 --- a/configure.py +++ b/configure.py @@ -162,8 +162,9 @@ def mkdir_structure(root_path,cwd, exclude, linkfiles): source = dirtmp+'/'+word dest = newdir+'/'+word - print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") - linkfile = os.symlink( source, dest) + if os.path.exists(source): + print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") + linkfile = os.symlink( source, dest) os.chdir(cwd) print(" ") From 06a0d6e1feaaca0d5ffa0f45d684303bd81dc357 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 10:13:52 -0700 Subject: [PATCH 063/325] change S to S0 in types --- data_util/fll_cat.f90 | 2 +- data_util/fll_duplicate.f90 | 6 +- data_util/fll_getndata.f90 | 6 +- data_util/fll_read.f90 | 4 +- data_util/fll_read_ffa.f90 | 6 +- data_util/fll_type.f90 | 10 +-- data_util/fll_write.f90 | 4 +- data_util/fll_write_ffa.f90 | 6 +- data_util/project.dep | 172 ++++++++++++++++++------------------ 9 files changed, 108 insertions(+), 108 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 259f320..fbe484d 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -276,7 +276,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) WRITE(TEXT,*)" ",SPACE,PNODE%L0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('S') - WRITE(TEXT,*)" ",SPACE,TRIM(PNODE%S) + WRITE(TEXT,*)" ",SPACE,TRIM(PNODE%S0) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE DEFAULT diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 594b9b2..2cec804 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -510,9 +510,9 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! PNEW%R0 = PNODE%R0 PNEW%D0 = PNODE%D0 - PNEW%I0 = PNODE%I0 - PNEW%L0 = PNODE%L0 - PNEW%S = PNODE%S + PNEW%I0 = PNODE%I0 + PNEW%L0 = PNODE%L0 + PNEW%S0 = PNODE%S0 END SUBROUTINE FLL_COPPY_NODE_ARRAYS diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 1d00e1c..46f840d 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -855,7 +855,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - STRING = PNODE%S + STRING = PNODE%S0 RETURN END FUNCTION FLL_GETNDATA_S @@ -918,7 +918,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - STRING = PNODE%S + STRING = PNODE%S0 RETURN END FUNCTION FLL_GETNDATA_S1 @@ -981,7 +981,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - STRING = PNODE%S + STRING = PNODE%S0 RETURN END FUNCTION FLL_GETNDATA_S2 diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index a3a4e0a..b3492fa 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -533,7 +533,7 @@ SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE > 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S0 END IF ELSE IF(NSIZE == 1)THEN @@ -675,7 +675,7 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE > 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S0 END IF ELSE IF(NSIZE == 1)THEN diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 24aa436..35bef12 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -600,7 +600,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE > 1)THEN READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S0 END IF ELSE IF(NSIZE == 1)THEN @@ -749,7 +749,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END DO ELSE READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,T - PNODE%S = T + PNODE%S0 = T END IF ELSE IF(NSIZE == 1)THEN @@ -776,7 +776,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) IF(NSIZE > 1)THEN READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%S1(I),I=1,NSIZE) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%S + READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%S0 END IF ELSE IF(NSIZE == 1)THEN diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 8a19094..aed2c54 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -125,11 +125,11 @@ MODULE FLL_TYPE_M CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() ! 2D array of strings REAL(RSINGLE) :: R0 ! real - REAL(RDOUBLE) :: D0 ! double - INTEGER(SINT) :: I0 ! integer - INTEGER(LINT) :: L0 ! long integer - CHARACTER(LEN=STRING_LENGHT) :: S ! string - CHARACTER :: C ! character + REAL(RDOUBLE) :: D0 ! double + INTEGER(SINT) :: I0 ! integer + INTEGER(LINT) :: L0 ! long integer + CHARACTER(LEN=STRING_LENGHT) :: S0 ! string + CHARACTER :: C ! character END TYPE DNODE ! diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 33a554e..12fcac9 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -382,7 +382,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) CASE('L') WRITE(IOUNIT, *)PNODE%L0 CASE('S') - WRITE(IOUNIT,*)"'",TRIM(PNODE%S),"'" + WRITE(IOUNIT,*)"'",TRIM(PNODE%S0),"'" CASE DEFAULT @@ -506,7 +506,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) CASE('L') WRITE(IOUNIT)PNODE%L0 CASE('S') - WRITE(IOUNIT)"'",PNODE%S,"'" + WRITE(IOUNIT)"'",PNODE%S0,"'" CASE DEFAULT diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 870868c..c2b0a6c 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -422,7 +422,7 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) CASE('J') WRITE(IOUNIT,*)PNODE%L0 CASE('S','L') - WRITE(IOUNIT,*)"'",PNODE%S,"'" + WRITE(IOUNIT,*)"'",PNODE%S0,"'" CASE DEFAULT @@ -604,9 +604,9 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) CASE('J') WRITE(IOUNIT)1_LINT,PNODE%L0 CASE('L') - WRITE(IOUNIT)1_LINT*STRING_LENGHT,PNODE%S + WRITE(IOUNIT)1_LINT*STRING_LENGHT,PNODE%S0 CASE('S') - WRITE(IOUNIT)1_LINT*NAME_LENGTH,PNODE%S(1:NAME_LENGTH) + WRITE(IOUNIT)1_LINT*NAME_LENGTH,PNODE%S0(1:NAME_LENGTH) END SELECT END IF END IF diff --git a/data_util/project.dep b/data_util/project.dep index d51ec2b..fdc4076 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -2,125 +2,125 @@ fll_deattach.o : \ fll_stich.o \ - fll_type.o \ - fll_out.o - -fll_mkdir.o : \ - fll_type.o \ - fll_mk.o + fll_out.o \ + fll_type.o -fll_read.o : \ +fll_nnodes.o : \ fll_funct_prt.o \ - fll_mv.o \ - fll_type.o \ - fll_mk.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_duplicate.o : \ - fll_mv.o \ - fll_type.o \ +fll_mkdir.o : \ fll_mk.o \ - fll_out.o - -fll_type.o : + fll_type.o -fll_locate.o : \ +fll_cat.o : \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o - -fll_rm.o : \ - fll_stich.o \ - fll_type.o \ - fll_out.o - -fll_getndata.o : \ - fll_locate.o \ - fll_type.o \ - fll_out.o + fll_type.o -fll_write.o : \ - fll_type.o \ - fll_out.o +fll_type.o : -fll_nnodes.o : \ +fll_stich.o : \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o -fll_write_ffa.o : \ - fll_type.o \ - fll_out.o +fll_funct_prt.o : \ + fll_out.o \ + fll_type.o fll_sweep.o : \ - fll_type.o \ fll_match_pattern.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_stich.o : \ - fll_type.o \ - fll_out.o +fll_read.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ + fll_type.o fll_cp.o : \ - fll_stich.o \ + fll_mv.o \ + fll_cat.o \ + fll_out.o \ fll_duplicate.o \ fll_rm.o \ - fll_out.o \ - fll_cat.o \ - fll_type.o \ - fll_mv.o + fll_stich.o \ + fll_type.o -fll_mods.o : \ - fll_cp.o \ - fll_nnodes.o \ +fll_mv.o : \ fll_stich.o \ - fll_sweep.o \ - fll_duplicate.o \ + fll_out.o \ fll_rm.o \ + fll_type.o + +fll_write.o : \ fll_out.o \ - fll_write.o \ - fll_cat.o \ - fll_getndata.o \ - fll_match_pattern.o \ - fll_read_ffa.o \ - fll_mkdir.o \ - fll_type.o \ - fll_write_ffa.o \ - fll_funct_prt.o \ - fll_mv.o \ + fll_type.o + +fll_getndata.o : \ fll_locate.o \ - fll_read.o \ - fll_deattach.o \ - fll_mk.o + fll_out.o \ + fll_type.o -fll_funct_prt.o : \ - fll_type.o \ - fll_out.o +fll_match_pattern.o : \ + fll_out.o \ + fll_type.o -fll_read_ffa.o : \ +fll_locate.o : \ fll_funct_prt.o \ + fll_out.o \ + fll_type.o + +fll_read_ffa.o : \ fll_mv.o \ - fll_type.o \ + fll_funct_prt.o \ fll_mk.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_out.o : \ +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ + fll_out.o \ fll_type.o -fll_cat.o : \ +fll_mods.o : \ + fll_mv.o \ + fll_deattach.o \ + fll_mkdir.o \ + fll_cat.o \ + fll_duplicate.o \ + fll_write.o \ + fll_match_pattern.o \ + fll_locate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_write_ffa.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_cp.o \ + fll_mk.o \ fll_type.o \ - fll_out.o + fll_nnodes.o \ + fll_read.o \ + fll_getndata.o \ + fll_out.o \ + fll_read_ffa.o -fll_match_pattern.o : \ - fll_type.o \ - fll_out.o +fll_rm.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o fll_mk.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_mv.o : \ - fll_stich.o \ - fll_type.o \ - fll_rm.o \ - fll_out.o +fll_out.o : \ + fll_type.o + +fll_write_ffa.o : \ + fll_out.o \ + fll_type.o From 88289bca32189ec20e5bb764b7d3d41c916c2611 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 10:14:22 -0700 Subject: [PATCH 064/325] move example to its own directory --- examples/Makefile | 26 +++---- examples/Simple_data_operation/Makefile | 67 +++++++++++++++++++ examples/{ => Simple_data_operation}/TEST | 0 examples/{ => Simple_data_operation}/TEST1 | 0 .../{ => Simple_data_operation}/fll_test.f90 | 0 .../fll_test_subr.f90 | 0 .../{ => Simple_data_operation}/project.dep | 8 +-- .../Simple_data_operation/src_dir_path.mk | 2 + examples/src_dir_path.mk | 1 + 9 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 examples/Simple_data_operation/Makefile rename examples/{ => Simple_data_operation}/TEST (100%) rename examples/{ => Simple_data_operation}/TEST1 (100%) rename examples/{ => Simple_data_operation}/fll_test.f90 (100%) rename examples/{ => Simple_data_operation}/fll_test_subr.f90 (100%) rename examples/{ => Simple_data_operation}/project.dep (65%) create mode 100644 examples/Simple_data_operation/src_dir_path.mk diff --git a/examples/Makefile b/examples/Makefile index 8bdd180..c197a7d 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -36,32 +36,26 @@ include ../config.mk DEP_FILE=project.dep -FMODDIRS= ../data_util +FMODDIRS= ../../data_util -FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) +#SUBDIRS= $(dir $(wildcard $(srcdir)/*)) +SUBDIRS= Simple_data_operation -OFILES=$(FFILES:%.f90=%.o) -XOFILES=$(wildcard ../data_util/*.o) ########################################################################### -all: $(EXE).x +all: $(SUBDIRS:%=%.all) include ../rules.mk -$(EXE).x: $(OFILES) $(XOFILES) - $(FC) $(LDFLAGS) -o $@ $^ +clean: $(SUBDIRS:%=%.clean) + rm -f *.x *.o *.mod -clean: - rm -f *.x *.o *.mod $(EXE) +depend: $(SUBDIRS:%=%.depend) -depend: $(FFILES) - @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) +install: $(SUBDIRS:%=%.install) -install: $(EXE).x $(EXE) - $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) - $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x +test: $(SUBDIRS:%=%.test) --include $(srcdir)/project.dep +chk: $(SUBDIRS:%=%.chk) diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile new file mode 100644 index 0000000..289024e --- /dev/null +++ b/examples/Simple_data_operation/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_test + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=project.dep + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +install: $(EXE).x $(EXE) + $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) + $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x + +-include $(srcdir)/project.dep diff --git a/examples/TEST b/examples/Simple_data_operation/TEST similarity index 100% rename from examples/TEST rename to examples/Simple_data_operation/TEST diff --git a/examples/TEST1 b/examples/Simple_data_operation/TEST1 similarity index 100% rename from examples/TEST1 rename to examples/Simple_data_operation/TEST1 diff --git a/examples/fll_test.f90 b/examples/Simple_data_operation/fll_test.f90 similarity index 100% rename from examples/fll_test.f90 rename to examples/Simple_data_operation/fll_test.f90 diff --git a/examples/fll_test_subr.f90 b/examples/Simple_data_operation/fll_test_subr.f90 similarity index 100% rename from examples/fll_test_subr.f90 rename to examples/Simple_data_operation/fll_test_subr.f90 diff --git a/examples/project.dep b/examples/Simple_data_operation/project.dep similarity index 65% rename from examples/project.dep rename to examples/Simple_data_operation/project.dep index f48062d..4b1a81c 100644 --- a/examples/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! +fll_test_subr.o : \ + ../../data_util/fll_mods.o + fll_test.o : \ - ../data_util/fll_mods.o \ + ../../data_util/fll_mods.o \ fll_test_subr.o - -fll_test_subr.o : \ - ../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/src_dir_path.mk b/examples/Simple_data_operation/src_dir_path.mk new file mode 100644 index 0000000..ab0bfbf --- /dev/null +++ b/examples/Simple_data_operation/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/examples/Simple_data_operation + diff --git a/examples/src_dir_path.mk b/examples/src_dir_path.mk index 7c19767..ac677d3 100644 --- a/examples/src_dir_path.mk +++ b/examples/src_dir_path.mk @@ -1 +1,2 @@ srcdir=$(PROJ_ROOT_PATH)/examples + From daf39552fafb64ef19a9f4dda8e76904c6ef99bf Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 10:14:42 -0700 Subject: [PATCH 065/325] prepare having MPI-IO tests --- examples/Example_MPI-IO/Makefile | 67 +++++++++++++ examples/Example_MPI-IO/create_mpi_struct.f90 | 94 +++++++++++++++++++ examples/Example_MPI-IO/mpi-IO.f90 | 70 ++++++++++++++ examples/Example_MPI-IO/project.dep | 8 ++ examples/Example_MPI-IO/src_dir_path.mk | 2 + 5 files changed, 241 insertions(+) create mode 100644 examples/Example_MPI-IO/Makefile create mode 100644 examples/Example_MPI-IO/create_mpi_struct.f90 create mode 100644 examples/Example_MPI-IO/mpi-IO.f90 create mode 100644 examples/Example_MPI-IO/project.dep create mode 100644 examples/Example_MPI-IO/src_dir_path.mk diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile new file mode 100644 index 0000000..289024e --- /dev/null +++ b/examples/Example_MPI-IO/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_test + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=project.dep + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +install: $(EXE).x $(EXE) + $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) + $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x + +-include $(srcdir)/project.dep diff --git a/examples/Example_MPI-IO/create_mpi_struct.f90 b/examples/Example_MPI-IO/create_mpi_struct.f90 new file mode 100644 index 0000000..08b51b6 --- /dev/null +++ b/examples/Example_MPI-IO/create_mpi_struct.f90 @@ -0,0 +1,94 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: creates mpi struct defining how many files will be +! saved and which partitions will be saving to each +! file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE CREATE_MPI_STRUCT_M +CONTAINS + + SUBROUTINE CREATE_MPI_STRUCT(PNODE) + + USE FLL_MODS_M + IMPLICIT NONE +! +! + TYPE(DNODE), POINTER :: PNODE,PTMP + TYPE(FUNC_DATA_SET) :: FPAR +! +! MAKE STRUCTURE +! + PNODE => FLL_MKDIR('MPI-IO',FPAR) +! + WRITE(*,*)' NAME OF OUTPUT FILE WITHOUT SUFFIX' + READ(*,*)NAME_OF_FILE +! +! create node for name of the I/O file and add it to the main structure +! + PTMP => FLL_MK('name-of-file','S', 1_LINT, 1_LINT, FPAR) + PTMP%S0 = TRIM(NAME_OF_FILE) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! create node with number of files which are to be saved +! + WRITE(*,*)' HOW MANY FILES DO YOU WANT TO SAVE' + READ(*,*)NFILES + PTMP => FLL_MK('N-files','L', 1_LINT, 1_LINT, FPAR) + PTMP%L0 = NFILES + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' + + + DO I=1,NFILES + + + + END DO + + + CALL FLL_CAT(PNODE, FPAR) + + + + END SUBROUTINE CREATE_MPI_STRUCT +END MODULE CREATE_MPI_STRUCT_M diff --git a/examples/Example_MPI-IO/mpi-IO.f90 b/examples/Example_MPI-IO/mpi-IO.f90 new file mode 100644 index 0000000..29529f1 --- /dev/null +++ b/examples/Example_MPI-IO/mpi-IO.f90 @@ -0,0 +1,70 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: test of MPI I-O operations +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM MPI-IO + + USE FLL_MODS_M + USE CREATE_MPI_STRUCT_M + + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT,I + CHARACTER :: FMT +! +! read TEST file and store it in PNODE +! file is an ASCII file +! + FLL_MPI_STRUCT => NULL() + CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT) + + CALL FLL_RM(FLL_MPI_STRUCT,FPAR) + + +END PROGRAM diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep new file mode 100644 index 0000000..a0b814e --- /dev/null +++ b/examples/Example_MPI-IO/project.dep @@ -0,0 +1,8 @@ +# This file is generated automatically. DO NOT EDIT! + +mpi-IO.o : \ + ../../data_util/fll_mods.o \ + create_mpi_struct.o + +create_mpi_struct.o : \ + ../../data_util/fll_mods.o diff --git a/examples/Example_MPI-IO/src_dir_path.mk b/examples/Example_MPI-IO/src_dir_path.mk new file mode 100644 index 0000000..74c100d --- /dev/null +++ b/examples/Example_MPI-IO/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/examples/Example_MPI-IO + From d028a1e2cacb6242785f6bb1172ea9fac3d920c4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 11:52:46 -0700 Subject: [PATCH 066/325] update dependency script If intrinsic modules, ignore them --- python_dep/fort_depend.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 3bf6197..e874fd7 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -106,7 +106,9 @@ def check_if_there(use,file): with open(file) as f: for line in f: if "module" in line.lower(): - if use in line: + extrline = line.lower() + extrline = extrline.replace("module", "") + if use.lower().strip() == extrline.strip(): return 1 f.close() @@ -185,8 +187,14 @@ def get_depends(fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: try: +# +# module is in the same directory +# tmp.append(m2f[j.lower()]) except KeyError: +# +# module is not, loop through all other files +# for k in ffiles: retval=check_if_there(use=j,file=k) if retval > 0: From 442128bb6fc6cc497e0da0cf1fbe4184697895e8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 11:53:01 -0700 Subject: [PATCH 067/325] remove troublemaking flags --- config/compset.gfortran | 4 ++-- config/compset.gfortran_debug | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/compset.gfortran b/config/compset.gfortran index 873ddca..d90cbbe 100644 --- a/config/compset.gfortran +++ b/config/compset.gfortran @@ -8,5 +8,5 @@ CC = gcc CFLAGS = -O2 -fopenmp C_LDFLAGS = -O2 -fopenmp MPI_FC = mpif90 -MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp -MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp diff --git a/config/compset.gfortran_debug b/config/compset.gfortran_debug index 4926b69..1e3a207 100644 --- a/config/compset.gfortran_debug +++ b/config/compset.gfortran_debug @@ -2,7 +2,7 @@ FC = gfortran FCMODINCFLAG = -I FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input UPPER_MODFILE_NAME = LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp CC = gcc -fopenmp From d4361cc8619ad701f7ca0def13134364bf67846d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 11:53:30 -0700 Subject: [PATCH 068/325] add definition of the fortran2008 complient desrciptors --- data_util/fll_type.f90 | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index aed2c54..b14966f 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -39,19 +39,11 @@ MODULE FLL_TYPE_M ! ! define std I/O desriptors -!#ifdef f2008 -!use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & -! stdout=>output_unit, & -! stderr=>error_unit -!#else - -! #define STDIN 5 -! #define STDOUT 6 -! #define STDERR 0 -! #define IOSTAT=55 -! #define IOLOG=99 - -!#endif +#ifdef f2008 +use, intrinsic :: iso_fortran_env, only : stdin=>input_unit, & + stdout=>output_unit, & + stderr=>error_unit +#endif ! ! Declarations @@ -80,10 +72,11 @@ MODULE FLL_TYPE_M ! Arguments declaration ! IMPLICIT NONE - +#ifndef f2008 INTEGER, PARAMETER :: STDIN =5 INTEGER, PARAMETER :: STDOUT=6 INTEGER, PARAMETER :: STDERR=0 +#endif INTEGER, PARAMETER :: IOSTATFILE=55 INTEGER, PARAMETER :: IOLOGFILE=99 @@ -104,10 +97,10 @@ MODULE FLL_TYPE_M ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! TYPE DNODE - CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list + CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list - INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 + INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 INTEGER(LINT) :: POS = 0, LENGTH = 0 TYPE (DNODE), POINTER :: & From 00e4b7f2acf034a9f14a62e451e22510142dd7e7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 11:54:00 -0700 Subject: [PATCH 069/325] add MPI-IO to Makefile --- examples/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index c197a7d..187bd48 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -36,10 +36,12 @@ include ../config.mk DEP_FILE=project.dep -FMODDIRS= ../../data_util +#FMODDIRS= ../../data_util #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) -SUBDIRS= Simple_data_operation +SUBDIRS= \ + Simple_data_operation \ + Example_MPI-IO From f0bc213d47d444cb66ea0997f1087d1e4608fd50 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 12:03:14 -0700 Subject: [PATCH 070/325] Update makefiles for MPI applications --- Makefile | 1 + examples/Makefile | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8bd948f..7ff5e5b 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ include rules.mk init: echo PROJ_ROOT_PATH=$(PWD) > config.mk echo MAKEDEPEND=$(PWD)/python_dep/fort_depend.py >> config.mk + echo MPI_FC=YES >> config.mk data_util.all: test.all: data_util.all diff --git a/examples/Makefile b/examples/Makefile index 187bd48..f506216 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -41,7 +41,10 @@ DEP_FILE=project.dep #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ Simple_data_operation \ - Example_MPI-IO + +ifneq ($(strip $(MPI_FC)),) + SUBDIRS+= Example_MPI-IO +endif From c4641dec7fbe2e544b734292b02794fbd9dc32de Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 13:53:53 -0700 Subject: [PATCH 071/325] update fll_getndata Do not need to specify the type --- data_util/fll_getndata.f90 | 120 +++++++----------- examples/Simple_data_operation/fll_test.f90 | 2 +- .../Simple_data_operation/fll_test_subr.f90 | 2 +- 3 files changed, 47 insertions(+), 77 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 46f840d..145e9f9 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNDATA_M ! External Modules used ! CONTAINS - FUNCTION FLL_GETNDATA_R0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -56,7 +56,6 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R0 Out returns value of real scalar ! @@ -65,7 +64,6 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RSINGLE) :: R0 ! @@ -81,11 +79,11 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -97,7 +95,7 @@ END FUNCTION FLL_GETNDATA_R0 - FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -122,7 +120,6 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R1 Out returns pointer to real array ! @@ -131,7 +128,6 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R1(:) ! @@ -146,11 +142,11 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -160,7 +156,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_R1 - FUNCTION FLL_GETNDATA_R2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -186,7 +182,6 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R2 Out returns pointer to real array ! @@ -195,7 +190,6 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R2(:,:) ! @@ -210,11 +204,11 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -226,7 +220,7 @@ END FUNCTION FLL_GETNDATA_R2 ! ! DOUBLE ! - FUNCTION FLL_GETNDATA_D0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -252,7 +246,6 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R1 Out returns double number ! @@ -261,7 +254,6 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RDOUBLE) :: R0 ! @@ -276,11 +268,11 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -292,7 +284,7 @@ END FUNCTION FLL_GETNDATA_D0 - FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -318,7 +310,6 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R1 Out returns pointer to double array ! @@ -327,7 +318,6 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R1(:) ! @@ -342,11 +332,11 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -357,7 +347,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_D1 - FUNCTION FLL_GETNDATA_D2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -383,7 +373,6 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! R1 Out returns pointer to double array ! @@ -392,7 +381,6 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R2(:,:) ! @@ -407,11 +395,11 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -423,7 +411,7 @@ END FUNCTION FLL_GETNDATA_D2 ! ! INTEGER ! - FUNCTION FLL_GETNDATA_I0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -449,7 +437,6 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I0 Out returns integer value ! @@ -458,7 +445,6 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(SINT) :: I0 ! @@ -473,11 +459,11 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -489,7 +475,7 @@ END FUNCTION FLL_GETNDATA_I0 - FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) ! ! Description: returns single real data of the node ! @@ -514,7 +500,6 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I1 Out returns pointer to integer array ! @@ -523,7 +508,6 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I1(:) ! @@ -538,11 +522,11 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -552,7 +536,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_I1 - FUNCTION FLL_GETNDATA_I2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -577,7 +561,6 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I2 Out returns pointer to integer array ! @@ -586,7 +569,6 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I2(:,:) ! @@ -601,11 +583,11 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -617,7 +599,7 @@ END FUNCTION FLL_GETNDATA_I2 ! ! LONG INTEGER ! - FUNCTION FLL_GETNDATA_L0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -642,7 +624,6 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I0 Out returns long integer value ! @@ -651,7 +632,6 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(LINT) :: I0 ! @@ -666,11 +646,11 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I0) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -682,7 +662,7 @@ END FUNCTION FLL_GETNDATA_L0 - FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) USE FLL_TYPE_M USE FLL_LOCATE_M @@ -696,7 +676,6 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I1 Out returns pointer to long integer array ! @@ -705,7 +684,6 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I1(:) ! @@ -720,11 +698,11 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -734,7 +712,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_L1 - FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -759,7 +737,6 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! I2 Out returns pointer to long integer array ! @@ -768,7 +745,6 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I2(:,:) ! @@ -783,11 +759,11 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -797,7 +773,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -822,7 +798,6 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! STRING Out returns string ! @@ -831,7 +806,6 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER CHARACTER(LEN=STRING_LENGHT) :: STRING ! @@ -846,11 +820,11 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',0_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -860,7 +834,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S -FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) +FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -885,7 +859,6 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! STRING Out returns pointer to string array ! @@ -894,7 +867,6 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:) ! @@ -909,11 +881,11 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',1_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -923,7 +895,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S1 - FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -948,7 +920,6 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) ! PNODE In pointer to data set ! NAME In name of pointer ! NUMBER Out number of pointer if more pointers of the same type are present -! LTYPE Out type of pointer ! FPAR In/Out structure containing function specific data ! STRING Out returns pointer to string array ! @@ -957,7 +928,6 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME - CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:,:) ! @@ -972,11 +942,11 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,LTYPE,NUMBER,FPAR) RESULT(STRING) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,LTYPE,2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',2_LINT,NUMBER,.FALSE.,FPAR) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' CALL FLL_OUT('ALL',FPAR) RETURN END IF diff --git a/examples/Simple_data_operation/fll_test.f90 b/examples/Simple_data_operation/fll_test.f90 index 654fb6c..792f77f 100644 --- a/examples/Simple_data_operation/fll_test.f90 +++ b/examples/Simple_data_operation/fll_test.f90 @@ -112,7 +112,7 @@ PROGRAM FLL_TEST ! 1. HUMID => PTMP%D1 ! 2. Locating the node in PNEW1 - HUMID => FLL_GETNDATA_D1(PNEW1,'Humidity','D',1_LINT,FPAR) + HUMID => FLL_GETNDATA_D1(PNEW1,'Humidity',1_LINT,FPAR) IF(.NOT.ASSOCIATED(HUMID))THEN STOP' DID NOT FIND HUMID' diff --git a/examples/Simple_data_operation/fll_test_subr.f90 b/examples/Simple_data_operation/fll_test_subr.f90 index 76ad474..5b11d16 100644 --- a/examples/Simple_data_operation/fll_test_subr.f90 +++ b/examples/Simple_data_operation/fll_test_subr.f90 @@ -94,7 +94,7 @@ SUBROUTINE FLL_TEST_SUBR(PNODE,PNODE1) ! ! find the values of pressure subset #1 and print the data on screen ! - PRESS => FLL_GETNDATA_D1(PTMP,'pressure','D',1_LINT,FPAR) + PRESS => FLL_GETNDATA_D1(PTMP,'pressure',1_LINT,FPAR) write(*,*)' Values of pressure are ',PRESS ! ! PNEW WAS CREATED HERE, IT DOES NOT BELONG TO ANY NODE (WAS NOT MOVED TO ANY NODE) From 2785312ce4645e6a7115fef2d35d08c14fa2ec85 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 15:16:10 -0700 Subject: [PATCH 072/325] temporary commit --- Makefile | 1 + data_util/fll_duplicate.f90 | 8 +- .../{mpi-IO.f90 => Example_mpi-IO.f90} | 38 +- examples/Example_MPI-IO/Makefile | 7 +- examples/Example_MPI-IO/create_data_set.f90 | 110 ++++ examples/Example_MPI-IO/create_mpi_struct.f90 | 63 +- examples/Example_MPI-IO/project.dep | 10 +- examples/Example_MPI-IO/read_input.f90 | 74 +++ mpi_util/Makefile | 66 ++ mpi_util/fll_mpi_duplicate.f90 | 593 ++++++++++++++++++ mpi_util/fll_mpi_mods.f90 | 39 ++ mpi_util/project.dep | 10 + mpi_util/src_dir_path.mk | 1 + 13 files changed, 988 insertions(+), 32 deletions(-) rename examples/Example_MPI-IO/{mpi-IO.f90 => Example_mpi-IO.f90} (60%) create mode 100644 examples/Example_MPI-IO/create_data_set.f90 create mode 100644 examples/Example_MPI-IO/read_input.f90 create mode 100644 mpi_util/Makefile create mode 100644 mpi_util/fll_mpi_duplicate.f90 create mode 100644 mpi_util/fll_mpi_mods.f90 create mode 100644 mpi_util/project.dep create mode 100644 mpi_util/src_dir_path.mk diff --git a/Makefile b/Makefile index 7ff5e5b..4435ec2 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ include src_dir_path.mk SUBDIRS= \ data_util\ +mpi_util \ examples\ ########################################################################### diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 2cec804..573a993 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -119,7 +119,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) PNEW => NULL() RETURN END IF - CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW,FPAR) END IF @@ -174,7 +174,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) PNEW => NULL() RETURN END IF - CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) + CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW, FPAR) OK = FLL_MV(PNEW, PDUPL, FPAR) FPAR%SUCCESS = .TRUE. ELSE @@ -221,7 +221,7 @@ END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE ! ! ! - SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) + SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! ! Description: duplicated data of the node ! @@ -514,7 +514,7 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%L0 = PNODE%L0 PNEW%S0 = PNODE%S0 - END SUBROUTINE FLL_COPPY_NODE_ARRAYS + END SUBROUTINE FLL_COPY_NODE_ARRAYS END MODULE FLL_DUPLICATE_M diff --git a/examples/Example_MPI-IO/mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 similarity index 60% rename from examples/Example_MPI-IO/mpi-IO.f90 rename to examples/Example_MPI-IO/Example_mpi-IO.f90 index 29529f1..250ed12 100644 --- a/examples/Example_MPI-IO/mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -43,28 +43,50 @@ ! Description ! ! - PROGRAM MPI-IO +PROGRAM EXAMPLE_MPI_IO + USE MPI USE FLL_MODS_M USE CREATE_MPI_STRUCT_M + USE READ_INPUT_M + USE CREATE_DATA_SET_M IMPLICIT NONE ! ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT + TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT,I + INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id CHARACTER :: FMT + + INTEGER(LINT) :: NFILES,NPROC + CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE +! +! Initialize MPI +! + CALL MPI_INIT(IERR) + CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) + + IF(WORLD_RANK == 0) THEN + CALL READ_INPUT(NAME_OF_FILE,NFILES,NPROC) +! +! initialize MPI +! + FLL_MPI_STRUCT => NULL() + CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,NPROC) + + CALL FLL_RM(FLL_MPI_STRUCT,FPAR) + + END IF ! -! read TEST file and store it in PNODE -! file is an ASCII file +! make some data set ! - FLL_MPI_STRUCT => NULL() - CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT) + CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) - CALL FLL_RM(FLL_MPI_STRUCT,FPAR) + CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) + CALL MPI_FINALIZE(IERR) END PROGRAM diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index 289024e..56c8fa6 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -29,13 +29,18 @@ # # -EXE = fll_test +EXE = MPI_Test include src_dir_path.mk include ../../config.mk DEP_FILE=project.dep +# Use MPI compilation in this file +FC =$(MPI_FC) +FFLAGS =$(MPI_FFLAGS) $(FINCFLAGS) + + FMODDIRS= ../../data_util FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) diff --git a/examples/Example_MPI-IO/create_data_set.f90 b/examples/Example_MPI-IO/create_data_set.f90 new file mode 100644 index 0000000..4f6392b --- /dev/null +++ b/examples/Example_MPI-IO/create_data_set.f90 @@ -0,0 +1,110 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: creates mpi struct defining how many files will be +! saved and which partitions will be saving to each +! file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE CREATE_DATA_SET_M +CONTAINS + + SUBROUTINE CREATE_DATA_SET(PNODE,NNODES,RANK) + + USE FLL_MODS_M + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE +! +! Local declarations +! + TYPE(DNODE), POINTER :: PTMP + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER(LINT) :: NNODES + INTEGER :: RANK + + REAL(RDOUBLE), POINTER :: PRESS(:), DENS(:), VELOC(:,:) +! +! MAKE STRUCTURE +! + PNODE => FLL_MKDIR('Main_Data_Set',FPAR) +! +! create 1-D double array of pressure fill it up with 101323 value and attach to PNODE +! + PTMP => FLL_MK('pressure','D', NNODES, 1_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) +! + PRESS => FLL_GETNDATA_D1(PNODE,'pressure',1_LINT,FPAR) + PRESS = 101232. +! +! create 1-D double array of desnity fill it up with 1.225 value and attach to PNODE +! + PTMP => FLL_MK('density','D',NNODES, 1_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) +! + DENS => FLL_GETNDATA_D1(PNODE,'density',1_LINT,FPAR) + DENS = 1.225 +! +! create 2-D double array of velocity fill it up with 100, 0, 0 values and attach to PNODE +! + PTMP => FLL_MK('velocity', 'D',NNODES, 3_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) +! + VELOC => FLL_GETNDATA_D2(PNODE,'velocity',1_LINT,FPAR) + VELOC(:,1) = 100. + VELOC(:,2) = 0. + VELOC(:,3) = 0. +! +! print data set on screen, only mpi root +! + IF(RANK == 0)CALL FLL_CAT(PNODE,6,.false., FPAR) + + RETURN + END SUBROUTINE CREATE_DATA_SET +END MODULE CREATE_DATA_SET_M diff --git a/examples/Example_MPI-IO/create_mpi_struct.f90 b/examples/Example_MPI-IO/create_mpi_struct.f90 index 08b51b6..3dd3eee 100644 --- a/examples/Example_MPI-IO/create_mpi_struct.f90 +++ b/examples/Example_MPI-IO/create_mpi_struct.f90 @@ -48,21 +48,24 @@ MODULE CREATE_MPI_STRUCT_M CONTAINS - SUBROUTINE CREATE_MPI_STRUCT(PNODE) + SUBROUTINE CREATE_MPI_STRUCT(PNODE,NAME_OF_FILE,NFILES,NPROC) USE FLL_MODS_M IMPLICIT NONE -! + + TYPE(DNODE), POINTER :: PNODE +! +! Local declarations ! - TYPE(DNODE), POINTER :: PNODE,PTMP + TYPE(DNODE), POINTER :: PTMP TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER(LINT) :: NFILES, I,J,NPROC, COUNT + CHARACTER(LEN=*) :: NAME_OF_FILE ! ! MAKE STRUCTURE ! PNODE => FLL_MKDIR('MPI-IO',FPAR) -! - WRITE(*,*)' NAME OF OUTPUT FILE WITHOUT SUFFIX' - READ(*,*)NAME_OF_FILE ! ! create node for name of the I/O file and add it to the main structure ! @@ -72,23 +75,47 @@ SUBROUTINE CREATE_MPI_STRUCT(PNODE) ! ! create node with number of files which are to be saved ! - WRITE(*,*)' HOW MANY FILES DO YOU WANT TO SAVE' - READ(*,*)NFILES - PTMP => FLL_MK('N-files','L', 1_LINT, 1_LINT, FPAR) + PTMP => FLL_MK('N-files','L', 1_LINT, 1_LINT, FPAR) PTMP%L0 = NFILES IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! create node with number processors the job will run at +! + PTMP => FLL_MK('N-proc','L', 1_LINT, 1_LINT, FPAR) + PTMP%L0 = NPROC + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' +! +! group processes +! there will be NFILES group +! each group would have max NPROC/NFILES partitions and the increment +! between them is NFILES +! +! in this way, each file should be associated to one partition from each node +! + DO J=1,NFILES +! +! Make group and add it to the main structure +! + PTMP => FLL_MK('group','L',NPROC/NFILES,1_LINT,FPAR) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' + + COUNT = 1 + DO I=J,NPROC,NFILES +! +! fill partition numbers +! + PTMP%L1(COUNT) = I + COUNT = COUNT + 1 - - DO I=1,NFILES - - + END DO END DO - - - CALL FLL_CAT(PNODE, FPAR) - - +! +! print node on the screen and save to files +! + CALL FLL_CAT(PNODE,6,.false., FPAR) + IF(.NOT.FLL_WRITE(PNODE,"io.str", 9, 'A', FPAR))STOP'Error writing file' + RETURN END SUBROUTINE CREATE_MPI_STRUCT END MODULE CREATE_MPI_STRUCT_M diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index a0b814e..f4d8847 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -1,8 +1,16 @@ # This file is generated automatically. DO NOT EDIT! -mpi-IO.o : \ +Example_mpi-IO.o : \ ../../data_util/fll_mods.o \ + read_input.o \ + create_data_set.o \ create_mpi_struct.o +read_input.o : \ + ../../data_util/fll_mods.o + create_mpi_struct.o : \ ../../data_util/fll_mods.o + +create_data_set.o : \ + ../../data_util/fll_mods.o diff --git a/examples/Example_MPI-IO/read_input.f90 b/examples/Example_MPI-IO/read_input.f90 new file mode 100644 index 0000000..c9bdc02 --- /dev/null +++ b/examples/Example_MPI-IO/read_input.f90 @@ -0,0 +1,74 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: creates mpi struct defining how many files will be +! saved and which partitions will be saving to each +! file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE READ_INPUT_M +CONTAINS + + SUBROUTINE READ_INPUT(NAME_OF_FILE,NFILES,NPROC) + + USE FLL_MODS_M + IMPLICIT NONE +! +! Local declarations +! + INTEGER(LINT) :: NFILES, NPROC + CHARACTER(LEN=*) :: NAME_OF_FILE +! +! create node for name of the I/O file and add it to the main structure +! + WRITE(*,*)' Name of file without suffix' + READ(*,*)NAME_OF_FILE + + WRITE(*,*)' Hom many files' + READ(*,*)NFILES + + WRITE(*,*)' How many processors' + READ(*,*)NPROC + + RETURN + END SUBROUTINE READ_INPUT +END MODULE READ_INPUT_M diff --git a/mpi_util/Makefile b/mpi_util/Makefile new file mode 100644 index 0000000..26b1b26 --- /dev/null +++ b/mpi_util/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# +include src_dir_path.mk +include ../config.mk + +# $(DEP_FILE) is a .dep file generated by fort_depend.py +DEP_FILE = project.dep + +# Use MPI compilation in this file +FC =$(MPI_FC) +FFLAGS =$(MPI_FFLAGS) $(FINCFLAGS) + +FMODDIRS= ../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) + +########################################################################### + +all: $(OFILES) +include ../rules.mk + +clean: + rm -f *.o *.mod + +test: + @echo No tests exist, yet. + + +depend: $(FFILES) + echo "Making dependencies ..." + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + + +-include $(srcdir)/$(DEP_FILE) + diff --git a/mpi_util/fll_mpi_duplicate.f90 b/mpi_util/fll_mpi_duplicate.f90 new file mode 100644 index 0000000..dc9c6e6 --- /dev/null +++ b/mpi_util/fll_mpi_duplicate.f90 @@ -0,0 +1,593 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +! +MODULE FLL_MPI_DUPLICATE_M +! +! Description: Contains duplicates node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MPI_DUPLICATE(PNODE,SENDPART,COMMUNICATOR,FPAR) RESULT(PNEW) +! +! Description: Contains nodes for duplicating DNODE data set from +! one partition to other partitions +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! COMMUNICATOR In MPI communicator +! SENDPART In sending partition +! PNEW Out duplicate node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART, COMMUNICATOR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCHILD + ITNEGER :: IRANK, IERR +! +! get rank of the process +! + CALL MPI_Comm_rank ( COMMUNICATOR, IRANK, IERR ) +! +! check the node is not null +! + + IF(IRANK == SENDPART)THEN +! +! sending partitions +! + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' MPI_DUPLICATE - null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PCHILD => PNODE%PCHILD + + IF(ASSOCIATED(PCHILD))THEN + + CALL FLL_MPI_SEND_NODE_DATA(PNODE,COMMUNICATOR,SENDPART) + + CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + IF(.NOT.FPAR%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + ELSE +! +! NODE IS A FILE NODE +! + CALL FLL_MPI_SEND_NODE_DATA(PNODE,COMMUNICATOR,SENDPART) + + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + + END IF + + ELSE +! +! RECEVING PARTITIONS +! + PNEW => NULL() + + DO + + PTMP => FLL_MPI_GET_NEW_NODE(PNEW, COMMUNICATOR, SENDPART) + + + END DO + + + + + + + IF(ASSOCIATED(PCHILD))THEN + PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) + IF(.NOT.FPAR%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + ELSE +! +! NODE IS A FILE NODE +! + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + + END IF + + + + + + + + + + + + + + + END IF +! +! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM +! + FPAR%SUCCESS = .TRUE. + RETURN + + END FUNCTION FLL_MPI_DUPLICATE +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PDUPL Out duplicate of PNODE +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD + LOGICAL :: OK +! + PCURR => PNODE + PCHILD => PNODE%PCHILD +! +! NODE IS A FILE NODE +! + IF(.NOT.ASSOCIATED(PCHILD))THEN + + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) + OK = FLL_MV(PNEW, PDUPL, FPAR) + FPAR%SUCCESS = .TRUE. + ELSE +! +! NODE IS DIR +! LOOP OVER CHILDREN +! + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD + + PNEW => FLL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF +! +! NODE HAS CHILDREN +! + DO WHILE(ASSOCIATED(PCHILD)) + + CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' + PCHILD => PCHILD%PNEXT + + END DO +! +! ADD TO PDUPL LIST +! + OK = FLL_MV(PNEW,PDUPL,FPAR) + PCURR => PNEXT + + END DO + END IF + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE +! +! +! + SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) +! +! Description: duplicated data of the node +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! PNEW Out duplicate of PNODE data +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! + INTEGER(LINT) :: NDIM, NSIZE, NNDIM, NNSIZE +! +! check node types +! + IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF +! +! COPY JUST NAME AND TYPE +! THE REST IS GOING TO BE AUTOMATIC +! + PNEW%LNAME = PNODE%LNAME + PNEW%LTYPE = PNODE%LTYPE +! +! IF DIR NODE, RETURN +! + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR. TRIM(PNODE%LTYPE) == 'N') RETURN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%R1))THEN + NNDIM = SIZE(PNEW%R1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%R1 = PNODE%R1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%D1))THEN + NNDIM = SIZE(PNEW%D1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%D1 = PNODE%D1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%I1))THEN + + NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%I1))THEN + NNDIM = SIZE(PNEW%I1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + END IF +! + IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%L1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%L1))THEN + NNDIM = SIZE(PNEW%L1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%L1 = PNODE%L1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + END IF + + IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%S1, DIM = 1, KIND = LINT) + + IF(ASSOCIATED(PNEW%S1))THEN + NNDIM = SIZE(PNEW%S1, DIM = 1, KIND = LINT) + + IF(NDIM /= NNDIM)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%S1 = PNODE%S1 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S1 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%R2))THEN + NNDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%R2 = PNODE%R2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%D2))THEN + NNDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%D2 = PNODE%D2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%I2))THEN + NNDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%I2 = PNODE%I2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%L2))THEN + NNDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%L2 = PNODE%L2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF + + IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) + + IF(ASSOCIATED(PNEW%L2))THEN + NNDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) + NNSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) + + IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + PNEW%S2 = PNODE%S2 + ELSE + WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S2 array not allocated',TRIM(PNEW%LNAME) + FPAR%SUCCESS = .FALSE. + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + PNEW%R0 = PNODE%R0 + PNEW%D0 = PNODE%D0 + PNEW%I0 = PNODE%I0 + PNEW%L0 = PNODE%L0 + PNEW%S0 = PNODE%S0 + + END SUBROUTINE FLL_COPPY_NODE_ARRAYS + + +END MODULE FLL_MPI_DUPLICATE_M diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 new file mode 100644 index 0000000..0dd0847 --- /dev/null +++ b/mpi_util/fll_mpi_mods.f90 @@ -0,0 +1,39 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +MODULE FLL_MPI_MODS_M +! +! Description: Contains list of modules of mpi_util fll library +! each function/subroutine using fll data utilities +! should then use statement +! USE FLL_MPI_MODS_M +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_MPI_DUPLICATE_M + +END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep new file mode 100644 index 0000000..d51ea9d --- /dev/null +++ b/mpi_util/project.dep @@ -0,0 +1,10 @@ +# This file is generated automatically. DO NOT EDIT! + +fll_mpi_mods.o : \ + fll_mpi_duplicate.o + +fll_mpi_duplicate.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o diff --git a/mpi_util/src_dir_path.mk b/mpi_util/src_dir_path.mk new file mode 100644 index 0000000..f9ec48e --- /dev/null +++ b/mpi_util/src_dir_path.mk @@ -0,0 +1 @@ +srcdir=$(PROJ_ROOT_PATH)/mpi_util From bdeb94ecac957028a4019103adbbb65118e713a3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 7 Nov 2016 21:22:05 -0700 Subject: [PATCH 073/325] some improvements Make script to check entire name of module not just part If module not found in any file, ignore it, assume it will come as part of linking (MPI etc) --- fort_depend.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 3bf6197..e874fd7 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -106,7 +106,9 @@ def check_if_there(use,file): with open(file) as f: for line in f: if "module" in line.lower(): - if use in line: + extrline = line.lower() + extrline = extrline.replace("module", "") + if use.lower().strip() == extrline.strip(): return 1 f.close() @@ -185,8 +187,14 @@ def get_depends(fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: try: +# +# module is in the same directory +# tmp.append(m2f[j.lower()]) except KeyError: +# +# module is not, loop through all other files +# for k in ffiles: retval=check_if_there(use=j,file=k) if retval > 0: From 5d5452e2507c16f3cb27f24781676178ea06d79e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 11:24:11 -0700 Subject: [PATCH 074/325] add additional print outs to python dependency script --- python_dep/fort_depend.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index e874fd7..66299c7 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -63,11 +63,13 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' return #Open file + print(" ") f=open(outfile,'w') f.write('# This file is generated automatically. DO NOT EDIT!\n') for i in dep.keys(): tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") + print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") for j in dep[i]: npathseg = j.count('/') if npathseg == 0: @@ -83,6 +85,7 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' stri=stri+"\n" f.write(stri) f.close() + print(" ") return def get_source(ext=[".f90",".F90"]): From 2b75d84e37f2fdf73d2b050b8a4c7bb3aed05e07 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 11:24:29 -0700 Subject: [PATCH 075/325] add header info to fll_duplicate --- data_util/fll_duplicate.f90 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 573a993..b7f1b26 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -225,6 +225,12 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! ! Description: duplicated data of the node ! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! ! External Modules used ! USE FLL_TYPE_M From 85562a79dd86e77844cebcc0daca1ebd6715e7a4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 12:28:48 -0700 Subject: [PATCH 076/325] add info about intrinsic modules --- python_dep/fort_depend.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 66299c7..36c7ac0 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -64,6 +64,8 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' #Open file print(" ") + print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") + print(" ") f=open(outfile,'w') f.write('# This file is generated automatically. DO NOT EDIT!\n') for i in dep.keys(): @@ -85,6 +87,7 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' stri=stri+"\n" f.write(stri) f.close() + print("\033[031m Finished ... \033[039m") print(" ") return @@ -112,7 +115,9 @@ def check_if_there(use,file): extrline = line.lower() extrline = extrline.replace("module", "") if use.lower().strip() == extrline.strip(): + f.close() return 1 + f.close() return 0 @@ -198,14 +203,22 @@ def get_depends(fob=[],m2f=[], ffiles=[]): # # module is not, loop through all other files # + istat = 0 for k in ffiles: retval=check_if_there(use=j,file=k) if retval > 0: + istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") - print ("\033[031m..... \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + + if istat== 0 and not(j == ""): + print("") + print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m..... \033[039m assuming internal module, not adding to dependency tree ... \033[032m\033[039m") + print("") deps[i.file_name]=tmp From ab70333355cb331a74ab89c227dbb876befa71d4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 14:46:43 -0700 Subject: [PATCH 077/325] fix bug in duplicate --- data_util/fll_duplicate.f90 | 71 +++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index b7f1b26..74d53a4 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -168,15 +168,26 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! IF(.NOT.ASSOCIATED(PCHILD))THEN - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW, FPAR) - OK = FLL_MV(PNEW, PDUPL, FPAR) - FPAR%SUCCESS = .TRUE. + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + + PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR) + OK = FLL_MV(PNEW, PDUPL, FPAR) + + PCURR => PNEXT + + END DO + + FPAR%SUCCESS = .TRUE. + ELSE ! ! NODE IS DIR @@ -258,7 +269,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! check node types ! IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -283,7 +294,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNDIM = SIZE(PNEW%R1, DIM = 1, KIND = LINT) IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -291,7 +302,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%R1 = PNODE%R1 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R1 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -306,7 +317,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNDIM = SIZE(PNEW%D1, DIM = 1, KIND = LINT) IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -314,7 +325,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%D1 = PNODE%D1 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D1 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -330,14 +341,14 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNDIM = SIZE(PNEW%I1, DIM = 1, KIND = LINT) IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN END IF PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I1 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -352,7 +363,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNDIM = SIZE(PNEW%L1, DIM = 1, KIND = LINT) IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -360,7 +371,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%L1 = PNODE%L1 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L1 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -375,7 +386,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNDIM = SIZE(PNEW%S1, DIM = 1, KIND = LINT) IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -383,7 +394,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%S1 = PNODE%S1 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S1 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -401,7 +412,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -409,7 +420,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%R2 = PNODE%R2 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R2 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -425,7 +436,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -433,7 +444,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%D2 = PNODE%D2 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D2 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -449,7 +460,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -457,7 +468,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%I2 = PNODE%I2 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I2 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -473,7 +484,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -481,7 +492,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%L2 = PNODE%L2 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L2 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -497,7 +508,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) NNSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN @@ -505,7 +516,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) PNEW%S2 = PNODE%S2 ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S2 array not allocated',TRIM(PNEW%LNAME) + WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. CALL FLL_OUT('ALL',FPAR) RETURN From df9515ef4b3e92f390e4884208561025a3878088 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 15:21:28 -0700 Subject: [PATCH 078/325] simplify duplicate --- data_util/fll_duplicate.f90 | 73 +++++++++++++------------------------ 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 74d53a4..e395d90 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -164,66 +164,45 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) PCURR => PNODE PCHILD => PNODE%PCHILD ! -! NODE IS A FILE NODE -! - IF(.NOT.ASSOCIATED(PCHILD))THEN - - DO WHILE(ASSOCIATED(PCURR)) - - PNEXT => PCURR%PNEXT - - PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - - CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR) - OK = FLL_MV(PNEW, PDUPL, FPAR) - - PCURR => PNEXT - - END DO - - FPAR%SUCCESS = .TRUE. - - ELSE -! -! NODE IS DIR ! LOOP OVER CHILDREN ! - DO WHILE(ASSOCIATED(PCURR)) + DO WHILE(ASSOCIATED(PCURR)) - PNEXT => PCURR%PNEXT - PCHILD=> PCURR%PCHILD + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD - PNEW => FLL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF + PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + IF(.NOT.ASSOCIATED(PCHILD))THEN + CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR) + OK = FLL_MV(PNEW, PDUPL, FPAR) + ELSE ! ! NODE HAS CHILDREN ! DO WHILE(ASSOCIATED(PCHILD)) - - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) - IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' - PCHILD => PCHILD%PNEXT - + + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' + PCHILD => PCHILD%PNEXT + END DO + + END IF ! ! ADD TO PDUPL LIST ! - OK = FLL_MV(PNEW,PDUPL,FPAR) - PCURR => PNEXT + OK = FLL_MV(PNEW,PDUPL,FPAR) + PCURR => PNEXT - END DO - END IF + END DO FPAR%SUCCESS = .TRUE. RETURN From 74fdc5a803ccb1eedecb95592a967d768ca8b231 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 15:22:00 -0700 Subject: [PATCH 079/325] cosmetic change in dependency python script --- python_dep/fort_depend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 36c7ac0..870d12d 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -217,7 +217,7 @@ def get_depends(fob=[],m2f=[], ffiles=[]): if istat== 0 and not(j == ""): print("") print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming internal module, not adding to dependency tree ... \033[032m\033[039m") + print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") print("") deps[i.file_name]=tmp From c125864e4511490ff09ac6d8f8267c20de67aa0f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 15:24:56 -0700 Subject: [PATCH 080/325] temporary commit --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 15 +- examples/Example_MPI-IO/Makefile | 4 +- examples/Example_MPI-IO/project.dep | 5 +- mpi_util/fll_mpi_duplicate.f90 | 829 +++++++++++---------- mpi_util/project.dep | 4 +- 5 files changed, 468 insertions(+), 389 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 250ed12..ff18fdf 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -47,6 +47,7 @@ PROGRAM EXAMPLE_MPI_IO USE MPI USE FLL_MODS_M + USE FLL_MPI_MODS_M USE CREATE_MPI_STRUCT_M USE READ_INPUT_M USE CREATE_DATA_SET_M @@ -56,7 +57,7 @@ PROGRAM EXAMPLE_MPI_IO ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET + TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id CHARACTER :: FMT @@ -76,16 +77,20 @@ PROGRAM EXAMPLE_MPI_IO ! FLL_MPI_STRUCT => NULL() CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,NPROC) - - CALL FLL_RM(FLL_MPI_STRUCT,FPAR) +! WRITE(*,*)' duplicating' +! PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) +! WRITE(*,*)' duplicate' +! CALL FLL_CAT(PNEW,6,.false., FPAR) END IF + + PNEW => FLL_MPI_DUPLICATE(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) ! ! make some data set ! - CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) + ! CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) - CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) + ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) CALL MPI_FINALIZE(IERR) diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index 56c8fa6..3733a7b 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -41,13 +41,13 @@ FC =$(MPI_FC) FFLAGS =$(MPI_FFLAGS) $(FINCFLAGS) -FMODDIRS= ../../data_util +FMODDIRS= ../../data_util ../../mpi_util FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) OFILES=$(FFILES:%.f90=%.o) -XOFILES=$(wildcard ../../data_util/*.o) +XOFILES=$(wildcard ../../data_util/*.o ../../mpi_util/*.o) ########################################################################### diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index f4d8847..1afee09 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -2,9 +2,10 @@ Example_mpi-IO.o : \ ../../data_util/fll_mods.o \ - read_input.o \ create_data_set.o \ - create_mpi_struct.o + read_input.o \ + create_mpi_struct.o \ + ../../mpi_util/fll_mpi_mods.o read_input.o : \ ../../data_util/fll_mods.o diff --git a/mpi_util/fll_mpi_duplicate.f90 b/mpi_util/fll_mpi_duplicate.f90 index dc9c6e6..0c8aa2b 100644 --- a/mpi_util/fll_mpi_duplicate.f90 +++ b/mpi_util/fll_mpi_duplicate.f90 @@ -21,7 +21,7 @@ ! MODULE FLL_MPI_DUPLICATE_M ! -! Description: Contains duplicates node +! Description: Distributes FLL list from one node to all others in communicator ! ! ! History: @@ -33,10 +33,10 @@ MODULE FLL_MPI_DUPLICATE_M ! External Modules used ! CONTAINS - FUNCTION FLL_MPI_DUPLICATE(PNODE,SENDPART,COMMUNICATOR,FPAR) RESULT(PNEW) + FUNCTION FLL_MPI_DUPLICATE(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! -! Description: Contains nodes for duplicating DNODE data set from -! one partition to other partitions +! Description: Contains duplicates node to PNEW mode +! the parent, previous and next pointers of PNEW node are NULL ! ! ! History: @@ -47,7 +47,6 @@ FUNCTION FLL_MPI_DUPLICATE(PNODE,SENDPART,COMMUNICATOR,FPAR) RESULT(PNEW) ! ! External Modules used ! - USE MPI USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M @@ -60,150 +59,90 @@ FUNCTION FLL_MPI_DUPLICATE(PNODE,SENDPART,COMMUNICATOR,FPAR) RESULT(PNEW) ! Arguments description ! Name In/Out Function ! PNODE In node to duplicate -! COMMUNICATOR In MPI communicator -! SENDPART In sending partition ! PNEW Out duplicate node +! COMMUNICATOR In MPI communicatior +! SENDPART In Sending partition ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART, COMMUNICATOR + INTEGER :: COMMUNICATOR,SENDPART ! -! Local declarations +! Local declarations ! TYPE(DNODE), POINTER :: PCHILD - ITNEGER :: IRANK, IERR + INTEGER :: RANK, IERR ! -! get rank of the process +! check the node is not null ! - CALL MPI_Comm_rank ( COMMUNICATOR, IRANK, IERR ) + FPAR%SUCCESS = .FALSE. ! -! check the node is not null +! If not sending partition, nullify pointer +! owherwise check that sending partition does not send NULL pointer and +! associate returning pointer with sending ! + CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) - IF(IRANK == SENDPART)THEN + DIFFPART: IF(SENDPART /= RANK)THEN + PNEW => NULL() + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) ! -! sending partitions +! If dir has childrenm loop over them +! the number of children in this routine is stored in +! NLINK, not ndim, ndim is set to 0 and then incremented automatically +! when adding children ! - FPAR%SUCCESS = .FALSE. - IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' MPI_DUPLICATE - null node ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - RETURN - END IF - - PCHILD => PNODE%PCHILD - - IF(ASSOCIATED(PCHILD))THEN - - CALL FLL_MPI_SEND_NODE_DATA(PNODE,COMMUNICATOR,SENDPART) - - CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,COMMUNICATOR,SENDPART,FPAR) - IF(.NOT.FPAR%SUCCESS)THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - - ELSE + IF(PNEW%NLINK > 0)THEN ! -! NODE IS A FILE NODE +! Node has children ! - CALL FLL_MPI_SEND_NODE_DATA(PNODE,COMMUNICATOR,SENDPART) - - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + CALL FLL_RECEIVE_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) END IF + RETURN + ELSE ! -! RECEVING PARTITIONS +! Sending partition ! - PNEW => NULL() - - DO - - PTMP => FLL_MPI_GET_NEW_NODE(PNEW, COMMUNICATOR, SENDPART) - - - END DO - - - - - - - IF(ASSOCIATED(PCHILD))THEN - PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - - CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) - IF(.NOT.FPAR%SUCCESS)THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - - ELSE -! -! NODE IS A FILE NODE -! - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW,FPAR) - + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN END IF + PNEW => PNODE + CALL BROADCAST_NODE_SEND(PNODE, COMMUNICATOR, SENDPART, FPAR) + + PCHILD => PNODE%PCHILD +! +! If node has children, duplicate them too +! + IF(ASSOCIATED(PCHILD))THEN + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + END IF + END IF DIFFPART + FPAR%SUCCESS = .TRUE. - - - - - - - END IF -! -! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM -! - FPAR%SUCCESS = .TRUE. + write(*,*)'---------- partition returning from main subr ', RANK RETURN END FUNCTION FLL_MPI_DUPLICATE ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) + RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ! Description: makes recursive duplicate of PNODE ! @@ -221,13 +160,15 @@ RECURSIVE SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! Arguments description ! Name In/Out Function ! PNODE In pointer which is to be duplicated -! PDUPL Out duplicate of PNODE +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! - TYPE(DNODE), POINTER :: PNODE,PDUPL - TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR ! ! Local declarations ! @@ -236,70 +177,105 @@ RECURSIVE SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! PCURR => PNODE PCHILD => PNODE%PCHILD -! -! NODE IS A FILE NODE -! - IF(.NOT.ASSOCIATED(PCHILD))THEN - - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - CALL FLL_COPPY_NODE_ARRAYS(PNODE, PNEW, FPAR) - OK = FLL_MV(PNEW, PDUPL, FPAR) - FPAR%SUCCESS = .TRUE. - ELSE -! ! NODE IS DIR ! LOOP OVER CHILDREN ! - DO WHILE(ASSOCIATED(PCURR)) +! WRITE(*,*)' .................... sub - sendind child ', PCURR%lname + DO WHILE(ASSOCIATED(PCURR)) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - PNEW => FLL_MK(PCURR%LNAME,'DIR',0_LINT,0_LINT,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF + CALL BROADCAST_NODE_SEND(PCURR, COMMUNICATOR, SENDPART, FPAR) ! ! NODE HAS CHILDREN ! DO WHILE(ASSOCIATED(PCHILD)) - CALL FLL_MPI_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) - IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) PCHILD => PCHILD%PNEXT END DO ! ! ADD TO PDUPL LIST ! - OK = FLL_MV(PNEW,PDUPL,FPAR) PCURR => PNEXT +! WRITE(*,*)' .................... sub - next sendind child ', PCURR%lname - END DO - END IF + END DO FPAR%SUCCESS = .TRUE. RETURN - END SUBROUTINE FLL_MPI_DUPLICATE_RECURSIVE_NODE + END SUBROUTINE FLL_SEND_RECURSIVE + + + SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used ! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PNEW In recevied pointer +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator +! FPAR In/Out structure containing function specific data +! +! Arguments declaration ! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR,PNEXT,PCHILD + LOGICAL :: OK + + integer :: incrm + + incrm = 0 + + DO + + incrm = incrm + 1 + write(*,*)' <<<<<<<<<<<<<< receving child # ', incrm + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) + WRITE(*,*)'<<<<<<<<<<<<<< RECEIVED NODE NAME ', PNEW%LNAME + if(incrm == 19)return + + END DO +! + + END SUBROUTINE FLL_RECEIVE_RECURSIVE +! +! + SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! - SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) +! Description: Boradcast - send the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation ! -! Description: duplicated data of the node ! ! External Modules used ! + USE MPI USE FLL_TYPE_M USE FLL_OUT_M @@ -310,284 +286,381 @@ SUBROUTINE FLL_COPPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! Arguments description ! Name In/Out Function ! PNODE In pointer data which is to be duplicated -! PNEW Out duplicate of PNODE data +! COMMUNICATOR In communicator +! SENDPART In sending partition ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! - TYPE(DNODE), POINTER :: PNODE,PNEW - TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART, COMMUNICATOR ! ! Local declarations ! - INTEGER(LINT) :: NDIM, NSIZE, NNDIM, NNSIZE + INTEGER(LINT) :: NDIM, NSIZE, CODE, IARR(3) + INTEGER :: IERR ! -! check node types +! Prepare header of the node ! - IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + CODE = GET_NCODE(PNODE) + NDIM = PNODE%NDIM + NSIZE = PNODE%NSIZE + + IARR(1) = CODE + IARR(2) = NDIM + IARR(3) = NSIZE ! -! COPY JUST NAME AND TYPE -! THE REST IS GOING TO BE AUTOMATIC +! Send node header ! - PNEW%LNAME = PNODE%LNAME - PNEW%LTYPE = PNODE%LTYPE + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) +! IF(IERR /= 0)THEN +! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' +! CALL FLL_OUT('ALL',FPAR) +! FPAR%SUCCESS = .FALSE. +! CODE = -1 +! RETURN +! END IF + + IF(CODE == 0) RETURN + IF(NDIM*NSIZE > 1) THEN ! -! IF DIR NODE, RETURN +! 1D ARRAYS ! - IF(TRIM(PNODE%LTYPE) == 'DIR' .OR. TRIM(PNODE%LTYPE) == 'N') RETURN + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF ! -! 1D ARRAYS +! 2D ARRAYS ! - IF(ASSOCIATED(PNODE%R1))THEN - NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) - - IF(ASSOCIATED(PNEW%R1))THEN - NNDIM = SIZE(PNEW%R1, DIM = 1, KIND = LINT) + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(CODE) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF - IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + END SUBROUTINE BROADCAST_NODE_SEND - PNEW%R1 = PNODE%R1 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R1 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF + FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) +! +! Description: Boradcast - receive the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! ! - IF(ASSOCIATED(PNODE%D1))THEN - NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_OUT_M + USE FLL_MK_M - IF(ASSOCIATED(PNEW%D1))THEN - NNDIM = SIZE(PNEW%D1, DIM = 1, KIND = LINT) + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! COMMUNICATOR In communicator +! SENDPART In sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR, SENDPART +! +! Local declarations +! + INTEGER(LINT) :: IARR(3), NDIM, NSIZE + INTEGER :: IERR + CHARACTER(LEN=TYPE_LENGTH) :: TYPE + CHARACTER(LEN=NAME_LENGTH) :: NAME +! +! Prepare header of the node +! + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART, COMMUNICATOR, IERR) + CALL MPI_BCAST(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + TYPE = GET_NTYPE(INT(IARR(1), KIND=SINT)) - PNEW%D1 = PNODE%D1 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D1 array not allocated',TRIM(PNEW%LNAME) + IF(IARR(1) == 0)THEN +! +! IF DIR, STORE THE NDIM DIMENSION IN NLINK AND +! KEEP NIDM = 0 +! UPON ADDING MODES TO DIR, NDIM IS INCREMENTED AUTOMATICALLY +! + PNODE => FLL_MK(NAME,TYPE,0_LINT,0_LINT ,FPAR) + PNODE%LNAME = NAME + PNODE%NLINK = IARR(2) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + PNODE => NULL() + RETURN + END IF + RETURN + ELSE + + PNODE => FLL_MK(NAME,TYPE,IARR(2),IARR(3) ,FPAR) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF END IF + + NDIM = IARR(2) + NSIZE = IARR(3) + IF(NDIM*NSIZE > 1 )THEN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF ! - IF(ASSOCIATED(PNODE%I1))THEN +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(INT(IARR(1), KIND=SINT)) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + PNODE%S0 = '' + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF - NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) + RETURN + + END FUNCTION BROADCAST_NODE_RECEIVE - IF(ASSOCIATED(PNEW%I1))THEN - NNDIM = SIZE(PNEW%I1, DIM = 1, KIND = LINT) - IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I1 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF + + + FUNCTION GET_NCODE(PNODE) RESULT(CODE) +! +! Description: gives back code for node ! - IF(ASSOCIATED(PNODE%L1))THEN - NDIM = SIZE(PNODE%L1, DIM = 1, KIND = LINT) +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M - IF(ASSOCIATED(PNEW%L1))THEN - NNDIM = SIZE(PNEW%L1, DIM = 1, KIND = LINT) + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! CODE Out return code +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + INTEGER :: CODE +! +! Local declaration +! + IF(.NOT.ASSOCIATED(PNODE))THEN + CODE = -1 + RETURN + END IF - IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + SELECT CASE(TRIM(PNODE%LTYPE)) - PNEW%L1 = PNODE%L1 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L1 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF + CASE('DIR','N') + CODE = 0 + CASE('R') + CODE = 1 + CASE('D') + CODE = 2 + CASE('I') + CODE = 3 + CASE('L') + CODE = 4 + CASE('S') + CODE = 5 + CASE('C') + CODE = 6 + CASE DEFAULT + CODE = -1 + END SELECT - END IF - IF(ASSOCIATED(PNODE%S1))THEN - NDIM = SIZE(PNODE%S1, DIM = 1, KIND = LINT) + END FUNCTION GET_NCODE - IF(ASSOCIATED(PNEW%S1))THEN - NNDIM = SIZE(PNEW%S1, DIM = 1, KIND = LINT) - IF(NDIM /= NNDIM)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - PNEW%S1 = PNODE%S1 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S1 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF + FUNCTION GET_NTYPE(CODE) RESULT(TYPE) ! -! 2D ARRAYS +! Description: gives back code for node ! - IF(ASSOCIATED(PNODE%R2))THEN - NDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) - NSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) - - IF(ASSOCIATED(PNEW%R2))THEN - NNDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) - NNSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) - - IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - - PNEW%R2 = PNODE%R2 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - R2 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF - - IF(ASSOCIATED(PNODE%D2))THEN - NDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) - NSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) - - IF(ASSOCIATED(PNEW%D2))THEN - NNDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) - NNSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) - - IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - - PNEW%D2 = PNODE%D2 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - D2 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF - - IF(ASSOCIATED(PNODE%I2))THEN - NDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) - NSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) - - IF(ASSOCIATED(PNEW%I2))THEN - NNDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) - NNSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) - - IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - - PNEW%I2 = PNODE%I2 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - I2 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF - - IF(ASSOCIATED(PNODE%L2))THEN - NDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) - NSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) - - IF(ASSOCIATED(PNEW%L2))THEN - NNDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) - NNSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) - - IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - - PNEW%L2 = PNODE%L2 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - L2 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M - IF(ASSOCIATED(PNODE%S2))THEN - NDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) - NSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) - - IF(ASSOCIATED(PNEW%L2))THEN - NNDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) - NNSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) - - IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - nodes do not have the same array dimensions', TRIM(PNODE%LNAME), TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - - PNEW%S2 = PNODE%S2 - ELSE - WRITE(FPAR%MESG,'(A,A,A)')' DUPLICATE - S2 array not allocated',TRIM(PNEW%LNAME) - FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) - RETURN - END IF - END IF + IMPLICIT NONE ! -! SCALARS AND STATICALLY DEFINED ARRAYS +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! TYPE Out type of node +! +! Arguments declaration ! - PNEW%R0 = PNODE%R0 - PNEW%D0 = PNODE%D0 - PNEW%I0 = PNODE%I0 - PNEW%L0 = PNODE%L0 - PNEW%S0 = PNODE%S0 + INTEGER :: CODE + CHARACTER(LEN=TYPE_LENGTH):: TYPE +! +! Local declaration +! + + SELECT CASE(CODE) + + CASE(0) + TYPE = 'DIR' + CASE(1) + TYPE = 'R' + CASE(2) + TYPE = 'D' + CASE(3) + TYPE = 'I' + CASE(4) + TYPE = 'L' + CASE(5) + TYPE = 'S' + CASE(6) + TYPE = 'C' + CASE DEFAULT + TYPE = '0' - END SUBROUTINE FLL_COPPY_NODE_ARRAYS + END SELECT + + + END FUNCTION GET_NTYPE + END MODULE FLL_MPI_DUPLICATE_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index d51ea9d..2d6f739 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -5,6 +5,6 @@ fll_mpi_mods.o : \ fll_mpi_duplicate.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o + ../data_util/fll_out.o \ + ../data_util/fll_type.o From 4f48c7d298b02dadbb81581985acf66cc57633bf Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 20:36:41 -0700 Subject: [PATCH 081/325] close file upon return from function --- fort_depend.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index e874fd7..870d12d 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -63,11 +63,15 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' return #Open file + print(" ") + print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") + print(" ") f=open(outfile,'w') f.write('# This file is generated automatically. DO NOT EDIT!\n') for i in dep.keys(): tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") + print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") for j in dep[i]: npathseg = j.count('/') if npathseg == 0: @@ -83,6 +87,8 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' stri=stri+"\n" f.write(stri) f.close() + print("\033[031m Finished ... \033[039m") + print(" ") return def get_source(ext=[".f90",".F90"]): @@ -109,7 +115,9 @@ def check_if_there(use,file): extrline = line.lower() extrline = extrline.replace("module", "") if use.lower().strip() == extrline.strip(): + f.close() return 1 + f.close() return 0 @@ -195,14 +203,22 @@ def get_depends(fob=[],m2f=[], ffiles=[]): # # module is not, loop through all other files # + istat = 0 for k in ffiles: retval=check_if_there(use=j,file=k) if retval > 0: + istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module is in \033[032m"+name+"\033[039m file") - print ("\033[031m..... \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + + if istat== 0 and not(j == ""): + print("") + print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print("") deps[i.file_name]=tmp From 359cbff564eb89029aa82a036e1c404b043acf9a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 8 Nov 2016 20:59:47 -0700 Subject: [PATCH 082/325] finished fll_mpi_duplicate --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 34 ++++++++++++++++++---- mpi_util/fll_mpi_duplicate.f90 | 26 +++++++---------- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index ff18fdf..bb0cc4b 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -64,11 +64,16 @@ PROGRAM EXAMPLE_MPI_IO INTEGER(LINT) :: NFILES,NPROC CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE + LOGICAL :: OK ! ! Initialize MPI ! CALL MPI_INIT(IERR) + + FLL_MPI_STRUCT => NULL() + CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) + write(*,*)' IRANK is ', WORLD_RANK IF(WORLD_RANK == 0) THEN CALL READ_INPUT(NAME_OF_FILE,NFILES,NPROC) @@ -77,14 +82,27 @@ PROGRAM EXAMPLE_MPI_IO ! FLL_MPI_STRUCT => NULL() CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,NPROC) -! WRITE(*,*)' duplicating' -! PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) -! WRITE(*,*)' duplicate' -! CALL FLL_CAT(PNEW,6,.false., FPAR) + WRITE(*,*)' duplicating' + PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) + WRITE(*,*)' duplicate' +! CALL FLL_CAT(PNEW,6,.false., FPAR) + + OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) + + CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) - END IF + END IF PNEW => FLL_MPI_DUPLICATE(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) + + if(WORLD_RANK == 1)THEN + CALL FLL_CAT(PNEW,6,.false., FPAR) + CALL FLL_RM(PNEW,FPAR) +! CALL FLL_RM(FLL_MPI_STRUCT,FPAR) +! + END IF + + ! ! make some data set ! @@ -92,6 +110,12 @@ PROGRAM EXAMPLE_MPI_IO ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) + if(WORLD_RANK == 0)then + CALL FLL_RM(FLL_MPI_STRUCT,FPAR) +! CALL FLL_RM(PNEW,FPAR) + end if + + CALL MPI_FINALIZE(IERR) END PROGRAM diff --git a/mpi_util/fll_mpi_duplicate.f90 b/mpi_util/fll_mpi_duplicate.f90 index 0c8aa2b..9610e49 100644 --- a/mpi_util/fll_mpi_duplicate.f90 +++ b/mpi_util/fll_mpi_duplicate.f90 @@ -99,7 +99,7 @@ FUNCTION FLL_MPI_DUPLICATE(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! ! Node has children ! - CALL FLL_RECEIVE_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) END IF @@ -134,8 +134,6 @@ FUNCTION FLL_MPI_DUPLICATE(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) FPAR%SUCCESS = .TRUE. - - write(*,*)'---------- partition returning from main subr ', RANK RETURN END FUNCTION FLL_MPI_DUPLICATE @@ -180,7 +178,6 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! NODE IS DIR ! LOOP OVER CHILDREN ! -! WRITE(*,*)' .................... sub - sendind child ', PCURR%lname DO WHILE(ASSOCIATED(PCURR)) PNEXT => PCURR%PNEXT @@ -200,7 +197,6 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ADD TO PDUPL LIST ! PCURR => PNEXT -! WRITE(*,*)' .................... sub - next sendind child ', PCURR%lname END DO @@ -238,25 +234,23 @@ SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: SENDPART,COMMUNICATOR + INTEGER(LINT) :: I ! ! Local declarations ! TYPE(DNODE), POINTER :: PCURR,PNEXT,PCHILD LOGICAL :: OK - integer :: incrm - - incrm = 0 - - DO - - incrm = incrm + 1 - write(*,*)' <<<<<<<<<<<<<< receving child # ', incrm + PCURR => PNODE + PCHILD => PNODE%PCHILD + + DO I = 1, PCURR%NLINK PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) - WRITE(*,*)'<<<<<<<<<<<<<< RECEIVED NODE NAME ', PNEW%LNAME - if(incrm == 19)return - + OK = FLL_MV(PNEW,PCURR, FPAR) + + IF(PNEW%NLINK >0) CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) + END DO ! From e31fda12d58627c653a9038f43037046d2b36b4f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 9 Nov 2016 07:57:01 -0700 Subject: [PATCH 083/325] rename function FLL_MPI_DUPLICATE to FLL_MPI_CP_ALL --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 64 +- mpi_util/fll_mpi_duplicate.f90 | 660 --------------------- mpi_util/fll_mpi_mods.f90 | 2 +- mpi_util/project.dep | 8 +- 4 files changed, 44 insertions(+), 690 deletions(-) delete mode 100644 mpi_util/fll_mpi_duplicate.f90 diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index bb0cc4b..1513e7c 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -82,38 +82,52 @@ PROGRAM EXAMPLE_MPI_IO ! FLL_MPI_STRUCT => NULL() CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,NPROC) - WRITE(*,*)' duplicating' - PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) - WRITE(*,*)' duplicate' -! CALL FLL_CAT(PNEW,6,.false., FPAR) - - OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) - - CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) +! WRITE(*,*)' duplicating' +! PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) +! WRITE(*,*)' duplicate' +! OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) +! CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) - END IF - PNEW => FLL_MPI_DUPLICATE(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) - - if(WORLD_RANK == 1)THEN - CALL FLL_CAT(PNEW,6,.false., FPAR) - CALL FLL_RM(PNEW,FPAR) -! CALL FLL_RM(FLL_MPI_STRUCT,FPAR) -! - END IF - + END IF ! -! make some data set +! Copy FLL_MPI_STRUCT date set which now exists on root partition only +! to all other partitions +! upon return, the function will return pointer to newly allocated data +! for all other partition then root partition +! On root partition, the PNEW pointer is pointing on FLL_MPI_STRUCT ! - ! CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) + PNEW => FLL_MPI_CP_ALL(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) + IF(WORLD_RANK /= 0)THEN +! +! make FLL_MPI_STRUCT point to PNEW so that we cane use the same names for all partitions +! + FLL_MPI_STRUCT => PNEW + END IF +! +! just test - if partition #1, print received data set + IF(WORLD_RANK == 1)THEN + CALL FLL_CAT(FLL_MPI_STRUCT,6,.FALSE., FPAR) + END IF +! +! make some data set similar to solution +! + IF(WORLD_RANK==0)WRITE(*,*)' creating data set' + CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) - - if(WORLD_RANK == 0)then - CALL FLL_RM(FLL_MPI_STRUCT,FPAR) -! CALL FLL_RM(PNEW,FPAR) - end if +! +! MPI_Barrier does not need to be here, +! just for testing purposes +! + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) +! +! CLEAN MEMORY +! + IF(WORLD_RANK==0)write(*,*)' Releasing memory' + CALL FLL_RM(FLL_MPI_STRUCT,FPAR) + CALL FLL_RM(PDATA_SET,FPAR) CALL MPI_FINALIZE(IERR) diff --git a/mpi_util/fll_mpi_duplicate.f90 b/mpi_util/fll_mpi_duplicate.f90 deleted file mode 100644 index 9610e49..0000000 --- a/mpi_util/fll_mpi_duplicate.f90 +++ /dev/null @@ -1,660 +0,0 @@ -! -! Copyright (C) 2016 Adam Jirasek -! -! This program is free software: you can redistribute it and/or modify -! it under the terms of the GNU Lesser General Public License as published by -! the Free Software Foundation, either version 3 of the License, or -! (at your option) any later version. -! -! This program is distributed in the hope that it will be useful, -! but WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -! GNU Lesser General Public License for more details. -! -! You should have received a copy of the GNU Lesser General Public License -! along with this program. If not, see . -! -! contact: libm3l@gmail.com -! -! -! -! -MODULE FLL_MPI_DUPLICATE_M -! -! Description: Distributes FLL list from one node to all others in communicator -! -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! -CONTAINS - FUNCTION FLL_MPI_DUPLICATE(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) -! -! Description: Contains duplicates node to PNEW mode -! the parent, previous and next pointers of PNEW node are NULL -! -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_MK_M - USE FLL_MV_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In node to duplicate -! PNEW Out duplicate node -! COMMUNICATOR In MPI communicatior -! SENDPART In Sending partition -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE,PNEW - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: COMMUNICATOR,SENDPART -! -! Local declarations -! - TYPE(DNODE), POINTER :: PCHILD - INTEGER :: RANK, IERR -! -! check the node is not null -! - FPAR%SUCCESS = .FALSE. -! -! If not sending partition, nullify pointer -! owherwise check that sending partition does not send NULL pointer and -! associate returning pointer with sending -! - CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) - - DIFFPART: IF(SENDPART /= RANK)THEN - PNEW => NULL() - - PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) -! -! If dir has childrenm loop over them -! the number of children in this routine is stored in -! NLINK, not ndim, ndim is set to 0 and then incremented automatically -! when adding children -! - IF(PNEW%NLINK > 0)THEN -! -! Node has children -! - CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) - - END IF - - RETURN - - ELSE -! -! Sending partition -! - IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - RETURN - END IF - - PNEW => PNODE - - CALL BROADCAST_NODE_SEND(PNODE, COMMUNICATOR, SENDPART, FPAR) - - PCHILD => PNODE%PCHILD -! -! If node has children, duplicate them too -! - IF(ASSOCIATED(PCHILD))THEN - - CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) - - END IF - - END IF DIFFPART - - FPAR%SUCCESS = .TRUE. - - RETURN - - END FUNCTION FLL_MPI_DUPLICATE -! -! DELETE CHID WITH ALL ITS CHILDREN -! - RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) -! -! Description: makes recursive duplicate of PNODE -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_MK_M - USE FLL_MV_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer which is to be duplicated -! SENDPART In sending partition rank -! COMMUNICATOR In Commuticator -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE,PDUPL - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART,COMMUNICATOR -! -! Local declarations -! - TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD - LOGICAL :: OK -! - PCURR => PNODE - PCHILD => PNODE%PCHILD -! NODE IS DIR -! LOOP OVER CHILDREN -! - DO WHILE(ASSOCIATED(PCURR)) - - PNEXT => PCURR%PNEXT - PCHILD=> PCURR%PCHILD - - CALL BROADCAST_NODE_SEND(PCURR, COMMUNICATOR, SENDPART, FPAR) -! -! NODE HAS CHILDREN -! - DO WHILE(ASSOCIATED(PCHILD)) - - CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) - PCHILD => PCHILD%PNEXT - - END DO -! -! ADD TO PDUPL LIST -! - PCURR => PNEXT - - END DO - - FPAR%SUCCESS = .TRUE. - RETURN - - END SUBROUTINE FLL_SEND_RECURSIVE - - - SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) -! -! Description: makes recursive duplicate of PNODE -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_MK_M - USE FLL_MV_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer which is to be duplicated -! PNEW In recevied pointer -! SENDPART In sending partition rank -! COMMUNICATOR In Commuticator -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE,PNEW - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART,COMMUNICATOR - INTEGER(LINT) :: I -! -! Local declarations -! - TYPE(DNODE), POINTER :: PCURR,PNEXT,PCHILD - LOGICAL :: OK - - PCURR => PNODE - PCHILD => PNODE%PCHILD - - DO I = 1, PCURR%NLINK - - PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) - OK = FLL_MV(PNEW,PCURR, FPAR) - - IF(PNEW%NLINK >0) CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) - - END DO -! - - END SUBROUTINE FLL_RECEIVE_RECURSIVE -! -! - SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) -! -! Description: Boradcast - send the node -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! - USE MPI - USE FLL_TYPE_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer data which is to be duplicated -! COMMUNICATOR In communicator -! SENDPART In sending partition -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE,PNEW - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART, COMMUNICATOR -! -! Local declarations -! - INTEGER(LINT) :: NDIM, NSIZE, CODE, IARR(3) - INTEGER :: IERR -! -! Prepare header of the node -! - CODE = GET_NCODE(PNODE) - NDIM = PNODE%NDIM - NSIZE = PNODE%NSIZE - - IARR(1) = CODE - IARR(2) = NDIM - IARR(3) = NSIZE -! -! Send node header -! - CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) - CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) -! IF(IERR /= 0)THEN -! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' -! CALL FLL_OUT('ALL',FPAR) -! FPAR%SUCCESS = .FALSE. -! CODE = -1 -! RETURN -! END IF - - IF(CODE == 0) RETURN - IF(NDIM*NSIZE > 1) THEN -! -! 1D ARRAYS -! - IF(ASSOCIATED(PNODE%R1))THEN - CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%D1))THEN - CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%I1))THEN - CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%L1))THEN - CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%S1))THEN - CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF -! -! 2D ARRAYS -! - IF(ASSOCIATED(PNODE%R2))THEN - CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%D2))THEN - CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%I2))THEN - CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%L2))THEN - CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%S2))THEN - CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF -! -! SCALARS AND STATICALLY DEFINED ARRAYS -! - ELSE - SELECT CASE(CODE) - CASE(1) - CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) - CASE(2) - CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) - CASE(3) - CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) - CASE(4) - CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) - CASE(5) - CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - END SELECT - END IF - - END SUBROUTINE BROADCAST_NODE_SEND - - - FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) -! -! Description: Boradcast - receive the node -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! - USE MPI - USE FLL_TYPE_M - USE FLL_OUT_M - USE FLL_MK_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer data which is to be duplicated -! COMMUNICATOR In communicator -! SENDPART In sending partition -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE - TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: COMMUNICATOR, SENDPART -! -! Local declarations -! - INTEGER(LINT) :: IARR(3), NDIM, NSIZE - INTEGER :: IERR - CHARACTER(LEN=TYPE_LENGTH) :: TYPE - CHARACTER(LEN=NAME_LENGTH) :: NAME -! -! Prepare header of the node -! - CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART, COMMUNICATOR, IERR) - CALL MPI_BCAST(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - - TYPE = GET_NTYPE(INT(IARR(1), KIND=SINT)) - - IF(IARR(1) == 0)THEN -! -! IF DIR, STORE THE NDIM DIMENSION IN NLINK AND -! KEEP NIDM = 0 -! UPON ADDING MODES TO DIR, NDIM IS INCREMENTED AUTOMATICALLY -! - PNODE => FLL_MK(NAME,TYPE,0_LINT,0_LINT ,FPAR) - PNODE%LNAME = NAME - PNODE%NLINK = IARR(2) - IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' - FPAR%SUCCESS = .FALSE. - PNODE => NULL() - RETURN - END IF - RETURN - - ELSE - - PNODE => FLL_MK(NAME,TYPE,IARR(2),IARR(3) ,FPAR) - IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' - FPAR%SUCCESS = .FALSE. - PNODE => NULL() - RETURN - END IF - END IF - - NDIM = IARR(2) - NSIZE = IARR(3) - IF(NDIM*NSIZE > 1 )THEN -! -! 1D ARRAYS -! - IF(ASSOCIATED(PNODE%R1))THEN - CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%D1))THEN - CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%I1))THEN - CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%L1))THEN - CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%S1))THEN - CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF -! -! 2D ARRAYS -! - IF(ASSOCIATED(PNODE%R2))THEN - CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%D2))THEN - CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%I2))THEN - CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%L2))THEN - CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) - RETURN - END IF - IF(ASSOCIATED(PNODE%S2))THEN - CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - RETURN - END IF -! -! SCALARS AND STATICALLY DEFINED ARRAYS -! - ELSE - SELECT CASE(INT(IARR(1), KIND=SINT)) - CASE(1) - CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) - CASE(2) - CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) - CASE(3) - CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) - CASE(4) - CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) - CASE(5) - PNODE%S0 = '' - CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) - END SELECT - END IF - - RETURN - - END FUNCTION BROADCAST_NODE_RECEIVE - - - - - - FUNCTION GET_NCODE(PNODE) RESULT(CODE) -! -! Description: gives back code for node -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer data which is to be duplicated -! CODE Out return code -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE - INTEGER :: CODE -! -! Local declaration -! - IF(.NOT.ASSOCIATED(PNODE))THEN - CODE = -1 - RETURN - END IF - - SELECT CASE(TRIM(PNODE%LTYPE)) - - CASE('DIR','N') - CODE = 0 - CASE('R') - CODE = 1 - CASE('D') - CODE = 2 - CASE('I') - CODE = 3 - CASE('L') - CODE = 4 - CASE('S') - CODE = 5 - CASE('C') - CODE = 6 - CASE DEFAULT - CODE = -1 - END SELECT - - - END FUNCTION GET_NCODE - - - - FUNCTION GET_NTYPE(CODE) RESULT(TYPE) -! -! Description: gives back code for node -! -! History: -! Version Date Patch number CLA Comment -! ------- -------- -------- --- ------- -! 1.1 10/10/16 Initial implementation -! -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer data which is to be duplicated -! TYPE Out type of node -! -! Arguments declaration -! - INTEGER :: CODE - CHARACTER(LEN=TYPE_LENGTH):: TYPE -! -! Local declaration -! - - SELECT CASE(CODE) - - CASE(0) - TYPE = 'DIR' - CASE(1) - TYPE = 'R' - CASE(2) - TYPE = 'D' - CASE(3) - TYPE = 'I' - CASE(4) - TYPE = 'L' - CASE(5) - TYPE = 'S' - CASE(6) - TYPE = 'C' - CASE DEFAULT - TYPE = '0' - - END SELECT - - - END FUNCTION GET_NTYPE - - - -END MODULE FLL_MPI_DUPLICATE_M diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index 0dd0847..b403e81 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -34,6 +34,6 @@ MODULE FLL_MPI_MODS_M ! ! External Modules used ! - USE FLL_MPI_DUPLICATE_M + USE FLL_MPI_CP_ALL_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 2d6f739..5ccdaff 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,10 +1,10 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_mods.o : \ - fll_mpi_duplicate.o - -fll_mpi_duplicate.o : \ +fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ ../data_util/fll_out.o \ ../data_util/fll_type.o + +fll_mpi_mods.o : \ + fll_mpi_cp_all.o From 2d550443bb0e614a621cdb5ee393fd18b15d713f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 9 Nov 2016 07:57:11 -0700 Subject: [PATCH 084/325] add forgotten function --- mpi_util/fll_mpi_cp_all.f90 | 660 ++++++++++++++++++++++++++++++++++++ 1 file changed, 660 insertions(+) create mode 100644 mpi_util/fll_mpi_cp_all.f90 diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 new file mode 100644 index 0000000..53aa0ae --- /dev/null +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -0,0 +1,660 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +! +MODULE FLL_MPI_CP_ALL_M +! +! Description: Distributes FLL list from one node to all others in communicator +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) +! +! Description: Contains duplicates node to PNEW mode +! the parent, previous and next pointers of PNEW node are NULL +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! PNEW Out duplicate node +! COMMUNICATOR In MPI communicatior +! SENDPART In Sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR,SENDPART +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCHILD + INTEGER :: RANK, IERR +! +! check the node is not null +! + FPAR%SUCCESS = .FALSE. +! +! If not sending partition, nullify pointer +! owherwise check that sending partition does not send NULL pointer and +! associate returning pointer with sending +! + CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) + + DIFFPART: IF(SENDPART /= RANK)THEN + PNEW => NULL() + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) +! +! If dir has childrenm loop over them +! the number of children in this routine is stored in +! NLINK, not ndim, ndim is set to 0 and then incremented automatically +! when adding children +! + IF(PNEW%NLINK > 0)THEN +! +! Node has children +! + CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) + + END IF + + RETURN + + ELSE +! +! Sending partition +! + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW => PNODE + + CALL BROADCAST_NODE_SEND(PNODE, COMMUNICATOR, SENDPART, FPAR) + + PCHILD => PNODE%PCHILD +! +! If node has children, duplicate them too +! + IF(ASSOCIATED(PCHILD))THEN + + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + + END IF + + END IF DIFFPART + + FPAR%SUCCESS = .TRUE. + + RETURN + + END FUNCTION FLL_MPI_CP_ALL +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD + LOGICAL :: OK +! + PCURR => PNODE + PCHILD => PNODE%PCHILD +! NODE IS DIR +! LOOP OVER CHILDREN +! + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD + + CALL BROADCAST_NODE_SEND(PCURR, COMMUNICATOR, SENDPART, FPAR) +! +! NODE HAS CHILDREN +! + DO WHILE(ASSOCIATED(PCHILD)) + + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + PCHILD => PCHILD%PNEXT + + END DO +! +! ADD TO PDUPL LIST +! + PCURR => PNEXT + + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE FLL_SEND_RECURSIVE + + + SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PNEW In recevied pointer +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR + INTEGER(LINT) :: I +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR,PNEXT,PCHILD + LOGICAL :: OK + + PCURR => PNODE + PCHILD => PNODE%PCHILD + + DO I = 1, PCURR%NLINK + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) + OK = FLL_MV(PNEW,PCURR, FPAR) + + IF(PNEW%NLINK >0) CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) + + END DO +! + + END SUBROUTINE FLL_RECEIVE_RECURSIVE +! +! + SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: Boradcast - send the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! COMMUNICATOR In communicator +! SENDPART In sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART, COMMUNICATOR +! +! Local declarations +! + INTEGER(LINT) :: NDIM, NSIZE, CODE, IARR(3) + INTEGER :: IERR +! +! Prepare header of the node +! + CODE = GET_NCODE(PNODE) + NDIM = PNODE%NDIM + NSIZE = PNODE%NSIZE + + IARR(1) = CODE + IARR(2) = NDIM + IARR(3) = NSIZE +! +! Send node header +! + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) +! IF(IERR /= 0)THEN +! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' +! CALL FLL_OUT('ALL',FPAR) +! FPAR%SUCCESS = .FALSE. +! CODE = -1 +! RETURN +! END IF + + IF(CODE == 0) RETURN + IF(NDIM*NSIZE > 1) THEN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(CODE) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF + + END SUBROUTINE BROADCAST_NODE_SEND + + + FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) +! +! Description: Boradcast - receive the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_OUT_M + USE FLL_MK_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! COMMUNICATOR In communicator +! SENDPART In sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR, SENDPART +! +! Local declarations +! + INTEGER(LINT) :: IARR(3), NDIM, NSIZE + INTEGER :: IERR + CHARACTER(LEN=TYPE_LENGTH) :: TYPE + CHARACTER(LEN=NAME_LENGTH) :: NAME +! +! Prepare header of the node +! + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART, COMMUNICATOR, IERR) + CALL MPI_BCAST(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + + TYPE = GET_NTYPE(INT(IARR(1), KIND=SINT)) + + IF(IARR(1) == 0)THEN +! +! IF DIR, STORE THE NDIM DIMENSION IN NLINK AND +! KEEP NIDM = 0 +! UPON ADDING MODES TO DIR, NDIM IS INCREMENTED AUTOMATICALLY +! + PNODE => FLL_MK(NAME,TYPE,0_LINT,0_LINT ,FPAR) + PNODE%LNAME = NAME + PNODE%NLINK = IARR(2) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + RETURN + + ELSE + + PNODE => FLL_MK(NAME,TYPE,IARR(2),IARR(3) ,FPAR) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + END IF + + NDIM = IARR(2) + NSIZE = IARR(3) + IF(NDIM*NSIZE > 1 )THEN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(INT(IARR(1), KIND=SINT)) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + PNODE%S0 = '' + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF + + RETURN + + END FUNCTION BROADCAST_NODE_RECEIVE + + + + + + FUNCTION GET_NCODE(PNODE) RESULT(CODE) +! +! Description: gives back code for node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! CODE Out return code +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + INTEGER :: CODE +! +! Local declaration +! + IF(.NOT.ASSOCIATED(PNODE))THEN + CODE = -1 + RETURN + END IF + + SELECT CASE(TRIM(PNODE%LTYPE)) + + CASE('DIR','N') + CODE = 0 + CASE('R') + CODE = 1 + CASE('D') + CODE = 2 + CASE('I') + CODE = 3 + CASE('L') + CODE = 4 + CASE('S') + CODE = 5 + CASE('C') + CODE = 6 + CASE DEFAULT + CODE = -1 + END SELECT + + + END FUNCTION GET_NCODE + + + + FUNCTION GET_NTYPE(CODE) RESULT(TYPE) +! +! Description: gives back code for node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! TYPE Out type of node +! +! Arguments declaration +! + INTEGER :: CODE + CHARACTER(LEN=TYPE_LENGTH):: TYPE +! +! Local declaration +! + + SELECT CASE(CODE) + + CASE(0) + TYPE = 'DIR' + CASE(1) + TYPE = 'R' + CASE(2) + TYPE = 'D' + CASE(3) + TYPE = 'I' + CASE(4) + TYPE = 'L' + CASE(5) + TYPE = 'S' + CASE(6) + TYPE = 'C' + CASE DEFAULT + TYPE = '0' + + END SELECT + + + END FUNCTION GET_NTYPE + + + +END MODULE FLL_MPI_CP_ALL_M From dfeb0bdf65a31a046afd6e94aede7d27abc21e20 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 9 Nov 2016 09:04:29 -0700 Subject: [PATCH 085/325] add prototype of fll_mpi_cp function --- mpi_util/fll_mpi_cp.f90 | 661 ++++++++++++++++++++++++++++++++++++ mpi_util/fll_mpi_cp_all.f90 | 7 +- mpi_util/project.dep | 6 + 3 files changed, 671 insertions(+), 3 deletions(-) create mode 100644 mpi_util/fll_mpi_cp.f90 diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 new file mode 100644 index 0000000..bb62a32 --- /dev/null +++ b/mpi_util/fll_mpi_cp.f90 @@ -0,0 +1,661 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +! +MODULE FLL_MPI_CP_M +! +! Description: Sends FLL list from one node to another +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) +! +! Description: Sends FLL subset to a specified process in comunicator +! if process ID == sending proceess ID, do not create +! data set, just return the pointer on existing data set +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! PNEW Out duplicate node +! COMMUNICATOR In MPI communicatior +! SENDPART In Sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR,SENDPART +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCHILD + INTEGER :: RANK, IERR +! +! check the node is not null +! + FPAR%SUCCESS = .FALSE. +! +! If not sending partition, nullify pointer +! owherwise check that sending partition does not send NULL pointer and +! associate returning pointer with sending +! + CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) + + DIFFPART: IF(SENDPART /= RANK)THEN + PNEW => NULL() + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) +! +! If dir has childrenm loop over them +! the number of children in this routine is stored in +! NLINK, not ndim, ndim is set to 0 and then incremented automatically +! when adding children +! + IF(PNEW%NLINK > 0)THEN +! +! Node has children +! + CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) + + END IF + + RETURN + + ELSE +! +! Sending partition +! + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PNEW => PNODE + + CALL BROADCAST_NODE_SEND(PNODE, COMMUNICATOR, SENDPART, FPAR) + + PCHILD => PNODE%PCHILD +! +! If node has children, duplicate them too +! + IF(ASSOCIATED(PCHILD))THEN + + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + + END IF + + END IF DIFFPART + + FPAR%SUCCESS = .TRUE. + + RETURN + + END FUNCTION FLL_MPI_CP +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD + LOGICAL :: OK +! + PCURR => PNODE + PCHILD => PNODE%PCHILD +! NODE IS DIR +! LOOP OVER CHILDREN +! + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD + + CALL BROADCAST_NODE_SEND(PCURR, COMMUNICATOR, SENDPART, FPAR) +! +! NODE HAS CHILDREN +! + DO WHILE(ASSOCIATED(PCHILD)) + + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + PCHILD => PCHILD%PNEXT + + END DO +! +! ADD TO PDUPL LIST +! + PCURR => PNEXT + + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END SUBROUTINE FLL_SEND_RECURSIVE + + + SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PNEW In recevied pointer +! SENDPART In sending partition rank +! COMMUNICATOR In Commuticator +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART,COMMUNICATOR + INTEGER(LINT) :: I +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR,PNEXT,PCHILD + LOGICAL :: OK + + PCURR => PNODE + PCHILD => PNODE%PCHILD + + DO I = 1, PCURR%NLINK + + PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) + OK = FLL_MV(PNEW,PCURR, FPAR) + + IF(PNEW%NLINK >0) CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) + + END DO +! + + END SUBROUTINE FLL_RECEIVE_RECURSIVE +! +! + SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) +! +! Description: Boradcast - send the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! COMMUNICATOR In communicator +! SENDPART In sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: SENDPART, COMMUNICATOR +! +! Local declarations +! + INTEGER(LINT) :: NDIM, NSIZE, CODE, IARR(3) + INTEGER :: IERR +! +! Prepare header of the node +! + CODE = GET_NCODE(PNODE) + NDIM = PNODE%NDIM + NSIZE = PNODE%NSIZE + + IARR(1) = CODE + IARR(2) = NDIM + IARR(3) = NSIZE +! +! Send node header +! + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) +! IF(IERR /= 0)THEN +! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' +! CALL FLL_OUT('ALL',FPAR) +! FPAR%SUCCESS = .FALSE. +! CODE = -1 +! RETURN +! END IF + + IF(CODE == 0) RETURN + IF(NDIM*NSIZE > 1) THEN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(CODE) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF + + END SUBROUTINE BROADCAST_NODE_SEND + + + FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) +! +! Description: Boradcast - receive the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_TYPE_M + USE FLL_OUT_M + USE FLL_MK_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! COMMUNICATOR In communicator +! SENDPART In sending partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR, SENDPART +! +! Local declarations +! + INTEGER(LINT) :: IARR(3), NDIM, NSIZE + INTEGER :: IERR + CHARACTER(LEN=TYPE_LENGTH) :: TYPE + CHARACTER(LEN=NAME_LENGTH) :: NAME +! +! Prepare header of the node +! + CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART, COMMUNICATOR, IERR) + CALL MPI_BCAST(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + + TYPE = GET_NTYPE(INT(IARR(1), KIND=SINT)) + + IF(IARR(1) == 0)THEN +! +! IF DIR, STORE THE NDIM DIMENSION IN NLINK AND +! KEEP NIDM = 0 +! UPON ADDING MODES TO DIR, NDIM IS INCREMENTED AUTOMATICALLY +! + PNODE => FLL_MK(NAME,TYPE,0_LINT,0_LINT ,FPAR) + PNODE%LNAME = NAME + PNODE%NLINK = IARR(2) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + RETURN + + ELSE + + PNODE => FLL_MK(NAME,TYPE,IARR(2),IARR(3) ,FPAR) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF + END IF + + NDIM = IARR(2) + NSIZE = IARR(3) + IF(NDIM*NSIZE > 1 )THEN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D1))THEN + CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%D2))THEN + CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%I2))THEN + CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%L2))THEN + CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + RETURN + END IF + IF(ASSOCIATED(PNODE%S2))THEN + CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + ELSE + SELECT CASE(INT(IARR(1), KIND=SINT)) + CASE(1) + CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CASE(2) + CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CASE(3) + CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CASE(4) + CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CASE(5) + PNODE%S0 = '' + CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + END SELECT + END IF + + RETURN + + END FUNCTION BROADCAST_NODE_RECEIVE + + + + + + FUNCTION GET_NCODE(PNODE) RESULT(CODE) +! +! Description: gives back code for node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! CODE Out return code +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + INTEGER :: CODE +! +! Local declaration +! + IF(.NOT.ASSOCIATED(PNODE))THEN + CODE = -1 + RETURN + END IF + + SELECT CASE(TRIM(PNODE%LTYPE)) + + CASE('DIR','N') + CODE = 0 + CASE('R') + CODE = 1 + CASE('D') + CODE = 2 + CASE('I') + CODE = 3 + CASE('L') + CODE = 4 + CASE('S') + CODE = 5 + CASE('C') + CODE = 6 + CASE DEFAULT + CODE = -1 + END SELECT + + + END FUNCTION GET_NCODE + + + + FUNCTION GET_NTYPE(CODE) RESULT(TYPE) +! +! Description: gives back code for node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! TYPE Out type of node +! +! Arguments declaration +! + INTEGER :: CODE + CHARACTER(LEN=TYPE_LENGTH):: TYPE +! +! Local declaration +! + + SELECT CASE(CODE) + + CASE(0) + TYPE = 'DIR' + CASE(1) + TYPE = 'R' + CASE(2) + TYPE = 'D' + CASE(3) + TYPE = 'I' + CASE(4) + TYPE = 'L' + CASE(5) + TYPE = 'S' + CASE(6) + TYPE = 'C' + CASE DEFAULT + TYPE = '0' + + END SELECT + + + END FUNCTION GET_NTYPE + + + +END MODULE FLL_MPI_CP_M diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index 53aa0ae..d64f228 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -35,8 +35,9 @@ MODULE FLL_MPI_CP_ALL_M CONTAINS FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! -! Description: Contains duplicates node to PNEW mode -! the parent, previous and next pointers of PNEW node are NULL +! Description: Broadcasts FLL subset to all processes in comunicator +! if process ID == sending proceess ID, do not create +! data set, just return the pointer on existing data set ! ! ! History: @@ -90,7 +91,7 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) ! -! If dir has childrenm loop over them +! If dir has children loop over them ! the number of children in this routine is stored in ! NLINK, not ndim, ndim is set to 0 and then incremented automatically ! when adding children diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 5ccdaff..da4602a 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -8,3 +8,9 @@ fll_mpi_cp_all.o : \ fll_mpi_mods.o : \ fll_mpi_cp_all.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o \ + ../data_util/fll_type.o From 4a2125a2475f320cf4efeda367b3409641f6d303 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Nov 2016 12:46:56 -0700 Subject: [PATCH 086/325] nodes having no data will not send/receive the data --- mpi_util/fll_mpi_cp_all.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index d64f228..0d91c54 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -369,7 +369,7 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ! SCALARS AND STATICALLY DEFINED ARRAYS ! - ELSE + ELSE IF(NDIM*NSIZE == 1) THEN SELECT CASE(CODE) CASE(1) CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) @@ -515,7 +515,7 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) ! ! SCALARS AND STATICALLY DEFINED ARRAYS ! - ELSE + ELSE IF(NDIM*NSIZE == 1) THEN SELECT CASE(INT(IARR(1), KIND=SINT)) CASE(1) CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) From 6f20747212e19aa5d311491780d60f262023e3e3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Nov 2016 12:47:12 -0700 Subject: [PATCH 087/325] finish fll_mpi_cp --- mpi_util/fll_mpi_cp.f90 | 121 ++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index bb62a32..bdbbb0e 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -63,13 +63,14 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! PNEW Out duplicate node ! COMMUNICATOR In MPI communicatior ! SENDPART In Sending partition +! RECPART In Receiving partition ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: COMMUNICATOR,SENDPART + INTEGER :: COMMUNICATOR,SENDPART,RECPART ! ! Local declarations ! @@ -89,7 +90,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) DIFFPART: IF(SENDPART /= RANK)THEN PNEW => NULL() - PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) + PNEW => NODE_RECEIVE(COMMUNICATOR, SENDPART, FPAR) ! ! If dir has childrenm loop over them ! the number of children in this routine is stored in @@ -119,7 +120,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) PNEW => PNODE - CALL BROADCAST_NODE_SEND(PNODE, COMMUNICATOR, SENDPART, FPAR) + CALL NODE_SEND(PNODE, COMMUNICATOR, SENDPART, RECPART, FPAR) PCHILD => PNODE%PCHILD ! @@ -127,7 +128,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! IF(ASSOCIATED(PCHILD))THEN - CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,RECPART,FPAR) END IF @@ -141,7 +142,7 @@ END FUNCTION FLL_MPI_CP ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) + RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ! ! Description: makes recursive duplicate of PNODE ! @@ -160,6 +161,7 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! Name In/Out Function ! PNODE In pointer which is to be duplicated ! SENDPART In sending partition rank +! RECPART In receiving partition rank ! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! @@ -167,7 +169,7 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! TYPE(DNODE), POINTER :: PNODE,PDUPL TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART,COMMUNICATOR + INTEGER :: SENDPART,RECPART,COMMUNICATOR ! ! Local declarations ! @@ -184,13 +186,13 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - CALL BROADCAST_NODE_SEND(PCURR, COMMUNICATOR, SENDPART, FPAR) + CALL NODE_SEND(PCURR, COMMUNICATOR, SENDPART, RECPART, FPAR) ! ! NODE HAS CHILDREN ! DO WHILE(ASSOCIATED(PCHILD)) - CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,FPAR) + CALL FLL_SEND_RECURSIVE(PCHILD,COMMUNICATOR,SENDPART,RECPART,FPAR) PCHILD => PCHILD%PNEXT END DO @@ -247,7 +249,7 @@ SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) DO I = 1, PCURR%NLINK - PNEW => BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) + PNEW => NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) OK = FLL_MV(PNEW,PCURR, FPAR) IF(PNEW%NLINK >0) CALL FLL_RECEIVE_RECURSIVE(PNEW,COMMUNICATOR,SENDPART,FPAR) @@ -258,7 +260,7 @@ SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) END SUBROUTINE FLL_RECEIVE_RECURSIVE ! ! - SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) + SUBROUTINE NODE_SEND(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ! ! Description: Boradcast - send the node ! @@ -283,13 +285,14 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! PNODE In pointer data which is to be duplicated ! COMMUNICATOR In communicator ! SENDPART In sending partition +! RECPART In receiving partition ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: SENDPART, COMMUNICATOR + INTEGER :: SENDPART, RECPART, COMMUNICATOR ! ! Local declarations ! @@ -308,15 +311,8 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ! Send node header ! - CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) - CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) -! IF(IERR /= 0)THEN -! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' -! CALL FLL_OUT('ALL',FPAR) -! FPAR%SUCCESS = .FALSE. -! CODE = -1 -! RETURN -! END IF + CALL MPI_SEND(IARR, 3, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SEND(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) IF(CODE == 0) RETURN IF(NDIM*NSIZE > 1) THEN @@ -324,70 +320,70 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! 1D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%R1, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D1))THEN - CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I1))THEN - CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L1))THEN - CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S1))THEN - CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF ! ! 2D ARRAYS ! IF(ASSOCIATED(PNODE%R2))THEN - CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%R2, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D2))THEN - CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I2))THEN - CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L2))THEN - CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S2))THEN - CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF ! ! SCALARS AND STATICALLY DEFINED ARRAYS ! - ELSE + ELSE IF(NDIM*NSIZE == 1 )THEN SELECT CASE(CODE) CASE(1) - CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%R0, 1, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(2) - CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%D0, 1, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(3) - CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%I0, 1, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(4) - CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%L0, 1, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(5) - CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_SEND(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) END SELECT END IF - END SUBROUTINE BROADCAST_NODE_SEND + END SUBROUTINE NODE_SEND - FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) + FUNCTION NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) ! ! Description: Boradcast - receive the node ! @@ -427,11 +423,18 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) INTEGER :: IERR CHARACTER(LEN=TYPE_LENGTH) :: TYPE CHARACTER(LEN=NAME_LENGTH) :: NAME + INTEGER STATUS(MPI_STATUS_SIZE) + + INTEGER :: TAG ! ! Prepare header of the node ! - CALL MPI_BCAST(IARR, 3, MPI_INTEGER8, SENDPART, COMMUNICATOR, IERR) - CALL MPI_BCAST(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(IARR, 3, MPI_INTEGER8, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) + CALL MPI_RECV(NAME, NAME_LENGTH, MPI_CHARACTER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) + TAG = STATUS(MPI_TAG) + IF(SENDPART /= TAG)THEN + STOP' COMMUNICATION ERROR' + END IF TYPE = GET_NTYPE(INT(IARR(1), KIND=SINT)) @@ -445,7 +448,7 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) PNODE%LNAME = NAME PNODE%NLINK = IARR(2) IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + WRITE(FPAR%MESG,'(A)')' NODE_RECEIVE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -456,7 +459,7 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) PNODE => FLL_MK(NAME,TYPE,IARR(2),IARR(3) ,FPAR) IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' BROADCAST_NODE_RECEIVE - error allocating PNEW ' + WRITE(FPAR%MESG,'(A)')' NODE_RECEIVE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -470,70 +473,70 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) ! 1D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - CALL MPI_BCAST(PNODE%R1, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%R1, NDIM*NSIZE, MPI_REAL, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D1))THEN - CALL MPI_BCAST(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I1))THEN - CALL MPI_BCAST(PNODE%I1, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L1))THEN - CALL MPI_BCAST(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S1))THEN - CALL MPI_BCAST(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF ! ! 2D ARRAYS ! IF(ASSOCIATED(PNODE%R2))THEN - CALL MPI_BCAST(PNODE%R2, NDIM*NSIZE, MPI_REAL,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%R2, NDIM*NSIZE, MPI_REAL, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D2))THEN - CALL MPI_BCAST(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I2))THEN - CALL MPI_BCAST(PNODE%I2, NDIM*NSIZE, MPI_INTEGER,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L2))THEN - CALL MPI_BCAST(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8,SENDPART, COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S2))THEN - CALL MPI_BCAST(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) RETURN END IF ! ! SCALARS AND STATICALLY DEFINED ARRAYS ! - ELSE + ELSE IF(NDIM*NSIZE == 1 )THEN SELECT CASE(INT(IARR(1), KIND=SINT)) CASE(1) - CALL MPI_BCAST(PNODE%R0, 1, MPI_REAL, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%R0, 1, MPI_REAL, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) CASE(2) - CALL MPI_BCAST(PNODE%D0, 1, MPI_DOUBLE, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%D0, 1, MPI_DOUBLE, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) CASE(3) - CALL MPI_BCAST(PNODE%I0, 1, MPI_INTEGER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%I0, 1, MPI_INTEGER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) CASE(4) - CALL MPI_BCAST(PNODE%L0, 1, MPI_INTEGER8, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%L0, 1, MPI_INTEGER8, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) CASE(5) PNODE%S0 = '' - CALL MPI_BCAST(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) + CALL MPI_RECV(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, SENDPART, MPI_ANY_TAG, COMMUNICATOR, STATUS, IERR ) END SELECT END IF RETURN - END FUNCTION BROADCAST_NODE_RECEIVE + END FUNCTION NODE_RECEIVE From f40f9cfea16b8cab736d74826e57e4d23084b40b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Nov 2016 12:54:11 -0700 Subject: [PATCH 088/325] add fll_mpi_mv function --- data_util/project.dep | 8 ++-- mpi_util/fll_mpi_mv.f90 | 103 ++++++++++++++++++++++++++++++++++++++++ mpi_util/project.dep | 6 +++ 3 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 mpi_util/fll_mpi_mv.f90 diff --git a/data_util/project.dep b/data_util/project.dep index fdc4076..d2272c1 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -68,15 +68,15 @@ fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_locate.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mk.o \ fll_out.o \ fll_type.o diff --git a/mpi_util/fll_mpi_mv.f90 b/mpi_util/fll_mpi_mv.f90 new file mode 100644 index 0000000..1b2f067 --- /dev/null +++ b/mpi_util/fll_mpi_mv.f90 @@ -0,0 +1,103 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +! +MODULE FLL_MPI_MV_M +! +! Description: Moves FLL list from one node to another +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) +! +! Description: Sends FLL subset to a specified process in comunicator +! if process ID == sending proceess ID, do not create +! data set, just return the pointer on existing data set +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MPI_CP_M + USE FLL_RM_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! PNEW Out duplicate node +! COMMUNICATOR In MPI communicatior +! SENDPART In Sending partition +! RECPART In Receiving partition +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: COMMUNICATOR,SENDPART,RECPART +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCHILD + INTEGER :: RANK, IERR +! +! check the node is not null +! + FPAR%SUCCESS = .FALSE. +! +! If not sending partition, nullify pointer +! owherwise check that sending partition does not send NULL pointer and +! associate returning pointer with sending +! + CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) + PNEW => NULL() + PNEW => FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) + + DIFFPART: IF(SENDPART == RANK)THEN + CALL FLL_RM(PNODE,FPAR) + PNEW => NULL() + END IF DIFFPART + + FPAR%SUCCESS = .TRUE. + + RETURN + + END FUNCTION FLL_MPI_MV + +END MODULE FLL_MPI_MV_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index da4602a..bbbf0ad 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,5 +1,11 @@ # This file is generated automatically. DO NOT EDIT! +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_out.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_type.o + fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ From e1e3f3701d6e37774705aae30cb5b0fe3a50e19c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 11 Nov 2016 08:27:31 -0700 Subject: [PATCH 089/325] update ppt files --- "fll\342\200\223FortranLinkedListLibrary.pdf" | Bin 431111 -> 442549 bytes ...\342\200\223FortranLinkedListLibrary.pptx" | Bin 77083 -> 83674 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git "a/fll\342\200\223FortranLinkedListLibrary.pdf" "b/fll\342\200\223FortranLinkedListLibrary.pdf" index f1f462841dd82d73465f177d7354424822b0fb11..af434194504381754b7b513815cd4c223e24e73b 100644 GIT binary patch delta 363611 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 z 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�awj~ousX{f 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£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 delta 353611 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

I~G>#<`iX!^oJ$t*ql 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%0AAkC0hsx$#aYy|>jIvZLK=Uv{g1*$?XpLEgsfSM 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

_VS3uN6t3gL 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

PUD7~KLFcLmtIJL*15N6iew!n6iPguAn4 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ƥN~IYaQTz8#MzFa6bxLtEqe`aTSnV z<`o)1bRZ^`D7~qyk4jI4Iu5$8r?Y81$@MN~eg0kY5-9kiuiL&|_^IP_Ux(KmBDTgq z(1-ckhvkaTp2+%Vtg*Z}Cdk(rtH5r8=uEPi@DZFw2O~FJv0jupU)sBeosG6q>v`{x z+Z^mO$GJeV7x!j=gTZ-8#FbxJbiGv}>$|^akM%-#d1IOmnu3~7Wzm-D<_NA$fhwZ( zk%LKHx#-rl(q`wlO~bd6e_yMO>hnDb?WC-znQbw7L?D!2( zoVJE|GdCHl5%=!qjHMa*5gDF}`G=6+n_xIB#UfwG=waepqKI_X_eVNNFIm~9{XgvN zTBE>EdRCZ+f=Ii;_2K59frsqS%ik54X;@oD^QMM2e!g=egA2MN+R*kvh{T6eGmX@p zvz!clya@BCf16JKr8eR;dVG4Z-ngVP1=Dc~@1h7761}kXyEnl012?*4L)JavBe|76b4ZD@?TH_(Aa3^I^~5w;rH z(Z%1(Y{R9X7+?abK!NiFi1Egs`$k#jbGfozp!k`CoJJAKHG)*05>>Y@p(_5p6Bo3m zwgZI<1aDozc=$laMeWCZAb%YMO1kB4POe}6#UmZd?uLBjekpI+83FV^=@&Sr5GPE; zZhhfXhbfve@A0=J{?<@Toj|}WKjcqbYWP@2^~fCXaAX$%JW0ku?$cCe^fb$)0cIbb zL%ps0ywkS7U!h+lUO&OMVQUhjfkE*dJQL+&3*|ZGH$rQTM~c(c#P$NU&6od97hT04 zUbKr$8ua$Pa|+qxJe%00ht?IZG@Q&Cg|bnwO>@ipIWH49SP{2c821Amxoh?3NO>lo z|749k;Bd(T-;pL4nv4`335d&MVl$v14&zJwhx)y8^HHC5gxJC{u;Q9+LD&of28hF) zLulh_fYr3OTy!U6@D%fu+bN*X9X_+CnblY!dCxNRl{oFkLm6`uf%j%z_B#y2?gh$d z+J6OIlo3zGhAB1oOtU`y-g>4AF@9wp>NuupXam8(gL4C>{p~M(BO%3!CQl4Ycshm` za)q$6f>R-Pm8?iFqGr19o26pe)Y-B2p*pXqCySY68b}vH9>$xiJ$l#~NDez|8o__Z zaI02S&YI!x8J20%{I~uV7xZ`sbv8slrG{lo z5Ai8+dBqufIIdcjgkT>%QJCzu;k2GBZg zS**|bvR4~()DR+QCW?} zuS1QqN?VLaA^SvruXw^x&5cIXEa=#6`QD=jf6xx?HHG>Io-Tsl<8u(Ub%&AM>EtxH-{W5-m%b6$(!=4UFjV!LPBU4*5jkJ z{L;Ok0;I7Z1~J?9zcTh{uJ@9+|M?L0Zjm#I_}4bnF=!-;-K0GKM&mmhyb^Xw%`$B!>VgJt0vE?U7*|coJ!CmcPz&mQ3N=BL$cjDFbLxj>i1D-f1PzL%;&{PE@b#nW6125W?5Hs0MRuAX zk|C?B*6Hl2(Z{u@0r)Rca1)z4+!gJyJ-6Z=v!!OU(pOaZ&<&6&x(@Ck-Fxme*)z&H zQv6O~nO!EqsDghJ^7PLFI!_E2fI)#pAFUpF}XjdIWQncZF|hdpL5;0fg+tG z77%lZAtI`0T1p?gQ!Esk6OdNhob7EDl+%bbS>!`s`JnMr=TEb;?UIs(_GfL2ncBDG zVzZ>Jh;(!FVr6B{IQ@9X&7WT3qh$AV28^%1XtrWTt2CuGHQRWG>8^|-@_=H(ZQgce zOdr1=duTVwn*{^z&I+`ikfeH@#;QhI5Be$SNPOq(a@9j?5!BJ7!odSfniaemLZ%-|JEws&w%zIl9=tQ+(pu1A3E44WI ze5K_@;z2cenn-F}OG)1RXt*Dc^}$w@1*N=q$9C(%ZSHOS#~^+}E)3-=5y-wn2^}`X zZ=v5=5O*llvvwhW(-bAg#$?sZUV`#QJiMT4?T|b zjAY|&}@PLlH&giG~Ty3X}D1=^g{+fd+ z?A7~2K5t=6RWo|vKJ1QPsr^$)6t-RhF?(*m-NC^|4uEyaYGS3^oQApVrOZXd77hO! zTOpFVU~)v98TH|kZm{~|T^_lF_`&~q?fcgNYevUu0JYba?_r?kNyt<^OaNs>&^EnB z%=3yf&3?^MlNj?IGi#o~w2i)Tz+@wYD~+S)Av1}#|M#c)UYb6BQ}h8tv{qdm<7CmcV) z{gi$Lu;MYgeo|Z$dA*@@NZRKpL>kdr7Rfk6J>Slx8cB)$#Mdo~Vt(*vWvDq~3CUYl za0z`#3)UY|2P13YTBt^{lZjfH{w5$WwAQ4l5TG{3R0+k?htK}jh8DN3_n6Uw@;2$k z>Ej+P_U?(oej<&#Z_)1G!oTHSm?!pD(~O=2+#(i=W3XZhvwZwdetEj~?uG{Vz}<0a za8oCdOSZ-mF`*IQ)Mw8XB5g|5-46a-B%Aqz6Za+(Tbl!qG2GR~ZiD{`)_3W`wOM(e z(4@gaPE}()D2%45Megm~D*j5{QlVIcxyDdt8)n8i$C3*QhTr3w*_k9iHS2S$85E{%h+x`O?^9a(!uh#XEPMLOAHHRwq!;Z*jBW zN%`6xPm}J|@cy~4Ur>GtJ`F`rV6^ZE;3Uq94kEg;;&7E++a1`I11~Vz!|%Fn2|+KX4&**4j(;7p z#(X^QiG}QMDRw+VukZA?KPb>m+^H6|zUcpH`nKQFnL15s#YgE}Px7n|qRb8j2+mw! zh4mLau30zXFiYT?*pY5A$}mDBwetSy;h;}9OcyhI^Ew^VC+U8ETrqpv z$DhL{atT}ApQd5RMJV`O{az6`Os{>l_nuUpKLoeIA6~0I+}_18KkGyYVq}`h)HhE& zepBqtxMoPlka?y2y7U@6W!JMi)W3K>uL&Dz#yr30WzzZLFZi~EeYiI15LRB8nM~he z){l1;Feng88>k3kx!5KfxmDXNxdy#&`{}_Mn_TSe@V5nD9b8u@BAE@OyjYAdLt?e3 zDOA(o`%Mf@%znmOPbPLSoV?)aCfMY9G>ieFPPh-t4&YVkuW;!Q3+$SMRTQV2S!M>r7_r3+IlhMol^}2x4 zAkWr?w+Q+6Ym#`Qy-68aNCbszwuZ_qvF+D2y&S%7XpYv@sp$HR=Lo!NCcqa>B^B*dgh?JUr1^1 zbYZdqeg>RGHQrT1*w(SUrNx^cj(Hu?|6`^NqHdf?=GyGeZi-=Wj(foI-C%M4>V z@hSDPKx36lGirrk1Vc~y*nGGkdXnSqciVpxdQrM-H{-+6FuW6iPNfqCZ@Y;&qZ6!1 zqNk(T8#n8#`eT5!&#N4LGWM1-nM!+9ycPf1hHGQw3azJlAV47Th1Vg8R zg~ir<+hi31Ja?Sih3Jv@S1K{95-b0e2lM6vL9O}V0Y89oTsrpD-vyxo+!pa@ylE$X ziA`=(erP<lzIi)HnFM ziXv>W3pd2+B6apun~7#a+b(qXrTopS9hI*XkBk+4=>wIUe_&7x7~$J$R>LYK4kvlF zIk^!jDiF)4)Rery7t?S7{I%^?WW$#gD2#|}!gGIT16OTfE4_7kUJ+nDX@PgSjnzf& z(|J5*Xit4ZRhEVftZP$EE=306KMb2#0oSQA0myU67$IsNWLbZ(7F7Hfs%ml(h^ZJF z$T6QA!|I3xHtAwryFSFQv-7H?%RbgGO!v)Y0dE$xXZ1nAaw!<+l7RW<4nKcSg`od$M9Wf%AYWl9mp-7_?nUc zT~^mf>%OtB8tvD6$AtQ5B*x-Am!)1LHP+eem^P#Nrv*elQ5(ViSFL7T6`05UV?j9> zH^aY0Sx`f9y8f{R=Z<{W=+xF!-)WVoEk-&n;SOeX=mU&Gdo}gpDFQJ?^JZT^ehB0t zS$uDaT6tR@R5PX%5SgjM;qqOITPQaZ(Aw!|MNF-AV4ht_xfc*b7|?scy5rxhgMWN1 zHbZp(Wz{&iTWtE!9$mQ_=mlRJ(M%K}$8vF`ofV!%k80DaDIX#9quG04f#_Yf(e^@; zy)UA!Y|t$)b^P?RdVdLGbje9v-?!e+pA;V?W3Vo@z8ZEZ>z{il_ zgdc;dGbZgSOrJ0F=e)Q-%9B^wR+AB_`>tYKOtDcOo0dHFQ8seT1p0S55}yK6WT?5g-}|bq3gm84Pe`pu~6Kf-Z1N9BbAfw_e6VvF-A%i*4)c!sfEP`y3`H7_gYzG0{6LIS2D^bHJ-KI*}4z^pfJJ75Ur?cjS*GfhL5Z zm{a_2=-Uo^;2X5-{x`Js)6S@ZC?1epX_=j|x zK&-bLBzbq7GZMdLnoYXBSZle+gRntq7RQmujTbX5ejyq*LJmK^MY+hc*ow33!~0#I z`wgvJZ)oLXo-1@F6>+}O(Ld~|;#f_1T%lk|Bl+rkuYB!;RH%Rdg0v3Jkk+FB5^$qX z;q)GTq0k9AtOv+>R1SqXcGL@gXx8R4gxK}-gL=Ov(ojMH|HJW9YcIW1*dvSM73l?N zB0qTi*1s<@t3se4Mp_nMW%#r3%NEJ7mZsH!g1{i#!R5?RsB?}mUChNj?Hc&lWG zX&hf1CY)rY|hOi(TTW`XC=+(Quv9~oB!gS6-BQi>ccMvfgXmYo~37kt47V0 zKr`m6>hm+K+7>m1C8a0uut}Pgoc6c2AB!Oiw;3{>%l*&T#3t}#%>`FOMJx8HZi*+5 z+>TmvxLLmzUU_du1%`pJyrI`Z=)VGUyW3LP(ZQG?`d|HQap3Q`Sh&8F@3E203H?6D zGEu?BIgM)NQDG;3;(L!RAu8&KpDLhp-ST`gSn}w3qqVZUD#Cgxn9Yy(;C#J*0CBQI z=Cc1rXCtXNR_|3Hbc&fN;$NsF44d;MFrwIMqWAXJrIS6P- z9FBND8FbW9J4|JM!juqUHDV=_m%U+^`6f+3EOP2UGG4&#v4}|{Kdz`5T`xI6G3UAW zy|6=OKKEE7A>al`LH200}#c$`s4z+MXItI9>tf8^69531v0#=}7<%7gev*~8 zq)gTC9{s%Me5R6uvogkhGTki+>R=NONSWhw#5@O!zM$x224$c;ksiauTskJ^h8Qih z2p(p|FKMRKk%GlRzxq|i9Rp)a_kw5zaLv=O>by%AnfJPlNPJU5RFR=;}ZzaJgKNl9w!F0bZn zG2QrJ4g1B_RBWY-IS~{yZ)wH2pV@N2{&lCitc`doCJk z3AVHZ^t$@@{pp_BKnKFQ#|O->4U(S18p|qg zg^MEp$Xj*7u~$rJWyGq|+xu;zM*ee&LHpxsSbtR@MAr9vJ=p7m&X3cB@UACAt6ycM z<1wp9(mDCL^{!wi>8GuZTz9++@_w=o%x{N?qk2PY zG|UEljbE|242U|X7xvgqnEu?y^dZ4gD|Bb35 z0rmwP%)IM@JH2kg|9P5A3@Fr4ykAt8_@Pu|fVik1&^%UC&knA-&1od%N{~F}suBFp zoqW(_c#_rzx2DH1I(=*hq0Tn5M99hdT@+bTP0qYFGA(WL=Sxq&`MOUxdwx7tzgRTI zHO)g^@lqq5pB-Uao-o8##dxBw&p zCc(jm9pxWoJJ^O*gX7T-7gWwZ)}=cciTI96?S$BnlJ&W-_xMf9kp?Wp)FZ9->Pzpq zhh{a*$o#qPP^^@`b93fv(BrH*nC?&qQ}QC=6qn4*XAYAcsHrYVoX|)2c;T6(HVq{H z^keT@d)3tJAS$DE3Ghf;MeT21@YKwRl9=0PQJWeibWv}le&Y2r zFR_MmdLJwz1#>_$Q9>(+JrEy@L;0l8hK8>0Ct7{$^4t3>S^iWIk_7X}8ts0~81Y!+ zjyM>KnKW5!w3x)8neUKKxo?vinptzHK#;NzTC*Bi4|>8K9mT$?;~PE2KLvfHwc)PR^e62O(}h~lST6Wf-*PxiRt7?F+93K#l@Y=jtc6(+}uJ7yBb zfFa6duQA&~b0)-k^JgpW#p4c<&*h5s$5S_}d!DUyDIWW!L)&@_d@1)DcSVUqtsqvg zFx4f-VmZb+84t(mpsWIDWe`On`82J3Ht3im0T5k5yJy+jjyV+-2GH(_w?sOI%-eP% zE#)t1=CG@3-65!sV)HZ2r-mMh&a_jDY?o5vH5t}X#L`MkM=W(MzQQ6Bwsr}H99#yw zlhPW5&HkHYehb$*67H7O1gSk@pjPGZ8|Kb1l0nBEXz9*!lA-#f@~s2$ zRrG{h@Wm1b1{2Rmz`NbacxU9Nw*>R>q;X96Hx}|6p~38LEboPKFX*odzid6ltomlD zSY#vIa}84XG5_Siu1)8b6&JU(phs#mM5 zL}qJn1Jw0PgoP=)5B~VQ$LtX;oFnm&(E2%DxIn8WU}l`xLr?e{Xg{o8()<{P4@ON0 zKTuY&`axDq5Lpnqpg|;8ZTY3N(Dq7*>~Hoy!N;a;ZOUad-G>NpJ@VM6y^{&ha`aY~+_Dk4G{>)VBgR-7e=RXP)k`I}7z4+15c;NP5YpM<`4Y;~!cJEyO zJhp=?O9kjcIM>Y1cYRYS4^^a^C?(@{*7YnG7!_D^=r$;IhyuR9 z45{WYNztP$R>8kZNZ}QbcKwDrFxFfgDBMT|G4IFQgdZTIdY&#Qipb{g zs5|H@K5CLO!T0`|Zs#}jA6+&U2ZsP4A5TZi&s$cRlA|25dVU;%tb|#xa^8?Hky>VMxS= zRDv|~j^vMghieDVxyO;D*MGgfp>H?E-hU;|_)h^5L5{=sQ4UbAtaY#@DWJh*z_rVY=!P}dvZ;Ewn;*c#0lK)deYNKZeQQzP4q8K}3cNY;BlMg9JpJMOpQ826GoN<< z>OTHAe@*<{#&}v@M#tcrp-wmE~NPgDQmb!n)F&x{?h97COdU!HtR-&wYF$Y_M@wkv)~QI1(5xES!p!R z$lAfh+B3mlMU-!nFwZ}+RA$m1?yRBszPRK&v`B5h%CHuw+9(m5(X_6sU0ARqt7Fl2 zz3z?;ldQ@s!M1MauN<(!6c{M0>Jy9rttmC*mUpCI+z7^EZsOd3YxO-{r@L2snfp-9 z`7z6G%;~E+Su2O6k96462=4vjYqW>ZWattw5R4Vr6I=5V=Ni?TqLHY-Bs?8Ja9s#I z7z=j|w`~E}OEI?R;n(w7Ee)?4s$pJR;l~EWaa5~Zl0KSYPv-=e*Yj4pZURfu7W`n%fv!=Wa>sfC*#asX341p`7Pr`f}&! zWb&Jd?3SzE)mj#%QCX(oK8C6 zgw$*sm$DYOaFa2bkvvP!AXvj`Q6+xIu&2TZY^_{WX^oKZP|u5uu}F2`^Os@N3Mg5|8oBOn*broYb-|WDMJ|b(q-SXQdZ<4%aI*>n8J@yea>JNphiCk?M(kC!#W# z9e+I~dwtU4_v*Su&BznL7FmXxsJ4R9XQl=S3uKq#L zHkeY~=}?c@>UZ70vG>sQ=}0N9G?CIetEx)461R;TEr^F;7n9B{-*|I~n0&AEZA%Ca zB^R{}W|CV?p6CBt=m@HytO>^eby@PJx6_W1^MuOhwb%#?NUl1ywLWBBT9C_&=?7|n zP4&}f>j<+uK$=Sm6}y^sA$XPQzs416s%1hxG@-oLFQo$U@ zVqL++LGZ=d6hryo&}7jQgNPy&72+qD=^@|JI|-$Nyocq46&nkJ!_>zG;~D9KrxWg_S{ytpt^)m22HTyaii)YC6+NyUNFE zo>@BHIl^o1ssz)4(#3WV5*YL!^h7ZGpxEQ$36gx!gH|LA!DKB$g7`MaJZO3k8>om+ z|J2uv{7LPG#Vr%LAvp~?;MAA%E)(AEnf}ThmHZP2m_i^grGUMgEb(gtOr z`&Rs{U~@=nb4gmM`K6;(S=!JL^xjIiJO>{V*qo!MOC#`5C2V%z4V2LAQ%Ho}I7`q+ST&*$S)6 zW4@R49M4L)6ZH~(H!gmaqe>%=Ub?Sd-?8A&CiM8$1z z1mq8cXsRluS_lWU6T)VuB&nwK1goQ=PiH8Wv63#UVURC}R6&@`G`7{;!&LFqB!R(P zeU0)%zM&HH#)`CUb#68JLGX&osZv6iT4jPpt;#Wd_FJX=^qJQBT>uAx9>^f7WrTsh zF^JKOSu-fnC>u@dTo+JT{UH{Woc_ce5>`xU^&U^7YubS!R|*n~TPg(|S5=NwGAT-U z_~tG4ciN3RYp{rQI$2d+UOB!f14zp&`036qFF#p*gU;>G0MW9-?~QI&Q+z7k%o1amILDpgx*dJ47H4+5RG;-3C#J*^EXo`GJg%G&-UDXLq@=TRc7 zm9)+McR+HD(c-IBL2ll`dyW1t{NRwt8I$|x>LFiE?n2@2lGMSUEGH5u1#q3QC_y&k zbgXkwlx3X`+4Ly$*2$b=l;-@cT~2yh#ObkZQ8o&_oPv9W9yJ|A{S!Ye_BNoaScuVg9O@wIV?1`{ z!q9)q^!X@Q*;L0w?8KJF-JtKDl3rz#`u~P|-pn7~%x?KDR1a8_wf@|mQW0Zv z5rp9RLmH+FnkYeG<2+F6k1R7<&!p51EprGc)iO)6z!N`pUCT5H6g!_Kx#NbPdZ=ZZ z1&T$?lEn7_@U^zIOe;aLG+B~K?)X|KTBd=Z*u*SJb$9&KoM;hYV_GH-3Vf}HIDD;5 zEz?p^?C&he8BhHC!Rme~7*%?6Wz~H3Fg}b!M`+0FSZjv_#<3_E?scfOB>AtL%(qNc#Q5`nVu30${Q1i`e7-%cEom54uwXdp4U=Pc zbw4|ds!u39vw@i**)%~Ygl6D^WjoVsVQJ~nSEXfmh{Kiv2 zYs(iDE1e}t?uqZdp|w>EiWLzIf7;jDY6Qi8hEa*xmwXOp+62d#d8zkv2;)~pM0+MR zB84vnNs@O`!G^z&Ti2OAM6R-=EBPGKr}wO`UAud(__}UTT)3^o-)?xj0m6RKTj0Aw zFRoX)zRu*k@+XeA&hm@ZJ8qxM)it2)f0EI*jhvn}J(0J;D9(bPV%rjCNGd+0yIRl5 z@k|PujT~Zc+F$U7Ue+~}%|F4f#CE!2uK0Jl!zt#x&+5mir5j7Xr47E_eD2?dzoXmQ zoxJ0c8LB_?PZ%|rFo?Ubd^N^Bt~k-WEeW16ImA3vWb6-_XNtH_8G>WtmIeAaDu$UD zJrlPL8#VQlM1IE1Zq*+1xac&sJo_#WoY=V5ZXS{6<jZC$vYaWrtJe}seF9sNc_^EoR-q*K=*fi=7QPkBsvMR`$q1M7mu zphmC8s743DCUgtBW4+b7sdz^B;Q9CnA!SH@>v$ngkQ@(ryzz0MChB2m&!WvQ>Vk29 zuQe^|KafC2JeFBzJ+&A)I{*Xo>xNDpvdg_9RgXPA}}+4>rD0=HZy+X zMP|l2Gk)zz_C{wuex<=5wo(G#wdJ>3DF$!1@XM@}gEz(b8H5YK>ni-H!cg$44*x+* zIe5A6LGbjh+~=|;OH;8wNQAy*cg6|TUxPmNrLaY0lSFEbfQ~{?BKSTvTlX&1Cn@MJ zC89lhJ4aPS0;;eHV3ibU2IgWC7*eoY7b!4lOuczolQcI}nO7a`hh82eps+icH`Oku zRn1kpFqzdZ&L7jKFL#`Xmd}wLM_oalbDt^A>YL{D=qFChUBRR-u1x~lxZ_l5j-kqV zxZC(<5=4X4gQ1SNGz=lA2^!rYgoAVpp)v^us#t18e~M@Uh?1C+^i=M*yhIDh@{V|B zbj7;&g7bN2rf(XUd5m}jzo?>Q+M$s_8amkewqM3|uHMK6+x8UAx<%Pz2E(Fz`cxIr zak`3{2`Qz1BC^XwG#hjBTJAt}t}D%|Xf z!{7sBUrkYfyZcS&%PNe<7-brJsG9@AtR8}=DqVsNEh^Kbo*5%C&eW8??$+2~^iZ+E zB`I#5W8zVPuT-=78?-@kj=_z+8fITy$@U6$!l~3bDyZ+)uS`x0qv*!Gs+(iIQQ`dc zlQiG8+vrzHT6o_Ed+kTX9u*G_K^)j#3mcG=4I{?q#E!X|A`lI;pTM{yRw{G{x%eRO$dgXuY z-QT)DhJO@il0vUUVDDD${y6j&c}sy~@0RKQ2>mEt@|J?c-mTsJ@$fAojed@29D)%- z$wL)17eHvtX&k~FLRm)@bVtnI&HMKD<|;mWw@dfO)%~Ix(!l+%+&I7q7%$I4NL+GX zq>G9_Eb^O`BfCC})ULL&>{81Y3%n^#EhA_}*1({q*_E97B%~Nr^-o<-C|dsM&7a<(!g>el_G^daU{O_?bV74qL89cX(>w_JYd(eDrl?gQ6{) zfY&wE4WuXT!oT>$N(bB@d2KzJHI4a9&hHlrgKDey>s~7jq#C~%7FJF! zbbhG*OJ*lMC%jmxw`k8OU|3i+lF6u34uv0CHf_PEW?W$3T1Y$|%y-uNBILxf^){Pt z4LjXvx+iZ<24KM25zGMRLj?wPFm3p%ql+?2B4%ObM=}II03r4PW zaUzxSG?KZk*M8mkYFI6sH8Sk-Di1?iBvS15ig9LGl+GUeNG#K3@ij6hcA@YoL244j z6(n3(c@=oW2J}rLJjBsXd`^>7scGYjEQoKtu)rTF;9GdikiN8h$DA)&lagd%;7r6^ zh*uM*K5nHA7MlEBlhvAsQ4`BEZhl;7_qTkXWI<|m!bNDobxdJFvdI$j`0wdH@^RNm zA-r>pPrkTwN|Z(P4Ix<}j&q#CxaGr-$9m8{h+lelAAr-#H>jz9WYjBQbWZdETRZDL zwzf^m|C6lW|FHbma{a}A*K{N_6W0RMuAC{s2sg9U5}3*QZAeiORf6*v^V?icQ)4Ewr}D&xM_|Oq z7&NDK18@rTjaH)_Q9TCg8Mjpp9icW2`k2hl{dVzx9<_6%XzHW{01w`q;;XdFSr+>8spe7_RIyAkP*^TGl|*Kd@%6Rc!n zu8ZHZ31>v_s@yrZrj@TB-g&f!+V6;5h(EE30G-hnCQn~QIutKdp158^v)_~xU{9nX zFxIp1r{q^Vfu?4?4q+>b>gYwfqxhRIk2TNn-o3)suQu7$utkES@Eg_}nn#VtD({|F zt5heY2qt)Z|8|KG4@4i;+)#}ql%%k8N>c`6GZXc^xBa!OYn(W0NE@KM#KCx2j zK$4oNnwGqJGPkL`mh4Q@Z&SVdpc1;(gljYS`JX&-k!CpeNj40tNh4bVZ~ShQtBI!r zNf+MpGIdF|rX?@dg|Ga3ZBbS6Pd{Cf^h`D8<$DKCs)8euQK|~%5?V~{=cR9^foD^I zPxM2A|5l%4#goK`Sn+K(KHaDo>TUXapqP|dB;I6e*Rka3TU7k!Hp2bi40^hO0mrZm zhQfh;$DoWapn-YEs0_y4fqTbPT^5c0M8`y3=Gp#Q$4p(;wm6b4ssF*+SH|QKMcd*O zcefUI*WzBj;_mJgcOBdd6nD4c?(Qzd-QC^capnEE$^G+^m+Ui{bAFuctsGg zxuLl0cs>RIh&9{Qc&g>2njA&A&V3cvjqMy6y$)}q1>zQVo!v#>8Er?jt{d9OE=D}B zJG^K=VkUR9uA8M}g;NM+w-U9#;*5wpRBMwajlf>#c#)HgQgy6%2y}FGM0>q?y?H}= zL3#&xk-WgX2wWjuA>AQ43OGFTyk&q-2${v)RI>q#PkngXh>pR$Wa)nTXil z2A)>&PNba+d1f;3CZx?0*;Z0^#+>(gZZe=JM9luwE^2JkJ16qcr6)|#ep1zd#z~pu zJg*+l#`l$si*%w1S+k_tm8G3i$9rDb43Z4d34?=B$620zLRVRCs!yt9ny8$>I^a5J zxdB=o2b&N0?1;Zdrw>kG9Q?frxfy$!aX*L3Fiz4QHDPqMR%^d)<}*% z>uE=y^1HLio#<=18@Y$c%gNix>&g4ctI4~`o5=^JOQu_ zKGSLqc34->gX`~~mO{fPN9MQewi8-YDS*`lZ&&V*mip2bv*4W8ly3)w35$^E%78q1 zI4S8@Y6)_<@UNtyR$>ZH{gL1p*=0P26BTfd+HA$4JRuz49OQ6{aqm~!H$E=bJhKiw zk8>uR?xf{1z88JI`yQ3}ol8B4EPVM;{b%8X--1lYgTIztG&7^X!5@+tU=!zlNYvxx z3OBPxCheNVyawsP)(*{2zIv&yj}1hMkBc)@VY|DOk(u@(-s6;ptJs6NepGbJwQjc4_w_T2w+lL${f8BseFw@u{W*v#V$Wf+9>1231rG1OW_ z|6KRWYc)X?5gA%q1oaZywI!B2MH!2{`0`K;KjI+Hl0z|5tz>q`2=T}3dIWH3NfOK1 zC!ILd;ByD*sbOwbDdHVj?)wboNp!4qYP1!{%CHsAYW+Egw!(Kc>vv1C=5eWer-kt# z?+ox>=J0rU@<0>C-p&$9>CjkXs(|J+|C+`I@BR@YxWkGSCXbKg68# zzmu}C1*G_qk71i4C>mz60F#>@@or@5FBb-fl}}F}q`V)=S)I(c4}@=mz5gIkKKiN8 zZTFO%3%CoQ3OYc7;Jk2U$0%O-(#aJVRrAI@IXb?A(EDWvHG?iJ#p4;se0xRWa4W8VG+}uF)v+Gn@`PM&9K@W5IG-PsiJ?U9M;r1lBeC-L+;%e#!LTQF=$7J!hl2P-=^*;)B z$#M?I=6VWa;bOghQKpcl_>}_`(6Ky=vWnCiz8T~Z6+=A!*|HBVo$iya{V>a>HjKO1`pCT)71C1#<#_5?!5ggRMhhNVaep&v!@uO z>=*rWE#Kxbu&%j|M}Vg6zN;vIUD4J{^O)?e+bkdaADEXaJ~>j)L4Nl?eJ@=A|J(1b zPN}?ng-3sOP5j?XAWtcyD+-HPb~rWah7@sa<4Y$qDBk@%X#m4Dz4uslo;F)O2Md$JCa&84dv6)~;D zI=kb_K5Fh1wxo>;?iJVSdqE>V4RAC?u{DPTjbhyke@vuME}5bYvqeY+Ylt|Ef<9e3 zD4vW>V&zPKP^M7u7)R~Ks5F5wehQkRiV4MGXsMKCzmg?@56Nt??0-7yyn+e#MT^z_5bG@5n6f=`z4dGfeivH!M{?Bi zk;I8sOq%;+UR=z@>hB-EWJXMUJQ1|+p(WqKd-?bn3{09xON3Al{v76FEKKaDZ$Mwp zy}U6sd^n-A_%!MndAVC`%r9|ZhcRHJ!Q>6@0FcU0h}9zWjHVp z7sHSlUPS8Il`XOhhFb^6v)%4S;?NUvX#n*=FA$~umkVa~#IXNZ1)K}Ht!7s{FKjB#ph4Q6u4MTNl z#h9FPlPGJ0HDK|r^*PBPbMt7Xr_-B9S0(4iME7Y9Da?<5u&bcTtc4a5cWo6guV}zK z7S4-V0l9$lSGyCdS>oh+?0pS?31MZ2UfN>$CP7%#-`Y7rJ!{pMD=p>tbxzi9Nerva zDNPJED~B2F)ojmoCvxU_F*7Iwy>ZupSEv%=VyEqM`sIUs@X0V2n(Z;@zhiL3MReeaC60-(2@0kL|!@o@Kzj7rT2#A*_AB<^XqEt`0 z#X~4eDzjtermIlH8YasWgBd1{nuGU!Rhw4bhF%H9`4!@}OSvrUWk7Wmq|=Avf}yu4 z>Se%m737Ut#3$YbYN}$MKh@zThF`rwP;7Dw0R`Y>r{t*@rP{^_|~t z1`J%9aNZsPoL{{Cn+?3PsD+r`fKQQ2oF)`djw(ziJrz!APC;r;@p=7bULZCF0!@KZ zvav*`!YR!A(duG91EWrn!n{Cs3KWo?Kq*Ye;IH}}syuK5Vuj9*3(J4Gi_ZgnEa9Nn z%MEMH!xch;DCFscBRNmN-~AAlzK3wWFL)7sWyf?8<7G>q5ZqOg@RpJYrJL*$Q0GJI zaK_Gz{&~sT24mZ|vc-$i?V1s!@HY_6%{Oan;Sn;X0dpH%2Ba4XL+v?&XZlfIWhcks zS8ex|6`xx%hTqPS)N>nK?7oK~?DRK(SY)@Z*nM|-Xk>qRSY+?I*uV~_7^S`-X`CI{ zpEo~O=#+3?bPeixw0!eg^`s#Nz>r^f#4^9^Yd^lCY)mYLA{MEul!@4R;z(FoLJ9hl zLWzWNhO$l!YP$vMl4jKK1Nly&FP6h+F5ERC-|-D0zF9i>w@~fpoCjecxrzAsbfISx zZPFdW6hox?9r){>%Twu-7!*+62epvghqMTaVPTrjVIQ*-Lfr|iA|E>egow`H&cW`y z2qEtHsws1Y^cad8LxX zfv=^4BR9Oo+x9N^wK|2W9l~#r?Os)_AEMcO6h@qC58|v)3y`U{-SSHciKu{+)eY4ABy!D{C9$9Wyr~Fmjyy zGzRf0Mh&Gg3{L^jO<8IKmqt&Gd`#}yV3PyJzU?zBA%FQfY@YIiGEvGH#7c7$g*Po^{ou~|K{cyx;BLaEjDSoybwOxNSR1f0bFJcC(mA!chxhzlZfskn z@{7YWqr`F!(geof0lhsgz_f#BO41a$$U70>dhra@jVY zI%b8IG8+D^#vH{fR{HK!G~>%dCy5loQwqOSN>1jPuxm_N0;-v?y!G(lS4=8PC=LI{^Xkl91B z=P)O5niow1g)EX-7MI_j*~6^o@K4}$-j_UA13`!+*F9yw&KK0rCLfQU@zMy7o`{Fd zICqb9*l!Q?kBy6A>R+DQlH6h6%sLNzSW{t)*%`uscVsbuD;J>31)#$8a(^JA>ImLo zu^Dawn2N?hFY8SH8>b*sTgW;7-~5i zY9SeF$rx%e7;0G?Y7rS~=@@G98)|u1BavZlKZvP8zRa2J{^1?>T>hCk7 z*{%hgdd+yM+osK&zi~cAe#tub*rL62g}Sn2xw53#p6ep-LLvGv=K7V+r@O9}NiO#X zC8o${9gkO9KwCgWKr@q!gp7o4G9fxHI!P`@F8<@S=*2|Rd!2<>Dw9br=HTsULgNMS zJSfAD{qq`!za&^HOE4wzBj7Z5uF%??AYTqx`PVSy>yn!h^KD7ZO00GId??vQ*7KWE z&ES0aecoFP$C8DWsLL|vH(u+rVOcGznwdl@UTZAlqH?w+i<6%6y?IjCnvMB@(?;uI zqP?hZa_4-m;Ps@fHY+hYjRM9Cd8t%l$fl z$Sqa_K2A}UaR@rR9et1CvFDqc_#d*cVM;qB@clH6`!!Yu${P7YR>wU z!#PAbthd0Jbzab0_s?dNRRYofoh%H(qi$Flw4kcHq$$T*n*+DGx1 z$shuprjdpIoflF*aU1PGvk5`^j*WP*t*~3Qf}IC(x9@9BzKnqU*ZId1-wC~>3PD=b zG%pqX_zp&XsV4`*2N|ir*w+w>Gs&R0M`yp}!;{N(w7+ z2UYv;B~Tdh;>jFEpplRnoRX^tIL3JGZoGna^btid6 z4f!5e=R>z%Hr+3lINMQns~zl+}4q%_Fxu# zdlm84RZB6WiYwU_`}e`8yXRZRNSC@M05ZCv2g9oD6wAWC4C|D7&e0Pg;h4 zcS1yZxpjF)S)Vx2zZozJ?hl>lc7QrVObB419UbD%*x~W9*m@c!5EIBV)#6cYoNUYW5a-@VFn^5^JpiEVEaM?{fYfY{rMdF*3$D9yAc zz$ltA_JL06elgbm>xkP!ZNq3yUghXM9ya5O2602!&s5g?-L472IhwTds|g3L9kv!M z?aA+|PM&%#Eqy2A?g#Hy4|C*JEAbz?*p4UHQjpD8rN$qAj64?;=* z+U_a=tgD^Yv(Cf1Z(3*nCa=6flqD3mxGai%PE%rWIn9l7>ew*w$Q20Qa{j7d2zmE2@Sxl9$`_%(yIFyCqkNbn5CGp>bF#z49+%Fcc&^AU8Uwi>d9> zfsM$>I&4|l>Z3OzB>|0T7EX?SnsU9^spI&>OnfeGPNNtMTs%UwRaCwzoQti^Tsymc ztTwW?u;}+$;M1V?n-}xO`3#HPZ>zaWEDa3}!RPSDTfqG+($vUoA5zq8f^?Pro$S|FAVRR!%>--U? z)oEwUtFZPSI5)P;@srkQL(sFT^H*>0l^Tji**f3hX-pGr^jOQCm3#N(>)c_LBJW0_ zpksdn0O{xzRnCrU-{Ew0%#~mZ0WbH=*=a`b{uuA-teQEQDRf3qU^6V2bbQcw>44VW zz*-MhwT!HWa(1%E@S}GEAHPjFi@2C9Q2a*91>FZ#m*Uq$L^93`U(g)uO*g2K1IE9G+WXyoG zQ@pD%P6`bEdr;jWN~9@h!TWXVvX1w58a%otiArmXciL<#Y?q?^g7Lom1Vg>ezIEdT zI9Y#jAd^_7)3m&>VqqHVTe_PY>=_b&s@4#^LcmK}bqdHk8;RD+Xj&E>zq)LZnk;&3 zK*F@ew;Wmbd2-sgS2IbHb(8+fqP5kZzk8f6;NeQxzF;y&SqeFrcR;cT6hy0p*wKwA z({R9W5x2wfv5$O2Sv3V|%}+aHIi98h7euGDmAFK|_7jFlR;w6&EO=t*^6ZW@ak041GZH|eV2STqEG?nD2bzyClWt3F?m01Kw_P-Y6LBSH zR-~g|^Ib}oEMc=#uwtgya z7Tw`}p_>U%B`xg!v|zLy)?~%kuU7JRy>w=;U%CqfMJk1zdx>z;hbC(YIA2xe%KaW* z?%gTZP6^zzJ$XYqlGf{0((VpC7B1=*$rJ z&FJvLdd}7)qP)(n$Hoa%3MP_)2KiGJ{B*Y+@7ky6Ys*|jTh}9_@1I`rAs^S*!zR7| zl$5QJ8#?1PYoy!h`{zin+TT>@Lah1c2_i0@IW0K!(o^nMOB4x#4{kE0B4SjR<(W_Q3TJA*2o0Fal@3e&l_^QNqhOh2V zft;j>dI4dk{>H<(h%SgczBP}YNSu3nb-6ScE$Umhj7t0j!8FiT*UH?+V4~jnPSvb3 z7+jT(qKM)zX^A$Av~E1WTWKbawFVA!)fN)bv!pS-+K(qc(!4dL!Tm}l+9nu~igcvY zdU9p&842&1mijz4j(D*#vMF+WWi&~0`@*fIbvJN_jc0V*$c@D#SW@~rN7c98=;SoV z5uRe_^xI;p)XZDW**r_Hg|79j%iRy8W?5drgq!Ya+5ffk4~`_D=iPh~v=U3U_Ss}! z=gc`zYGdj7=g%2fae;*t4V{zkZ0(04rc68ZA1uwp%SEux7`AeVqfBctyH4WKZ`}NO z7Al2GVnLJ}cV|nl0`-GYxA5|THnr2m_xo}MTq@RvK8yT)r9(?r$66!z-8*pG^ddaNLz#Q z4?0vv+7BJGvJ0sqf3P#**zhBLLq)$~50zNF>E#Zk@QXv`*s^bH5o_`=ugl zd+{S}sj-}0U~%2J2cbokX-o8^n;{fs_btLJVmZ?4ZK3<@=E%v;8a&}kl{h;@LxUIC z#ln|GzIWa(%2no$JGD1~=UnFF<+iyWC%*M4O6?20wjdvBNBk=K!|`6-020_nr=~*$ z$1|e`BFqSYAqoW{gKea2kd~=v^NeDY^k4(DQtiC6aw;QyWUI+<&USq$BTIFpe&nST z^6=}>ZwLdqaXDix#lb#xrU;hE; zjrV{Zc(_N_IJlwSwbwAcrzlKu2;ZU(l1c#RbGKdW$Ipc3=IkAhMe2z{&d}13%4yAw z;_85bcz?2|r2Uj~g(HCvjp0;#??Jm^WM0;nZ+RM}dgdRunx2t+4Q)!pqYzlKK?^oW zw=JO(w{U!ptQSM7YY#QIuig>u^NQ=k&Qdp~Dt{T3)((kj+p9JrCjU@_`v|@TZY%@d zX=tyUuT+<5t|3+Es4H_pwv3yN{)8=;JzIh}@9%gXOtj~n@6U4$Gu9z@j1G&FX@ri|gq@rHrDCElD1vL_Y#x9em$ChoK*VL<)5V({P1bqy{q1)Wh2d7c=gA*! zi@Taak1h5^wp?&_bs8KMMhDClsSTAfd*wXm7&oq7~{bSgo zF(7y=Vzi7{hNdiDVwX|pY<*5Qc501vHA*Uhwxm6v$A4+MiHUBSqE=3gP<{e@2eoJ! zAY2ITLe=Z$-F^^=&tJJOXho$c5Qu;V4paeqVCT53l&Y53x$A_84aVi?7Q1TZ>f20wdDOw&Ps)PZ zC46xr1eUok8Coo}t+bYd%Zx$6T)!`yRCt5i9-nUW5+9}J&S@f>_&TlUYVFFyqv(p% zHpb=Nt!F!U+4O#-I~={t{9+iNvD5{MiCGsE_I@j>EX%INK*znX96cf6ge)>9+EW{@(xd~vR?C%3Ek=Ro7RJdKt>Z}S=WudDBg9N>vjLSls7dF z6oHTLo|EuvIo_!P3@N}uT?+Zn&Pg<;9n83Nvr~f?q9U(Rn@&%5ubFa+QC987U_wIk z9Gi?`k6;;mT%yg==GwAfIw5`6;sVZjHRBQtv)dTwPsI zz_7b=RlT*=sO~fhY1X?Uk8Afd_TN^C72_YXnZ~JSDM_`Hl!m~~vvDO{e+ml$ET+|K zjhXl++uiJP*u)!`SKInuuh{-SfjS701Eqrsy2w_ovP+uQE}kab@?I{6wC!r#+%OQIhakP-|`hJ4#ely`ym> z7l>|EPWMvcGv9%wZkshGXJ+b-+jR>AtHFuowXRoHqR+$`(DaoE9m zbR+u`YOGu($(+OKyJ!^TKmG-^K9%BA{w;17ArWIqqxMsO#EqwLUL4{r5Xa5#m4cVk z>V6bKYXgvWxob$!*~XE$r^=MdU}HugjWVLf_8K!8lp^=tUC6tS(Q$m`!J7D@g%CsV zyF|2etP3rX)6o3NiosYJ6)e2Ai{O|+OD9q#@2(sDadJzv)Q4FH84Qbz$Hf2^7XrB#L! zNUm+2lVz!)!X+fE!F2CXmP)HRa5=*obVhipWp1sL{#kb9iSNcCkiz7_gq2a;PH6s6 z$GlWAtoTEBzv)ciN&2$)?Mv{*tCvJsOdNS?2twtho%Q)C@mmI2u$fruN@tgm{2yV} z1{dH{SL05ru+dewNs8Cda#YG`txGhN5jxH5N;X|tYBsgnXzGcBg77NNX}C7<$Lca! z$}>1MO2VYWax}F}?}%C7zi8juQa!?EEGn~O&~)_KSsgW*=GtOynA+-ml&Esic@z-c_90-yELa*v!yhOt6udS2L6cR6hIk-_~=^l{b`WA53rQ_zz;7C9@P} zT$tFV#;a3UwQIkcjT8}geLRSgs5{=A)c}+tLRxPc9=4h# zMwe?Ri%FYn-qWW6kWSz!V#kD2LpUtF_(qie#Q6Fb*VnlIc+QI$ITdX48Vw6doyA_b ze=jeznCqAijUi?G#gzRH{=4Db^}v{uxx|Cig0dk#hQ)9n#vD6UXfrPnb2Z1f482=N zYT6G!DK?A3mrswx?X+wsEjDd#W} z6-xc~OY?0&PD%AEe@`eesjSw}r?#ihF3!D8E?d%M)|?d9E@0{2;5+~8c;jL;C;=W0 zHg;wvX%ibWCv%psEId4H9IXHIR8QOB+~Vh!1m4r#sZxgNQ&Nm6SIASOg2@A+AOb1q zWBuq)eMx`&E_CdVFJ8Xwk6>6%#~3F}9*UrOtomSSU0<(RUSIxoz5t8- zY3;y!Ur6YLr1Ju3d4KcJ;Th(C@XoAlJK$M)>4TC&{R2xPk*cc8=5wl(bde?++zB1_ zdO|x8zi^&>IZK?|X-fw3X*V3puOX;};|>!b6f?HL*V0vZO49TC`)6y%LTq`fdZuum zK9g%(1bvwly>WS9K5)QX^PS7M$s0>yk5|bm9LDG7rI8m1>$AO@EleyJA7$dM*~7^7 zy0vJlF&U=?9uos>Q90VgFylJ(pLz=P0RAP3*$36!rn;bUx+JCV(3h{e<`>#cyKT_W z-fNPf``OV~OpK`;d>0XcJH)qw2z#Q~-TJ_k6U#NO;GJfj(_G8#3foK=B86CUC%>7` zNwblQ^fCatZA%$?e~dL@7=JJ8{uz4i8Ax60VsX>5r_t-_9eht@ej(WCe&lr#K*x#E z?u>dT$)MNZppul-pwB0v(b4Aoehm;?xr0Ybyy@D+IuhLUg*a`IUdt-z1-kPs*@*$~TIyaHcJ5ze# zH0}-eL^dr1*5dS`ep-NXkY;kM@MZGR-8$ZSB)`^Y4A)apE>_Aj!t`yCb3nLGC+#Pa znR??<`~gwk0GoxGx-gHRi}nXVdG-}aAP(?wsEEhz%=!5~IN5p=@6!P2Wh}bawZGhS zuqDQ_Y1LxfwceSyUCsK`)0cdY6F@{!n2&bf|DZHzTbZb9UB z=4U~^DElr^A-XEmLzJ@>umv(-^KcN8Ura; zfgWwN&$3$L7iLlfT|dXRX|*IFs$7IwzvDJVI9Ap%+0!d;=Wlf5(D%1IKOb%&EUv@J zQRV^uwby5uhlt49p(HxrQ)=xs|2#93^Un!O~5J+)hSiEFIaDi%7K%v$~MFiKxGME1d#te)jF*F^4QCi1p7*q zn^S`9Vdb8^P9l(hGTg$se~ib=s-a=NRry0h`5YyJ5)f~47|(48FLVHI7i{X|p-1+$ zp0O2M`{6Bu;2)6bZE@Nq;dF34)DUgCVwM<52<9DVQxAfQROVFTJ!@-@oe2_-yn~EJ zdnntPJ`8zGTY5Hh-LlU{kg3M4X{*K&#;h_`aOP8|i)Bj9tyvE3mXz_lN#g$lRZxQmH&2X~x zi8JylIE?W0D6No2O%RAapVBz1<6FvUQv+9xxD&kCI6weGi<&s)1GD_dvosjS%RO5 zUjA*4=Iv|VUi|Mk@zh_MoD*p(S^Y<_!MnesXeg1Y;O&AH1&Q*jw{tdjb8g z*EW!R1vANqV0rD{AKXX|jJYTh2({W1_9Z_?yN83ueQf}zIPHE+Ai41A1mXtr4*WD{ zv+ny*TDq0DH`P28r7FklQ7O?HMSan3Q(K^;!H7up2<}J~EFD6drN-T>IzK?ldtSGF zRkFBYiY#4b5tjj*OB72&^+k4YKgzZvm)rm~%9O&UQOLv*j464fVLz&3+;L?&pu1rY zOC}}LN#MPlB6c$l& z=NJ*I8>%Rn0qI42T(Yx*f4U?0>K0rEMxo?>!+%^AwUodfFgcZp+@Wp7Wn7Lf4v$O9 zM?IE2iv(HRUvBUO)L8%8yZ1210hG zL;>wO*xBOQm7%jx2?lin`s{TdHrB22yRB!4r>U0yyJr`dU<+-1?!=6j$l(MO+7jEJ zUl3;}DWm);4iu&AaS7&TtNSD9iB%`#jB5;b8Ne~?*`HWeBrN}Ss~)t@ZkvpHX@?E0 zK7FTOH~%KpSVvg8h8}eif_%kLU!TPn%L4EeK6?^jXh zZzDwLVCt7QnJY5kQXx_%QV&TJN7lR;4&1KdH}hg+1Z-@BDCBeT)AooAe&5^2lv5rx zBi&T&&AK?PVQ@2*Y8`9g#xTJ)vkbSQ5TqTi$Z`dmVc#;aXW7)B>^E@MzP%7!dI2eC zRO3~fX0+_g~L23j^mSafIcS*5zs8HLY`PXx(Y~I$*=@nDL%QZkDP*%mPI)1 z3KXeiScaYeQl?g@5KBQfipMP%lMhp*kf5V7{)V6IwuPQ*8T>N7MItksC8HIr2wkXAWejhBTt+J0K!A&kqkowA#VqImM zh{C6+&o;qLE9`UUM08u)D=Uh1`E6$kU8QXm3SEV56AE3$Z8cC^aUTMRud>e(#8=wK zl)zow#}w}-5muDIo!zGd;``f&0phFZ^PwPCGR#6J0-dUC0}2%P)K{VCtqGyj(-mUs zVIc`_Kf+)W+=Rk(K&zE~-k{aeK7P<@d7lpGRXdC~;V}i>mAYCfY$ahar_UO+TGGb= zS}p5yp|DZhmY}ea-}azrps~+DU!c8GqNq^Vwxp;~G%Q6|qqPr0w+3lf^qGLPOZu=W z7!^c<_(g(%&+-2jxhim2A7B1|1@OObbpHkGzvAo**8d)%HEW7rEu)O1uD_W^8G8uf zIGj`c8QaPpPjB_LP$K{A?lshmBz?eEZuXrimIc3#F;)RabF?nlf+MMXdlgiu%2^R= z90?9Em}w3;F{){d)CC@;|L}l5{8iX59g&R9$`G2L6tM4TL#%`_qg`lPNLk1uUE8cf zc3{dfZfvPvVpd|5+RdIp)2BSD+^amU+|T~of_4V8a9BDnnUYl|)NL?efbDmL8 ztBOP$hA4dx7>Ax+l2|D|wi)eBb%ZbrWFn{+^Pt*~_e z>Znj5xb$0dEoq_8Y6X+hHzjZ-l0vV-b!qoiXGSIDhouObuJ~~sGnS|3jA)uTngE)N z;n8?(sWb?X2`DUI2AYD6qI$Y_*VKqq2_i0HG+i2*bAW9r<(IapNey$qeM-u3A0`1H zl>rkTmapm;DUDBnl#U^tA9rYYJX;#Nlm3!;ggc|a_!8{+VfainvmmV}u4pN&C!uI5 zq-S?dBAvxXv{f_7?V5aqI#Z;5?^@VdeN`!)#rzg@WK?l&HsRgZjKcFkRfv+jeo!OG z+CDfS$o!Uhq*LhHG;+cHpjFsNHp~VHb%v44!M69`QW5~;w=gp&(v|iJYALz~JEPJ} zEN|gQ;uY5rGdI7yqK-5Q^;n6FpP?7Lf*s}9i1aCB*{C`KYotb$=T97EgF076= zOQzg2^Y_&8#wx>yi^ZDyFQ@cKqp9`jLoOotTq?1^!!`xDZlf?KOg>l$)Ft6yrbcSx@LaCsZ39mL;v2n!s zM1|6lIUR10R?oc(@6aasrrd#5FQOUELJsND6jhe;-3qPdC-}lWG&uxwJXaUS1?~TU zC1GK03btdbxHN*hF+$UmSE0LhZIA_{5}Ojn3}NBYsS{cBFYFmx`)7=3?D0f&HzIPi#M2 z&Jy{Td>bDDAK!k?FIY?)DZ5*nGxRU_HZ2s=ZYm@xXv zm)`-1H-1PyB&b&8%^R9csZF>Q_>G+g)eWB&(1uZiN{6=)Y!%MEq#r-ECzMI6K?K;D z5U$&zN9M)16OWC6d87{5G6L_`vNW#;$OrHThzBrNNLP)QXCLGaj7PlXRq%BS{y|sX zTjawPU#%QlVLh(A%Co~0%0(L}8?Xx425?{jd?9yDZhC_wk*1@RLCIT91N*r_^ZZ)J zqIu9YEODn*o$gA99OQ))%o*ZSW94}0KQ%B_s6!w+|GTGUy48Mr;D+mb`SE-}U!=@L z)ZF{a4bHVmM7 zrhTSYzN8wYDN5&BA6)FLd9pumS86ZTboZtTSr7kHa=~w{e0>aLXD3>^rqN7VM_=c) zP&3txkQh8M0EUx9kI1lG&s>*ntZV*W;hvKi+nlo>TR4>-J1}*s^E*d_0x2h@6<_3z z!Z`=8Sg<{x6LVRGpoHcxyvjuhybQpQf}RTTvKt$gBh^Y7Oc@`E@Oy)Uk-Z_GRT=z% zW-aAhZXw+POz9sB`gJ(VTf6YZ%Q~4ZnS1X#q%K4EpZ%X~yS$3xOS8(=^mqQVrAi!< zBc(LK`XC>J09REO!{1k-;w5=-@OSz#B z3ZniP)CGC#?mlET6*@inMC zv(xxQbp)4Q1!^5nZ41`5WcSfUwWfY?+v5L1d{<)7-}$`TGpyM7D%hx>Nmp~1qCT7*vK?m?t~wMw z6gJq6pSutOGmbe-sxMF1uWYnr=rJgKUyp3$WN>L%5g`V7NM%TsE_QudX6R%@X$VRP z4Bx9RZhd-rIAyRsAv}N?1{Vp+Pf;J!4x1Sr7aS2b7@VR@UjGX-E-n-%B%~j>5Rm=l z5cU=t-VY)hB?jdd=Gs^LE9@aOl<%*v2$zroUonQj{(&>az~n>F2(iXMxq)%Td?5#8 z?1JO=b?ZW21f$aj-v(pThcNWR?c#1h$imkLgA!tw>!SSbx6=hQcClVag`cC?hb(wV;Y@%M$T)J-BcKtUcK>{!W5CTx|P+nkdD6eR4D36ero|`(G zM4PT%wtkI%8(_BJwh)~#>tMRDx{$iiy5PDnx)46lZC~2J_)z#@`4C>wxxc(ZxWTyL zbA$0g^T7dp;C#rZu*8t};6z=zn+p0UmtU#~LjRLyaNWMRp}K)BLa(B%!mc8$LarjM zLcbC=eKLz3Y!yZm(IWUN%qsjU#46%1SR07{ODUg>0wD-p0bT)90nq@V2B8LK-L=L{lhUboyei6i=UWtJjng^ zO#tUB)yF)sYgmQcyr#scpQ@&KsRdF;qG)C0zVQ+~e`o6awiQu^j{Pvw+Tfmypp+LFxJU7`a@n%)ykZhZ~3%%eL5mEEW~-F41s$qnlS zRA&9FUqo3s^l0(3>FH<+vf&^1$g}B8ahW<>WUD##P`6n~p!ZJCEa1OI<(G~=c3kq; z*uhh{sS(QR-AfKYy1dM_0m$~Bv^)(PIJ;esw6tbtoU8N}%llIg`9@N4aws2qPQH3B zxh+d;Lz1Xx-G(|YoV;h%xnw1f)Ra6m)vt`L<{spKUwgi|MRFpL-6VR9uce)v%+^?| zI61#3qB=gGy>b0FdBj-O&)=drme`tek>hFKa8aal3)Uffd>;O(TJ(_DYi6!j3Urwv zQy-SJU~)dZC!u{2csVcTcj&2!CeC|X{3iDge3gB2^QT6p@7dqtyKI}CSGHS(T@!{0 z{-2Xu!5)8n#F?f`Z-4IUP77v9o^yBv_{i8I@Xnsxs(BF?Ef@;qy5avOX(H+6+W^&G zVFhSe6x_qup#7F+j|3=ZFjJqnm#$jma<>d8iRIjzn=6l`+D4FeC7JaHP) z?m6vO)&ZP%Ze<2a*-jqz(x$1s*3rLN@{7oCiBdl6yD4lndcjg`{gy1IN*6gsHB^j$ zhkOQiM=r@t$dkw6@T4*kla3x+S*|2M&@h0qv8LVsL)TZw^bvJY7I$|qPH}fBE$;5_ z?rsC6xVuAfcXxMpx8m+n;0MdM+0A~N>?Y@rJ9j3Nd2jB#Wb*DgXN8l&ZJ=UKZ%r1v zz89BZJuWSN&0J*Z`6ODTcs3n4cA-p@g=5sdy44(R_LwszIUz=Qa`j;?qMUJEX!$lI zyP7E7e37rGo5OG994;9UT{3cU%zGP()mQc#iY%2%HCowk?Lj`{9q*jM$;2^NRpt_F zWb)sfS!1DzIV8PXoJm96q$L|ap$F}?)pvvy@TT99r@s|sLZzgoF@li*I$A3m7fKXo z;kNLs5a_mWmOZGbH`;<g;(rg@!M2-*~AGwWXI=Du0 zYlkv8CeLf^1pK<*p5jq}5#Ty#Gf5Ik<;OJ4yw5i|menJd5fnZ_C7b8#e)WIee+{nK zQV6MO%CIWES19eW4+#VEhEVP$37*Zs5K$2UVL`jfdZ4p->(jQAcd3 zu4_S4VMSiDd8mnAP3>7yB4LohjF*KJ$c^H8%PrE0i!US{geRFZR1hx??~SwRr5@2$ z=nA#!U#!GKj_&}c&PaI{b36A_Lp`CT!yn8Yb_Lb-6uuT5a8{SRMh$}|e=(;wv*gI( z^XipQv#_p~~*d@9TnpoEmS+3==p*9Rfp~?QWQv!WBCXEo zo7X%nV8{S+`w z@ULtmIsQSE+gLKQ>-raU`R=ok&8(1zgXz|%g!QsVL@l?E)~oZ=+6J20;cbAZc7Z2GKa2z48!6r?smV=NHAD->$E3-tX?_ z^>y4e{gcDQ;C6R&RuB>lW!BC^1x=DwOJ+2*Xb>5gZG>vpKFH14n_*yPKMAMj{%hIv zk{{rkO3O}-J!E%9W^V6j+tw9t)OyYmuV0f5Q|!jb_oEgA$wj_o;Xd%8`CZkTE0_ht zRb9x*$V6SBcDkFZ7mgvYzKGHC9^jgq?NKZ_I?=8%h4fon`g_7o`f8m{+L}Rx8 zRNhCHjdRxyAEd(SkccZcFD}0QEyR?%oLGFollRW|A5gEN35-UUd?5eB`70VY@Fx-3 z(367CTVu8a)c4E1Lv&v}c(H{~#L#=zrFDyYk}*5_Sm4Rbc&`@&N7qG9j%V^G5Zt!U z7+b8H!;sPeCZ7%DJ7&$=u&qj&=`T1;fvlzImbSTo{eOXc+b*qx;)Gky- z2WBS4EBGYbbr*;EyN3+c3#QOfbbMgE7UXmT_|roADwEIMRThM89L$DBexLX$#2ctKWol?e1&Nn{wRRaY?!~_&Cc9 zT%fwY0R~Q8t65oO)ao5n{b6Bt_C|!4VId2UB<_6&w*kp_v%|&`tlFe-T_4&Ey=ruKLZP}Y!xSKypHV#pmd3byZShO9} z18pYm+5NlGaz#_oH0!Q{WYqISSu)LnX=%xRAn37C!qmU9BqiK4mI?5x&||c6WAvp> z_s;ux$_H8W?xBLdPPbib?xKUU4E=0L85uYdQnxh!#RQ1Z&Us9fgDD1#GUZbvccv`^z;z@k1WW;JM?AW3spLE4ody?~xAjmDfB$Pg zXEd&R|8M(lZpX0gZNByR%qzb4w?D~6LwTj`Mflkw8xhU;(cy1TiMkaUtoIJZ*X&p@dv6OloaC%ik#crsF2!bIOb-*sh1qyn8xtT{V46NL zoNhxABbJ)Z?4^`cV$agOKa3>l9=1T6-|Wq#&-Kc-{jrj6jM~QAetps2u5u-T>#pcv z+&(=aXWha0EIh;fiF3nYz4^k~Yy+cxY{>$hEn6Z0VwLl3>8|G=tCK)yM!d9n7MJnqYT#cW2AKD@L8u)T zqvI$3ad1CxP*k5|U4obY*|m*Z=FOtw#i3Glt59*f%taOxgi}(u?KWl(i>c#Znb5sY2Zc%JF!q2wTr>3Z@k*&LM;$+!_dIL^x7J zIIx%R$G=T*6PPV~JQ4s|R!6z^p9u|?@z6ipAVRXU5v7N+VyEEBrJT1vx}{7t<=VUt zC(?MxbOG_uMy~#PmG^gdqeigMrQc&dD}CN^dRV zYOP1n?F;3qt=Vb+G% z0-**g*ti&0`4)J)zOJ>nyjD#!*q*MuFCLtz=4a&vQ+-1!H?8;GyZA@RTHYZ?1-8mhkEw@wFn>ZaZ>mT2PY%)1KklKQEX)qYW=@4 z9Z%TA9Ak`tkq}EvY#7RPknCl4485L7YuJ&VO&aIu67+9W+dRYbo&fTibg&UFPDHPhBzE3Ml75oV#%L zPok-nz7?%CkQR$0(BHF5botW)x7emoiP1`>N|nT?an3VN-a-!NF>>I-vsc@rL`_c9 z)HtKI169Bbu1Cru7(FyRJim96Y6Cs1(Ry^JIwYUJSv4D9Y*|mYTOX3yp(vfSbQ~Lt z=>79ow%9A`n%v2E7pOccDd1?Blv;$%;Cya+T=<&NcU#m-_))~@B$i~Q-z#T zIh+W$t~MxM6u_VO4M~C6xE?~0hVu9}-A43vRXYo&d5Kqw(u9hRz3NcH6mq_)15~gs ztE#GEGjvaiaXLdxY;I}>3{bF9vS%g7LZWfU`-s+ z*1xb;D$>HFI5^55V|agzcjT-7E+=YlPzkv6+5mGNRv(6bj4}ngx~#x9?pHodF!uUT*F@QDQZUk=6*H+IL$4a_?XxP%GsmvHn2u zo(^`(G|^31Bb}YL-&WkWf|rzsM=&=MsPnF&b4sfkTVM3lZPc-HCGu*ixQ=k9H?1Lc zKXhLTPa8{{??pf$w^PVX&JZizUx`^0J&SG)WrH|= zh;LmDdrs^;(>KHYhDv>cS^_5Ks{1vh+0EgyW}comNaSlGVwRuTqHg*8tcwWs3v-Sg zWC#D0j{HCv=U>5Z3di3oijkbn36}J1S6(dp7iNLru)+(d-ybzc+YiHsoFX4^A{i)0zm9YL35t<_EX+l<}J!Qy1--#RYN| zE+Rrss%Q3j@H>Byr$3qjcqC3;-LoCTfK2+smA5H4L3MO1t;|0&EmBUN`LApxROn@7 zbn6EL;%n%hc)41qv%jrRJ%NvG7E5Us>xDY}@PY;#zXLtXCuOb%_eZhNlo#)n+A#@_%biNdWyr!0?isPYT*k~Y1?&9(QRk3~?By!|=>aLPs4^g*@ z5H8^^v}tt_ns@EVoh%6r|B{QJ+Wu@&g|_m=qR0Y`i89Zv#1=%GetzRW zQ@q~Wcw~_THkwnrBW`*tyBI`0KnU|B3cr`CCKQ=1-~3^!sP=JEYl}fFFb9O6fx=BG zy!uOVcG7y7x~qoOv<_DkWy+W%rAus68pJUxOHam$S}nmz%I4o{^BqQ-7}kjlAJ2l; zUo}8cLE#@lm3>a1Jyt_RE?pWuIKJk2F2jRLf?7mrNWzV)9IG((e8GbU&>)M4zo#)~ zNKrkcU&}kvYg=w@gpRPBTBs-8hz#m&(jt{jM7f@|R zIETPzH(vO}lpw$cZhT4`Ts!=}o~^W188V+~G#Q?E8jO_+In7@$*`c@^Q=sZ5>AKw2 zY31ma+=-t`K;WHf&Chn4i~f|+N=j4naB@2 zLK|Be5qlh24V!@8Z~D6gch_09W5Ca9o-DlZ$96H3n{Rx#NfuRkk?V{oJmYI3+)3X<&*IO-)5OOqY_5w*$pK?L3<$Ue<9$l^%<$zGs2f2Qp53 z(`GxI^jLebkg%~#at#{k-|=FExWTwhw6Ur+rxZ`_JRe{0WayfKUU7M~ z;h9YLIOlq>u%O9Y?XRZ)ql3v4GLt>Qx!rLUkRAc1*0T#sKE~eupevV+k$36uT6Awm z=U2arQ9^t@0^eu%pICvOF)L2lq3Magq?@lCGp?2x@A4M}uk9n9yzBpIU}r_4Jgwjk z6g8&eIjUX&uFTD{QRg?d2Z<=jD7U1ELR1u0R2(*C{iWy#cj09GB3X@1)m66JKPo7Q zNEHF=YF&k8H)GLc3&`sJ%e@A26in^q`$gxp+TDQTvW)Nmyi#<_3`*51!rW+o+9Dc( za=sd)TE6uJo8xjc;f=_|LdJ6g@|#!_MK@HgvM<@4((0p+Mo%NtMiJ_9{TkY|Mw-bZ z*YB39n8w2Nc&tA;sw`?Fy(*~9S*{8apUuk z4k+9{&7doZtsn4|P>FvX*{SSA9ErlM6{F5SrsE_%yr*QqIpsl`5UeVNG`~`cX{O?# z2^j=zNyVOeI9spbWX2UBeJB@m2L$87>ue}*nDyTODdWMORzCUyj{TP(4RqU0SKh$u z&f0BcvG?%bzmHw9#Wlt^JJDTVUlyy_o)Dk5-2OthAoo5f+)Pc{wj#MlBX72rGH^Lk zKNd-&C{}~n)o}UZde7%}2p6IUN>K*a-LsUGbB$Q77je(kNiz&bV&!u~1MCokC`8klSE|ZIvhYniZ!L9)dBgYzMcPTaGn-qL=ps+4&9G7ZK$NVR|mv>zV z9d4X&t|_LZAmSNBQLu*%rTMJ7C_+!Sk3PO8m+(?3q{89k%F7KWiKOIxWhaxPbPVrw z#f`i?iz1uvqDi8Ixls91CGb8*nP_%B1~PNSA%C&8Yb*#zRdy-Mt6c_@OF4m^BO?Ml zO8nbzO8Lttgk2?*s@ogHX_M@=*^it#-!LEWEa4S1F8uVWm(MC($r+TVbw@ef4_?u+ zrOcU+C!HQfR_-ZpO*I_jJTzI&LJ;~RLhMQW+)_)W7~h0tX-5d>1N#yFRulwg+I;U$ z1eXdHo?%r96j`UpDW_nmpWICo;kXIZ;xE< zexr=LM&XWNHUZR0E2ZFtWxq!5#X6{h8xCQ=G*f+6Oa|4Zj!L(cVdv)eJxJlUn!3iK z>e+0E8O{mQ#Xuq*6yo=5}jPLnTWyGyeWH~u(BV)9og>) zd083&ndo&~WcXcV8xEc;6Kfgfc!^3{uZV?9Dr*W^px`{^ut7gXUW_FcsS8+wZUVk< zi-R8ArSXwC9l}@ z%$bkjRK@Z@@Dl^sWO#^2Z6;(_$#X1a|1)%_@N{aH$0o`yH`0Uej01`k*o?IexU#~3 zFua6OryI9p0s-#pBemP$AD-kNj@9BvaYuDYm@-bGYKBw-u){;&56A0GU}Dhk(f&&7 zoq)7v29g;f;3X&VD$kGvqL+}44 zH5_w(%4>THEb6x|IB)?T=<1i^M~9saYrFuc$WgvB}kDy@<)p{Y_0_?)WPi6 zaA?K8Uv}`hsK`pkp6doQusQ^Nt%w4#MzG?c*K{2iq;Edt8@N)~KP%ctXu%ca_6i(b zFIp;K=EsCGcNNa;967%-Ec2<437TPkng}$6TIJpe10qT$C*ZbD)S&l*ahVjoB0QZx zJJ+Hj0=jvn@{)nLx7=@^Mq^Z!T)2%nzBtr87Fny`D_P;a;B^Sm@j;2}78D=tTP67t zL=m-{h}d^%J&!;BRHBWE$rq=CU)PXRdB}U^CIjJ+DB51(w@1vZ2pdLrT<(10 z&hZ8$`|07eMz88tiVS|$*wV6c4Jdlr-hYyHVDqEV1jKHwaTE5A5P}f=C84(2N+~GQ z3f^c!msGB0C>vB;Q+O2g7EPmPWKMpL?Mu8sZ~%%w0x9*(-nYycN3sxF zf^*=2lyA=1skBC zr$Y@o-&EevL0LR~N6!4yiKK5N48~iF^-O%MtYa!SayI9$N(Zq0=+l~=zq~w3A&hj3 ziQ_`3m+{rsE@qnxq8Tvrab{^=NkM~u+kr8sMU`l~w*Xex3a9X)$n#llhd#v+e^{c7 zd(Gu43=P&*A?}nG-D9tbcgT9c_TN?XOFLBSDM%SNXo*5MgeF~W7PIg@d*dY>qkD#c z&AQi5m8@gA)}TN-x#BI4YX!=gNmCF%Lh?ifBN)Y;2c4kIf)@Jg#1DDIG^j@di;>=8 zpA(XW^Bi&=z%nSJ)RPTw>Qew;Aw6T}u;o<5zZ_G3vQUAI9=?se4$%5+%A>KYUl5>Y zFQ*LfZp@i;bZd-~9SHjeagXG7^AH4}CJ>b+KVX@ffihwk(73?)!M!m;+5!_R;zsDGPoLF|BxyN+{kuU(OV3UhG$;sE94b%rcp* zqv}Ez$#2};6=p0TJ(;>c_4!Ws?JY=UsM!s@$$b#$QM-=nQk%VCCHaO+=wYJkqC@BL zn(FZr0$;(6F?GPrxxNBL`>A_Kv7z@pwx{$P?^ItK5qJZ!bMj`B7O0Xj3ho<|5^`wqfrHSM)j4BT`<{Ete?ibK9bWIGH;v4{^8LvHamra&H@Jg!sa}i!!k1hjc}SDp4lQF1ZCQznc?MoGGmL*9s+1Qt_?g zEBr4Bkc9m#n~5Mm95!H#*6G7*__8;*Y+2D`NP^HW+*L%F2}eSF8ZS)0tYht zMLL>EHxd#Q=YVT`d^x9lte^Vof7BNr)kmAvH$_1i;X8(Ha76{L8A~m-nhM>4)2qnS zp(;MAQeuD(GV6a1c12`;)%m5(uJo_4a_js0996+lhg%4cLY_9sl(eMd)7kJ?ES7C5 z5f#1qSkJY!(f*Xu{rs=7K@8$Fsef)?Ep?WUIUjY_B^VV`TU)`G!$%;@oN9#9xq=W$ z!7SCTLZ!)a+)Y@|Vk!zgePG_q=it- zQiFyKE92m=9oX|WV}TAg8*Qo(QL?yWG@P6anXSCF`{%C)tz~I)2T^S4qLL`viNkYb zwP&e;u5RpYm(@KV;mBJrjM=`!b5wQmus+)hA@UsX2KJCh6)yq*Qk^1L>rkVgUVRp1 zLYCKR7s44Y0sAtH+TSaGGXF_RCZ4_gveg;0CMGy^&SWhi@8b_~$e>fAhN;4%!)ZNW zM}9TufGq5w#f}`vvF{LE;idA@XKMW5c$!@oE&^y@CgC%Z>~W`#yY3{s`@^C07{z+r ze>zq{x)t{Sh_)mAaRP#BsPxCiRH*XLgHlPQz>!ePU$*XO#JjK%>z^#?#4F5DWb1IW zLJ43-Gj`VJS-rlr^gvX!7a1Bok*9#@U~ZCMUS_+I6yay8I>``eGM)$?`^Wn=<3_!= zj_^Z#)egsjC1%5VAXq~+HZYrLVP-14Bxw%_7aF9-ks!*BU?*pOI7uGT-M;nLU2CmrtG(9ur~Se{EUY_!y@0Y%6P7hF zSLnZ9FB95hS^#l8#U?_`cgoMW7l3S*eJJT#(8?cA7qdS`emg7bcSvKb$fy{^K%4h+ zYkoRT>VJyH!=frA*+!AV@l86efY3nUwPl2tN0OJac^m!a)iJ0`)$UELJ6H8xhR*Gm zt)K(K0l}iMkMWtN6PU0}w-=%P?L-lvZe_7Jmg#JTeVnQDbtXap6~a%bKy6J13Rf;v{r;DYkMK;1<%jR-Q< z3^O?^rBaC(7lD9-xBodD5ZtWWYnGgp{OWO2DN=KOE z14|`P*1;ENJ$CkM-v0>N_C^XqXSh254q2pj~J3|Xl zlrC6EHI)*zkc!$WRQU}QsSNW6#R#T?~JQmKp+OxlsmWyuAv(B>Wse5z6rI#!PL@jgD-u zJwpiFTRsnJ^M$wAJWCO4&Bg|{>p;@?Q3*(DQ9IVec^ zij3OnJ`Bp2z1&pV_8JhN>Ti}(wHMjpEpvv& zn<9R@d8i5IZ}wnGX6wHhM%M*UQ{s&QDYPZGQrv%%2sXaExrW~KA)6b z*#2tvl$2v6TKuIb!^&$uoPNejbxBfPkFrt!3cgxUUo(MPRln@y*N!EFguzL@;UXW6qZRCQo;KmLP;#qri=lPF&638{AY2q0qfnDXj=3srt8;(}6?$1gcBQJxl)|`M&@#hGeq@gP3 z@?D=e%^Jh@4;b-z*Uib9*JG7k^D%qkYJt68Q+u_$v_5y|dGc&vjk*?+_0rYFrk+fT zv+?9bh8R8)HzyQ!!%CM?bHiiA8EfxlBN2id)94=pV2Qt`a_|r#b#iA>q_bCpd80G0 z*0d25`mrXAF@lr6(oz!pEh#M)TW_70u?^{iMZ_dU86 zo#ShYVA7hS24^68BTf4ES?+L8#f?C+I{$DU#fgBwZkWxvEm(s*klKW%3W;KtDDj0! ze_h_cV{=y(6o4hCf9 z2rWM5_tq~;tUK@$ZGsus3!?-w#XkwnVHr4R8b5kmWmE787F&$8CRcX?{c!fr5MicX zgi}&Lsu~!RBeZ$2+z;sY^6@DYtkg zTcP8A-6;>;5r66m6T}!2hVI}K29|SEPa;0@RJ6u2Yzr0b{hK9l;3dvPs^O1_o?N?f z-2iVPYz4L|ZQ}^A20;SZAEF!Y|3VQ-#iCC!8A0IAwY4R|G39%ILBC3ogQezrBH5}2 zNMsI3dg%Cmk`WxOD2;7juL4_sWS0^->kaYlr7)kF%!js@I8FS!QO7z|jE$(}JE}Dt zgbdelYa!WCZ(NA)Lb5WVwj0-3+7XncusiaZZ zOzw)9WaU#p=t@69zk5=+u44%MH&pgKvHP~ZQjIp4Obsc>yy!BQOn!8k z;VIN!rn;FXDbutEI@N+&PSH5k=4)gI@6YeurCnQFy}q~{R%0uOS3Vd6Fx~Cc0!zx) zP$sp!oU4rumh-;l)}x0ZoR@EF=^}g4)b_ZqZ(iSeg$OP;HI6m6cU>E+E{NV)J>C92 zb$MASopgVT7cK4Z1E!oRD5S$QCH3s+}Ai64Ons~S!s zTCk_vPx>#pVtJqjR!M`^6q)T%K_ObmtqjlIIjC~`aWF^YZnvNVGVNH*&dxo{?@zxD zu9JFZS$*DPz^-BqFA!mg`nFX9TOMhz!JyBOp==(Ud!F6}46ZUU-Un~yS-F>arjvTH zQbRnSKQNmn;7}ksPSV{_zz7p}kFwLt`{rm@P_8wwI{x^lJTiXdUvFSthkRh{c+Wi* zd{BQ_qdxmEW}Qcl6S`Cj(EqRCfxT;) zjqHSVlD+Bvgk1T`)OY(Cx$ks6h#z=sZqL|YW}&azun?p@=7PW7h-#tN;NBP;!CvH^ zhd$tKU+-UM>;kZOcD=WQ9*0i0(d1grC@s|ceKH-Gpe_c0d;33|UwoN1UIiP#eYOy` zBi0Rj0#j1`H9gUIK-dk06Jrq@*9?05IqxtQ3G+vPKph(Z;x-hW7t|WbXbyn(^g->Y z4?&{pdeQ#Gb0?6%{MG0Wy9~(x5BndbgP>61d@^C&S_zq|G{iI?VZq=uNeTZR7BZwQ z9X>7VxHV2dYrJvEyi%`J%bNNJhLv+?NeSkx(kK7br~vb>!;|N!dx?iF?Yq?p=;3`! zbMs^M=)7}T@2vYt>nO6oyl2Re1?%MliW^x^#;0Y`tmlG^6sFGL9HK0Y)9(YqrB?b{dOo|dHsUPJcbJ)J#R4m+GFRzg~Xrp zu`_l z3f3L-_)%&9kU~t2g*ANnRAx-2e z8pNMER-8MvMpfUV8!8w^AJ?}bFk!qG*pv1*Z`6jkV3Uw zH#o0k@ixii(h1IY5HIM_B0;X(VQpe%Xt~*;Gl8XQ{wiK@{NcA;_rzM|{8iKA@jYN& z*~tr%v(6z#BfU;T(5b41!am#nf?iHq!wZJH&A*N~?F@~e>F`hzF$Cb$F!kQhH7fLx>9MxIK;xd>!}z0tUdf>O0K@{= z@Lst-eh`ZR+H%+jF1-)&v1q}7!LDMiBr$Kx5GC2fos;?)3mt0($kl#G{3$ z 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ⅆ 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%0APx;;) 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 diff --git "a/fll\342\200\223FortranLinkedListLibrary.pptx" "b/fll\342\200\223FortranLinkedListLibrary.pptx" index 1a2bf23c4a09174afb4d217c91089f1853ebe7ba..7e2b6a1ee4aef8b7e71c99dde7fc50a56e559409 100644 GIT binary patch delta 50533 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 z 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

?hI17)? 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 K@E#X}0sarzQ1$Ep From 2580c48f7d30807fff39b00042ec84c70d7b4962 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 13 Nov 2016 20:52:39 -0700 Subject: [PATCH 090/325] update dependency file --- data_util/project.dep | 168 ++++++++++----------- examples/Simple_data_operation/project.dep | 4 +- mpi_util/project.dep | 24 +-- python_dep/fort_depend.py | 89 +++++++---- 4 files changed, 159 insertions(+), 126 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index d2272c1..84b9a7d 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,126 +1,124 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ +fll_nnodes.o : \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_funct_prt.o -fll_nnodes.o : \ - fll_funct_prt.o \ +fll_mv.o : \ + fll_type.o \ + fll_stich.o \ fll_out.o \ - fll_type.o + fll_rm.o -fll_mkdir.o : \ +fll_read_ffa.o : \ + fll_type.o \ + fll_mv.o \ + fll_out.o \ fll_mk.o \ - fll_type.o + fll_funct_prt.o -fll_cat.o : \ - fll_out.o \ - fll_type.o +fll_write.o : \ + fll_type.o \ + fll_out.o -fll_type.o : +fll_match_pattern.o : \ + fll_type.o \ + fll_out.o -fll_stich.o : \ - fll_out.o \ - fll_type.o +fll_deattach.o : \ + fll_type.o \ + fll_stich.o \ + fll_out.o -fll_funct_prt.o : \ +fll_duplicate.o : \ + fll_type.o \ + fll_mv.o \ fll_out.o \ - fll_type.o + fll_mk.o -fll_sweep.o : \ - fll_match_pattern.o \ - fll_out.o \ - fll_type.o +fll_cat.o : \ + fll_type.o \ + fll_out.o -fll_read.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o +fll_write_ffa.o : \ + fll_type.o \ + fll_out.o -fll_cp.o : \ +fll_mk.o : \ + fll_type.o \ + fll_out.o + +fll_read.o : \ + fll_type.o \ fll_mv.o \ - fll_cat.o \ fll_out.o \ - fll_duplicate.o \ - fll_rm.o \ - fll_stich.o \ - fll_type.o + fll_mk.o \ + fll_funct_prt.o -fll_mv.o : \ - fll_stich.o \ - fll_out.o \ - fll_rm.o \ - fll_type.o +fll_stich.o : \ + fll_type.o \ + fll_out.o -fll_write.o : \ - fll_out.o \ - fll_type.o +fll_funct_prt.o : \ + fll_type.o \ + fll_out.o -fll_getndata.o : \ - fll_locate.o \ - fll_out.o \ - fll_type.o +fll_mkdir.o : \ + fll_type.o \ + fll_mk.o -fll_match_pattern.o : \ - fll_out.o \ - fll_type.o +fll_rm.o : \ + fll_type.o \ + fll_stich.o \ + fll_out.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ +fll_sweep.o : \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_match_pattern.o fll_locate.o : \ - fll_funct_prt.o \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_funct_prt.o -fll_duplicate.o : \ +fll_cp.o : \ + fll_stich.o \ fll_mv.o \ - fll_mk.o \ + fll_rm.o \ + fll_cat.o \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_duplicate.o + +fll_getndata.o : \ + fll_type.o \ + fll_out.o \ + fll_locate.o fll_mods.o : \ - fll_mv.o \ + fll_match_pattern.o \ + fll_getndata.o \ fll_deattach.o \ - fll_mkdir.o \ + fll_mv.o \ + fll_stich.o \ + fll_rm.o \ + fll_cp.o \ fll_cat.o \ - fll_duplicate.o \ + fll_read_ffa.o \ fll_write.o \ - fll_match_pattern.o \ - fll_locate.o \ - fll_sweep.o \ - fll_rm.o \ + fll_nnodes.o \ fll_write_ffa.o \ + fll_out.o \ fll_funct_prt.o \ - fll_stich.o \ - fll_cp.o \ - fll_mk.o \ + fll_locate.o \ fll_type.o \ - fll_nnodes.o \ + fll_duplicate.o \ + fll_mkdir.o \ fll_read.o \ - fll_getndata.o \ - fll_out.o \ - fll_read_ffa.o - -fll_rm.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o - -fll_mk.o : \ - fll_out.o \ - fll_type.o + fll_mk.o \ + fll_sweep.o fll_out.o : \ fll_type.o - -fll_write_ffa.o : \ - fll_out.o \ - fll_type.o diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/project.dep index 4b1a81c..248c2d0 100644 --- a/examples/Simple_data_operation/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -4,5 +4,5 @@ fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - ../../data_util/fll_mods.o \ - fll_test_subr.o + fll_test_subr.o \ + ../../data_util/fll_mods.o diff --git a/mpi_util/project.dep b/mpi_util/project.dep index bbbf0ad..c2dc1d6 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,22 +1,22 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_mv.o : \ - fll_mpi_cp.o \ - ../data_util/fll_out.o \ - ../data_util/fll_rm.o \ - ../data_util/fll_type.o - -fll_mpi_cp_all.o : \ +fll_mpi_cp.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_mk.o \ + ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_type.o + ../data_util/fll_mk.o fll_mpi_mods.o : \ fll_mpi_cp_all.o -fll_mpi_cp.o : \ +fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_mk.o \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mk.o + +fll_mpi_mv.o : \ + ../data_util/fll_rm.o \ + ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_type.o + fll_mpi_cp.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 870d12d..25a372e 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -19,7 +19,7 @@ #Definitions -def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() @@ -29,11 +29,23 @@ def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build= print(" ") print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") - - ff=get_all_files(path=path) +# +# get rid of ../ in deps +# + if not(dep == None): + dep = [w.replace('../', ' ') for w in dep] +# +# get files where to look for modules +# + ff=get_all_files(path=path, dep =dep) + + print(" ") + print(" Looking for modules in files:") + print(ff) + l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) - depends=get_depends(fob=l,m2f=mod2fil,ffiles=ff) + depends=get_depends(cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) if verbose: for i in depends.keys(): @@ -91,25 +103,34 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' print(" ") return -def get_source(ext=[".f90",".F90"]): +def get_source(ext=[".f90",".F90",".f",".F"]): "Return all files ending with any of ext" tmp=os.listdir(".") + fil=[] for i in ext: fil.extend(filter(lambda x: x.endswith(i),tmp)) return fil -def get_all_files(path): +def get_all_files(path,dep): matches = [] for root, dirnames, filenames in os.walk(path): - for filename in fnmatch.filter(filenames, '*.f90'): - matches.append(os.path.join(root, filename)) + + if not(dep == None): + for i in dep: + if i.strip() in root: + for filename in fnmatch.filter(filenames, '*.f*'): + matches.append(os.path.join(root, filename)) + + else: + for filename in fnmatch.filter(filenames, '*.f*'): + matches.append(os.path.join(root, filename)) return matches def check_if_there(use,file): "return if you see module name" - with open(file) as f: + with open(file, errors='ignore') as f: for line in f: if "module" in line.lower(): extrline = line.lower() @@ -129,6 +150,8 @@ def create_file_objs(files=None, macros={}): if files is None: files = get_source() + files = get_source() + for i in files: source_file = file_obj() @@ -146,7 +169,7 @@ def get_uses(infile=None, macros={}): uses=[] - with open(infile,'r') as f: + with open(infile,'r', errors='ignore') as f: t=f.readlines() for i in t: @@ -170,7 +193,7 @@ def get_contains(infile=None): contains=[] - with open(infile,'r') as f: + with open(infile,'r', errors='ignore') as f: t=f.readlines() for i in t: @@ -189,8 +212,9 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(fob=[],m2f=[], ffiles=[]): +def get_depends(cwd,fob=[],m2f=[], ffiles=[]): deps={} + istat = 0 for i in fob: tmp=[] for j in i.uses: @@ -199,28 +223,37 @@ def get_depends(fob=[],m2f=[], ffiles=[]): # module is in the same directory # tmp.append(m2f[j.lower()]) + istat = 1 except KeyError: # # module is not, loop through all other files # istat = 0 for k in ffiles: - retval=check_if_there(use=j,file=k) - if retval > 0: - istat = 1 - name=os.path.splitext(k)[0]+'.o' - tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + dir,fil=os.path.split(k) + dir = dir+ "/" + retval = 0 + + if not(cwd.strip() == dir): + retval=check_if_there(use=j,file=k) + + if retval > 0: + istat = 1 + name=os.path.splitext(k)[0]+'.o' + tmp.append(name.lower()) + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") + print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + break if istat== 0 and not(j == ""): - print("") - print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print("") - - deps[i.file_name]=tmp + print("") + print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print("") + + if not(istat == 0): + deps[i.file_name]=tmp return deps @@ -272,6 +305,7 @@ def __init__(self): parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') + parser.add_argument('-d','--dep_dir',nargs='+',action='append',help='Preferred dependecy directory') # Parse the command line arguments args = parser.parse_args() @@ -287,9 +321,10 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' root_dir = args.root_dir[0] if args.root_dir else None + dep_dir = args.dep_dir[0] if args.dep_dir else None if not root_dir: print ("\033[031mError: \033[039m missing path to project root directory \033[032m") sys.exit() - run(path=root_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(path=root_dir, dep=dep_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From cd6a88afb6298d1cd7c3be749505298f449a8d0d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 13 Nov 2016 22:15:08 -0700 Subject: [PATCH 091/325] add prototype of function --- data_util/fll_getnbytes.f90 | 332 ++++++++++++++++++++++++++++++++++++ data_util/project.dep | 178 +++++++++---------- 2 files changed, 424 insertions(+), 86 deletions(-) create mode 100644 data_util/fll_getnbytes.f90 diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 new file mode 100644 index 0000000..0d2880f --- /dev/null +++ b/data_util/fll_getnbytes.f90 @@ -0,0 +1,332 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +! +! +MODULE FLL_GETNBYTES_M +! +! Description: Counts byte length of the list +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) +! +! Description: Get size of linked list in bytes +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In node to duplicate +! BYTES Out size of list +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: BYTES +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCHILD +! +! BODY OF SUBROUTINE +! +! +! check the node is not null +! + PNEW => NULL() + FPAR%SUCCESS = .FALSE. + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + PCHILD => PNODE%PCHILD +! +! IF NODE HAS CHILDREN, GETNBYTES ALL OF THEM +! + IF(ASSOCIATED(PCHILD))THEN + PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + CALL FLL_GETNBYTES_RECURSIVE_NODE(PCHILD,PNEW,FPAR) + IF(.NOT.FPAR%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - error duplicting children nodes ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + ELSE +! +! NODE IS A FILE NODE +! + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + CALL FLL_GETDATALENGTH(PNODE, PNEW,FPAR) + + END IF + + FPAR%SUCCESS = .TRUE. + RETURN + + END FUNCTION FLL_GETNBYTES +! +! DELETE CHID WITH ALL ITS CHILDREN +! + RECURSIVE FUNCTION FLL_GETNBYTES_RECURSIVE_NODE(PNODE,PDUPL,FPAR) RESULT(BYTES) +! +! Description: makes recursive duplicate of PNODE +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer which is to be duplicated +! PDUPL Out duplicate of PNODE +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PDUPL + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! + TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD + LOGICAL :: OK +! + PCURR => PNODE + PCHILD => PNODE%PCHILD +! +! LOOP OVER CHILDREN +! + DO WHILE(ASSOCIATED(PCURR)) + + PNEXT => PCURR%PNEXT + PCHILD=> PCURR%PCHILD + + IF(.NOT.ASSOCIATED(PNEW))THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNEW => NULL() + RETURN + END IF + + IF(.NOT.ASSOCIATED(PCHILD))THEN + CALL FLL_GETDATALENGTH(PCURR, PNEW, FPAR) + ELSE +! +! NODE HAS CHILDREN +! + DO WHILE(ASSOCIATED(PCHILD)) + + CALL FLL_GETNBYTES_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + IF(.NOT.FPAR%SUCCESS) STOP'GETNBYTES - Error duplicating nodes' + PCHILD => PCHILD%PNEXT + + END DO + + END IF +! +! ADD TO PDUPL LIST +! + OK = FLL_MV(PNEW,PDUPL,FPAR) + PCURR => PNEXT + + END DO + + FPAR%SUCCESS = .TRUE. + RETURN + + END FUNCTION FLL_GETNBYTES_RECURSIVE_NODE +! +! +! + FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) +! +! Description: duplicated data of the node +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In pointer data which is to be duplicated +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PNEW + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! + INTEGER(LINT) :: NDIM, NSIZE, NNDIM, NNSIZE +! +! IF DIR NODE, RETURN +! + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR. TRIM(PNODE%LTYPE) == 'N') RETURN +! +! 1D ARRAYS +! + IF(ASSOCIATED(PNODE%R1))THEN + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + BYTES = 4*NDIM + RETURN + END IF +! + IF(ASSOCIATED(PNODE%D1))THEN + NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) + BYTES = 8*NDIM + RETURN + END IF + IF(ASSOCIATED(PNODE%I1))THEN + NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) + BYTES = 4*NDIM + RETURN + END IF + IF(ASSOCIATED(PNODE%L1))THEN + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + BYTES = 8*NDIM + RETURN + END IF + IF(ASSOCIATED(PNODE%S1))THEN + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + BYTES = NAME_LENGTH*NDIM + RETURN + END IF +! +! 2D ARRAYS +! + IF(ASSOCIATED(PNODE%R2))THEN + NDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) + BYTES = 4*NDIM*NSIZE + RETURN + END IF + + IF(ASSOCIATED(PNODE%D2))THEN + NDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) + BYTES = 8*NDIM*NSIZE + RETURN + END IF + + IF(ASSOCIATED(PNODE%I2))THEN + NDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) + BYTES = 4*NDIM*NSIZE + RETURN + END IF + + IF(ASSOCIATED(PNODE%L2))THEN + NDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) + BYTES = 8*NDIM*NSIZE + RETURN + END IF + + IF(ASSOCIATED(PNODE%S2))THEN + NDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) + NSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) + BYTES = NAME_LENGTH*NDIM*NSIZE + RETURN + END IF +! +! SCALARS AND STATICALLY DEFINED ARRAYS +! + SELECT CASE(PNODE%LTYPE) + CASE('R') + BYTES = 4 + CASE('D') + BYTES = 8 + CASE('I') + BYTES = 4 + CASE('L') + BYTES = 8 + CASE('S') + BYTES = NAME_LENGTH + END SELECT + + RETURN + + END FUNCTION FLL_GETDATALENGTH + + +END MODULE FLL_GETNBYTES_M diff --git a/data_util/project.dep b/data_util/project.dep index 84b9a7d..7951c50 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,124 +1,130 @@ # This file is generated automatically. DO NOT EDIT! -fll_nnodes.o : \ - fll_type.o \ +fll_out.o : \ + fll_type.o + +fll_getndata.o : \ fll_out.o \ - fll_funct_prt.o + fll_locate.o \ + fll_type.o -fll_mv.o : \ - fll_type.o \ - fll_stich.o \ +fll_mods.o : \ + fll_nnodes.o \ + fll_read_ffa.o \ fll_out.o \ - fll_rm.o + fll_rm.o \ + fll_funct_prt.o \ + fll_sweep.o \ + fll_write.o \ + fll_cat.o \ + fll_mk.o \ + fll_mkdir.o \ + fll_cp.o \ + fll_stich.o \ + fll_getndata.o \ + fll_duplicate.o \ + fll_deattach.o \ + fll_read.o \ + fll_match_pattern.o \ + fll_locate.o \ + fll_mv.o \ + fll_write_ffa.o \ + fll_type.o fll_read_ffa.o : \ - fll_type.o \ - fll_mv.o \ fll_out.o \ + fll_funct_prt.o \ + fll_mv.o \ fll_mk.o \ - fll_funct_prt.o - -fll_write.o : \ - fll_type.o \ - fll_out.o - -fll_match_pattern.o : \ - fll_type.o \ - fll_out.o + fll_type.o -fll_deattach.o : \ - fll_type.o \ +fll_cp.o : \ + fll_out.o \ + fll_rm.o \ + fll_cat.o \ fll_stich.o \ - fll_out.o - -fll_duplicate.o : \ - fll_type.o \ + fll_duplicate.o \ fll_mv.o \ + fll_type.o + +fll_sweep.o : \ fll_out.o \ - fll_mk.o + fll_match_pattern.o \ + fll_type.o -fll_cat.o : \ - fll_type.o \ - fll_out.o +fll_locate.o : \ + fll_out.o \ + fll_funct_prt.o \ + fll_type.o -fll_write_ffa.o : \ - fll_type.o \ - fll_out.o +fll_mv.o : \ + fll_out.o \ + fll_rm.o \ + fll_stich.o \ + fll_type.o -fll_mk.o : \ - fll_type.o \ - fll_out.o +fll_deattach.o : \ + fll_out.o \ + fll_stich.o \ + fll_type.o -fll_read.o : \ - fll_type.o \ - fll_mv.o \ +fll_getnbytes.o : \ fll_out.o \ + fll_mv.o \ fll_mk.o \ - fll_funct_prt.o + fll_type.o -fll_stich.o : \ - fll_type.o \ - fll_out.o +fll_mk.o : \ + fll_out.o \ + fll_type.o -fll_funct_prt.o : \ - fll_type.o \ - fll_out.o +fll_duplicate.o : \ + fll_out.o \ + fll_mv.o \ + fll_mk.o \ + fll_type.o fll_mkdir.o : \ - fll_type.o \ - fll_mk.o + fll_mk.o \ + fll_type.o + +fll_nnodes.o : \ + fll_out.o \ + fll_funct_prt.o \ + fll_type.o fll_rm.o : \ - fll_type.o \ + fll_out.o \ fll_stich.o \ - fll_out.o + fll_type.o -fll_sweep.o : \ - fll_type.o \ +fll_write_ffa.o : \ fll_out.o \ - fll_match_pattern.o + fll_type.o -fll_locate.o : \ - fll_type.o \ +fll_read.o : \ fll_out.o \ - fll_funct_prt.o - -fll_cp.o : \ - fll_stich.o \ + fll_funct_prt.o \ fll_mv.o \ - fll_rm.o \ - fll_cat.o \ + fll_mk.o \ + fll_type.o + +fll_write.o : \ fll_out.o \ - fll_type.o \ - fll_duplicate.o + fll_type.o -fll_getndata.o : \ - fll_type.o \ +fll_funct_prt.o : \ fll_out.o \ - fll_locate.o + fll_type.o -fll_mods.o : \ - fll_match_pattern.o \ - fll_getndata.o \ - fll_deattach.o \ - fll_mv.o \ - fll_stich.o \ - fll_rm.o \ - fll_cp.o \ - fll_cat.o \ - fll_read_ffa.o \ - fll_write.o \ - fll_nnodes.o \ - fll_write_ffa.o \ +fll_match_pattern.o : \ fll_out.o \ - fll_funct_prt.o \ - fll_locate.o \ - fll_type.o \ - fll_duplicate.o \ - fll_mkdir.o \ - fll_read.o \ - fll_mk.o \ - fll_sweep.o + fll_type.o -fll_out.o : \ +fll_cat.o : \ + fll_out.o \ + fll_type.o + +fll_stich.o : \ + fll_out.o \ fll_type.o From 415052864d098ba0f3b80f3ddf4f753ae7920e48 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 07:46:49 -0700 Subject: [PATCH 092/325] opening file for python 2 and python 3 --- python_dep/fort_depend.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 25a372e..0a53d67 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -130,7 +130,9 @@ def get_all_files(path,dep): def check_if_there(use,file): "return if you see module name" - with open(file, errors='ignore') as f: + + if sys.version_info < (3,0): + with open(file) as f: for line in f: if "module" in line.lower(): extrline = line.lower() @@ -138,7 +140,15 @@ def check_if_there(use,file): if use.lower().strip() == extrline.strip(): f.close() return 1 - + else: + with open(file) as f: + with open(file, errors='ignore') as f: + if "module" in line.lower(): + extrline = line.lower() + extrline = extrline.replace("module", "") + if use.lower().strip() == extrline.strip(): + f.close() + return 1 f.close() return 0 @@ -169,7 +179,11 @@ def get_uses(infile=None, macros={}): uses=[] - with open(infile,'r', errors='ignore') as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r',errors='ignore') as f: t=f.readlines() for i in t: @@ -193,7 +207,12 @@ def get_contains(infile=None): contains=[] - with open(infile,'r', errors='ignore') as f: +# with open(infile,'r', errors='ignore') as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r', errors='ignore') as f: t=f.readlines() for i in t: From 5fc408f3262b0c63286734cc21e8a7f3fa1d5800 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 08:00:40 -0700 Subject: [PATCH 093/325] add comments to python script --- python_dep/fort_depend.py | 44 ++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 0a53d67..4d3c363 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -36,8 +36,11 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= dep = [w.replace('../', ' ') for w in dep] # # get files where to look for modules +# if list of preferred directories is specified in dep +# list only these files, otherwise +# list all file in path dir # - ff=get_all_files(path=path, dep =dep) + ff=get_all_files(path=path, dep=dep) print(" ") print(" Looking for modules in files:") @@ -45,7 +48,10 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) - depends=get_depends(cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) +# +# make dependencies +# + depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) if verbose: for i in depends.keys(): @@ -62,7 +68,9 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): "Write the dependencies to outfile" - #Test file doesn't exist +# +#Test file doesn't exist +# if os.path.exists(outfile): if not(overwrite): print ("\033[031mWarning file exists.\033[039m") @@ -73,8 +81,9 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' pass else: return - - #Open file +# +#Open file +# print(" ") print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") print(" ") @@ -112,16 +121,24 @@ def get_source(ext=[".f90",".F90",".f",".F"]): fil.extend(filter(lambda x: x.endswith(i),tmp)) return fil -def get_all_files(path,dep): +def get_all_files(path,dep): +# +# list all fortran files +# matches = [] for root, dirnames, filenames in os.walk(path): - +# +# specified list of preferred directories +# list only those +# if not(dep == None): for i in dep: if i.strip() in root: for filename in fnmatch.filter(filenames, '*.f*'): matches.append(os.path.join(root, filename)) - +# +# otherwise include all files from path dir +# else: for filename in fnmatch.filter(filenames, '*.f*'): matches.append(os.path.join(root, filename)) @@ -207,7 +224,6 @@ def get_contains(infile=None): contains=[] -# with open(infile,'r', errors='ignore') as f: if sys.version_info < (3,0): with open(infile,'r') as f: t=f.readlines() @@ -220,7 +236,7 @@ def get_contains(infile=None): if tmp: contains.append(tmp.group('modname').strip()) - # Remove duplicates before returning +# Remove duplicates before returning return list(set(contains)) def file_objs_to_mod_dict(file_objs=[]): @@ -231,7 +247,7 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(cwd,fob=[],m2f=[], ffiles=[]): +def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} istat = 0 for i in fob: @@ -239,13 +255,14 @@ def get_depends(cwd,fob=[],m2f=[], ffiles=[]): for j in i.uses: try: # -# module is in the same directory +# module is in the same directory, include it # tmp.append(m2f[j.lower()]) istat = 1 except KeyError: # -# module is not, loop through all other files +# module is not, loop through all other files specified in ffiles +# these are files found in function get_all_files # istat = 0 for k in ffiles: @@ -263,7 +280,6 @@ def get_depends(cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") - break if istat== 0 and not(j == ""): print("") From 7b704cbee5a3b8d735509bd3f8a8b5e2ed47475a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 08:00:56 -0700 Subject: [PATCH 094/325] modified dependencies --- data_util/project.dep | 130 ++++++++++----------- examples/Simple_data_operation/project.dep | 8 +- mpi_util/project.dep | 24 ++-- 3 files changed, 81 insertions(+), 81 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index 7951c50..4ec9344 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,130 +1,130 @@ # This file is generated automatically. DO NOT EDIT! -fll_out.o : \ +fll_deattach.o : \ + fll_stich.o \ + fll_out.o \ fll_type.o -fll_getndata.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_out.o \ - fll_locate.o \ fll_type.o -fll_mods.o : \ - fll_nnodes.o \ - fll_read_ffa.o \ +fll_getnbytes.o : \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ - fll_rm.o \ - fll_funct_prt.o \ - fll_sweep.o \ - fll_write.o \ - fll_cat.o \ + fll_type.o + +fll_mkdir.o : \ fll_mk.o \ - fll_mkdir.o \ - fll_cp.o \ - fll_stich.o \ - fll_getndata.o \ - fll_duplicate.o \ - fll_deattach.o \ - fll_read.o \ - fll_match_pattern.o \ - fll_locate.o \ - fll_mv.o \ - fll_write_ffa.o \ fll_type.o -fll_read_ffa.o : \ +fll_cat.o : \ fll_out.o \ - fll_funct_prt.o \ - fll_mv.o \ - fll_mk.o \ fll_type.o -fll_cp.o : \ +fll_stich.o : \ fll_out.o \ - fll_rm.o \ - fll_cat.o \ - fll_stich.o \ - fll_duplicate.o \ - fll_mv.o \ fll_type.o -fll_sweep.o : \ +fll_funct_prt.o : \ fll_out.o \ - fll_match_pattern.o \ fll_type.o -fll_locate.o : \ +fll_sweep.o : \ + fll_match_pattern.o \ fll_out.o \ + fll_type.o + +fll_read.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ fll_type.o -fll_mv.o : \ +fll_cp.o : \ + fll_mv.o \ + fll_cat.o \ fll_out.o \ + fll_duplicate.o \ fll_rm.o \ fll_stich.o \ fll_type.o -fll_deattach.o : \ - fll_out.o \ +fll_mv.o : \ fll_stich.o \ + fll_out.o \ + fll_rm.o \ fll_type.o -fll_getnbytes.o : \ +fll_write.o : \ fll_out.o \ - fll_mv.o \ - fll_mk.o \ fll_type.o -fll_mk.o : \ +fll_getndata.o : \ + fll_locate.o \ fll_out.o \ fll_type.o -fll_duplicate.o : \ +fll_match_pattern.o : \ fll_out.o \ - fll_mv.o \ - fll_mk.o \ fll_type.o -fll_mkdir.o : \ +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ fll_mk.o \ - fll_type.o - -fll_nnodes.o : \ fll_out.o \ - fll_funct_prt.o \ fll_type.o -fll_rm.o : \ +fll_locate.o : \ + fll_funct_prt.o \ fll_out.o \ - fll_stich.o \ fll_type.o -fll_write_ffa.o : \ +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_read.o : \ - fll_out.o \ - fll_funct_prt.o \ +fll_mods.o : \ fll_mv.o \ + fll_deattach.o \ + fll_mkdir.o \ + fll_cat.o \ + fll_duplicate.o \ + fll_write.o \ + fll_match_pattern.o \ + fll_locate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_write_ffa.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_cp.o \ fll_mk.o \ - fll_type.o - -fll_write.o : \ + fll_type.o \ + fll_nnodes.o \ + fll_read.o \ + fll_getndata.o \ fll_out.o \ - fll_type.o + fll_read_ffa.o -fll_funct_prt.o : \ +fll_rm.o : \ + fll_stich.o \ fll_out.o \ fll_type.o -fll_match_pattern.o : \ +fll_mk.o : \ fll_out.o \ fll_type.o -fll_cat.o : \ - fll_out.o \ +fll_out.o : \ fll_type.o -fll_stich.o : \ +fll_write_ffa.o : \ fll_out.o \ fll_type.o diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/project.dep index 248c2d0..0bbc702 100644 --- a/examples/Simple_data_operation/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! -fll_test_subr.o : \ - ../../data_util/fll_mods.o - fll_test.o : \ - fll_test_subr.o \ + ../../data_util/fll_mods.o \ + fll_test_subr.o + +fll_test_subr.o : \ ../../data_util/fll_mods.o diff --git a/mpi_util/project.dep b/mpi_util/project.dep index c2dc1d6..bbbf0ad 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,22 +1,22 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_cp.o : \ +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_out.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_type.o + +fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ ../data_util/fll_out.o \ - ../data_util/fll_mk.o + ../data_util/fll_type.o fll_mpi_mods.o : \ fll_mpi_cp_all.o -fll_mpi_cp_all.o : \ +fll_mpi_cp.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mk.o - -fll_mpi_mv.o : \ - ../data_util/fll_rm.o \ - ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ ../data_util/fll_out.o \ - fll_mpi_cp.o + ../data_util/fll_type.o From 4048d0f24aa7dd479b91f14b019f203c65bd70e0 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 09:48:58 -0700 Subject: [PATCH 095/325] distinguish between L and S string --- data_util/fll_getndata.f90 | 6 +++--- data_util/fll_read_ffa.f90 | 4 ++-- data_util/fll_type.f90 | 27 ++++++++++++++------------- data_util/fll_write_ffa.f90 | 14 +++++++------- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 145e9f9..66a262b 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -807,7 +807,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER - CHARACTER(LEN=STRING_LENGHT) :: STRING + CHARACTER(LEN=LSTRING_LENGTH) :: STRING ! ! local declarations ! @@ -868,7 +868,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER - CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:) + CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:) ! ! local declarations ! @@ -929,7 +929,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) TYPE(DNODE), POINTER :: PNODE CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER - CHARACTER(LEN=STRING_LENGHT), POINTER :: STRING(:,:) + CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:,:) ! ! local declarations ! diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 35bef12..346ca6c 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -178,7 +178,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! TYPE(DNODE), POINTER :: PNEW TYPE(FUNC_DATA_SET) :: FPAR_H - CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=SSTRING_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: LTYPE,FTYPE INTEGER(LINT) :: NDIM, NSIZE,NNODES,NDIMO,NSIZEO LOGICAL :: OK,EXTRALINE @@ -667,7 +667,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! ! Local declarations ! - CHARACTER(LEN=NAME_LENGTH) :: T + CHARACTER(LEN=SSTRING_LENGTH) :: T INTEGER(LINT) :: I,J INTEGER :: IOSTAT LOGICAL :: OK diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index b14966f..0be32a0 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -65,7 +65,7 @@ MODULE FLL_TYPE_M ! ERR_MSG_LENGTH length of string for error message ! ERR_PATH_LENGTH length of string for path of in err message ! FILE_NAME_LENGTH length of string for file names -! STRING_LENGHT length of long string +! LSTRING_LENGTH length of long string ! MAX_SUB maximum number of subsets in each node ! @@ -90,38 +90,39 @@ MODULE FLL_TYPE_M INTEGER, PARAMETER :: ERR_MSG_LENGTH = 256 INTEGER, PARAMETER :: ERR_PATH_LENGTH = 1024 INTEGER, PARAMETER :: FILE_NAME_LENGTH = 1024 - INTEGER, PARAMETER :: STRING_LENGHT = 72 + INTEGER, PARAMETER :: LSTRING_LENGTH = 72 + INTEGER, PARAMETER :: SSTRING_LENGTH = NAME_LENGTH INTEGER, PARAMETER :: MAX_SUB = 32000 ! ! DEFINITION OF THE DATA SET OF THE NODE IN LINKED LIST ! TYPE DNODE - CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list + CHARACTER(LEN=NAME_LENGTH) :: LNAME = '' ! name the list CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 - INTEGER(LINT) :: POS = 0, LENGTH = 0 + INTEGER(LINT) :: DATA_LENGTH = 0 TYPE (DNODE), POINTER :: & - PPAR =>NULL(),& ! Pointer to parent list + PPAR =>NULL(),& ! Pointer to parent list PCHILD =>NULL(),& ! Pointer to first child list PNEXT =>NULL(),& ! Pointer to next list PPREV =>NULL(),& ! Pointer to previous list - PLINK =>NULL() ! Pointer to link target + PLINK =>NULL() ! Pointer to link target - REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) =>NULL() ! real arrays - REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) =>NULL() ! double arrays - INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) =>NULL() ! integer arrays - INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) =>NULL() ! long integer arrays - CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S1(:)=>NULL() ! 1D array of strings - CHARACTER(LEN=STRING_LENGHT), POINTER, CONTIGUOUS :: S2(:,:)=>NULL() ! 2D array of strings + REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) => NULL() ! real arrays + REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) => NULL() ! double arrays + INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) => NULL() ! integer arrays + INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) => NULL() ! long integer arrays + CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S1(:) => NULL() ! 1D array of strings + CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S2(:,:)=> NULL() ! 2D array of strings REAL(RSINGLE) :: R0 ! real REAL(RDOUBLE) :: D0 ! double INTEGER(SINT) :: I0 ! integer INTEGER(LINT) :: L0 ! long integer - CHARACTER(LEN=STRING_LENGHT) :: S0 ! string + CHARACTER(LEN=LSTRING_LENGTH) :: S0 ! string CHARACTER :: C ! character END TYPE DNODE diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index c2b0a6c..9ce4d98 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -472,7 +472,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) LOGICAL :: SAVED CHARACTER(LEN=TYPE_LENGTH) :: NTYPE ='N', LTYPE - CHARACTER(LEN=NAME_LENGTH) :: SHTEXT + CHARACTER(LEN=SSTRING_LENGTH) :: SHTEXT SAVED = .FALSE. LTYPE = PNODE%LTYPE @@ -528,9 +528,9 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) IF(PNODE%FTYPE == 'L')THEN - WRITE(IOUNIT)NDIM*STRING_LENGHT,(PNODE%S1(I),I=1,NDIM) + WRITE(IOUNIT)NDIM*LSTRING_LENGTH,(PNODE%S1(I),I=1,NDIM) ELSE - WRITE(IOUNIT)NDIM*NAME_LENGTH + WRITE(IOUNIT)NDIM*SSTRING_LENGTH DO I = 1,NDIM SHTEXT = PNODE%S1(I) WRITE(IOUNIT)SHTEXT @@ -577,9 +577,9 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) IF(PNODE%FTYPE == 'L')THEN - WRITE(IOUNIT)NDIM*NSIZE*STRING_LENGHT,((PNODE%S2(I,J), I = 1,NDIM),J=1,NSIZE) + WRITE(IOUNIT)NDIM*NSIZE*LSTRING_LENGTH,((PNODE%S2(I,J), I = 1,NDIM),J=1,NSIZE) ELSE - WRITE(IOUNIT)NDIM*NSIZE*NAME_LENGTH + WRITE(IOUNIT)NDIM*NSIZE*SSTRING_LENGTH DO J=1,NSIZE DO I=1,NDIM SHTEXT = PNODE%S2(I,J) @@ -604,9 +604,9 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) CASE('J') WRITE(IOUNIT)1_LINT,PNODE%L0 CASE('L') - WRITE(IOUNIT)1_LINT*STRING_LENGHT,PNODE%S0 + WRITE(IOUNIT)1_LINT*LSTRING_LENGTH,PNODE%S0 CASE('S') - WRITE(IOUNIT)1_LINT*NAME_LENGTH,PNODE%S0(1:NAME_LENGTH) + WRITE(IOUNIT)1_LINT*SSTRING_LENGTH,PNODE%S0(1:SSTRING_LENGTH) END SELECT END IF END IF From 66d18c86bd5854fa6fe77c7e15696e56c0c8f99d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 09:49:08 -0700 Subject: [PATCH 096/325] complete getnbytes --- data_util/fll_getnbytes.f90 | 176 +++++---------------- data_util/fll_mods.f90 | 1 + data_util/project.dep | 27 ++-- examples/Example_MPI-IO/Example_mpi-IO.f90 | 14 +- 4 files changed, 66 insertions(+), 152 deletions(-) diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 index 0d2880f..7184f7b 100644 --- a/data_util/fll_getnbytes.f90 +++ b/data_util/fll_getnbytes.f90 @@ -17,8 +17,6 @@ ! contact: libm3l@gmail.com ! ! -! -! MODULE FLL_GETNBYTES_M ! ! Description: Counts byte length of the list @@ -33,7 +31,7 @@ MODULE FLL_GETNBYTES_M ! External Modules used ! CONTAINS - FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) + RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) ! ! Description: Get size of linked list in bytes ! @@ -67,14 +65,12 @@ FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) ! ! Local declarations ! - TYPE(DNODE), POINTER :: PCHILD + TYPE(DNODE), POINTER :: PCHILD,PNEXT ! ! BODY OF SUBROUTINE -! ! ! check the node is not null ! - PNEW => NULL() FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - null node ' @@ -84,127 +80,30 @@ FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) END IF PCHILD => PNODE%PCHILD + + BYTES = FLL_GETDATALENGTH(PNODE,FPAR) ! ! IF NODE HAS CHILDREN, GETNBYTES ALL OF THEM ! - IF(ASSOCIATED(PCHILD))THEN - PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' + DO WHILE (ASSOCIATED(PCHILD)) + + BYTES = BYTES + FLL_GETNBYTES(PCHILD,FPAR) + + IF(.NOT.FPAR%SUCCESS)THEN + WRITE(FPAR%MESG,'(A)')' GETNBYTES - error duplicting children nodes ' + CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. - PNEW => NULL() RETURN END IF - CALL FLL_GETNBYTES_RECURSIVE_NODE(PCHILD,PNEW,FPAR) - IF(.NOT.FPAR%SUCCESS)THEN - WRITE(FPAR%MESG,'(A)')' GETNBYTES - error duplicting children nodes ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF + PCHILD => PCHILD%PNEXT - ELSE -! -! NODE IS A FILE NODE -! - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - CALL FLL_GETDATALENGTH(PNODE, PNEW,FPAR) - - END IF + END DO FPAR%SUCCESS = .TRUE. RETURN END FUNCTION FLL_GETNBYTES -! -! DELETE CHID WITH ALL ITS CHILDREN -! - RECURSIVE FUNCTION FLL_GETNBYTES_RECURSIVE_NODE(PNODE,PDUPL,FPAR) RESULT(BYTES) -! -! Description: makes recursive duplicate of PNODE -! -! External Modules used -! - USE FLL_TYPE_M - USE FLL_MK_M - USE FLL_MV_M - USE FLL_OUT_M - - IMPLICIT NONE -! -! Declarations -! -! Arguments description -! Name In/Out Function -! PNODE In pointer which is to be duplicated -! PDUPL Out duplicate of PNODE -! FPAR In/Out structure containing function specific data -! -! Arguments declaration -! - TYPE(DNODE), POINTER :: PNODE,PDUPL - TYPE(FUNC_DATA_SET) :: FPAR -! -! Local declarations -! - TYPE(DNODE), POINTER :: PCURR, PNEXT,PNEW,PCHILD - LOGICAL :: OK -! - PCURR => PNODE - PCHILD => PNODE%PCHILD -! -! LOOP OVER CHILDREN -! - DO WHILE(ASSOCIATED(PCURR)) - - PNEXT => PCURR%PNEXT - PCHILD=> PCURR%PCHILD - - IF(.NOT.ASSOCIATED(PNEW))THEN - WRITE(FPAR%MESG,'(A)')' GETNBYTES - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNEW => NULL() - RETURN - END IF - - IF(.NOT.ASSOCIATED(PCHILD))THEN - CALL FLL_GETDATALENGTH(PCURR, PNEW, FPAR) - ELSE -! -! NODE HAS CHILDREN -! - DO WHILE(ASSOCIATED(PCHILD)) - - CALL FLL_GETNBYTES_RECURSIVE_NODE(PCHILD,PNEW, FPAR) - IF(.NOT.FPAR%SUCCESS) STOP'GETNBYTES - Error duplicating nodes' - PCHILD => PCHILD%PNEXT - - END DO - - END IF -! -! ADD TO PDUPL LIST -! - OK = FLL_MV(PNEW,PDUPL,FPAR) - PCURR => PNEXT - - END DO - - FPAR%SUCCESS = .TRUE. - RETURN - - END FUNCTION FLL_GETNBYTES_RECURSIVE_NODE -! -! ! FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) ! @@ -232,8 +131,9 @@ FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) ! ! Arguments declaration ! - TYPE(DNODE), POINTER :: PNODE,PNEW - TYPE(FUNC_DATA_SET) :: FPAR + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: BYTES ! ! Local declarations ! @@ -241,34 +141,36 @@ FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) ! ! IF DIR NODE, RETURN ! + BYTES = NAME_LENGTH + TYPE_LENGTH + 8 + 8 + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR. TRIM(PNODE%LTYPE) == 'N') RETURN ! ! 1D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) - BYTES = 4*NDIM + NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) + BYTES = BYTES + 4*NDIM RETURN END IF ! IF(ASSOCIATED(PNODE%D1))THEN - NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) - BYTES = 8*NDIM + NDIM = SIZE(PNODE%D1, DIM = 1, KIND = LINT) + BYTES = BYTES + 8*NDIM RETURN END IF IF(ASSOCIATED(PNODE%I1))THEN - NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) - BYTES = 4*NDIM + NDIM = SIZE(PNODE%I1, DIM = 1, KIND = LINT) + BYTES = BYTES + 4*NDIM RETURN END IF IF(ASSOCIATED(PNODE%L1))THEN - NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) - BYTES = 8*NDIM + NDIM = SIZE(PNODE%L1, DIM = 1, KIND = LINT) + BYTES = BYTES + 8*NDIM RETURN END IF IF(ASSOCIATED(PNODE%S1))THEN - NDIM = SIZE(PNODE%R1, DIM = 1, KIND = LINT) - BYTES = NAME_LENGTH*NDIM + NDIM = SIZE(PNODE%S1, DIM = 1, KIND = LINT) + BYTES = BYTES + LSTRING_LENGTH*NDIM RETURN END IF ! @@ -277,35 +179,35 @@ FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) IF(ASSOCIATED(PNODE%R2))THEN NDIM = SIZE(PNODE%R2, DIM = 1, KIND = LINT) NSIZE = SIZE(PNODE%R2, DIM = 2, KIND = LINT) - BYTES = 4*NDIM*NSIZE + BYTES = BYTES + 4*NDIM*NSIZE RETURN END IF IF(ASSOCIATED(PNODE%D2))THEN NDIM = SIZE(PNODE%D2, DIM = 1, KIND = LINT) NSIZE = SIZE(PNODE%D2, DIM = 2, KIND = LINT) - BYTES = 8*NDIM*NSIZE + BYTES = BYTES + 8*NDIM*NSIZE RETURN END IF IF(ASSOCIATED(PNODE%I2))THEN NDIM = SIZE(PNODE%I2, DIM = 1, KIND = LINT) NSIZE = SIZE(PNODE%I2, DIM = 2, KIND = LINT) - BYTES = 4*NDIM*NSIZE + BYTES = BYTES + 4*NDIM*NSIZE RETURN END IF IF(ASSOCIATED(PNODE%L2))THEN NDIM = SIZE(PNODE%L2, DIM = 1, KIND = LINT) NSIZE = SIZE(PNODE%L2, DIM = 2, KIND = LINT) - BYTES = 8*NDIM*NSIZE + BYTES = BYTES + 8*NDIM*NSIZE RETURN END IF - IF(ASSOCIATED(PNODE%S2))THEN + IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM = 1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM = 2, KIND = LINT) - BYTES = NAME_LENGTH*NDIM*NSIZE + BYTES = BYTES + LSTRING_LENGTH*NDIM*NSIZE RETURN END IF ! @@ -313,15 +215,15 @@ FUNCTION FLL_GETDATALENGTH(PNODE,FPAR) RESULT(BYTES) ! SELECT CASE(PNODE%LTYPE) CASE('R') - BYTES = 4 + BYTES = BYTES + 4 CASE('D') - BYTES = 8 + BYTES = BYTES + 8 CASE('I') - BYTES = 4 + BYTES = BYTES + 4 CASE('L') - BYTES = 8 + BYTES = BYTES + 8 CASE('S') - BYTES = NAME_LENGTH + BYTES = BYTES + LSTRING_LENGTH END SELECT RETURN diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 52b3728..c5e3632 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -55,5 +55,6 @@ MODULE FLL_MODS_M USE FLL_GETNDATA_M USE FLL_OUT_M USE FLL_MATCH_PATTERN_M + USE FLL_GETNBYTES_M END MODULE FLL_MODS_M diff --git a/data_util/project.dep b/data_util/project.dep index 4ec9344..e7f5de0 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -92,26 +92,27 @@ fll_duplicate.o : \ fll_mods.o : \ fll_mv.o \ - fll_deattach.o \ + fll_out.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_match_pattern.o \ + fll_type.o \ fll_mkdir.o \ fll_cat.o \ - fll_duplicate.o \ fll_write.o \ - fll_match_pattern.o \ - fll_locate.o \ - fll_sweep.o \ - fll_rm.o \ fll_write_ffa.o \ - fll_funct_prt.o \ - fll_stich.o \ - fll_cp.o \ + fll_getnbytes.o \ fll_mk.o \ - fll_type.o \ + fll_deattach.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ fll_nnodes.o \ - fll_read.o \ fll_getndata.o \ - fll_out.o \ - fll_read_ffa.o + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o fll_rm.o : \ fll_stich.o \ diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 1513e7c..ffe14ae 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -62,7 +62,7 @@ PROGRAM EXAMPLE_MPI_IO INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id CHARACTER :: FMT - INTEGER(LINT) :: NFILES,NPROC + INTEGER(LINT) :: NFILES,NPROC,BYTES CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK ! @@ -89,6 +89,9 @@ PROGRAM EXAMPLE_MPI_IO ! OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) ! CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) + BYTES = FLL_GETNBYTES(FLL_MPI_STRUCT,FPAR) + WRITE(*,*)' Length of data set is ',BYTES + END IF ! @@ -105,8 +108,12 @@ PROGRAM EXAMPLE_MPI_IO ! FLL_MPI_STRUCT => PNEW END IF + + BYTES = FLL_GETNBYTES(FLL_MPI_STRUCT,FPAR) + WRITE(*,*)' -------- Length of data is ',WORLD_RANK,BYTES ! ! just test - if partition #1, print received data set +! IF(WORLD_RANK == 1)THEN CALL FLL_CAT(FLL_MPI_STRUCT,6,.FALSE., FPAR) END IF @@ -114,7 +121,10 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,100_LINT, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,100000_LINT, WORLD_RANK) + + BYTES = FLL_GETNBYTES(PDATA_SET,FPAR) + WRITE(*,*)' -------- Size of data is ',WORLD_RANK,BYTES ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! From 1dbd3495f66806510b560373362a34f37136f686 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 11:34:47 -0700 Subject: [PATCH 097/325] fix for files containing only intrinsic modules or no modules --- python_dep/fort_depend.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 4d3c363..20dbc55 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -43,7 +43,7 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= ff=get_all_files(path=path, dep=dep) print(" ") - print(" Looking for modules in files:") + print("\033[031m Looking for modules in files:\033[039m") print(ff) l=create_file_objs(files,macros) @@ -93,11 +93,19 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") - for j in dep[i]: + if not(dep[i] == ""): + + for j in dep[i]: npathseg = j.count('/') if npathseg == 0: +# +# module is in the file located in the same directory +# tmp,fil=os.path.split(j) else: +# +# module is in file located in different directory +# fil = get_relative_path_name(j,path=path,cwd=cwd) if "../" in fil: @@ -107,6 +115,7 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' stri=stri+"\n" f.write(stri) + f.close() print("\033[031m Finished ... \033[039m") print(" ") @@ -119,6 +128,7 @@ def get_source(ext=[".f90",".F90",".f",".F"]): fil=[] for i in ext: fil.extend(filter(lambda x: x.endswith(i),tmp)) + return fil def get_all_files(path,dep): @@ -179,15 +189,24 @@ def create_file_objs(files=None, macros={}): files = get_source() + print(" ") + print("\033[031m Looking for modules for files:\033[039m") + print(" ") + + for i in files: source_file = file_obj() + + print(i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.contains = get_contains(i) l.append(source_file) + print(" ") + return l def get_uses(infile=None, macros={}): @@ -250,7 +269,10 @@ def file_objs_to_mod_dict(file_objs=[]): def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} istat = 0 + for i in fob: + print("") + print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: try: @@ -264,7 +286,6 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): # module is not, loop through all other files specified in ffiles # these are files found in function get_all_files # - istat = 0 for k in ffiles: dir,fil=os.path.split(k) dir = dir+ "/" @@ -289,6 +310,8 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): if not(istat == 0): deps[i.file_name]=tmp + else: + deps[i.file_name]="" return deps From 3558da6ec4940ebce33285058edd6f5c6a2ad3aa Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 11:34:55 -0700 Subject: [PATCH 098/325] typos --- data_util/fll_write.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 12fcac9..378c3bc 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -84,7 +84,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CASE('U','u','*')! UNKNOWN - UNSPECIFIED FORMAT FMT_LOC = 'U' CASE DEFAULT - WRITE(FPAR%MESG,'(A,A)')' Write_ffaunknown format',TRIM(FMT) + WRITE(FPAR%MESG,'(A,A)')' Write unknown format',TRIM(FMT) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -104,7 +104,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) END SELECT IF(ISTAT/=0) THEN - WRITE(FPAR%MESG,'(A,A)')' Write_ffaerror opening file ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. @@ -175,7 +175,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) POS = 0 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' Write_ffa - null node ' + WRITE(FPAR%MESG,'(A)')' Write - null node ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN From 44b9ae285d09d5b422359fb825213a4cffb7b2e7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 11:35:39 -0700 Subject: [PATCH 099/325] fix dependencies --- data_util/project.dep | 2 -- mpi_util/fll_mpi_mods.f90 | 3 +++ mpi_util/project.dep | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index e7f5de0..4d3f495 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -11,8 +11,6 @@ fll_nnodes.o : \ fll_type.o fll_getnbytes.o : \ - fll_mv.o \ - fll_mk.o \ fll_out.o \ fll_type.o diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index b403e81..527686a 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -35,5 +35,8 @@ MODULE FLL_MPI_MODS_M ! External Modules used ! USE FLL_MPI_CP_ALL_M + USE FLL_MPI_CP_M + USE FLL_MPI_MV_M + USE FLL_MPI_SUM_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index bbbf0ad..28fe629 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -12,7 +12,13 @@ fll_mpi_cp_all.o : \ ../data_util/fll_out.o \ ../data_util/fll_type.o +fll_mpi_sum.o : \ + ../data_util/fll_mods.o + fll_mpi_mods.o : \ + fll_mpi_mv.o \ + fll_mpi_cp.o \ + fll_mpi_sum.o \ fll_mpi_cp_all.o fll_mpi_cp.o : \ From b331c17748adeddad2a2ccf55359f4b709713928 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 11:35:54 -0700 Subject: [PATCH 100/325] add fll_mpi_sum --- mpi_util/fll_mpi_sum.f90 | 178 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 mpi_util/fll_mpi_sum.f90 diff --git a/mpi_util/fll_mpi_sum.f90 b/mpi_util/fll_mpi_sum.f90 new file mode 100644 index 0000000..0d0e54e --- /dev/null +++ b/mpi_util/fll_mpi_sum.f90 @@ -0,0 +1,178 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine FLL_MPI_SUM +! +! Date: 2016-10-10 +! +! +! +MODULE FLL_MPI_SUM_M +! +! Description: Counts byte length of the list +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +! +! + SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM, NSIZE ,R,D,I,L,R1,D1,I1,L1) +! +! Description: performs sum operation in MPI_ALLREDUCE +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 11/11/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M +! +! Declarations +! +! Arguments description +! Name In/Out Function +! CIMMUNICATOR In Communicator +! NDIM, NSIZE In dimensions of arrays, if 1 variable is scalar +! R,R# In real scalar or array +! D,D# In double scalar or array +! I,I# In integer scalar or array +! L,L# In long integer scalar or array +! +! Arguments declaration +! + INTEGER(LINIT) :: NDIM + REAL(RSINGLE), OPTIONAL :: R,R1(:) + REAL(RDOUBLE), OPTIONAL :: D,D1(:) + + INTEGER(SINT), OPTIONAL :: I,I1(:) + INTEGER(LINT), OPTIONAL :: L,L1(:) +! +! Local declaration +! + REAL(RSINGLE), ALLOCATABLE :: TR1(:) + REAL(RDOUBLE), ALLOCATABLE :: TD1(:) + + INTEGER(SINT), ALLOCATABLE :: TI1(:) + INTEGER(LINT), ALLOCATABLE :: TL1(:) + + REAL(RSINGLE) :: TR + REAL(RDOUBLE) :: TD + + INTEGER(SINT) :: TI + INTEGER(LINT) :: TL + + INTEGER :: ISTAT,IERR +! +! Body of subroutine +! +! +! vector/matrix +! + VECSCAL: IF(NDIM > 1)THEN + + IF(PRESENT(R1))THEN + ALLOCATE(TR1(NDIM), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + TR1 = R1 + CALL MPI_ALLREDUCE(TR1,R1,NDIM,MPI_REAL,MPI_SUM,COMMUNICATOR,IERR) + DEALLOCATE(TR1, STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + RETURN + END IF + + IF(PRESENT(D1))THEN + ALLOCATE(TD1(NDIM), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + TD1 = D1 + CALL MPI_ALLREDUCE(TD1,D1,NDIM,MPI_DOUBLE,MPI_SUM,COMMUNICATOR,IERR) + DEALLOCATE(TD1, STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + RETURN + END IF + + IF(PRESENT(I1))THEN + ALLOCATE(TI1(NDIM), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + TI1 = I1 + CALL MPI_ALLREDUCE(TI1,I1,NDIM,MPI_INTEGER,MPI_SUM,COMMUNICATOR,IERR) + DEALLOCATE(TI1, STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + RETURN + END IF + + IF(PRESENT(L1) + ALLOCATE(TL1(NDIM), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + TL1 = L1 + CALL MPI_ALLREDUCE(TL1,L1,NDIM,MPI_INTEGER8,MPI_SUM,COMMUNICATOR,IERR) + DEALLOCATE(TL1, STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + RETURN + END IF +! +! Scalars +! + ELSE + + IF(PRESENT(R))THEN + TR = R + CALL MPI_ALLREDUCE(TR,R,1,MPI_REAL,MPI_SUM,COMMUNICATOR,IERR) + RETURN + END IF + + IF(PRESENT(D))THEN + TD = D + CALL MPI_ALLREDUCE(TD,D,1,MPI_DOUBLE,MPI_SUM,COMMUNICATOR,IERR) + RETURN + END IF + + IF(PRESENT(I))THEN + TI = I + CALL MPI_ALLREDUCE(TI,I,1,MPI_INTEGER,MPI_SUM,COMMUNICATOR,IERR) + RETURN + END IF + + IF(PRESENT(L))THEN + TL = L + CALL MPI_ALLREDUCE(TL,L,1,MPI_INTEGER8,MPI_SUM,COMMUNICATOR,IERR) + RETURN + END IF + + + END IF VECSCAL + +! + RETURN + + END SUBROUTINE FLL_MPI_SUM + +END MODULE FLL_MPI_SUM_M From 75659cdcdbe8c8cdbb58685fce057f25d8bfe3b9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 11:42:39 -0700 Subject: [PATCH 101/325] comp errors in fll_mpi_sum --- mpi_util/fll_mpi_sum.f90 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mpi_util/fll_mpi_sum.f90 b/mpi_util/fll_mpi_sum.f90 index 0d0e54e..8636974 100644 --- a/mpi_util/fll_mpi_sum.f90 +++ b/mpi_util/fll_mpi_sum.f90 @@ -40,7 +40,8 @@ MODULE FLL_MPI_SUM_M ! ! ! - SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM, NSIZE ,R,D,I,L,R1,D1,I1,L1) +CONTAINS + SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM ,R,D,I,L,R1,D1,I1,L1) ! ! Description: performs sum operation in MPI_ALLREDUCE ! @@ -69,7 +70,8 @@ SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM, NSIZE ,R,D,I,L,R1,D1,I1,L1) ! ! Arguments declaration ! - INTEGER(LINIT) :: NDIM + INTEGER(LINT) :: NDIM + INTEGER :: COMMUNICATOR REAL(RSINGLE), OPTIONAL :: R,R1(:) REAL(RDOUBLE), OPTIONAL :: D,D1(:) @@ -129,7 +131,7 @@ SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM, NSIZE ,R,D,I,L,R1,D1,I1,L1) RETURN END IF - IF(PRESENT(L1) + IF(PRESENT(L1))THEN ALLOCATE(TL1(NDIM), STAT = ISTAT) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' TL1 = L1 From 24d1a41137ddbb11e30201b7415c7229583fffb2 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 14:00:06 -0700 Subject: [PATCH 102/325] rename ambiguous function name --- data_util/fll_write_ffa.f90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 9ce4d98..5538a37 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -186,9 +186,9 @@ SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) END IF IF(FMT == 'A')THEN - CALL FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + CALL FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) ELSE - CALL FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + CALL FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) END IF PCHILD => PNODE%PCHILD @@ -252,9 +252,9 @@ RECURSIVE SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) DO WHILE(ASSOCIATED(PCURR)) IF(FMT == 'A')THEN - CALL FLL_SAVE_NODE_A(PCURR, IOUNIT, FPAR) + CALL FLL_SAVE_NODE_A_FFA(PCURR, IOUNIT, FPAR) ELSE - CALL FLL_SAVE_NODE_B(PCURR, IOUNIT, POS, FPAR) + CALL FLL_SAVE_NODE_B_FFA(PCURR, IOUNIT, POS, FPAR) END IF PNEXT => PCURR%PNEXT @@ -273,7 +273,7 @@ END SUBROUTINE FLL_WRITE_FFA_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) + SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) ! ! Description: Writes node and its data to an ASCII file ! @@ -432,9 +432,9 @@ SUBROUTINE FLL_SAVE_NODE_A(PNODE, IOUNIT, FPAR) RETURN - END SUBROUTINE FLL_SAVE_NODE_A + END SUBROUTINE FLL_SAVE_NODE_A_FFA - SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) + SUBROUTINE FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) ! ! Description: Writes node and its data to a binary file ! @@ -613,6 +613,6 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) RETURN - END SUBROUTINE FLL_SAVE_NODE_B + END SUBROUTINE FLL_SAVE_NODE_B_FFA END MODULE FLL_WRITE_FFA_M From 726545c24c35c6dae049768ba30ae429c3909bed Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 14:00:42 -0700 Subject: [PATCH 103/325] prototype of mpi_write --- data_util/project.dep | 2 ++ mpi_util/fll_mpi_mods.f90 | 1 + mpi_util/project.dep | 17 +++++++++++------ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index 4d3f495..3723677 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -22,6 +22,8 @@ fll_cat.o : \ fll_out.o \ fll_type.o +fll_type.o : + fll_stich.o : \ fll_out.o \ fll_type.o diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index 527686a..15553b9 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -38,5 +38,6 @@ MODULE FLL_MPI_MODS_M USE FLL_MPI_CP_M USE FLL_MPI_MV_M USE FLL_MPI_SUM_M + USE FLL_MPI_WRITE_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 28fe629..905c451 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,11 +1,5 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_mv.o : \ - fll_mpi_cp.o \ - ../data_util/fll_out.o \ - ../data_util/fll_rm.o \ - ../data_util/fll_type.o - fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ @@ -18,9 +12,20 @@ fll_mpi_sum.o : \ fll_mpi_mods.o : \ fll_mpi_mv.o \ fll_mpi_cp.o \ + fll_mpi_write.o \ fll_mpi_sum.o \ fll_mpi_cp_all.o +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_out.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_type.o + +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o + fll_mpi_cp.o : \ ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ From f537363580ecd9bf064662a5cadcf4602522dc18 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 14:01:25 -0700 Subject: [PATCH 104/325] cleanup --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 31 +++++++++++---------- examples/Example_MPI-IO/create_data_set.f90 | 8 +++++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index ffe14ae..0b82dff 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -59,12 +59,14 @@ PROGRAM EXAMPLE_MPI_IO CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id + INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC CHARACTER :: FMT - INTEGER(LINT) :: NFILES,NPROC,BYTES + INTEGER(LINT) :: NFILES,BYTES CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK + + INTEGER(LINT), ALLOCATABLE :: POS(:) ! ! Initialize MPI ! @@ -75,13 +77,15 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) write(*,*)' IRANK is ', WORLD_RANK + call MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) + IF(WORLD_RANK == 0) THEN - CALL READ_INPUT(NAME_OF_FILE,NFILES,NPROC) + CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) ! ! initialize MPI ! FLL_MPI_STRUCT => NULL() - CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,NPROC) + CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,1_LINT*NPROC) ! WRITE(*,*)' duplicating' ! PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) @@ -89,10 +93,6 @@ PROGRAM EXAMPLE_MPI_IO ! OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) ! CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) - BYTES = FLL_GETNBYTES(FLL_MPI_STRUCT,FPAR) - WRITE(*,*)' Length of data set is ',BYTES - - END IF ! ! Copy FLL_MPI_STRUCT date set which now exists on root partition only @@ -108,9 +108,6 @@ PROGRAM EXAMPLE_MPI_IO ! FLL_MPI_STRUCT => PNEW END IF - - BYTES = FLL_GETNBYTES(FLL_MPI_STRUCT,FPAR) - WRITE(*,*)' -------- Length of data is ',WORLD_RANK,BYTES ! ! just test - if partition #1, print received data set ! @@ -121,10 +118,12 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,100000_LINT, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) - BYTES = FLL_GETNBYTES(PDATA_SET,FPAR) - WRITE(*,*)' -------- Size of data is ',WORLD_RANK,BYTES + ALLOCATE(POS(NPROC)) + POS = 0 + POS(WORLD_RANK+1) = FLL_GETNBYTES(PDATA_SET,FPAR) + WRITE(*,*)' -------- Size of data is ',POS ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! @@ -132,6 +131,9 @@ PROGRAM EXAMPLE_MPI_IO ! just for testing purposes ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + CALL FLL_MPI_SUM(MPI_COMM_WORLD, 1_LINT*NPROC,L1=POS) + WRITE(*,*)' SUM is ', POS ! ! CLEAN MEMORY ! @@ -139,6 +141,7 @@ PROGRAM EXAMPLE_MPI_IO CALL FLL_RM(FLL_MPI_STRUCT,FPAR) CALL FLL_RM(PDATA_SET,FPAR) + deallocate(pos) CALL MPI_FINALIZE(IERR) diff --git a/examples/Example_MPI-IO/create_data_set.f90 b/examples/Example_MPI-IO/create_data_set.f90 index 4f6392b..98e1e8e 100644 --- a/examples/Example_MPI-IO/create_data_set.f90 +++ b/examples/Example_MPI-IO/create_data_set.f90 @@ -67,7 +67,13 @@ SUBROUTINE CREATE_DATA_SET(PNODE,NNODES,RANK) ! ! MAKE STRUCTURE ! - PNODE => FLL_MKDIR('Main_Data_Set',FPAR) + PNODE => FLL_MKDIR('partition',FPAR) +! +! add number of partition +! + PTMP => FLL_MK('part_number','L', 1_lint, 1_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' + PTMP%L0 = RANK+1 ! ! create 1-D double array of pressure fill it up with 101323 value and attach to PNODE ! From b0abf57229311077e483d88f4b84b47204175f8f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 14:01:56 -0700 Subject: [PATCH 105/325] added prototype of fll_mpi_write --- mpi_util/fll_mpi_write.f90 | 218 +++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 mpi_util/fll_mpi_write.f90 diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 new file mode 100644 index 0000000..c2dc659 --- /dev/null +++ b/mpi_util/fll_mpi_write.f90 @@ -0,0 +1,218 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MPI_WRITE_M +! +! Description: contains subroutine writing file in paralell mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) RESULT(OK) +! +! Description: contains subroutine writing file in paralell mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + USE FLL_MPI_SUM_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! OPTION In Type of write +! COMMUNICATOR In communicator +! FPAR In/Out structure containing function specific data +! OK Out Success or fail +! ROOT_RANK In Rank of the root process +! Rank In Rank of the process +! +! Arguments declaration +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT,RANK, ROOT_RANK, COMMUNICATOR + CHARACTER :: OPTION + LOGICAL OK +! +! local declarations +! + INTEGER :: ISTAT,IERR,NPROC + INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) + INTEGER(LINT) :: POS1,I,PART_NUM +! +! DETERMINE RORMAT' +! + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + + CALL MPI_BARRIER(COMMUNICATOR, IERR) + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF +! +! Get number of processors +! + CALL MPI_Comm_size (COMMUNICATOR, NPROC, IERR ) +! +! Get length of each data set +! + ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' + POS = 0 + + POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) + IF(RANK == ROOT_RANK) POS(1) = 36 + 36 + (NPROC+1)*8 + CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=POS) + + WRITE(*,*)' -------- Size of data is ',POS +! +! ... and distribute to all partitions +! + CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT*NPROC,L1=POS) +! +! Calculate displacement +! + PART_NUM = FLL_GETNDATA_L0(PNODE, 'part_number',1_LINT, FPAR) + + DISPL = 0 + + DO I=1,PART_NUM+1 + DISPL(I) = DISPL(I) + POS(I) + END DO + CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) +! +! Position in file with empty write statement +! + IF(RANK == ROOT_RANK)THEN + WRITE(IOUNIT,POS=0) + POS1 = FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) + ELSE + WRITE(IOUNIT,POS=DISPL(RANK+2)) + END IF +! +! Write linked list +! + CALL FLL_WRITE_LIST(PNODE,IOUNIT,'B',FPAR) +! +! MPI_Barrier does not need to be here, +! just for testing purposes +! + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF + + DEALLOCATE(POS, DISPL, STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' + + OK = .TRUE. + RETURN + + END FUNCTION FLL_MPI_WRITE + + + FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) +! +! Description: contains subroutine writing file in paralell mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_MODS_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! NPROC In Number of processes +! DISPL In Length of each partition record +! IOUNIT In Number of unit +! FPAR In/Out structure containing function specific data +! OK Out Success or fail +! +! Arguments declaration +! + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT,NPROC + INTEGER(LINT) :: DISPL(:),POS +! +! Local declarations +! + TYPE(DNODE), POINTER :: PTMP + + PTMP => FLL_MKDIR('partitioned_file', FPAR) + PTMP%NDIM = NPROC + 1 ! Number of partitioned solutions and displacement vector + CALL FLL_SAVE_NODE_B(PTMP, IOUNIT, 0_LINT, FPAR) + POS = FLL_GETNBYTES(PTMP,FPAR) + CALL FLL_RM(PTMP,FPAR) + + PTMP => FLL_MK('displacements','L', NPROC+1_LINT, 1_LINT, FPAR) +! +! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) +! + POS = POS + FLL_GETNBYTES(PTMP,FPAR) + DISPL(1) = POS + + PTMP%L1 = DISPL + CALL FLL_SAVE_NODE_B(PTMP, IOUNIT, 0_LINT, FPAR) + CALL FLL_RM(PTMP,FPAR) + + RETURN + + END FUNCTION FLL_PART_FILE_HEADER +END MODULE FLL_MPI_WRITE_M From 1ffb657eb7e5a19c0e3a0b7177a12080ed9f49ad Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 15:03:19 -0700 Subject: [PATCH 106/325] bug fix for getndata IDIM = 0 type --- data_util/fll_getndata.f90 | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 66a262b..bc808bc 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -88,7 +88,7 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) RETURN END IF - R0 = PNODE%R0 + R0 = PFIND%R0 RETURN END FUNCTION FLL_GETNDATA_R0 @@ -277,7 +277,7 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) RETURN END IF - R0 = PNODE%D0 + R0 = PFIND%D0 RETURN END FUNCTION FLL_GETNDATA_D0 @@ -468,7 +468,7 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) RETURN END IF - I0 = PNODE%I0 + I0 = PFIND%I0 RETURN END FUNCTION FLL_GETNDATA_I0 @@ -655,7 +655,8 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) RETURN END IF - I0 = PNODE%L0 + I0 = PFIND%L0 + RETURN END FUNCTION FLL_GETNDATA_L0 @@ -829,7 +830,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) RETURN END IF - STRING = PNODE%S0 + STRING = PFIND%S0 RETURN END FUNCTION FLL_GETNDATA_S From 53b5d7e573d4a8c43546f4b302958cbab4eae05f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 15:23:48 -0700 Subject: [PATCH 107/325] tmp commit --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 19 +++++-------------- examples/Example_MPI-IO/create_data_set.f90 | 4 ++-- mpi_util/fll_mpi_write.f90 | 14 ++++++++------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 0b82dff..7b0550f 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -75,7 +75,6 @@ PROGRAM EXAMPLE_MPI_IO FLL_MPI_STRUCT => NULL() CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) - write(*,*)' IRANK is ', WORLD_RANK call MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) @@ -109,21 +108,12 @@ PROGRAM EXAMPLE_MPI_IO FLL_MPI_STRUCT => PNEW END IF ! -! just test - if partition #1, print received data set -! - IF(WORLD_RANK == 1)THEN - CALL FLL_CAT(FLL_MPI_STRUCT,6,.FALSE., FPAR) - END IF -! ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) +! CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) - ALLOCATE(POS(NPROC)) - POS = 0 - POS(WORLD_RANK+1) = FLL_GETNBYTES(PDATA_SET,FPAR) - WRITE(*,*)' -------- Size of data is ',POS + CALL CREATE_DATA_SET(PDATA_SET,1000_LINT, WORLD_RANK) ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! @@ -132,8 +122,9 @@ PROGRAM EXAMPLE_MPI_IO ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - CALL FLL_MPI_SUM(MPI_COMM_WORLD, 1_LINT*NPROC,L1=POS) - WRITE(*,*)' SUM is ', POS + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + + ! ! CLEAN MEMORY ! diff --git a/examples/Example_MPI-IO/create_data_set.f90 b/examples/Example_MPI-IO/create_data_set.f90 index 98e1e8e..0d52dcf 100644 --- a/examples/Example_MPI-IO/create_data_set.f90 +++ b/examples/Example_MPI-IO/create_data_set.f90 @@ -71,9 +71,9 @@ SUBROUTINE CREATE_DATA_SET(PNODE,NNODES,RANK) ! ! add number of partition ! - PTMP => FLL_MK('part_number','L', 1_lint, 1_LINT, FPAR) - IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' + PTMP => FLL_MK('part_number','L', 1_LINT, 1_LINT, FPAR) PTMP%L0 = RANK+1 + IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' ! ! create 1-D double array of pressure fill it up with 101323 value and attach to PNODE ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index c2dc659..6943292 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -105,14 +105,14 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, POS = 0 POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) + IF(RANK == ROOT_RANK) POS(1) = 36 + 36 + (NPROC+1)*8 CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=POS) - - WRITE(*,*)' -------- Size of data is ',POS ! ! ... and distribute to all partitions ! - CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT*NPROC,L1=POS) + CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT*NPROC+1,L1=POS) + write(*,*)' POS ', part_num, POS ! ! Calculate displacement ! @@ -120,10 +120,11 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, DISPL = 0 - DO I=1,PART_NUM+1 - DISPL(I) = DISPL(I) + POS(I) + DO I=2,PART_NUM+1 + DISPL(I) = DISPL(I-1) + POS(I-1) END DO - CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) +! CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT+1,L1=DISPL) + write(*,*)' DISPL ', part_num, displ ! ! Position in file with empty write statement ! @@ -131,6 +132,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, WRITE(IOUNIT,POS=0) POS1 = FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) ELSE + write(*,*)' POS is ', rank, displ(rank+2) WRITE(IOUNIT,POS=DISPL(RANK+2)) END IF ! From aaeb869f6e6cdd2d162b08d2e702d3c0454c3637 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 19:17:57 -0700 Subject: [PATCH 108/325] initial implementation of mpi_write --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 2 -- examples/Simple_data_operation/fll_test.f90 | 4 ++- mpi_util/fll_mpi_sum.f90 | 16 +++++----- mpi_util/fll_mpi_write.f90 | 35 ++++++++++++++------- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 7b0550f..c0b39ea 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -131,8 +131,6 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK==0)write(*,*)' Releasing memory' CALL FLL_RM(FLL_MPI_STRUCT,FPAR) CALL FLL_RM(PDATA_SET,FPAR) - - deallocate(pos) CALL MPI_FINALIZE(IERR) diff --git a/examples/Simple_data_operation/fll_test.f90 b/examples/Simple_data_operation/fll_test.f90 index 792f77f..b8346df 100644 --- a/examples/Simple_data_operation/fll_test.f90 +++ b/examples/Simple_data_operation/fll_test.f90 @@ -69,13 +69,15 @@ PROGRAM FLL_TEST ! read TEST file and store it in PNODE ! file is an ASCII file ! - PNODE => FLL_READ('TEST',8,'A',FPAR) +! PNODE => FLL_READ('TEST',8,'A',FPAR) + PNODE => FLL_READ('PartitionedFile',8,'B',FPAR) ! ! print node on the screen ! CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) WRITE(*,*) WRITE(*,*)'------------------------------------------------------1' + stop ! ! read TEST1 ASCII file and store it in PNODE1 ! diff --git a/mpi_util/fll_mpi_sum.f90 b/mpi_util/fll_mpi_sum.f90 index 8636974..a6508da 100644 --- a/mpi_util/fll_mpi_sum.f90 +++ b/mpi_util/fll_mpi_sum.f90 @@ -103,41 +103,41 @@ SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM ,R,D,I,L,R1,D1,I1,L1) IF(PRESENT(R1))THEN ALLOCATE(TR1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:106 ' TR1 = R1 CALL MPI_ALLREDUCE(TR1,R1,NDIM,MPI_REAL,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TR1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:110 ' RETURN END IF IF(PRESENT(D1))THEN ALLOCATE(TD1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:116 ' TD1 = D1 CALL MPI_ALLREDUCE(TD1,D1,NDIM,MPI_DOUBLE,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TD1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:120 ' RETURN END IF IF(PRESENT(I1))THEN ALLOCATE(TI1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:126 ' TI1 = I1 CALL MPI_ALLREDUCE(TI1,I1,NDIM,MPI_INTEGER,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TI1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:130 ' RETURN END IF IF(PRESENT(L1))THEN ALLOCATE(TL1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:136 ' TL1 = L1 CALL MPI_ALLREDUCE(TL1,L1,NDIM,MPI_INTEGER8,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TL1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:140 ' RETURN END IF ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index 6943292..c278204 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -77,7 +77,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! INTEGER :: ISTAT,IERR,NPROC INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) - INTEGER(LINT) :: POS1,I,PART_NUM + INTEGER(LINT) :: POS1,I,PART_NUM,LOC_DISPL ! ! DETERMINE RORMAT' ! @@ -101,35 +101,48 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! Get length of each data set ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' - POS = 0 + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:104 ' + POS = 0 POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) +! +! header = 16 + 4 + 8 + 8 (name, type, ndim, nsize) +! +! header + long int array +! + IF(RANK == ROOT_RANK) THEN + POS(1) = 36 + 36 + (NPROC+1)*8 + END IF - IF(RANK == ROOT_RANK) POS(1) = 36 + 36 + (NPROC+1)*8 - CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=POS) + CALL MPI_BARRIER(COMMUNICATOR, IERR) ! ! ... and distribute to all partitions ! - CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT*NPROC+1,L1=POS) - write(*,*)' POS ', part_num, POS + CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT+NPROC,L1=POS) ! ! Calculate displacement ! PART_NUM = FLL_GETNDATA_L0(PNODE, 'part_number',1_LINT, FPAR) + write(*,*)' POS ', part_num, POS + + CALL MPI_BARRIER(COMMUNICATOR, IERR) + + LOC_DISPL = 1 DISPL = 0 DO I=2,PART_NUM+1 - DISPL(I) = DISPL(I-1) + POS(I-1) + LOC_DISPL = LOC_DISPL + POS(I-1) END DO -! CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT+1,L1=DISPL) + DISPL(PART_NUM+1) = LOC_DISPL + CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) + DISPL(1) = 1 write(*,*)' DISPL ', part_num, displ ! ! Position in file with empty write statement ! IF(RANK == ROOT_RANK)THEN - WRITE(IOUNIT,POS=0) + WRITE(IOUNIT,POS=1) POS1 = FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) ELSE write(*,*)' POS is ', rank, displ(rank+2) @@ -153,7 +166,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, END IF DEALLOCATE(POS, DISPL, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:156 ' OK = .TRUE. RETURN From 7e31a6339c1dbd3542d8c5822150355ffd552e0a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 19:29:12 -0700 Subject: [PATCH 109/325] fll_mpi_write seems to be working --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 4 +-- mpi_util/fll_mpi_write.f90 | 42 +++++++++++++++++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index c0b39ea..5065a04 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -111,9 +111,9 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' -! CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) - CALL CREATE_DATA_SET(PDATA_SET,1000_LINT, WORLD_RANK) +! CALL CREATE_DATA_SET(PDATA_SET,1000_LINT, WORLD_RANK) ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index c278204..eb980e1 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -42,6 +42,39 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! ------- -------- -------- --- ------- ! 1.1 10/10/16 Initial implementation ! +! +! structure of the MPI file is as follows +! +! the main directory is a partitioned_file +! followed by displacement which is a byte position of each partiton in the file +! each data on patition is in subset partition +! +! this is an example of a file with four partitions +! +! -DIR- 5\ partitioned_file +! -L- 5x1 displacements 1 113 40000301 +! -DIR- 4\ partition +! -L- 1x1 part_number 1 +! -D- 1000000x1 pressure +! -D- 1000000x1 density +! -D- 1000000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 2 +! -D- 1100000x1 pressure +! -D- 1100000x1 density +! -D- 1100000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 3 +! -D- 1200000x1 pressure +! -D- 1200000x1 density +! -D- 1200000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 4 +! -D- 1300000x1 pressure +! -D- 1300000x1 density +! -D- 1300000x3 velocity + + ! ! External Modules used ! @@ -79,7 +112,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) INTEGER(LINT) :: POS1,I,PART_NUM,LOC_DISPL ! -! DETERMINE RORMAT' +! use always binary fomat ! OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& ACCESS='STREAM',IOSTAT=ISTAT) @@ -123,10 +156,6 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! Calculate displacement ! PART_NUM = FLL_GETNDATA_L0(PNODE, 'part_number',1_LINT, FPAR) - write(*,*)' POS ', part_num, POS - - CALL MPI_BARRIER(COMMUNICATOR, IERR) - LOC_DISPL = 1 DISPL = 0 @@ -137,7 +166,6 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, DISPL(PART_NUM+1) = LOC_DISPL CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) DISPL(1) = 1 - write(*,*)' DISPL ', part_num, displ ! ! Position in file with empty write statement ! @@ -145,7 +173,6 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, WRITE(IOUNIT,POS=1) POS1 = FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) ELSE - write(*,*)' POS is ', rank, displ(rank+2) WRITE(IOUNIT,POS=DISPL(RANK+2)) END IF ! @@ -221,7 +248,6 @@ FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) ! POS = POS + FLL_GETNBYTES(PTMP,FPAR) - DISPL(1) = POS PTMP%L1 = DISPL CALL FLL_SAVE_NODE_B(PTMP, IOUNIT, 0_LINT, FPAR) From 58e7fd2aa3671a52e43988007d94f1861289960c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 20:53:24 -0700 Subject: [PATCH 110/325] additional changes --- fort_depend.py | 165 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 129 insertions(+), 36 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 870d12d..20dbc55 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -19,7 +19,7 @@ #Definitions -def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() @@ -29,11 +29,29 @@ def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build= print(" ") print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") - - ff=get_all_files(path=path) +# +# get rid of ../ in deps +# + if not(dep == None): + dep = [w.replace('../', ' ') for w in dep] +# +# get files where to look for modules +# if list of preferred directories is specified in dep +# list only these files, otherwise +# list all file in path dir +# + ff=get_all_files(path=path, dep=dep) + + print(" ") + print("\033[031m Looking for modules in files:\033[039m") + print(ff) + l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) - depends=get_depends(fob=l,m2f=mod2fil,ffiles=ff) +# +# make dependencies +# + depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) if verbose: for i in depends.keys(): @@ -50,7 +68,9 @@ def run(path,files=None,verbose=True,overwrite=None,output=None,macros={},build= def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): "Write the dependencies to outfile" - #Test file doesn't exist +# +#Test file doesn't exist +# if os.path.exists(outfile): if not(overwrite): print ("\033[031mWarning file exists.\033[039m") @@ -61,8 +81,9 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' pass else: return - - #Open file +# +#Open file +# print(" ") print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") print(" ") @@ -72,11 +93,19 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") - for j in dep[i]: + if not(dep[i] == ""): + + for j in dep[i]: npathseg = j.count('/') if npathseg == 0: +# +# module is in the file located in the same directory +# tmp,fil=os.path.split(j) else: +# +# module is in file located in different directory +# fil = get_relative_path_name(j,path=path,cwd=cwd) if "../" in fil: @@ -86,30 +115,51 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' stri=stri+"\n" f.write(stri) + f.close() print("\033[031m Finished ... \033[039m") print(" ") return -def get_source(ext=[".f90",".F90"]): +def get_source(ext=[".f90",".F90",".f",".F"]): "Return all files ending with any of ext" tmp=os.listdir(".") + fil=[] for i in ext: fil.extend(filter(lambda x: x.endswith(i),tmp)) + return fil -def get_all_files(path): +def get_all_files(path,dep): +# +# list all fortran files +# matches = [] for root, dirnames, filenames in os.walk(path): - for filename in fnmatch.filter(filenames, '*.f90'): - matches.append(os.path.join(root, filename)) +# +# specified list of preferred directories +# list only those +# + if not(dep == None): + for i in dep: + if i.strip() in root: + for filename in fnmatch.filter(filenames, '*.f*'): + matches.append(os.path.join(root, filename)) +# +# otherwise include all files from path dir +# + else: + for filename in fnmatch.filter(filenames, '*.f*'): + matches.append(os.path.join(root, filename)) return matches def check_if_there(use,file): "return if you see module name" - with open(file) as f: + + if sys.version_info < (3,0): + with open(file) as f: for line in f: if "module" in line.lower(): extrline = line.lower() @@ -117,7 +167,15 @@ def check_if_there(use,file): if use.lower().strip() == extrline.strip(): f.close() return 1 - + else: + with open(file) as f: + with open(file, errors='ignore') as f: + if "module" in line.lower(): + extrline = line.lower() + extrline = extrline.replace("module", "") + if use.lower().strip() == extrline.strip(): + f.close() + return 1 f.close() return 0 @@ -129,15 +187,26 @@ def create_file_objs(files=None, macros={}): if files is None: files = get_source() + files = get_source() + + print(" ") + print("\033[031m Looking for modules for files:\033[039m") + print(" ") + + for i in files: source_file = file_obj() + + print(i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.contains = get_contains(i) l.append(source_file) + print(" ") + return l def get_uses(infile=None, macros={}): @@ -146,7 +215,11 @@ def get_uses(infile=None, macros={}): uses=[] - with open(infile,'r') as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r',errors='ignore') as f: t=f.readlines() for i in t: @@ -170,7 +243,11 @@ def get_contains(infile=None): contains=[] - with open(infile,'r') as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r', errors='ignore') as f: t=f.readlines() for i in t: @@ -178,7 +255,7 @@ def get_contains(infile=None): if tmp: contains.append(tmp.group('modname').strip()) - # Remove duplicates before returning +# Remove duplicates before returning return list(set(contains)) def file_objs_to_mod_dict(file_objs=[]): @@ -189,38 +266,52 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(fob=[],m2f=[], ffiles=[]): +def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} + istat = 0 + for i in fob: + print("") + print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: try: # -# module is in the same directory +# module is in the same directory, include it # tmp.append(m2f[j.lower()]) + istat = 1 except KeyError: # -# module is not, loop through all other files +# module is not, loop through all other files specified in ffiles +# these are files found in function get_all_files # - istat = 0 for k in ffiles: - retval=check_if_there(use=j,file=k) - if retval > 0: - istat = 1 - name=os.path.splitext(k)[0]+'.o' - tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + dir,fil=os.path.split(k) + dir = dir+ "/" + retval = 0 + + if not(cwd.strip() == dir): + retval=check_if_there(use=j,file=k) + + if retval > 0: + istat = 1 + name=os.path.splitext(k)[0]+'.o' + tmp.append(name.lower()) + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") + print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") if istat== 0 and not(j == ""): - print("") - print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print("") - - deps[i.file_name]=tmp + print("") + print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print("") + + if not(istat == 0): + deps[i.file_name]=tmp + else: + deps[i.file_name]="" return deps @@ -272,6 +363,7 @@ def __init__(self): parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') + parser.add_argument('-d','--dep_dir',nargs='+',action='append',help='Preferred dependecy directory') # Parse the command line arguments args = parser.parse_args() @@ -287,9 +379,10 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' root_dir = args.root_dir[0] if args.root_dir else None + dep_dir = args.dep_dir[0] if args.dep_dir else None if not root_dir: print ("\033[031mError: \033[039m missing path to project root directory \033[032m") sys.exit() - run(path=root_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(path=root_dir, dep=dep_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From 428dd8e8c1efd8d637a5c6c5e07fc1d912835443 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 21:48:39 -0700 Subject: [PATCH 111/325] bug in python script --- python_dep/fort_depend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 20dbc55..541dc4b 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -170,7 +170,8 @@ def check_if_there(use,file): else: with open(file) as f: with open(file, errors='ignore') as f: - if "module" in line.lower(): + for line in f: + if "module" in line.lower(): extrline = line.lower() extrline = extrline.replace("module", "") if use.lower().strip() == extrline.strip(): From 784d0514f02dbf4cf7ee07ec98959ea1302f0bd3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 22:15:02 -0700 Subject: [PATCH 112/325] remove barriers --- mpi_util/fll_mpi_write.f90 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index eb980e1..723b35f 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -117,7 +117,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& ACCESS='STREAM',IOSTAT=ISTAT) - CALL MPI_BARRIER(COMMUNICATOR, IERR) +! CALL MPI_BARRIER(COMMUNICATOR, IERR) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) @@ -146,8 +146,6 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, IF(RANK == ROOT_RANK) THEN POS(1) = 36 + 36 + (NPROC+1)*8 END IF - - CALL MPI_BARRIER(COMMUNICATOR, IERR) ! ! ... and distribute to all partitions ! From abceecf5f601ca373e3c9edf0e5881c0df1dd798 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 22:18:27 -0700 Subject: [PATCH 113/325] added prototype of mpi_read --- data_util/project.dep | 172 ++++++++--------- examples/Example_MPI-IO/Example_mpi-IO.f90 | 6 +- examples/Simple_data_operation/project.dep | 6 +- mpi_util/fll_mpi_mods.f90 | 1 + mpi_util/fll_mpi_read.f90 | 209 +++++++++++++++++++++ mpi_util/project.dep | 38 ++-- 6 files changed, 325 insertions(+), 107 deletions(-) create mode 100644 mpi_util/fll_mpi_read.f90 diff --git a/data_util/project.dep b/data_util/project.dep index 3723677..e08c39a 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,131 +1,131 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o - fll_nnodes.o : \ + fll_type.o \ fll_funct_prt.o \ - fll_out.o \ - fll_type.o + fll_out.o -fll_getnbytes.o : \ - fll_out.o \ - fll_type.o - -fll_mkdir.o : \ +fll_read_ffa.o : \ + fll_type.o \ fll_mk.o \ - fll_type.o - -fll_cat.o : \ - fll_out.o \ - fll_type.o - -fll_type.o : - -fll_stich.o : \ - fll_out.o \ - fll_type.o - -fll_funct_prt.o : \ - fll_out.o \ - fll_type.o + fll_mv.o \ + fll_funct_prt.o \ + fll_out.o -fll_sweep.o : \ - fll_match_pattern.o \ - fll_out.o \ - fll_type.o +fll_mk.o : \ + fll_type.o \ + fll_out.o fll_read.o : \ + fll_type.o \ + fll_mk.o \ fll_mv.o \ fll_funct_prt.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o + fll_out.o + +fll_locate.o : \ + fll_type.o \ + fll_funct_prt.o \ + fll_out.o + +fll_cat.o : \ + fll_type.o \ + fll_out.o + +fll_rm.o : \ + fll_type.o \ + fll_stich.o \ + fll_out.o fll_cp.o : \ + fll_stich.o \ fll_mv.o \ + fll_rm.o \ + fll_duplicate.o \ fll_cat.o \ fll_out.o \ - fll_duplicate.o \ - fll_rm.o \ - fll_stich.o \ fll_type.o -fll_mv.o : \ +fll_deattach.o : \ + fll_type.o \ fll_stich.o \ - fll_out.o \ - fll_rm.o \ - fll_type.o + fll_out.o + +fll_write_ffa.o : \ + fll_type.o \ + fll_out.o fll_write.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_getndata.o : \ - fll_locate.o \ - fll_out.o \ - fll_type.o +fll_funct_prt.o : \ + fll_type.o \ + fll_out.o fll_match_pattern.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o +fll_mkdir.o : \ + fll_type.o \ + fll_mk.o -fll_locate.o : \ - fll_funct_prt.o \ - fll_out.o \ +fll_out.o : \ fll_type.o +fll_mv.o : \ + fll_type.o \ + fll_rm.o \ + fll_stich.o \ + fll_out.o + fll_duplicate.o : \ - fll_mv.o \ + fll_type.o \ fll_mk.o \ - fll_out.o \ - fll_type.o + fll_mv.o \ + fll_out.o fll_mods.o : \ - fll_mv.o \ - fll_out.o \ fll_funct_prt.o \ - fll_stich.o \ - fll_match_pattern.o \ + fll_rm.o \ + fll_duplicate.o \ + fll_read.o \ + fll_deattach.o \ fll_type.o \ - fll_mkdir.o \ + fll_mv.o \ fll_cat.o \ + fll_read_ffa.o \ fll_write.o \ + fll_stich.o \ + fll_getndata.o \ + fll_match_pattern.o \ + fll_nnodes.o \ + fll_mkdir.o \ fll_write_ffa.o \ fll_getnbytes.o \ - fll_mk.o \ - fll_deattach.o \ - fll_duplicate.o \ fll_sweep.o \ - fll_rm.o \ - fll_nnodes.o \ - fll_getndata.o \ - fll_read_ffa.o \ fll_locate.o \ fll_cp.o \ - fll_read.o - -fll_rm.o : \ - fll_stich.o \ fll_out.o \ - fll_type.o + fll_mk.o -fll_mk.o : \ - fll_out.o \ - fll_type.o +fll_getnbytes.o : \ + fll_type.o \ + fll_out.o -fll_out.o : \ - fll_type.o +fll_stich.o : \ + fll_type.o \ + fll_out.o -fll_write_ffa.o : \ - fll_out.o \ - fll_type.o +fll_sweep.o : \ + fll_type.o \ + fll_match_pattern.o \ + fll_out.o + +fll_getndata.o : \ + fll_type.o \ + fll_locate.o \ + fll_out.o + +fll_type.o : diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 5065a04..30d3cd4 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -57,7 +57,7 @@ PROGRAM EXAMPLE_MPI_IO ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW + TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC CHARACTER :: FMT @@ -124,6 +124,10 @@ PROGRAM EXAMPLE_MPI_IO OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + ! ! CLEAN MEMORY diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/project.dep index 0bbc702..4b1a81c 100644 --- a/examples/Simple_data_operation/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! +fll_test_subr.o : \ + ../../data_util/fll_mods.o + fll_test.o : \ ../../data_util/fll_mods.o \ fll_test_subr.o - -fll_test_subr.o : \ - ../../data_util/fll_mods.o diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index 15553b9..d1f56a5 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -39,5 +39,6 @@ MODULE FLL_MPI_MODS_M USE FLL_MPI_MV_M USE FLL_MPI_SUM_M USE FLL_MPI_WRITE_M + USE FLL_MPI_READ_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 new file mode 100644 index 0000000..8f5f2a6 --- /dev/null +++ b/mpi_util/fll_mpi_read.f90 @@ -0,0 +1,209 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MPI_READ_M +! +! Description: contains subroutine reading file in paralell mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) RESULT(PNODE) +! +! Description: contains subroutine readig file in paralell mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! structure of the MPI file is as follows +! +! the main directory is a partitioned_file +! followed by displacement which is a byte position of each partiton in the file +! each data on patition is in subset partition +! +! this is an example of a file with four partitions +! +! -DIR- 5\ partitioned_file +! -L- 5x1 displacements 1 113 40000301 +! -DIR- 4\ partition +! -L- 1x1 part_number 1 +! -D- 1000000x1 pressure +! -D- 1000000x1 density +! -D- 1000000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 2 +! -D- 1100000x1 pressure +! -D- 1100000x1 density +! -D- 1100000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 3 +! -D- 1200000x1 pressure +! -D- 1200000x1 density +! -D- 1200000x3 velocity +! -DIR- 4\ partition +! -L- 1x1 part_number 4 +! -D- 1300000x1 pressure +! -D- 1300000x1 density +! -D- 1300000x3 velocity + + +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + USE FLL_MPI_CP_ALL_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! OPTION In Type of write +! COMMUNICATOR In communicator +! FPAR In/Out structure containing function specific data +! OK Out Success or fail +! ROOT_RANK In Rank of the root process +! Rank In Rank of the process +! +! Arguments declaration +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT,RANK, ROOT_RANK, COMMUNICATOR + CHARACTER :: OPTION +! +! local declarations +! + TYPE(DNODE), POINTER :: PTMP, PTMP1 + INTEGER :: ISTAT,IERR + INTEGER(LINT), POINTER :: DISPL(:) + INTEGER(LINT) :: POS +! +! use always binary fomat +! + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! Position in file with empty write statement +! + IF(RANK == ROOT_RANK)THEN +! INQUIRE(UNIT=IOUNIT,POS=1_LINT) + PTMP => FLL_RPART_FILE_HEADER(IOUNIT, FPAR) + END IF + + PTMP1 => FLL_MPI_CP_ALL(PTMP,COMMUNICATOR,ROOT_RANK,FPAR) + IF(RANK /= ROOT_RANK) PTMP => PTMP1 + + DISPL => PTMP%L1 +! +! Read linked list +! + PNODE => READ_NODE(IOUNIT,'B',DISPL(RANK+2),FPAR) + + if(rank ==0)CALL FLL_CAT(PNODE,6,.false., FPAR) +! +! MPI_Barrier does not need to be here, +! just for testing purposes +! + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + CALL FLL_RM(PTMP, FPAR) + + + FPAR%SUCCESS = .TRUE. + RETURN + + END FUNCTION FLL_MPI_READ + + + FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) +! +! Description: contains subroutine reading file header +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_MODS_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! IOUNIT In Number of unit +! FPAR In/Out structure containing function specific data +! PNEW Returns array of displacements +! +! Arguments declaration +! + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + TYPE(DNODE), POINTER :: PNEW +! +! Local declarations +! + CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=TYPE_LENGTH) :: TYPE + INTEGER(LINT) :: NDIM,NSIZE,I + + READ(IOUNIT)NAME,TYPE,NDIM,NSIZE + READ(IOUNIT)NAME,TYPE,NDIM,NSIZE + PNEW => FLL_MK(NAME,TYPE,NDIM,NSIZE,FPAR) + READ(IOUNIT)(PNEW%L1(I), I=1,NDIM) + + RETURN + + END FUNCTION FLL_RPART_FILE_HEADER +END MODULE FLL_MPI_READ_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 905c451..dc1ea67 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,33 +1,37 @@ # This file is generated automatically. DO NOT EDIT! +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_out.o \ + ../data_util/fll_type.o + +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o + fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ ../data_util/fll_out.o \ ../data_util/fll_type.o -fll_mpi_sum.o : \ - ../data_util/fll_mods.o - fll_mpi_mods.o : \ - fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_sum.o \ fll_mpi_cp.o \ + fll_mpi_mv.o \ fll_mpi_write.o \ - fll_mpi_sum.o \ fll_mpi_cp_all.o -fll_mpi_mv.o : \ - fll_mpi_cp.o \ - ../data_util/fll_out.o \ - ../data_util/fll_rm.o \ - ../data_util/fll_type.o - -fll_mpi_write.o : \ - ../data_util/fll_mods.o \ - fll_mpi_sum.o - fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ ../data_util/fll_out.o \ ../data_util/fll_type.o + +fll_mpi_read.o : \ + ../data_util/fll_mods.o + +fll_mpi_sum.o : \ + ../data_util/fll_mods.o From b0be7276e38d094f9e7f3b530a8461f8ba948743 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 22:46:01 -0700 Subject: [PATCH 114/325] Add reading binary file from position --- data_util/fll_read.f90 | 85 +++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index b3492fa..95388a3 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -149,6 +149,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! READ INITIAL NODE ! + POS = 1 PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,FPAR) CLOSE(IOUNIT) @@ -257,7 +258,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CASE('A') CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) CASE('B') - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) END SELECT END IF @@ -398,9 +399,10 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) CASE('B') NSIZE = 0 - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NDIM,nsize - FPAR%SUCCESS = .TRUE. - RETURN + READ(IOUNIT,IOSTAT=IOSTAT,POS = POS)NAME,LTYPE,NDIM,NSIZE + INQUIRE(UNIT = IOUNIT, POS=POS) + FPAR%SUCCESS = .TRUE. + RETURN END SELECT WRITE(FPAR%MESG,'(A)')' Read - reading header error ' @@ -561,7 +563,7 @@ END SUBROUTINE READ_DATA_ASCII ! ! READ DATA ! - SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) ! ! Description: Function reads data contained in Pnode, bindary file ! @@ -583,18 +585,19 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! ! Arguments description ! Name In/Out Function -! PNODE In Pointer to node +! PNODE In Pointer to node ! IOUNIT In Number of unit -! LTYPE In type of node -! NDIM In 1st dimension of array in the node -! NSIZE In 2nd dimension of array in the node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! POS In Position in file ! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT - INTEGER(LINT) :: NDIM,NSIZE + INTEGER(LINT) :: NDIM,NSIZE,POS CHARACTER(*) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR ! @@ -610,30 +613,38 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%R0 + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF CASE('D') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%D0 + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%D0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -641,15 +652,19 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('I') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%I0 + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%I0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -657,15 +672,19 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('L') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)PNODE%L0 + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%L0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) - ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -673,15 +692,19 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('S') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) + READ(IOUNIT,*,IOSTAT=IOSTAT, POS=POS)(PNODE%S1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%S0 + READ(IOUNIT,*,IOSTAT=IOSTAT, POS=POS)PNODE%S0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%S1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%S2(I,J),J=1,NSIZE),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF From e91822d17c0a19f02d39c7d04aef5a81dcce526c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 14 Nov 2016 22:46:13 -0700 Subject: [PATCH 115/325] finish mpi_read --- mpi_util/fll_mpi_read.f90 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 8f5f2a6..19fed56 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -138,9 +138,10 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R ! ! Read linked list ! - PNODE => READ_NODE(IOUNIT,'B',DISPL(RANK+2),FPAR) + POS = DISPL(RANK+2) + PNODE => READ_NODE(IOUNIT,'B',POS,FPAR) - if(rank ==0)CALL FLL_CAT(PNODE,6,.false., FPAR) + if(rank ==1)CALL FLL_CAT(PNODE,6,.false., FPAR) ! ! MPI_Barrier does not need to be here, ! just for testing purposes From 66827044c0005a5756fb49663ab0ac5f7b798921 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 15 Nov 2016 21:26:33 -0700 Subject: [PATCH 116/325] tie everything to RANK index --- mpi_util/fll_mpi_write.f90 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index 723b35f..f9aa533 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -158,10 +158,12 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, LOC_DISPL = 1 DISPL = 0 - DO I=2,PART_NUM+1 +! DO I=2,PART_NUM+1 + DO I=2,RANK+2 LOC_DISPL = LOC_DISPL + POS(I-1) END DO - DISPL(PART_NUM+1) = LOC_DISPL +! DISPL(PART_NUM+1) = LOC_DISPL + DISPL(RANK+2) = LOC_DISPL CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) DISPL(1) = 1 ! From d19026df9f11ac34dc501f049192eb61786d3782 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 15 Nov 2016 21:26:42 -0700 Subject: [PATCH 117/325] release memory --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 30d3cd4..3d72e24 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -76,7 +76,7 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) - call MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) + CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) IF(WORLD_RANK == 0) THEN CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) @@ -111,9 +111,9 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) + !CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) -! CALL CREATE_DATA_SET(PDATA_SET,1000_LINT, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,10_LINT, WORLD_RANK) ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! @@ -127,14 +127,14 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) - - ! ! CLEAN MEMORY ! IF(WORLD_RANK==0)write(*,*)' Releasing memory' CALL FLL_RM(FLL_MPI_STRUCT,FPAR) CALL FLL_RM(PDATA_SET,FPAR) + CALL FLL_RM(PTMP,FPAR) + CALL MPI_FINALIZE(IERR) From 2ad306f0638c31e19d70ae1f8c2cbe7a079c6086 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 11:34:49 -0700 Subject: [PATCH 118/325] add missing recursive instruction --- mpi_util/fll_mpi_cp.f90 | 2 +- mpi_util/fll_mpi_cp_all.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index bdbbb0e..5dc10ae 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -209,7 +209,7 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR END SUBROUTINE FLL_SEND_RECURSIVE - SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) + RECURSIVE SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ! Description: makes recursive duplicate of PNODE ! diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index 0d91c54..3aa622f 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -207,7 +207,7 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) END SUBROUTINE FLL_SEND_RECURSIVE - SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) + RECURSIVE SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! ! Description: makes recursive duplicate of PNODE ! From 93a32272b5937c3223f456de5ef09ad36bf1b3b2 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 11:37:07 -0700 Subject: [PATCH 119/325] add size of data to stdoutput --- data_util/project.dep | 172 ++++++++++----------- examples/Example_MPI-IO/Example_mpi-IO.f90 | 14 +- mpi_util/project.dep | 43 +++--- 3 files changed, 117 insertions(+), 112 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index e08c39a..3723677 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -1,131 +1,131 @@ # This file is generated automatically. DO NOT EDIT! +fll_deattach.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o + fll_nnodes.o : \ - fll_type.o \ fll_funct_prt.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_read_ffa.o : \ - fll_type.o \ +fll_getnbytes.o : \ + fll_out.o \ + fll_type.o + +fll_mkdir.o : \ fll_mk.o \ - fll_mv.o \ - fll_funct_prt.o \ - fll_out.o + fll_type.o -fll_mk.o : \ - fll_type.o \ - fll_out.o +fll_cat.o : \ + fll_out.o \ + fll_type.o -fll_read.o : \ - fll_type.o \ - fll_mk.o \ - fll_mv.o \ - fll_funct_prt.o \ - fll_out.o +fll_type.o : -fll_locate.o : \ - fll_type.o \ - fll_funct_prt.o \ - fll_out.o +fll_stich.o : \ + fll_out.o \ + fll_type.o -fll_cat.o : \ - fll_type.o \ - fll_out.o +fll_funct_prt.o : \ + fll_out.o \ + fll_type.o -fll_rm.o : \ - fll_type.o \ - fll_stich.o \ - fll_out.o +fll_sweep.o : \ + fll_match_pattern.o \ + fll_out.o \ + fll_type.o + +fll_read.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ + fll_type.o fll_cp.o : \ - fll_stich.o \ fll_mv.o \ - fll_rm.o \ - fll_duplicate.o \ fll_cat.o \ fll_out.o \ + fll_duplicate.o \ + fll_rm.o \ + fll_stich.o \ fll_type.o -fll_deattach.o : \ - fll_type.o \ +fll_mv.o : \ fll_stich.o \ - fll_out.o - -fll_write_ffa.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_rm.o \ + fll_type.o fll_write.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_funct_prt.o : \ - fll_type.o \ - fll_out.o +fll_getndata.o : \ + fll_locate.o \ + fll_out.o \ + fll_type.o fll_match_pattern.o : \ - fll_type.o \ - fll_out.o - -fll_mkdir.o : \ - fll_type.o \ - fll_mk.o + fll_out.o \ + fll_type.o -fll_out.o : \ +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ fll_type.o -fll_mv.o : \ - fll_type.o \ - fll_rm.o \ - fll_stich.o \ - fll_out.o +fll_locate.o : \ + fll_funct_prt.o \ + fll_out.o \ + fll_type.o fll_duplicate.o : \ - fll_type.o \ - fll_mk.o \ fll_mv.o \ - fll_out.o + fll_mk.o \ + fll_out.o \ + fll_type.o fll_mods.o : \ - fll_funct_prt.o \ - fll_rm.o \ - fll_duplicate.o \ - fll_read.o \ - fll_deattach.o \ - fll_type.o \ fll_mv.o \ - fll_cat.o \ - fll_read_ffa.o \ - fll_write.o \ + fll_out.o \ + fll_funct_prt.o \ fll_stich.o \ - fll_getndata.o \ fll_match_pattern.o \ - fll_nnodes.o \ + fll_type.o \ fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ fll_write_ffa.o \ fll_getnbytes.o \ + fll_mk.o \ + fll_deattach.o \ + fll_duplicate.o \ fll_sweep.o \ + fll_rm.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ fll_locate.o \ fll_cp.o \ - fll_out.o \ - fll_mk.o + fll_read.o -fll_getnbytes.o : \ - fll_type.o \ - fll_out.o - -fll_stich.o : \ - fll_type.o \ - fll_out.o +fll_rm.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o -fll_sweep.o : \ - fll_type.o \ - fll_match_pattern.o \ - fll_out.o +fll_mk.o : \ + fll_out.o \ + fll_type.o -fll_getndata.o : \ - fll_type.o \ - fll_locate.o \ - fll_out.o +fll_out.o : \ + fll_type.o -fll_type.o : +fll_write_ffa.o : \ + fll_out.o \ + fll_type.o diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 3d72e24..3fc9768 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -62,7 +62,7 @@ PROGRAM EXAMPLE_MPI_IO INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC CHARACTER :: FMT - INTEGER(LINT) :: NFILES,BYTES + INTEGER(LINT) :: NFILES,BYTES,BYTESN CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK @@ -94,7 +94,7 @@ PROGRAM EXAMPLE_MPI_IO END IF ! -! Copy FLL_MPI_STRUCT date set which now exists on root partition only +! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc ! to all other partitions ! upon return, the function will return pointer to newly allocated data ! for all other partition then root partition @@ -111,9 +111,11 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - !CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) + BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) + WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN - CALL CREATE_DATA_SET(PDATA_SET,10_LINT, WORLD_RANK) +! CALL CREATE_DATA_SET(PDATA_SET,10_LINT, WORLD_RANK) ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) ! @@ -126,7 +128,9 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + BYTESN = FLL_GETNBYTES(PTMP,FPAR) + WRITE(*,*)' Partition reads data set size of ', WORLD_RANK,BYTESN ! ! CLEAN MEMORY ! diff --git a/mpi_util/project.dep b/mpi_util/project.dep index dc1ea67..2003752 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,37 +1,38 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_mv.o : \ +fll_mpi_mods.o : \ fll_mpi_cp.o \ - ../data_util/fll_rm.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o + fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o -fll_mpi_write.o : \ - ../data_util/fll_mods.o \ - fll_mpi_sum.o +fll_mpi_sum.o : \ + ../data_util/fll_mods.o fll_mpi_cp_all.o : \ - ../data_util/fll_mk.o \ ../data_util/fll_mv.o \ + ../data_util/fll_mk.o \ ../data_util/fll_out.o \ ../data_util/fll_type.o -fll_mpi_mods.o : \ - fll_mpi_read.o \ - fll_mpi_sum.o \ - fll_mpi_cp.o \ - fll_mpi_mv.o \ - fll_mpi_write.o \ +fll_mpi_read.o : \ + ../data_util/fll_mods.o \ fll_mpi_cp_all.o -fll_mpi_cp.o : \ - ../data_util/fll_mk.o \ - ../data_util/fll_mv.o \ +fll_mpi_mv.o : \ + fll_mpi_cp.o \ ../data_util/fll_out.o \ + ../data_util/fll_rm.o \ ../data_util/fll_type.o -fll_mpi_read.o : \ - ../data_util/fll_mods.o +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o -fll_mpi_sum.o : \ - ../data_util/fll_mods.o +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o \ + ../data_util/fll_type.o From ee0c3d7c3df09b73ec59e1fa133cb4144682d73a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 12:35:19 -0700 Subject: [PATCH 120/325] protect agains NULL communicator --- mpi_util/fll_mpi_cp.f90 | 5 +++++ mpi_util/fll_mpi_cp_all.f90 | 5 +++++ mpi_util/fll_mpi_mv.f90 | 5 +++++ mpi_util/fll_mpi_read.f90 | 4 ++++ mpi_util/fll_mpi_sum.f90 | 4 ++++ mpi_util/fll_mpi_write.f90 | 6 +++++- 6 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index 5dc10ae..0cbbe6e 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -48,6 +48,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! ! External Modules used ! + USE MPI USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M @@ -77,6 +78,10 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PCHILD INTEGER :: RANK, IERR ! +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! ! check the node is not null ! FPAR%SUCCESS = .FALSE. diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index 3aa622f..d955b24 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -48,6 +48,7 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! ! External Modules used ! + USE MPI USE FLL_TYPE_M USE FLL_MK_M USE FLL_MV_M @@ -76,6 +77,10 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PCHILD INTEGER :: RANK, IERR ! +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! ! check the node is not null ! FPAR%SUCCESS = .FALSE. diff --git a/mpi_util/fll_mpi_mv.f90 b/mpi_util/fll_mpi_mv.f90 index 1b2f067..4b9865c 100644 --- a/mpi_util/fll_mpi_mv.f90 +++ b/mpi_util/fll_mpi_mv.f90 @@ -48,6 +48,7 @@ FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! ! External Modules used ! + USE MPI USE FLL_TYPE_M USE FLL_MPI_CP_M USE FLL_RM_M @@ -77,6 +78,10 @@ FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PCHILD INTEGER :: RANK, IERR ! +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! ! check the node is not null ! FPAR%SUCCESS = .FALSE. diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 19fed56..0599ceb 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -112,6 +112,10 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R INTEGER(LINT), POINTER :: DISPL(:) INTEGER(LINT) :: POS ! +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! ! use always binary fomat ! OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& diff --git a/mpi_util/fll_mpi_sum.f90 b/mpi_util/fll_mpi_sum.f90 index a6508da..a048295 100644 --- a/mpi_util/fll_mpi_sum.f90 +++ b/mpi_util/fll_mpi_sum.f90 @@ -97,6 +97,10 @@ SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM ,R,D,I,L,R1,D1,I1,L1) ! Body of subroutine ! ! +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! ! vector/matrix ! VECSCAL: IF(NDIM > 1)THEN diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index f9aa533..f3f7943 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -112,7 +112,11 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) INTEGER(LINT) :: POS1,I,PART_NUM,LOC_DISPL ! -! use always binary fomat +! if not in group, return +! + IF(COMMUNICATOR == MPI_COMM_NULL)RETURN +! +! use always binary fomat ! OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& ACCESS='STREAM',IOSTAT=ISTAT) From eaa7691ad92400727ea7533bf2a900cb8c897f0d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 13:05:02 -0700 Subject: [PATCH 121/325] sync return parameters for MPI_COMM_NULL --- mpi_util/fll_mpi_cp.f90 | 5 ++++- mpi_util/fll_mpi_cp_all.f90 | 5 ++++- mpi_util/fll_mpi_mv.f90 | 5 ++++- mpi_util/fll_mpi_read.f90 | 5 ++++- mpi_util/fll_mpi_write.f90 | 5 ++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index 0cbbe6e..dcdfa66 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -80,7 +80,10 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! ! if not in group, return ! - IF(COMMUNICATOR == MPI_COMM_NULL)RETURN + IF(COMMUNICATOR == MPI_COMM_NULL)THEN + PNEW => NULL() + RETURN + END IF ! ! check the node is not null ! diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index d955b24..03a07a4 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -79,7 +79,10 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! ! if not in group, return ! - IF(COMMUNICATOR == MPI_COMM_NULL)RETURN + IF(COMMUNICATOR == MPI_COMM_NULL)THEN + PNEW => NULL() + RETURN + END IF ! ! check the node is not null ! diff --git a/mpi_util/fll_mpi_mv.f90 b/mpi_util/fll_mpi_mv.f90 index 4b9865c..7a25e2b 100644 --- a/mpi_util/fll_mpi_mv.f90 +++ b/mpi_util/fll_mpi_mv.f90 @@ -80,7 +80,10 @@ FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! ! if not in group, return ! - IF(COMMUNICATOR == MPI_COMM_NULL)RETURN + IF(COMMUNICATOR == MPI_COMM_NULL)THEN + PNEW => NULL() + RETURN + END IF ! ! check the node is not null ! diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 0599ceb..0d39379 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -114,7 +114,10 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R ! ! if not in group, return ! - IF(COMMUNICATOR == MPI_COMM_NULL)RETURN + IF(COMMUNICATOR == MPI_COMM_NULL)THEN + PNODE => NULL() + RETURN + END IF ! ! use always binary fomat ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index f3f7943..0cd0e2d 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -114,7 +114,10 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! ! if not in group, return ! - IF(COMMUNICATOR == MPI_COMM_NULL)RETURN + IF(COMMUNICATOR == MPI_COMM_NULL)THEN + OK = .FALSE. + RETURN + END IF ! ! use always binary fomat ! From 7d8ea523c4e8f7fcb834c60e4fa49352a5ba40c8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 13:59:06 -0700 Subject: [PATCH 122/325] change output --- data_util/fll_getnbytes.f90 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 index 7184f7b..043cad9 100644 --- a/data_util/fll_getnbytes.f90 +++ b/data_util/fll_getnbytes.f90 @@ -71,10 +71,11 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) ! ! check the node is not null ! + BYTES = 0 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT('LOG',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF From aa09b6cbaa67f13ba3a0505a9b775373d5106a93 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 13:59:34 -0700 Subject: [PATCH 123/325] add saving and reading group file --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 59 ++++++++++++++++++---- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 3fc9768..c0f00d0 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -59,14 +59,17 @@ PROGRAM EXAMPLE_MPI_IO CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC + INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT CHARACTER :: FMT - INTEGER(LINT) :: NFILES,BYTES,BYTESN + INTEGER(LINT) :: NFILES,BYTES,BYTESN,J + integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK INTEGER(LINT), ALLOCATABLE :: POS(:) + INTEGER, ALLOCATABLE :: EVEN_RANK(:) + INTEGER :: E_RANK ! ! Initialize MPI ! @@ -111,33 +114,71 @@ PROGRAM EXAMPLE_MPI_IO ! make some data set similar to solution ! IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,1000000_LINT+100000*WORLD_RANK, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN ! CALL CREATE_DATA_SET(PDATA_SET,10_LINT, WORLD_RANK) - - ! CALL MPI_Comm_group ( MPI_COMM_WORLD, world_group_id, ierr ) -! -! MPI_Barrier does not need to be here, -! just for testing purposes ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + WRITE(*,*)' READING FILES' CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) BYTESN = FLL_GETNBYTES(PTMP,FPAR) WRITE(*,*)' Partition reads data set size of ', WORLD_RANK,BYTESN + CALL FLL_RM(PTMP,FPAR) + +! +! make a group and save to a separate file +! +! +! Get a group identifier for MPI_COMM_WORLD. +! + CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) +! + EVEN_P = ( NPROC + 1 ) / 2 + ALLOCATE ( EVEN_RANK(1:EVEN_P), STAT = ISTAT ) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' + + ISTAT = 0 + DO I = 0, NPROC - 1, 2 + ISTAT = ISTAT + 1 + EVEN_RANK(ISTAT) = I+1 + END DO +! +! create group in parent group: world_group_id, number of processes +! in that group is: even_p +! the processesare: even_rank(:) +! the group ID is then +! + CALL MPI_Group_incl(WORLD_GROUP_ID, EVEN_P, EVEN_RANK, EVEN_GROUP_ID, IERR ) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + CALL MPI_Comm_create(MPI_COMM_WORLD, EVEN_GROUP_ID, EVEN_COMM_ID, IERR ) + + IF(EVEN_COMM_ID /= MPI_COMM_NULL)THEN + CALL MPI_Comm_rank(EVEN_COMM_ID, E_RANK, IERR ) + END IF + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) + + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + PTMP => NULL() + PTMP => FLL_MPI_READ('PartitionedFile',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) + BYTESN = FLL_GETNBYTES(PTMP,FPAR) + WRITE(*,*)' Partition reads data set size of ', WORLD_RANK,BYTESN + CALL FLL_RM(PTMP,FPAR) + ! ! CLEAN MEMORY ! IF(WORLD_RANK==0)write(*,*)' Releasing memory' CALL FLL_RM(FLL_MPI_STRUCT,FPAR) CALL FLL_RM(PDATA_SET,FPAR) - CALL FLL_RM(PTMP,FPAR) CALL MPI_FINALIZE(IERR) From aa09ed9a47b0c56a60913af55fdc2472dd9e9ecb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 15:16:17 -0700 Subject: [PATCH 124/325] add prototyme of NM model for MPI WRITE --- mpi_util/fll_mpi_mods.f90 | 1 + mpi_util/fll_mpi_write_nm.f90 | 77 +++++++++++++++++++++++++++++++++++ mpi_util/project.dep | 31 ++++++++------ 3 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 mpi_util/fll_mpi_write_nm.f90 diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index d1f56a5..ea2315a 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -39,6 +39,7 @@ MODULE FLL_MPI_MODS_M USE FLL_MPI_MV_M USE FLL_MPI_SUM_M USE FLL_MPI_WRITE_M + USE FLL_MPI_WRITE_NM_M USE FLL_MPI_READ_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 new file mode 100644 index 0000000..ca6379a --- /dev/null +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -0,0 +1,77 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MPI_WRITE_NM_M +! +! Description: contains subroutine writing file in paralell mode from N processors to M files +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_MPI_WRITE_NM(PNODE,FILE,IOUNIT,FILE_TAB,FPAR) RESULT(OK) +! +! Description: contains subroutine writing file in paralell mode from N processors to M files +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + USE FLL_MPI_WRITE_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FILE_TAB In Specifies which partition saves to which file +! FPAR In/Out structure containing function specific data +! OK Out Success or fail +! +! Arguments declaration +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE, FILE_TAB + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + LOGICAL OK +! +! local declarations +! + + END FUNCTION FLL_MPI_WRITE_NM + +END MODULE FLL_MPI_WRITE_NM_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 2003752..2e77303 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,31 +1,36 @@ # This file is generated automatically. DO NOT EDIT! +fll_mpi_cp_all.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o + +fll_mpi_sum.o : \ + ../data_util/fll_mods.o + +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o + fll_mpi_mods.o : \ fll_mpi_cp.o \ + fll_mpi_write_nm.o \ fll_mpi_write.o \ fll_mpi_sum.o \ fll_mpi_mv.o \ fll_mpi_read.o \ fll_mpi_cp_all.o -fll_mpi_sum.o : \ - ../data_util/fll_mods.o - -fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o - fll_mpi_read.o : \ ../data_util/fll_mods.o \ fll_mpi_cp_all.o fll_mpi_mv.o : \ fll_mpi_cp.o \ + ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_rm.o \ - ../data_util/fll_type.o + ../data_util/fll_rm.o fll_mpi_write.o : \ ../data_util/fll_mods.o \ @@ -33,6 +38,6 @@ fll_mpi_write.o : \ fll_mpi_cp.o : \ ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o + ../data_util/fll_out.o From 9073db9c34fe076cb1e035656c95e8f97c4278d1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 15:16:33 -0700 Subject: [PATCH 125/325] example module cleanup --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index c0f00d0..b6346cc 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -62,7 +62,7 @@ PROGRAM EXAMPLE_MPI_IO INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT CHARACTER :: FMT - INTEGER(LINT) :: NFILES,BYTES,BYTESN,J + INTEGER(LINT) :: NFILES,BYTES,BYTESN,NSIZE integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK @@ -70,6 +70,7 @@ PROGRAM EXAMPLE_MPI_IO INTEGER(LINT), ALLOCATABLE :: POS(:) INTEGER, ALLOCATABLE :: EVEN_RANK(:) INTEGER :: E_RANK + REAL :: RANDNUM ! ! Initialize MPI ! @@ -89,17 +90,11 @@ PROGRAM EXAMPLE_MPI_IO FLL_MPI_STRUCT => NULL() CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,1_LINT*NPROC) -! WRITE(*,*)' duplicating' -! PNEW => FLL_CP(FLL_MPI_STRUCT, NULL(), FPAR) -! WRITE(*,*)' duplicate' -! OK = FLL_MV(PNEW, FLL_MPI_STRUCT,FPAR) -! CALL FLL_CAT(FLL_MPI_STRUCT,6,.false., FPAR) - END IF ! ! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc ! to all other partitions -! upon return, the function will return pointer to newly allocated data +! Upon return, the function will return pointer to newly allocated data ! for all other partition then root partition ! On root partition, the PNEW pointer is pointing on FLL_MPI_STRUCT ! @@ -112,13 +107,13 @@ PROGRAM EXAMPLE_MPI_IO END IF ! ! make some data set similar to solution -! - IF(WORLD_RANK==0)WRITE(*,*)' creating data set' - CALL CREATE_DATA_SET(PDATA_SET,100000_LINT+10000*WORLD_RANK, WORLD_RANK) + NSIZE = 100000 + + CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN - -! CALL CREATE_DATA_SET(PDATA_SET,10_LINT, WORLD_RANK) +! +! Write - each partition to one common file ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) From e34259cb4f4f67c8d854a5afae9c839ffbe2a375 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 16 Nov 2016 19:29:07 -0700 Subject: [PATCH 126/325] correct STOP ERR MEMORY statements --- mpi_util/fll_mpi_sum.f90 | 16 ++++++++-------- mpi_util/fll_mpi_write.f90 | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mpi_util/fll_mpi_sum.f90 b/mpi_util/fll_mpi_sum.f90 index a048295..631de78 100644 --- a/mpi_util/fll_mpi_sum.f90 +++ b/mpi_util/fll_mpi_sum.f90 @@ -107,41 +107,41 @@ SUBROUTINE FLL_MPI_SUM(COMMUNICATOR, NDIM ,R,D,I,L,R1,D1,I1,L1) IF(PRESENT(R1))THEN ALLOCATE(TR1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:106 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:110 ' TR1 = R1 CALL MPI_ALLREDUCE(TR1,R1,NDIM,MPI_REAL,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TR1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:110 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:114 ' RETURN END IF IF(PRESENT(D1))THEN ALLOCATE(TD1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:116 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:120 ' TD1 = D1 CALL MPI_ALLREDUCE(TD1,D1,NDIM,MPI_DOUBLE,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TD1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:120 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:124 ' RETURN END IF IF(PRESENT(I1))THEN ALLOCATE(TI1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:126 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:130 ' TI1 = I1 CALL MPI_ALLREDUCE(TI1,I1,NDIM,MPI_INTEGER,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TI1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:130 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:134 ' RETURN END IF IF(PRESENT(L1))THEN ALLOCATE(TL1(NDIM), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:136 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_sum ERR:140 ' TL1 = L1 CALL MPI_ALLREDUCE(TL1,L1,NDIM,MPI_INTEGER8,MPI_SUM,COMMUNICATOR,IERR) DEALLOCATE(TL1, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:140 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_mpi_sum ERR:144 ' RETURN END IF ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index 0cd0e2d..fb7a29b 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -141,7 +141,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! Get length of each data set ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:104 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:144 ' POS = 0 POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) @@ -200,7 +200,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, END IF DEALLOCATE(POS, DISPL, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:156 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:203 ' OK = .TRUE. RETURN From b06473a876ce509b296b2cb6171e42f66b444f50 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 09:18:05 -0700 Subject: [PATCH 127/325] correct typo --- configure.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.py b/configure.py index 1e5bd94..e6eacc0 100755 --- a/configure.py +++ b/configure.py @@ -184,8 +184,8 @@ def mkconfigfile(path, cwd,version, bin_dir): if not(os.path.exists(filename)): print ("\033[031mError: \033[039m \033[031m"+version+"\033[039m verion of compiler is not available") - print ("\033[031m \033[039m available options are: \033[032m gfotran\033[039m") - print ("\033[031m \033[039m \033[032m gfotran_debug\033[039m") + print ("\033[031m \033[039m available options are: \033[032m gfortran\033[039m") + print ("\033[031m \033[039m \033[032m gfortran_debug\033[039m") print ("\033[031m \033[039m \033[032m x86_64\033[039m") print ("\033[031m \033[039m \033[032m x86_64_debug\033[039m") sys.exit() @@ -285,8 +285,8 @@ def print_header(): if not compiler: print ("\033[031mError: \033[039m missing compiler settings, specify option \033[031m-c \033[032m") - print ("\033[031m \033[039m available options are: \033[032m gfotran\033[039m") - print ("\033[031m \033[039m \033[032m gfotran_debug\033[039m") + print ("\033[031m \033[039m available options are: \033[032m gfortran\033[039m") + print ("\033[031m \033[039m \033[032m gfortran_debug\033[039m") print ("\033[031m \033[039m \033[032m x86_64\033[039m") print ("\033[031m \033[039m \033[032m x86_64_debug\033[039m") sys.exit() From fc9ad44885778ac8b503324f301ff84b826ea28d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 09:44:14 -0700 Subject: [PATCH 128/325] add linking python scripts --- configure.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/configure.py b/configure.py index e6eacc0..dd1cb23 100755 --- a/configure.py +++ b/configure.py @@ -20,7 +20,7 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= # definition of parameters # print_header() - linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep']) + linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep', '*.py']) exclude =(['python_dep', 'config', '.git']) # # @@ -166,6 +166,23 @@ def mkdir_structure(root_path,cwd, exclude, linkfiles): print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") linkfile = os.symlink( source, dest) +# +# check if python script +# + if os.path.isdir(dirtmp): + for file in os.listdir(dirtmp): + if file.endswith(".py"): + source = dirtmp+'/'+file + dest = newdir+'/'+file + try: + os.remove(file) + print ("\033[031mDIAG: \033[039m script file \033[032m"+file+"\033[039m already exists, removing ....") + except OSError: + pass + + print ("\033[031mDIAG: \033[039m linking sript file \033[032m"+source+"\033[039m ....") + linkfile = os.symlink( source, dest) + os.chdir(cwd) print(" ") From 0c9b14a15a7da9a74abbe723ec260ba26f798ffa Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 10:30:38 -0700 Subject: [PATCH 129/325] add accessories and the first utility --- accessories/Makefile | 59 +++++++++++++++++++ accessories/fll_cat/Makefile | 67 ++++++++++++++++++++++ accessories/fll_cat/fll_cat.f90 | 72 +++++++++++++++++++++++ accessories/fll_cat/fll_cat.py | 88 +++++++++++++++++++++++++++++ accessories/fll_cat/project.dep | 4 ++ accessories/fll_cat/src_dir_path.mk | 2 + accessories/src_dir_path.mk | 2 + 7 files changed, 294 insertions(+) create mode 100644 accessories/Makefile create mode 100644 accessories/fll_cat/Makefile create mode 100644 accessories/fll_cat/fll_cat.f90 create mode 100755 accessories/fll_cat/fll_cat.py create mode 100644 accessories/fll_cat/project.dep create mode 100644 accessories/fll_cat/src_dir_path.mk create mode 100644 accessories/src_dir_path.mk diff --git a/accessories/Makefile b/accessories/Makefile new file mode 100644 index 0000000..86bb1b3 --- /dev/null +++ b/accessories/Makefile @@ -0,0 +1,59 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# +include src_dir_path.mk +include ../config.mk + +DEP_FILE=project.dep + +#FMODDIRS= ../../data_util + +#SUBDIRS= $(dir $(wildcard $(srcdir)/*)) +SUBDIRS= \ + fll_cat + + + +########################################################################### + +all: $(SUBDIRS:%=%.all) + +include ../rules.mk + +clean: $(SUBDIRS:%=%.clean) + rm -f *.x *.o *.mod + +depend: $(SUBDIRS:%=%.depend) + +install: $(SUBDIRS:%=%.install) + +test: $(SUBDIRS:%=%.test) + +chk: $(SUBDIRS:%=%.chk) diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile new file mode 100644 index 0000000..b6d1313 --- /dev/null +++ b/accessories/fll_cat/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_cat + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=project.dep + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +install: $(EXE).x $(EXE) + $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) + $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x + +-include $(srcdir)/project.dep diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 new file mode 100644 index 0000000..ce6b329 --- /dev/null +++ b/accessories/fll_cat/fll_cat.f90 @@ -0,0 +1,72 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints file on screen +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM FLL_CATU + + USE FLL_MODS_M + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER :: FMT +! +! read a file and print on screen +! + READ(*,*)FILE + READ(*,*)FMT + + PNODE => FLL_READ(FILE,8,FMT,FPAR) +! +! print node on the screen +! + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) + WRITE(*,*) + CALL FLL_RM(PNODE,FPAR) + + +END PROGRAM diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py new file mode 100755 index 0000000..30a56fb --- /dev/null +++ b/accessories/fll_cat/fll_cat.py @@ -0,0 +1,88 @@ +#!/usr/bin/python +# +# +# this is a python script wj +# +import os +import sys +from subprocess import Popen, PIPE + +#Definitions + +def run(file,fmt): +# +# execute +# + print_header() +# + path = os.path.dirname(os.path.abspath(__file__)) + cwd = os.getcwd() + + path = check_path(path=path) + cwd = check_path(path=cwd) + + executable = path+"fll_cat.x" + + if not os.path.isfile(file): + print(" ") + print("\033[031mERROR:\033[039m specified file \033[032m"+file+"\033[039m does not exist, terminating .... ") + sys.exit() + + print(" ") + print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + print("\033[039m Specified file format is: \033[032m"+fmt+"\033[039m") + print(" ") + + p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here + p.communicate(os.linesep.join([file, fmt])) + +def print_header(): + print(" ") + print ("\033[031m************************************************************************************ \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m* \033[039m fll_cat - v1.1 \033[031m * \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m* \033[039m prints content of file on screen \033[031m * \033[039m") + print ("\033[031m* * \033[039m") + print ("\033[031m************************************************************************************ \033[039m") + + +def check_path(path): + if not(path.endswith("/")): + path=path + "/" + + return path + + + +#Script +if __name__ == "__main__": + import argparse + + # Add command line arguments + parser = argparse.ArgumentParser(description='FLL configure script') + parser.add_argument('-i','--file',nargs=1,help='Files to process') + parser.add_argument('-f','--format',nargs=1,help='Format of the file') + + # Parse the command line arguments + args = parser.parse_args() + + file = args.file[0] if args.file else None + format = args.format[0] if args.format else None + + if not file: + print ("\033[031mError: \033[039m missing name of file\033[031m-c \033[032m") + sys.exit() + + if not format: + print ("\033[031mError: \033[039m missing file format\033[031m-c \033[032m") + print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") + print ("\033[031m \033[039m \033[032m b - binary\033[039m") + sys.exit() + else: + if not('a') or not('A') or not('b') or not('B'): + print ("\033[031mError: \033[039m wrong specified file format\033[031m-c \033[032m") + sys.exit() + + run(file=file,fmt=format) diff --git a/accessories/fll_cat/project.dep b/accessories/fll_cat/project.dep new file mode 100644 index 0000000..3cbf9f1 --- /dev/null +++ b/accessories/fll_cat/project.dep @@ -0,0 +1,4 @@ +# This file is generated automatically. DO NOT EDIT! + +fll_cat.o : \ + ../../data_util/fll_mods.o diff --git a/accessories/fll_cat/src_dir_path.mk b/accessories/fll_cat/src_dir_path.mk new file mode 100644 index 0000000..6b2dc8c --- /dev/null +++ b/accessories/fll_cat/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/accessories/fll_cat + diff --git a/accessories/src_dir_path.mk b/accessories/src_dir_path.mk new file mode 100644 index 0000000..c67bc12 --- /dev/null +++ b/accessories/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/accessories + From a8c0ec24ea27c71f737e8265b29ea839071c4a3d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 10:30:49 -0700 Subject: [PATCH 130/325] add to main Makefile --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 4435ec2..2438e91 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ include src_dir_path.mk SUBDIRS= \ data_util\ mpi_util \ +accessories\ examples\ ########################################################################### From 56e71acbf0b7eeb777dfa5b65032a1c25a052a1d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 10:32:07 -0700 Subject: [PATCH 131/325] tmp commit --- data_util/project.dep | 8 ++++---- examples/Example_MPI-IO/Example_mpi-IO.f90 | 4 +++- mpi_util/fll_mpi_mods.f90 | 1 + mpi_util/project.dep | 4 ++++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/data_util/project.dep b/data_util/project.dep index 3723677..e518aee 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -72,15 +72,15 @@ fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mk.o \ fll_out.o \ fll_type.o -fll_locate.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index b6346cc..9de2e6a 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -57,7 +57,7 @@ PROGRAM EXAMPLE_MPI_IO ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP + TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP,PMPI TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT CHARACTER :: FMT @@ -77,6 +77,8 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_INIT(IERR) FLL_MPI_STRUCT => NULL() + + PMPI => FLL_MPI_PROC_STRUCT(FPAR) CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index ea2315a..9d2123d 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -41,5 +41,6 @@ MODULE FLL_MPI_MODS_M USE FLL_MPI_WRITE_M USE FLL_MPI_WRITE_NM_M USE FLL_MPI_READ_M + USE FLL_MPI_PROC_STRUCT_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 2e77303..c839e40 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -15,6 +15,7 @@ fll_mpi_write_nm.o : \ fll_mpi_mods.o : \ fll_mpi_cp.o \ + fll_mpi_proc_struct.o \ fll_mpi_write_nm.o \ fll_mpi_write.o \ fll_mpi_sum.o \ @@ -22,6 +23,9 @@ fll_mpi_mods.o : \ fll_mpi_read.o \ fll_mpi_cp_all.o +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o + fll_mpi_read.o : \ ../data_util/fll_mods.o \ fll_mpi_cp_all.o From ece3d6c1d592b53af569333021003f10b689c301 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 11:45:59 -0700 Subject: [PATCH 132/325] add option SCAN to read and cat --- accessories/fll_cat/fll_cat.f90 | 7 +- accessories/fll_cat/fll_cat.py | 15 +++-- data_util/fll_cat.f90 | 29 +++++--- data_util/fll_read.f90 | 116 ++++++++++++++++++++++++++++---- mpi_util/fll_mpi_read.f90 | 2 +- 5 files changed, 139 insertions(+), 30 deletions(-) diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index ce6b329..bb9e551 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -53,18 +53,19 @@ PROGRAM FLL_CATU CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER :: FMT + CHARACTER :: FMT, SCAN ! ! read a file and print on screen ! READ(*,*)FILE READ(*,*)FMT + READ(*,*)SCAN - PNODE => FLL_READ(FILE,8,FMT,FPAR) + PNODE => FLL_READ(FILE,8,FMT,FPAR,SCAN = SCAN) ! ! print node on the screen ! - CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN) WRITE(*,*) CALL FLL_RM(PNODE,FPAR) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 30a56fb..f795d61 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -9,7 +9,7 @@ #Definitions -def run(file,fmt): +def run(file,fmt,scan): # # execute # @@ -34,7 +34,7 @@ def run(file,fmt): print(" ") p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt])) + p.communicate(os.linesep.join([file, fmt, scan])) def print_header(): print(" ") @@ -64,13 +64,20 @@ def check_path(path): parser = argparse.ArgumentParser(description='FLL configure script') parser.add_argument('-i','--file',nargs=1,help='Files to process') parser.add_argument('-f','--format',nargs=1,help='Format of the file') + parser.add_argument('-s','--scan',action='store_true',help='Scan file only',required=False) # Parse the command line arguments args = parser.parse_args() file = args.file[0] if args.file else None format = args.format[0] if args.format else None - + scan = args.scan + + if not scan: + scan = 'n' + else: + scan = 'Y' + if not file: print ("\033[031mError: \033[039m missing name of file\033[031m-c \033[032m") sys.exit() @@ -85,4 +92,4 @@ def check_path(path): print ("\033[031mError: \033[039m wrong specified file format\033[031m-c \033[032m") sys.exit() - run(file=file,fmt=format) + run(file=file,fmt=format, scan=scan) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index fbe484d..bbced31 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -34,7 +34,7 @@ MODULE FLL_CAT_M ! CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -59,14 +59,22 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT LOGICAL :: PARENT + CHARACTER, OPTIONAL :: SCAN ! ! Local types ! TYPE(DNODE), POINTER :: PCHILD INTEGER(LINT) :: POS + CHARACTER :: SCAN_LOC ! ! body of subroutine ! + IF(PRESENT(SCAN))THEN + SCAN_LOC = SCAN + ELSE + SCAN_LOC = 'N' + END IF + POS = 1 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN @@ -82,20 +90,19 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR) IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is: ', PNODE%PPAR%LNAME WRITE(*,*) END IF - CALL FLL_PRINT(PNODE, IOUNIT, POS, FPAR) + CALL FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,FPAR) FPAR%SUCCESS = .TRUE. RETURN END SUBROUTINE FLL_CAT ! -! print node recursively ! - RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,FPAR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -119,6 +126,7 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS INTEGER :: IOUNIT + CHARACTER :: SCAN ! ! Local variables ! @@ -133,12 +141,12 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,FPAR) ! DO WHILE(ASSOCIATED(PCURR)) - CALL FLL_PRINT(PCURR, IOUNIT, POS, FPAR) + CALL FLL_PRINT(PCURR, IOUNIT, POS, SCAN, FPAR) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FPAR) + CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN,FPAR) END IF PCURR => PNEXT @@ -153,7 +161,7 @@ END SUBROUTINE FLL_CAT_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) + SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! ! Description: print content of PNODE ! @@ -178,6 +186,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT INTEGER(LINT) :: POS + CHARACTER :: SCAN ! ! Local variables ! @@ -208,6 +217,10 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, FPAR) RETURN ELSE WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'x',TRIM(ADJUSTL(NSSTR)),' ',SPACE,TRIM(PNODE%LNAME) + IF(SCAN == 'Y')THEN + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + END IF END IF ! ! print 1D arrays diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 95388a3..5434987 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_M ! CONTAINS - FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -85,6 +85,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! IOUNIT In Number of unit ! FMT In Format - a,A ASCII, b,B - Binary, * not specified ! FPAR In/Out structure containing function specific data +! SCAN In Optional parameter - scan only file ! ! Arguments declaration ! @@ -93,6 +94,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT + CHARACTER, OPTIONAL :: SCAN ! ! Local declarations ! @@ -100,8 +102,8 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS + CHARACTER :: SCAN_LOC - INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) @@ -127,6 +129,12 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) PNODE => NULL() RETURN END SELECT + + IF(PRESENT(SCAN))THEN + SCAN_LOC = SCAN + ELSE + SCAN_LOC = 'N' + END IF ! ! OPEN THE FILE ! @@ -150,7 +158,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! READ INITIAL NODE ! POS = 1 - PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,FPAR) + PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN,FPAR) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -165,7 +173,7 @@ END FUNCTION FLL_READ ! ! READS NODE ! - RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) + RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -194,12 +202,13 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! FMT In Format - a,A ASCII, b,B - Binary ! POS In/Out Position in bindary file ! FPAR In/Out structure containing function specific data +! SCAN In Scan only ! ! Arguments declaration ! INTEGER(LINT), INTENT(OUT) :: POS TYPE(DNODE), POINTER :: PNODE - CHARACTER :: FMT + CHARACTER :: FMT, SCAN TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT ! @@ -241,7 +250,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN DO NNODES = 1,NDIM - PNEW => READ_NODE(IOUNIT,FMT,POS,FPAR) + PNEW => READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' ! ! ATTACH TO PNODE @@ -258,7 +267,11 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CASE('A') CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) CASE('B') - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + IF(SCAN /= 'Y')THEN + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + ELSE + POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END IF END SELECT END IF @@ -584,14 +597,14 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) ! Declarations ! ! Arguments description -! Name In/Out Function +! Name In/Out Function ! PNODE In Pointer to node -! IOUNIT In Number of unit -! LTYPE In type of node -! NDIM In 1st dimension of array in the node -! NSIZE In 2nd dimension of array in the node -! POS In Position in file -! FPAR In/Out structure containing function specific data +! IOUNIT In Number of unit +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! POS In Position in file +! FPAR In/Out structure containing function specific data ! ! Arguments declaration ! @@ -723,5 +736,80 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) RETURN END SUBROUTINE READ_DATA_BIN + + + + + + + FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) +! +! Description: Function gets new position for reading bindary file without allocating arrays +! used for scanning files +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! POS In Position in file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: NDIM, NSIZE, POS + CHARACTER(LEN=*) :: LTYPE +! +! Local declaration +! + INTEGER :: LENGTH +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R', 'I') + LENGTH = 4 + + CASE('D', 'L') + LENGTH = 8 + + + CASE('S') + LENGTH = LSTRING_LENGTH + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + POS = (NDIM * NSIZE ) *LENGTH + + RETURN + + END FUNCTION GET_NEW_POS END MODULE FLL_READ_M diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 0d39379..c1f4cab 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -146,7 +146,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R ! Read linked list ! POS = DISPL(RANK+2) - PNODE => READ_NODE(IOUNIT,'B',POS,FPAR) + PNODE => READ_NODE(IOUNIT,'B',POS,'N',FPAR) if(rank ==1)CALL FLL_CAT(PNODE,6,.false., FPAR) ! From 65559496d6c5efdbbfa51b99b30bdb1c58bc7a4f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 12:04:01 -0700 Subject: [PATCH 133/325] for scanning purposes - read and print scalar values --- data_util/fll_cat.f90 | 4 ++-- data_util/fll_read.f90 | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index bbced31..9acffe9 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -198,7 +198,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) SAVED = .FALSE. - NDIM = PNODE%NDIM + NDIM = PNODE%NDIM NSIZE = PNODE%NSIZE SPACE(:) = ' ' ! @@ -217,7 +217,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) RETURN ELSE WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'x',TRIM(ADJUSTL(NSSTR)),' ',SPACE,TRIM(PNODE%LNAME) - IF(SCAN == 'Y')THEN + IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN WRITE(IOUNIT, *)TRIM(TEXT1) RETURN END IF diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 5434987..a71a7d6 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -270,7 +270,11 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) IF(SCAN /= 'Y')THEN CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) ELSE - POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + ELSE + POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END IF END IF END SELECT From 9b0e2fcb29ad6a2a8e0f598429ecde8d9f7a6538 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 12:25:56 -0700 Subject: [PATCH 134/325] add additional output info to fll_cat --- accessories/fll_cat/fll_cat.py | 11 +++++++++-- examples/Example_MPI-IO/Example_mpi-IO.f90 | 3 +-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index f795d61..4ac2358 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -29,8 +29,15 @@ def run(file,fmt,scan): sys.exit() print(" ") - print("\033[039m Specified file is: \033[032m"+file+"\033[039m") - print("\033[039m Specified file format is: \033[032m"+fmt+"\033[039m") + print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + if fmt == 'b' or fmt == 'B': + print("\033[039m Specified file format is: \033[032mbinary\033[039m") + else: + print("\033[039m Specified file format is: \033[032mASCII \033[039m") + + if scan == 'Y': + print(" ") + print("\033[035m ... running in scan only mode ... \033[039m") print(" ") p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 9de2e6a..59813fe 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -126,9 +126,8 @@ PROGRAM EXAMPLE_MPI_IO PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) BYTESN = FLL_GETNBYTES(PTMP,FPAR) - WRITE(*,*)' Partition reads data set size of ', WORLD_RANK,BYTESN + WRITE(*,*)' Partition all-reads data set size of ', WORLD_RANK,BYTESN CALL FLL_RM(PTMP,FPAR) - ! ! make a group and save to a separate file ! From fed96694c5a03793c5253d7d942b892e5192427c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 14:38:19 -0700 Subject: [PATCH 135/325] udpate printout --- data_util/fll_cat.f90 | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 9acffe9..8500181 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -194,6 +194,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) LOGICAL :: SAVED CHARACTER*2048 :: TEXT,TEXT1 CHARACTER*72 :: NDSTR,NSSTR + CHARACTER*16 :: NAME CHARACTER(3*POS) SPACE SAVED = .FALSE. @@ -201,22 +202,26 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) NDIM = PNODE%NDIM NSIZE = PNODE%NSIZE SPACE(:) = ' ' + WRITE(NAME, '(A16)')ADJUSTL(PNODE%LNAME) ! ! print headers ! - WRITE(NDSTR,'(I10)')PNODE%NDIM - WRITE(NSSTR,'(I10)')PNODE%NSIZE + WRITE(NDSTR,'(I8)')PNODE%NDIM + WRITE(NSSTR,'(I8)')PNODE%NSIZE IF(TRIM(PNODE%LTYPE) == 'DIR')THEN - WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'\ ',SPACE,TRIM(PNODE%LNAME) + WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'\ ',SPACE,ADJUSTL(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN - WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'\ ',SPACE,TRIM(PNODE%LNAME) + WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'\ ',SPACE,ADJUSTL(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE - WRITE(TEXT1,*)"-",TRIM(PNODE%LTYPE),"- ",TRIM(ADJUSTL(NDSTR)),'x',TRIM(ADJUSTL(NSSTR)),' ',SPACE,TRIM(PNODE%LNAME) + WRITE(TEXT1,'(A,A3,A,A,A,A,A,A)')& + "-",TRIM(PNODE%LTYPE),"- ",TRIM(NDSTR),'x',ADJUSTL(TRIM(NSSTR)),SPACE,NAME IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN WRITE(IOUNIT, *)TRIM(TEXT1) RETURN @@ -226,7 +231,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! print 1D arrays ! IF(ASSOCIATED(PNODE%R1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)" ",(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN @@ -234,38 +239,38 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%I1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)" ",(PNODE%I1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN - WRITE(TEXT,*)" ",SPACE,(PNODE%L1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)" ",(PNODE%L1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN - WRITE(TEXT,*)" ",SPACE,(TRIM(PNODE%S1(I)), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)" ",(TRIM(PNODE%S1(I)), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ! ! print 2D arrays ! ELSE IF(ASSOCIATED(PNODE%R2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%D2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",((PNODE%D2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%I2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",((PNODE%I2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN - WRITE(TEXT,*)" ",SPACE,((PNODE%L2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",((PNODE%L2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN - WRITE(TEXT,*)" ",SPACE,((TRIM(PNODE%S2(I,J)), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)" ",((TRIM(PNODE%S2(I,J)), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. END IF @@ -277,19 +282,19 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) IF(NDIM /= 0 .AND. NSIZE /= 0)THEN SELECT CASE(PNODE%LTYPE) CASE('R') - WRITE(TEXT,*)" ",SPACE,PNODE%R0 + WRITE(TEXT,*)" ",PNODE%R0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('D') - WRITE(TEXT,*)" ",SPACE,PNODE%D0 + WRITE(TEXT,*)" ",PNODE%D0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('I') - WRITE(TEXT,*)" ",SPACE,PNODE%I0 + WRITE(TEXT,*)" ",PNODE%I0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('L') - WRITE(TEXT,*)" ",SPACE,PNODE%L0 + WRITE(TEXT,*)" ",PNODE%L0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('S') - WRITE(TEXT,*)" ",SPACE,TRIM(PNODE%S0) + WRITE(TEXT,*)" ",TRIM(PNODE%S0) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE DEFAULT From 5d3bbd603ed919472c3209e5a3029154e65dfda9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 14:38:29 -0700 Subject: [PATCH 136/325] fix bug in fll_read --- data_util/fll_read.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index a71a7d6..ca9f51b 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -158,7 +158,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! READ INITIAL NODE ! POS = 1 - PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN,FPAR) + PNODE => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN From a4bc64e70633b0b542499d11c07eb8029a10476e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 15:44:59 -0700 Subject: [PATCH 137/325] update example to separate files --- data_util/fll_cat.f90 | 39 +++++++++--------- examples/Example_MPI-IO/Example_mpi-IO.f90 | 47 ++++++++++++++++------ 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 8500181..3a31177 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -202,7 +202,8 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) NDIM = PNODE%NDIM NSIZE = PNODE%NSIZE SPACE(:) = ' ' - WRITE(NAME, '(A16)')ADJUSTL(PNODE%LNAME) + + WRITE(NAME, '(A16)')(PNODE%LNAME) ! ! print headers ! @@ -211,16 +212,16 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) IF(TRIM(PNODE%LTYPE) == 'DIR')THEN WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& - "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'\ ',SPACE,ADJUSTL(PNODE%LNAME) + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& - "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'\ ',SPACE,ADJUSTL(PNODE%LNAME) + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE - WRITE(TEXT1,'(A,A3,A,A,A,A,A,A)')& + WRITE(TEXT1,'(A,A3,A,A,A,A,A,A16)')& "-",TRIM(PNODE%LTYPE),"- ",TRIM(NDSTR),'x',ADJUSTL(TRIM(NSSTR)),SPACE,NAME IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN WRITE(IOUNIT, *)TRIM(TEXT1) @@ -231,46 +232,46 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! print 1D arrays ! IF(ASSOCIATED(PNODE%R1))THEN - WRITE(TEXT,*)" ",(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)"=",(PNODE%R1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN - WRITE(TEXT,*)" ",(PNODE%D1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)"=",(PNODE%D1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN - WRITE(TEXT,*)" ",(PNODE%I1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)"=",(PNODE%I1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN - WRITE(TEXT,*)" ",(PNODE%L1(I), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)"=",(PNODE%L1(I), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN - WRITE(TEXT,*)" ",(TRIM(PNODE%S1(I)), I = 1,MIN(NDIM,3_LINT)) + WRITE(TEXT,*)"=",(TRIM(PNODE%S1(I)), I = 1,MIN(NDIM,3_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ! ! print 2D arrays ! ELSE IF(ASSOCIATED(PNODE%R2))THEN - WRITE(TEXT,*)" ",((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)"=",((PNODE%R2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN - WRITE(TEXT,*)" ",((PNODE%D2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)"=",((PNODE%D2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN - WRITE(TEXT,*)" ",((PNODE%I2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)"=",((PNODE%I2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN - WRITE(TEXT,*)" ",((PNODE%L2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)"=",((PNODE%L2(I,J), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN - WRITE(TEXT,*)" ",((TRIM(PNODE%S2(I,J)), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) + WRITE(TEXT,*)"=",((TRIM(PNODE%S2(I,J)), J = 1,MIN(NSIZE,2_LINT)), I=1,MIN(NDIM,2_LINT)) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) SAVED = .TRUE. END IF @@ -282,19 +283,19 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) IF(NDIM /= 0 .AND. NSIZE /= 0)THEN SELECT CASE(PNODE%LTYPE) CASE('R') - WRITE(TEXT,*)" ",PNODE%R0 + WRITE(TEXT,*)"=",PNODE%R0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('D') - WRITE(TEXT,*)" ",PNODE%D0 + WRITE(TEXT,*)"=",PNODE%D0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('I') - WRITE(TEXT,*)" ",PNODE%I0 + WRITE(TEXT,*)"=",PNODE%I0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('L') - WRITE(TEXT,*)" ",PNODE%L0 + WRITE(TEXT,*)"=",PNODE%L0 WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE('S') - WRITE(TEXT,*)" ",TRIM(PNODE%S0) + WRITE(TEXT,*)"=",TRIM(PNODE%S0) WRITE(IOUNIT, *)TRIM(TEXT1),TRIM(TEXT) CASE DEFAULT diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 59813fe..77b37e2 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -56,21 +56,18 @@ PROGRAM EXAMPLE_MPI_IO ! ! SUBROUTINE MOVES NODE ! - CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE, FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP,PMPI + TYPE(DNODE), POINTER :: FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP,PMPI TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT,I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT - CHARACTER :: FMT + INTEGER :: I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT - INTEGER(LINT) :: NFILES,BYTES,BYTESN,NSIZE - integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID + INTEGER(LINT) :: NFILES,BYTESN,NSIZE + integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID,ODD_GROUP_ID,ODD_COMM_ID CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK - INTEGER(LINT), ALLOCATABLE :: POS(:) - INTEGER, ALLOCATABLE :: EVEN_RANK(:) + INTEGER, ALLOCATABLE :: EVEN_RANK(:),ODD_RANK(:) INTEGER :: E_RANK - REAL :: RANDNUM + REAL :: START, FINISH ! ! Initialize MPI ! @@ -109,7 +106,7 @@ PROGRAM EXAMPLE_MPI_IO END IF ! ! make some data set similar to solution - NSIZE = 100000 + NSIZE = 100000 + 100*WORLD_RANK CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) @@ -118,10 +115,14 @@ PROGRAM EXAMPLE_MPI_IO ! Write - each partition to one common file ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)CALL CPU_TIME(START) OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) - WRITE(*,*)' READING FILES' + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING TIME IS ', FINISH-START + END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) @@ -137,13 +138,14 @@ PROGRAM EXAMPLE_MPI_IO CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) ! EVEN_P = ( NPROC + 1 ) / 2 - ALLOCATE ( EVEN_RANK(1:EVEN_P), STAT = ISTAT ) + ALLOCATE ( EVEN_RANK(1:EVEN_P), ODD_RANK(1:EVEN_P), STAT = ISTAT ) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' ISTAT = 0 DO I = 0, NPROC - 1, 2 ISTAT = ISTAT + 1 EVEN_RANK(ISTAT) = I+1 + ODD_RANK(ISTAT) = I END DO ! ! create group in parent group: world_group_id, number of processes @@ -158,9 +160,28 @@ PROGRAM EXAMPLE_MPI_IO IF(EVEN_COMM_ID /= MPI_COMM_NULL)THEN CALL MPI_Comm_rank(EVEN_COMM_ID, E_RANK, IERR ) END IF - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) + CALL MPI_Group_incl(WORLD_GROUP_ID, EVEN_P, ODD_RANK, ODD_GROUP_ID, IERR ) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + CALL MPI_Comm_create(MPI_COMM_WORLD, ODD_GROUP_ID, ODD_COMM_ID, IERR ) + + IF(EVEN_COMM_ID /= MPI_COMM_NULL)THEN + CALL MPI_Comm_rank(EVEN_COMM_ID, E_RANK, IERR ) + END IF + IF(ODD_COMM_ID /= MPI_COMM_NULL)THEN + CALL MPI_Comm_rank(ODD_COMM_ID, E_RANK, IERR ) + END IF + + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + CALL CPU_TIME(START) + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group_1',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group_2',12,0, E_RANK, ODD_COMM_ID, 'A', FPAR) + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING PART FILES TIME IS ', FINISH-START + END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) PTMP => NULL() From f2b292fd4da8801a378e2c984eee7f1a852df751 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 16:01:51 -0700 Subject: [PATCH 138/325] add color output --- data_util/fll_cat.f90 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 3a31177..cc55ce8 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -202,7 +202,6 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) NDIM = PNODE%NDIM NSIZE = PNODE%NSIZE SPACE(:) = ' ' - WRITE(NAME, '(A16)')(PNODE%LNAME) ! ! print headers @@ -211,13 +210,17 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) WRITE(NSSTR,'(I8)')PNODE%NSIZE IF(TRIM(PNODE%LTYPE) == 'DIR')THEN - WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& - "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) + WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& + achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& + achar(27),"[32m-",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN - WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& - "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) +! WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& +! "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) + WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& + achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& + achar(27),"[32m-",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE From e4a399cc4fe5924ebe61e5f3079fdbab0ec1604c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Nov 2016 21:39:04 -0700 Subject: [PATCH 139/325] fix for python 3 --- accessories/fll_cat/fll_cat.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 4ac2358..a7df2d6 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -6,6 +6,8 @@ import os import sys from subprocess import Popen, PIPE +import unicodedata +import ast #Definitions @@ -39,9 +41,13 @@ def run(file,fmt,scan): print(" ") print("\033[035m ... running in scan only mode ... \033[039m") print(" ") - - p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt, scan])) + + if sys.version_info < (3,0): + p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here + p.communicate(os.linesep.join([file, fmt, scan])) + else: + p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here + p.communicate(os.linesep.join( [file, fmt, scan])) def print_header(): print(" ") From 2ca1a8d7084ca84ef4deae69e432af0e4b4a1e94 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 07:22:57 -0700 Subject: [PATCH 140/325] add prototype of function --- mpi_util/fll_mpi_proc_struct.f90 | 122 +++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 mpi_util/fll_mpi_proc_struct.f90 diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 new file mode 100644 index 0000000..3fee1b7 --- /dev/null +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -0,0 +1,122 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: creates global structure for MPI saving process and subprocesses structure +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_MPI_PROC_STRUCT_M +CONTAINS + + FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) +! +! Description: Creates structure with header for MPI process definition +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE +! +! Local declarations +! + TYPE(DNODE), POINTER :: PTMP,PSUBPROC + TYPE(FUNC_DATA_SET) :: FPAR + + INTEGER :: WORLD_GROUP_ID, IERR, NPROC + + LOGICAL :: OK + +! +! MAKE STRUCTURE +! + PNODE => FLL_MKDIR('MPI_prc_str',FPAR) + + CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) + CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) + + PTMP => FLL_MK('World_comm', 'I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = MPI_COMM_WORLD + OK = FLL_MV(PTMP, PNODE, FPAR) + + PTMP => FLL_MK('World_group', 'I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = WORLD_GROUP_ID + OK = FLL_MV(PTMP, PNODE, FPAR) + + PTMP => FLL_MK('Nproc', 'I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = NPROC + OK = FLL_MV(PTMP, PNODE, FPAR) + + + + PSUBPROC => FLL_MKDIR('Subprocs',FPAR) + IF(.NOT.FLL_MV(PSUBPROC, PNODE, FPAR))THEN + WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving Subprocs' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + + + PTMP => FLL_MKDIR('IO_struct',FPAR) + IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN + WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO_struct' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! print node on the screen and save to files +! + CALL FLL_CAT(PNODE,6,.false., FPAR) + + FPAR%SUCCESS = .TRUE. + RETURN + END FUNCTION FLL_MPI_PROC_STRUCT +END MODULE FLL_MPI_PROC_STRUCT_M From 527fab6abae92fceccb76a98559fd66c6dc6d69c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 09:52:27 -0700 Subject: [PATCH 141/325] rename function to be consistent with other functions --- data_util/fll_getndata.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index bc808bc..4307544 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -774,7 +774,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -833,7 +833,7 @@ FUNCTION FLL_GETNDATA_S(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) STRING = PFIND%S0 RETURN - END FUNCTION FLL_GETNDATA_S + END FUNCTION FLL_GETNDATA_S0 FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) ! From 7a18a6b4a8b2317841944f97410c9beef242773f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 09:52:40 -0700 Subject: [PATCH 142/325] finish IO structure subroutine --- mpi_util/fll_mpi_proc_struct.f90 | 155 +++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 7 deletions(-) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 3fee1b7..ed4e6d9 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -44,6 +44,17 @@ ! ! MODULE FLL_MPI_PROC_STRUCT_M +! +! Description: Contains functions prepairing MPI structures +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! CONTAINS FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) @@ -61,7 +72,15 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) USE MPI USE FLL_MODS_M IMPLICIT NONE - +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to MPI structure +! +! Arguments declaration +! TYPE(DNODE), POINTER :: PNODE ! ! Local declarations @@ -79,7 +98,7 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) PNODE => FLL_MKDIR('MPI_prc_str',FPAR) CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) - CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) + CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, IERR ) PTMP => FLL_MK('World_comm', 'I', 1_LINT, 1_LINT, FPAR) PTMP%I0 = MPI_COMM_WORLD @@ -94,7 +113,6 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) OK = FLL_MV(PTMP, PNODE, FPAR) - PSUBPROC => FLL_MKDIR('Subprocs',FPAR) IF(.NOT.FLL_MV(PSUBPROC, PNODE, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving Subprocs' @@ -111,12 +129,135 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) FPAR%SUCCESS = .FALSE. RETURN END IF -! -! print node on the screen and save to files -! - CALL FLL_CAT(PNODE,6,.false., FPAR) FPAR%SUCCESS = .TRUE. RETURN END FUNCTION FLL_MPI_PROC_STRUCT + + + + SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) +! +! Description: Contains function prepiring MPI I/O structure +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to MPI structure +! NAME_OF_FILE In Name of output file +! EXTENSION In File extension (suffix) +! NFILES In Number of files +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=*) :: NAME_OF_FILE,EXTENSION + INTEGER(LINT) :: NFILES +! +! Local declarations +! + TYPE(DNODE), POINTER :: PTMP,PSUBPROC,PIOSTR,PDIR + INTEGER(LINT) :: I,J, COUNT,NSTEP + INTEGER :: IERR,NPROC,WORLD_GROUP_ID,GROUP_ID, COMM_ID + CHARACTER(LEN=NAME_LENGTH) :: FILENAME + CHARACTER(LEN=5) :: STR + INTEGER, ALLOCATABLE :: EVEN_RANK(:) +! +! MAKE STRUCTURE +! + PSUBPROC => FLL_LOCATE(PNODE,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) + PIOSTR => FLL_LOCATE(PSUBPROC,'IO_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) + + CALL MPI_Comm_size( MPI_COMM_WORLD, NPROC, IERR ) + CALL MPI_Comm_group( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) +! +! group processes +! there will be NFILES group +! each group would have max NPROC/NFILES partitions and the increment +! between them is NFILES +! +! in this way, each file should be associated to one partition from each node +! + NSTEP = NPROC/NFILES + + ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + + DO J=1,NFILES +! +! create node for name of the I/O file and add it to the main structure +! + PDIR => FLL_MKDIR('IO', FPAR) + IF(.NOT.FLL_MV(PDIR, PIOSTR, FPAR))STOP' ERROR MOVING NODE' + + WRITE(STR,'(I5)')J + WRITE(FILENAME,*)ADJUSTL(TRIM(NAME_OF_FILE))//"_",TRIM(ADJUSTL(STR))//".",ADJUSTL(TRIM(EXTENSION)) + + PTMP => FLL_MK('name-of-file','S', 1_LINT, 1_LINT, FPAR) + PTMP%S0 = TRIM(FILENAME) + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVIN NODE' +! +! create node with number processors the job will run at +! + PTMP => FLL_MK('proc','L', NSTEP, 1_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! group processes +! there will be NFILES group +! each group would have max NPROC/NFILES partitions and the increment +! between them is NFILES +! +! in this way, each file should be associated to one partition from each node +! + COUNT = 1 + DO I=J,NPROC,NSTEP +! +! fill partition numbers +! + PTMP%L1(COUNT) = I +! +! Partition is always +1 larger than rank of the process +! + EVEN_RANK(COUNT) = I-1 + COUNT = COUNT + 1 + + END DO + + CALL MPI_Group_incl(WORLD_GROUP_ID, INT(NSTEP, KIND = SINT), EVEN_RANK, GROUP_ID, IERR ) + CALL MPI_Comm_create(MPI_COMM_WORLD, GROUP_ID, COMM_ID, IERR ) + + PTMP => FLL_MK('communicator','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = COMM_ID + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' + + CALL MPI_GROUP_FREE(GROUP_ID, IERR) +! +! print node on the screen and save to files +! + END DO + + DEALLOCATE(EVEN_RANK, STAT = IERR) + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + + RETURN + + END SUBROUTINE FLL_IO_STRUCT + + + END MODULE FLL_MPI_PROC_STRUCT_M From f3cd2528917dc77251e45b082fff54b69887800a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 11:06:11 -0700 Subject: [PATCH 143/325] finish MPI-IO in N-M mode --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 167 +++++++----------- examples/Example_MPI-IO/create_mpi_struct.f90 | 121 ------------- examples/Example_MPI-IO/project.dep | 8 +- mpi_util/fll_mpi_proc_struct.f90 | 81 +++++++-- mpi_util/fll_mpi_read.f90 | 41 +++-- mpi_util/fll_mpi_write.f90 | 68 +++++-- mpi_util/fll_mpi_write_nm.f90 | 51 +++++- 7 files changed, 252 insertions(+), 285 deletions(-) delete mode 100644 examples/Example_MPI-IO/create_mpi_struct.f90 diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 77b37e2..5af25c2 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -48,7 +48,6 @@ PROGRAM EXAMPLE_MPI_IO USE MPI USE FLL_MODS_M USE FLL_MPI_MODS_M - USE CREATE_MPI_STRUCT_M USE READ_INPUT_M USE CREATE_DATA_SET_M @@ -58,144 +57,108 @@ PROGRAM EXAMPLE_MPI_IO ! TYPE(DNODE), POINTER :: FLL_MPI_STRUCT, PDATA_SET, PNEW,PTMP,PMPI TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: I,IERR,WORLD_RANK,world_group_id,NPROC,ISTAT + INTEGER :: IERR,WORLD_RANK,world_group_id,NPROC,ISTAT - INTEGER(LINT) :: NFILES,BYTESN,NSIZE + INTEGER(LINT) :: NFILES,BYTESN,NSIZE,I integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID,ODD_GROUP_ID,ODD_COMM_ID CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK INTEGER, ALLOCATABLE :: EVEN_RANK(:),ODD_RANK(:) - INTEGER :: E_RANK + INTEGER :: E_RANK,O_RANK,COMM REAL :: START, FINISH + + TYPE(DNODE), POINTER ::PIOSTR,PSUBPROC,PIO ! ! Initialize MPI ! - CALL MPI_INIT(IERR) - - FLL_MPI_STRUCT => NULL() - - PMPI => FLL_MPI_PROC_STRUCT(FPAR) - + CALL MPI_INIT(IERR) CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) - CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) - IF(WORLD_RANK == 0) THEN - CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) + FLL_MPI_STRUCT => NULL() ! -! initialize MPI +! initiate MPI structure with all info ! - FLL_MPI_STRUCT => NULL() - CALL CREATE_MPI_STRUCT(FLL_MPI_STRUCT,NAME_OF_FILE,NFILES,1_LINT*NPROC) - - END IF + PMPI => FLL_MPI_PROC_STRUCT(FPAR) ! -! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc -! to all other partitions -! Upon return, the function will return pointer to newly allocated data -! for all other partition then root partition -! On root partition, the PNEW pointer is pointing on FLL_MPI_STRUCT +! define how to save files for N-M saving model ! - PNEW => FLL_MPI_CP_ALL(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) - IF(WORLD_RANK /= 0)THEN + CALL FLL_IO_STRUCT(PMPI,'ada','bmpi',2_LINT, FPAR) ! -! make FLL_MPI_STRUCT point to PNEW so that we cane use the same names for all partitions -! - FLL_MPI_STRUCT => PNEW +! print the strucute on the screen and save into ASCII file +! + IF(WORLD_RANK == 0)THEN + CALL FLL_CAT(PMPI,6,.FALSE., FPAR) + IF(.NOT.FLL_WRITE(PMPI,"io.str", 9, 'A', FPAR))STOP'Error writing file' END IF ! -! make some data set similar to solution - NSIZE = 100000 + 100*WORLD_RANK +! create sample data se +! + NSIZE = 100000 + 100*WORLD_RANK - CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) - BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) - WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN + CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) + BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) + WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN ! -! Write - each partition to one common file +! save to one file, all partitions at the same time ! - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)CALL CPU_TIME(START) - - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) - - IF(WORLD_RANK == 0)THEN + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)CALL CPU_TIME(START) + + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + + IF(WORLD_RANK == 0)THEN CALL CPU_TIME(FINISH) WRITE(*,*)' SAVING TIME IS ', FINISH-START - END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - - PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) - BYTESN = FLL_GETNBYTES(PTMP,FPAR) - WRITE(*,*)' Partition all-reads data set size of ', WORLD_RANK,BYTESN - CALL FLL_RM(PTMP,FPAR) -! -! make a group and save to a separate file -! -! -! Get a group identifier for MPI_COMM_WORLD. -! - CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) -! - EVEN_P = ( NPROC + 1 ) / 2 - ALLOCATE ( EVEN_RANK(1:EVEN_P), ODD_RANK(1:EVEN_P), STAT = ISTAT ) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY' - - ISTAT = 0 - DO I = 0, NPROC - 1, 2 - ISTAT = ISTAT + 1 - EVEN_RANK(ISTAT) = I+1 - ODD_RANK(ISTAT) = I - END DO + END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! -! create group in parent group: world_group_id, number of processes -! in that group is: even_p -! the processesare: even_rank(:) -! the group ID is then +! save to several separate files +! all partitions at the same time ! - CALL MPI_Group_incl(WORLD_GROUP_ID, EVEN_P, EVEN_RANK, EVEN_GROUP_ID, IERR ) - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - CALL MPI_Comm_create(MPI_COMM_WORLD, EVEN_GROUP_ID, EVEN_COMM_ID, IERR ) + IF(WORLD_RANK == 0)CALL CPU_TIME(START) - IF(EVEN_COMM_ID /= MPI_COMM_NULL)THEN - CALL MPI_Comm_rank(EVEN_COMM_ID, E_RANK, IERR ) - END IF + OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) - CALL MPI_Group_incl(WORLD_GROUP_ID, EVEN_P, ODD_RANK, ODD_GROUP_ID, IERR ) - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - CALL MPI_Comm_create(MPI_COMM_WORLD, ODD_GROUP_ID, ODD_COMM_ID, IERR ) - - IF(EVEN_COMM_ID /= MPI_COMM_NULL)THEN - CALL MPI_Comm_rank(EVEN_COMM_ID, E_RANK, IERR ) - END IF + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING TIME IS ', FINISH-START + END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(ODD_COMM_ID /= MPI_COMM_NULL)THEN - CALL MPI_Comm_rank(ODD_COMM_ID, E_RANK, IERR ) - END IF + IF(WORLD_RANK == 0) THEN + CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) + END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - CALL CPU_TIME(START) - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group_1',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile_group_2',12,0, E_RANK, ODD_COMM_ID, 'A', FPAR) - IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING PART FILES TIME IS ', FINISH-START - END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - PTMP => NULL() - PTMP => FLL_MPI_READ('PartitionedFile',10,0, E_RANK, EVEN_COMM_ID, 'A', FPAR) - BYTESN = FLL_GETNBYTES(PTMP,FPAR) - WRITE(*,*)' Partition reads data set size of ', WORLD_RANK,BYTESN - CALL FLL_RM(PTMP,FPAR) +! +! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc +! to all other partitions +! Upon return, the function will return pointer to newly allocated data +! for all other partition then root partition +! On root partition, the PNEW pointer is pointing on FLL_MPI_STRUCT +! +! PNEW => FLL_MPI_CP_ALL(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) +! IF(WORLD_RANK /= 0)THEN +! +! make FLL_MPI_STRUCT point to PNEW so that we cane use the same names for all partitions +! +! FLL_MPI_STRUCT => PNEW +! END IF + +! PTMP => FLL_MPI_READ('PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) +! BYTESN = FLL_GETNBYTES(PTMP,FPAR) +! WRITE(*,*)' Partition all-reads data set size of ', WORLD_RANK,BYTESN +! CALL FLL_RM(PTMP,FPAR) ! ! CLEAN MEMORY ! - IF(WORLD_RANK==0)write(*,*)' Releasing memory' - CALL FLL_RM(FLL_MPI_STRUCT,FPAR) - CALL FLL_RM(PDATA_SET,FPAR) + IF(WORLD_RANK==0)write(*,*)' Releasing memory' + CALL FLL_RM(FLL_MPI_STRUCT,FPAR) + CALL FLL_RM(PDATA_SET,FPAR) CALL MPI_FINALIZE(IERR) diff --git a/examples/Example_MPI-IO/create_mpi_struct.f90 b/examples/Example_MPI-IO/create_mpi_struct.f90 deleted file mode 100644 index 3dd3eee..0000000 --- a/examples/Example_MPI-IO/create_mpi_struct.f90 +++ /dev/null @@ -1,121 +0,0 @@ -! -! Copyright (C) 2016 Adam Jirasek -! -! This program is free software: you can redistribute it and/or modify -! it under the terms of the GNU Lesser General Public License as published by -! the Free Software Foundation, either version 3 of the License, or -! (at your option) any later version. -! -! This program is distributed in the hope that it will be useful, -! but WITHOUT ANY WARRANTY; without even the implied warranty of -! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -! GNU Lesser General Public License for more details. -! -! You should have received a copy of the GNU Lesser General Public License -! along with this program. If not, see . -! -! contact: libm3l@gmail.com -! -! - -! -! Sample program -! -! Date: 2016-10-10 -! -! -! -! -! Description: creates mpi struct defining how many files will be -! saved and which partitions will be saving to each -! file -! -! -! Input parameters: -! -! -! Return value: -! -! -! -! Modifications: -! Date Version Patch number CLA -! -! -! Description -! -! -MODULE CREATE_MPI_STRUCT_M -CONTAINS - - SUBROUTINE CREATE_MPI_STRUCT(PNODE,NAME_OF_FILE,NFILES,NPROC) - - USE FLL_MODS_M - IMPLICIT NONE - - TYPE(DNODE), POINTER :: PNODE -! -! Local declarations -! - TYPE(DNODE), POINTER :: PTMP - TYPE(FUNC_DATA_SET) :: FPAR - - INTEGER(LINT) :: NFILES, I,J,NPROC, COUNT - CHARACTER(LEN=*) :: NAME_OF_FILE -! -! MAKE STRUCTURE -! - PNODE => FLL_MKDIR('MPI-IO',FPAR) -! -! create node for name of the I/O file and add it to the main structure -! - PTMP => FLL_MK('name-of-file','S', 1_LINT, 1_LINT, FPAR) - PTMP%S0 = TRIM(NAME_OF_FILE) - IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' -! -! create node with number of files which are to be saved -! - PTMP => FLL_MK('N-files','L', 1_LINT, 1_LINT, FPAR) - PTMP%L0 = NFILES - IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' -! -! create node with number processors the job will run at -! - PTMP => FLL_MK('N-proc','L', 1_LINT, 1_LINT, FPAR) - PTMP%L0 = NPROC - IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' -! -! group processes -! there will be NFILES group -! each group would have max NPROC/NFILES partitions and the increment -! between them is NFILES -! -! in this way, each file should be associated to one partition from each node -! - DO J=1,NFILES -! -! Make group and add it to the main structure -! - PTMP => FLL_MK('group','L',NPROC/NFILES,1_LINT,FPAR) - IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' - - COUNT = 1 - DO I=J,NPROC,NFILES -! -! fill partition numbers -! - PTMP%L1(COUNT) = I - COUNT = COUNT + 1 - - END DO - - END DO -! -! print node on the screen and save to files -! - CALL FLL_CAT(PNODE,6,.false., FPAR) - IF(.NOT.FLL_WRITE(PNODE,"io.str", 9, 'A', FPAR))STOP'Error writing file' - - RETURN - END SUBROUTINE CREATE_MPI_STRUCT -END MODULE CREATE_MPI_STRUCT_M diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index 1afee09..144588f 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -2,16 +2,12 @@ Example_mpi-IO.o : \ ../../data_util/fll_mods.o \ - create_data_set.o \ read_input.o \ - create_mpi_struct.o \ - ../../mpi_util/fll_mpi_mods.o + ../../mpi_util/fll_mpi_mods.o \ + create_data_set.o read_input.o : \ ../../data_util/fll_mods.o -create_mpi_struct.o : \ - ../../data_util/fll_mods.o - create_data_set.o : \ ../../data_util/fll_mods.o diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index ed4e6d9..4fa4724 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -93,10 +93,13 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) LOGICAL :: OK ! -! MAKE STRUCTURE +! Main pointer ! PNODE => FLL_MKDIR('MPI_prc_str',FPAR) - +! +! find world communicator, world group and number of processes and +! save to file +! CALL MPI_Comm_group ( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, IERR ) @@ -111,8 +114,9 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) PTMP => FLL_MK('Nproc', 'I', 1_LINT, 1_LINT, FPAR) PTMP%I0 = NPROC OK = FLL_MV(PTMP, PNODE, FPAR) - - +! +! define structure Subprocs +! PSUBPROC => FLL_MKDIR('Subprocs',FPAR) IF(.NOT.FLL_MV(PSUBPROC, PNODE, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving Subprocs' @@ -120,8 +124,9 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) FPAR%SUCCESS = .FALSE. RETURN END IF - - +! +! add to is IO_struct +! PTMP => FLL_MKDIR('IO_struct',FPAR) IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO_struct' @@ -173,16 +178,18 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! TYPE(DNODE), POINTER :: PTMP,PSUBPROC,PIOSTR,PDIR INTEGER(LINT) :: I,J, COUNT,NSTEP - INTEGER :: IERR,NPROC,WORLD_GROUP_ID,GROUP_ID, COMM_ID + INTEGER :: IERR,NPROC,WORLD_GROUP_ID,GROUP_ID, COMM_ID,IOUNIT,LOC_RANK CHARACTER(LEN=NAME_LENGTH) :: FILENAME CHARACTER(LEN=5) :: STR INTEGER, ALLOCATABLE :: EVEN_RANK(:) ! -! MAKE STRUCTURE +! In MPI_prc_str find MPI_prc_str -> Subprocs -> IO_struct ! PSUBPROC => FLL_LOCATE(PNODE,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) PIOSTR => FLL_LOCATE(PSUBPROC,'IO_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) - +! +! get number of processors and world group +! CALL MPI_Comm_size( MPI_COMM_WORLD, NPROC, IERR ) CALL MPI_Comm_group( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) ! @@ -197,20 +204,38 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' - +! +! loop over number of separate files, define which partition is going to be +! saving in what file (defined by EVEN_RANK array +! DO J=1,NFILES ! +! define IOunit - so that user does not have to do it and they +! do not collide +! + IOUNIT = 10+J +! ! create node for name of the I/O file and add it to the main structure ! PDIR => FLL_MKDIR('IO', FPAR) IF(.NOT.FLL_MV(PDIR, PIOSTR, FPAR))STOP' ERROR MOVING NODE' - +! +! create name of the file from the stem, number of file, and suffix +! WRITE(STR,'(I5)')J WRITE(FILENAME,*)ADJUSTL(TRIM(NAME_OF_FILE))//"_",TRIM(ADJUSTL(STR))//".",ADJUSTL(TRIM(EXTENSION)) - +! +! save it to the IO structure +! PTMP => FLL_MK('name-of-file','S', 1_LINT, 1_LINT, FPAR) - PTMP%S0 = TRIM(FILENAME) - IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVIN NODE' + PTMP%S0 = ADJUSTL(TRIM(FILENAME)) + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! save number of IO desrciptor +! + PTMP => FLL_MK('io-descrpt','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = IOUNIT + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' ! ! create node with number processors the job will run at ! @@ -237,20 +262,42 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) COUNT = COUNT + 1 END DO - +! +! create group and communicator +! group will contain processes in EVEN_RANK array +! CALL MPI_Group_incl(WORLD_GROUP_ID, INT(NSTEP, KIND = SINT), EVEN_RANK, GROUP_ID, IERR ) CALL MPI_Comm_create(MPI_COMM_WORLD, GROUP_ID, COMM_ID, IERR ) - +! +! save comminicator +! PTMP => FLL_MK('communicator','I', 1_LINT, 1_LINT, FPAR) PTMP%I0 = COMM_ID IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! if in the group, get local rank of the process and save it +! if not in the group, set process local rank to -1 +! + IF(COMM_ID /= MPI_COMM_NULL)THEN + CALL MPI_Comm_rank(COMM_ID, LOC_RANK, IERR ) + ELSE + LOC_RANK = -1 + END IF + PTMP => FLL_MK('loc_prc_rank','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = LOC_RANK + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! free group, will not be needed +! CALL MPI_GROUP_FREE(GROUP_ID, IERR) ! ! print node on the screen and save to files ! END DO - +! +! free memory +! DEALLOCATE(EVEN_RANK, STAT = IERR) IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index c1f4cab..197363f 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -130,28 +130,35 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R FPAR%SUCCESS = .FALSE. RETURN END IF + + CALL MPI_BARRIER(COMMUNICATOR, IERR) ! -! Position in file with empty write statement +! If root processor, read initial set and +! get positions for each subset, ie. each partition solution ! IF(RANK == ROOT_RANK)THEN -! INQUIRE(UNIT=IOUNIT,POS=1_LINT) PTMP => FLL_RPART_FILE_HEADER(IOUNIT, FPAR) END IF - +! +! distribute that info to all partitions +! PTMP1 => FLL_MPI_CP_ALL(PTMP,COMMUNICATOR,ROOT_RANK,FPAR) IF(RANK /= ROOT_RANK) PTMP => PTMP1 - +! +! get position in a file for each partition +! DISPL => PTMP%L1 ! ! Read linked list ! POS = DISPL(RANK+2) +! +! use read node, so that you read just +! what is in the subdir (subset) +! PNODE => READ_NODE(IOUNIT,'B',POS,'N',FPAR) - - if(rank ==1)CALL FLL_CAT(PNODE,6,.false., FPAR) ! -! MPI_Barrier does not need to be here, -! just for testing purposes +! close and use MPI barier to sync ! CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -160,10 +167,12 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R FPAR%SUCCESS = .FALSE. RETURN END IF - - CALL FLL_RM(PTMP, FPAR) - - + CALL MPI_BARRIER(COMMUNICATOR, IERR) +! +! release memory +! + CALL FLL_RM(PTMP, FPAR) + FPAR%SUCCESS = .TRUE. RETURN @@ -172,7 +181,8 @@ END FUNCTION FLL_MPI_READ FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) ! -! Description: contains subroutine reading file header +! Description: Reads header of partitione file containing +! positions of each record in the file ! ! ! History: @@ -205,7 +215,10 @@ FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: TYPE INTEGER(LINT) :: NDIM,NSIZE,I - +! +! read name, type, ndim, nsize +! create node, read valus of record positions and return +! READ(IOUNIT)NAME,TYPE,NDIM,NSIZE READ(IOUNIT)NAME,TYPE,NDIM,NSIZE PNEW => FLL_MK(NAME,TYPE,NDIM,NSIZE,FPAR) diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index fb7a29b..8b785f3 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -88,8 +88,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! Arguments description ! Name In/Out Function ! FILE In Name of file -! PNODE Out Node to a first node in list from a file -! IOUNIT In Number of unit +! PNODE Out Node to be written! IOUNIT In Number of unit ! OPTION In Type of write ! COMMUNICATOR In communicator ! FPAR In/Out structure containing function specific data @@ -123,8 +122,10 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& ACCESS='STREAM',IOSTAT=ISTAT) - -! CALL MPI_BARRIER(COMMUNICATOR, IERR) +! +! use barrier, without barrier there were problems on cluster +! + CALL MPI_BARRIER(COMMUNICATOR, IERR) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) @@ -138,14 +139,20 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! CALL MPI_Comm_size (COMMUNICATOR, NPROC, IERR ) ! -! Get length of each data set +! Get position and length of each data set +! there will be totally n+1 subset, +! subset #1 is a headet of the file +! subsets #2: are actual data from each partition ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:144 ' - +! +! get length of each data subset of actual data +! POS = 0 POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) ! +! the first subset is a header ! header = 16 + 4 + 8 + 8 (name, type, ndim, nsize) ! ! header + long int array @@ -154,27 +161,35 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, POS(1) = 36 + 36 + (NPROC+1)*8 END IF ! -! ... and distribute to all partitions +! ... and distribute length of each subset to all partitions ! CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT+NPROC,L1=POS) ! -! Calculate displacement +! Calculate displacement, ie where each subset starts ! PART_NUM = FLL_GETNDATA_L0(PNODE, 'part_number',1_LINT, FPAR) - +! +! the first subset will start always at position 1 +! ie. beginning of the file +! LOC_DISPL = 1 DISPL = 0 -! DO I=2,PART_NUM+1 DO I=2,RANK+2 LOC_DISPL = LOC_DISPL + POS(I-1) END DO -! DISPL(PART_NUM+1) = LOC_DISPL +! +! define subset position for all other partitions +! and propagate this to all partitions +! DISPL(RANK+2) = LOC_DISPL CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) +! +! set explicitely that the first subset (file header) starts at position 1, ie. beginning of the file DISPL(1) = 1 ! -! Position in file with empty write statement +! Position process to the file - ie. invoke empty write statement at position POS +! If group root process, write file header! ! IF(RANK == ROOT_RANK)THEN WRITE(IOUNIT,POS=1) @@ -183,12 +198,11 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, WRITE(IOUNIT,POS=DISPL(RANK+2)) END IF ! -! Write linked list +! Write data set ! CALL FLL_WRITE_LIST(PNODE,IOUNIT,'B',FPAR) ! -! MPI_Barrier does not need to be here, -! just for testing purposes +! close file and sync with barrier ! CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -199,6 +213,10 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, RETURN END IF + CALL MPI_BARRIER(COMMUNICATOR, IERR) +! +! free memory +! DEALLOCATE(POS, DISPL, STAT = ISTAT) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:203 ' @@ -210,7 +228,7 @@ END FUNCTION FLL_MPI_WRITE FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! -! Description: contains subroutine writing file in paralell mode +! Description: write header for partitioned file ! ! ! History: @@ -243,19 +261,31 @@ FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! Local declarations ! TYPE(DNODE), POINTER :: PTMP - +! +! make a head node and say it contains number of partitions + one subsets +! PTMP => FLL_MKDIR('partitioned_file', FPAR) PTMP%NDIM = NPROC + 1 ! Number of partitioned solutions and displacement vector +! +! save it +! CALL FLL_SAVE_NODE_B(PTMP, IOUNIT, 0_LINT, FPAR) +! +! get length of saved data set and remove it +! POS = FLL_GETNBYTES(PTMP,FPAR) CALL FLL_RM(PTMP,FPAR) - +! +! make subset displacement containing positions of each record in the file +! PTMP => FLL_MK('displacements','L', NPROC+1_LINT, 1_LINT, FPAR) ! ! THE DATA CAN BE ACCESSE DIRECTLY THROUGH PTMP%D(:) ! POS = POS + FLL_GETNBYTES(PTMP,FPAR) - +! +! save it and remove from memory +! PTMP%L1 = DISPL CALL FLL_SAVE_NODE_B(PTMP, IOUNIT, 0_LINT, FPAR) CALL FLL_RM(PTMP,FPAR) diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index ca6379a..6152c75 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -32,7 +32,7 @@ MODULE FLL_MPI_WRITE_NM_M ! CONTAINS - FUNCTION FLL_MPI_WRITE_NM(PNODE,FILE,IOUNIT,FILE_TAB,FPAR) RESULT(OK) + FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! ! Description: contains subroutine writing file in paralell mode from N processors to M files ! @@ -55,7 +55,7 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,FILE,IOUNIT,FILE_TAB,FPAR) RESULT(OK) ! Arguments description ! Name In/Out Function ! FILE In Name of file -! PNODE Out Node to a first node in list from a file +! PNODE In Node to be written ! IOUNIT In Number of unit ! FILE_TAB In Specifies which partition saves to which file ! FPAR In/Out structure containing function specific data @@ -63,14 +63,53 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,FILE,IOUNIT,FILE_TAB,FPAR) RESULT(OK) ! ! Arguments declaration ! - CHARACTER(*) :: FILE - TYPE(DNODE), POINTER :: PNODE, FILE_TAB + TYPE(DNODE), POINTER :: PNODE,PMPI TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT LOGICAL OK ! -! local declarations +! Local declarations ! + TYPE(DNODE), POINTER :: PSUBPROC,PIOSTR,PIO + INTEGER :: COMM,IOUNIT,WORLD_RANK,IERR,LOC_RANK + INTEGER(LINT) :: I + CHARACTER(LEN=NAME_LENGTH) :: NAME_OF_FILE + + OK = .FALSE. +! +! get processor rank in world group +! + CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) +! +! find MPI_prc_str -> Subprocs -> IO_struct +! + PSUBPROC => FLL_LOCATE(PMPI,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) + PIOSTR => FLL_LOCATE(PSUBPROC,'IO_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) +! +! loop over IO subsets +! + DO I=1,PIOSTR%NDIM + + PIO => FLL_LOCATE(PIOSTR,'IO','*',-1_LINT,I,.FALSE.,FPAR) +! +! find: communicator +! name of file to save into +! desrcriptor for the file +! local process rank, for each group of processes it will start with 0 +! + COMM = FLL_GETNDATA_I0(PIO,'communicator',1_LINT,FPAR) + NAME_OF_FILE = FLL_GETNDATA_S0(PIO,'name-of-file',1_LINT,FPAR) + IOUNIT = FLL_GETNDATA_I0(PIO,'io-descrpt', 1_LINT, FPAR) + LOC_RANK = FLL_GETNDATA_I0(PIO,'loc_prc_rank', 1_LINT, FPAR) +! +! Print some info +! + IF(COMM /= MPI_COMM_NULL)write(*,*)' Partition saving :', world_rank,LOC_RANK,trim(NAME_OF_FILE), IOUNIT +! +! save file, ROOT_RANK is always 0, use local rank +! + OK = FLL_MPI_WRITE(PNODE,NAME_OF_FILE,IOUNIT,0, LOC_RANK, COMM, 'A', FPAR) + + END DO END FUNCTION FLL_MPI_WRITE_NM From 30a78120f52fc6818919f487d664243c90de025b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 11:10:03 -0700 Subject: [PATCH 144/325] remove *.py from list of default files --- configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.py b/configure.py index dd1cb23..63300ee 100755 --- a/configure.py +++ b/configure.py @@ -20,7 +20,7 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= # definition of parameters # print_header() - linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep', '*.py']) + linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep']) exclude =(['python_dep', 'config', '.git']) # # From 598a479c1d9f8b18381950ce35953124e5298e2f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 12:12:05 -0700 Subject: [PATCH 145/325] fix bug --- mpi_util/fll_mpi_proc_struct.f90 | 9 ++++++++- mpi_util/fll_mpi_write_nm.f90 | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 4fa4724..6c47e42 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -202,6 +202,13 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! NSTEP = NPROC/NFILES + IF(NFILES == NPROC)THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')' fll_mpi_write_nm - error witing files, nfiles == npart ' + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' ! @@ -250,7 +257,7 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! in this way, each file should be associated to one partition from each node ! COUNT = 1 - DO I=J,NPROC,NSTEP + DO I=J,NPROC,NFILES ! ! fill partition numbers ! diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index 6152c75..0c49825 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -103,7 +103,7 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! ! Print some info ! - IF(COMM /= MPI_COMM_NULL)write(*,*)' Partition saving :', world_rank,LOC_RANK,trim(NAME_OF_FILE), IOUNIT + IF(COMM /= MPI_COMM_NULL)write(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) ! ! save file, ROOT_RANK is always 0, use local rank ! From f43b5452a6083377630d83708e125ed77861cd17 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 13:34:40 -0700 Subject: [PATCH 146/325] remove loops from readwrite routines --- data_util/fll_read.f90 | 40 +++++++++++++++++++++++++------------- data_util/fll_write.f90 | 40 +++++++++++++++++++------------------- mpi_util/fll_mpi_write.f90 | 2 +- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index ca9f51b..b64980b 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -630,18 +630,21 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NSIZE) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R0 +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R0 INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%R1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%R2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%R2(:,:) INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -649,7 +652,8 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) CASE('D') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NSIZE) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%D1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%D0 @@ -657,10 +661,12 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%D1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%D1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%D2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%D2(:,:) INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -669,7 +675,8 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) CASE('I') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NSIZE) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%I1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%I0 @@ -677,10 +684,12 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%I1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%I1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%I2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%I2(:,:) INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -689,7 +698,8 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) CASE('L') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NSIZE) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%L1(:) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%L0 @@ -697,10 +707,12 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NDIM) - INQUIRE(UNIT = IOUNIT, POS=POS) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%L1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%L1(:) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) +! READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)((PNODE%L2(I,J),J=1,NSIZE),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%L2(:,:) INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 378c3bc..38a1671 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -440,20 +440,16 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ! 1 D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - NDIM = SIZE(PNODE%R1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%R1(I), I = 1,NDIM) + WRITE(IOUNIT)PNODE%R1(:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D1))THEN - NDIM = SIZE(PNODE%D1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%D1(I), I = 1,NDIM) + WRITE(IOUNIT)PNODE%D1(:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I1))THEN - NDIM = SIZE(PNODE%I1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%I1(I), I = 1,NDIM) + WRITE(IOUNIT)PNODE%I1(:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L1))THEN - NDIM = SIZE(PNODE%L1, DIM =1, KIND = LINT) - WRITE(IOUNIT)(PNODE%L1(I), I = 1,NDIM) + WRITE(IOUNIT)PNODE%L1(:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) @@ -465,24 +461,28 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ! 2D ARRAYS ! ELSE IF(ASSOCIATED(PNODE%R2))THEN - NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) - NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) +! NDIM = SIZE(PNODE%R2, DIM =1, KIND = LINT) +! NSIZE = SIZE(PNODE%R2, DIM =2, KIND = LINT) +! WRITE(IOUNIT)((PNODE%R2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)PNODE%R2(:,:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%D2))THEN - NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) - NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) +! NDIM = SIZE(PNODE%D2, DIM =1, KIND = LINT) +! NSIZE = SIZE(PNODE%D2, DIM =2, KIND = LINT) +! WRITE(IOUNIT)((PNODE%D2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)PNODE%D2(:,:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%I2))THEN - NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) - NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) +! NDIM = SIZE(PNODE%I2, DIM =1, KIND = LINT) +! NSIZE = SIZE(PNODE%I2, DIM =2, KIND = LINT) +! WRITE(IOUNIT)((PNODE%I2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)PNODE%I2(:,:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%L2))THEN - NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) - NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) - WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) +! NDIM = SIZE(PNODE%L2, DIM =1, KIND = LINT) +! NSIZE = SIZE(PNODE%L2, DIM =2, KIND = LINT) +! WRITE(IOUNIT)((PNODE%L2(I,J), J = 1,NSIZE), I=1,NDIM) + WRITE(IOUNIT)PNODE%L2(:,:) SAVED = .TRUE. ELSE IF(ASSOCIATED(PNODE%S2))THEN NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index 8b785f3..ef31a0e 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -121,7 +121,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! use always binary fomat ! OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& - ACCESS='STREAM',IOSTAT=ISTAT) + ACCESS='STREAM',ACTION='WRITE', IOSTAT=ISTAT) ! ! use barrier, without barrier there were problems on cluster ! From 9b921399ac164bb6b4a48e6ce21e3dfa2cd1fc2e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 13:34:51 -0700 Subject: [PATCH 147/325] expand example --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 5af25c2..87a9e6d 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -95,7 +95,7 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 100000 + 100*WORLD_RANK + NSIZE = 1000000 !+ 100*WORLD_RANK CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) @@ -131,8 +131,19 @@ PROGRAM EXAMPLE_MPI_IO CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) END IF + CALL FLL_RM(PMPI,FPAR) + PMPI => FLL_MPI_PROC_STRUCT(FPAR) + CALL FLL_IO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) + IF(WORLD_RANK == 0)CALL CPU_TIME(START) + OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) + + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING TIME IS ', FINISH-START + END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! ! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc From 913860ca2def4b8e3e8283a5f97285a1743e0dc6 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 14:13:14 -0700 Subject: [PATCH 148/325] remove forgotten - (dash) from output --- data_util/fll_cat.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index cc55ce8..06e0ed6 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -212,7 +212,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) IF(TRIM(PNODE%LTYPE) == 'DIR')THEN WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& - achar(27),"[32m-",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' + achar(27),"[32m",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN @@ -220,7 +220,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& - achar(27),"[32m-",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' + achar(27),"[32m",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' WRITE(IOUNIT, *)TRIM(TEXT1) RETURN ELSE From 14b6d8c01d1940fd64190f2614a457c79efee28e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 18 Nov 2016 18:19:33 -0700 Subject: [PATCH 149/325] update fll_py output --- accessories/fll_cat/fll_cat.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index a7df2d6..145842e 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -52,12 +52,11 @@ def run(file,fmt,scan): def print_header(): print(" ") print ("\033[031m************************************************************************************ \033[039m") - print ("\033[031m* * \033[039m") - print ("\033[031m* \033[039m fll_cat - v1.1 \033[031m * \033[039m") - print ("\033[031m* * \033[039m") - print ("\033[031m* * \033[039m") - print ("\033[031m* \033[039m prints content of file on screen \033[031m * \033[039m") - print ("\033[031m* * \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m fll_cat - v1.1 \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m prints content of file on screen \033[031m \033[039m") + print ("\033[031m \033[039m") print ("\033[031m************************************************************************************ \033[039m") From 0d1e129375d346c2302c7af7c203afb4c6a94558 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 19 Nov 2016 19:32:15 -0700 Subject: [PATCH 150/325] update README --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aab49e8..d98394f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,28 @@ Usage Here's an example of how to use `fort_depend.py` in your makefiles: # Script to generate the dependencies + # for example - look into www.github.com/libm3l/fll project + # + # specify location of fort_depend.py script + # MAKEDEPEND=/path/to/fort_depend.py + # + # specify location of fortran project root directory + # the script can now make dependencies for project with source + # files located in different directories. The script the search in each of them + # for fortran modules + # The PROJ_ROOT_PATH specifies the common directory for all the project subdirevtories + # + PROJ_ROOT_PATH =/path/to_proj_root_dir + # + # specify preferre path, ie. for big projects, rather then seaarch all directories in PROJ_ROOT_PATH + # you can specify those directories where the module are located + # if not specified, the script will be searching through entire tree + # + + FMODDIRS= \ + ../common \ + ../../util \ # $(DEP_FILE) is a .dep file generated by fort_depend.py DEP_FILE = my_project.dep @@ -31,6 +52,6 @@ Here's an example of how to use `fort_depend.py` in your makefiles: # when you change your source $(DEP_FILE): $(OBJECTS) @echo "Making dependencies!" - cd $(SRCPATH) && $(MAKEDEPEND) -w -o /path/to/$(DEP_FILE) -f $(OBJECTS) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) include $(DEP_FILE) From 320a86f804370d8dfda2d5b58a629997e254876c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 20 Nov 2016 20:30:23 -0700 Subject: [PATCH 151/325] add saving individual files to Example --- accessories/fll_cat/Makefile | 3 +- examples/Example_MPI-IO/Example_mpi-IO.f90 | 21 +++++- examples/Example_MPI-IO/Save_inivid_files.f90 | 69 +++++++++++++++++++ examples/Example_MPI-IO/project.dep | 18 +++-- mpi_util/Makefile | 2 +- mpi_util/fll_mpi_proc_struct.f90 | 2 +- mpi_util/project.dep | 60 ++++++++-------- 7 files changed, 132 insertions(+), 43 deletions(-) create mode 100644 examples/Example_MPI-IO/Save_inivid_files.f90 diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index b6d1313..dbbe3b7 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -58,7 +58,8 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + install: $(EXE).x $(EXE) $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 5af25c2..f081063 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -50,6 +50,7 @@ PROGRAM EXAMPLE_MPI_IO USE FLL_MPI_MODS_M USE READ_INPUT_M USE CREATE_DATA_SET_M + USE SAVE_INDIVID_FILES_M IMPLICIT NONE ! @@ -95,7 +96,7 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 100000 + 100*WORLD_RANK + NSIZE = 100000 !+ 100*WORLD_RANK CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) @@ -110,7 +111,7 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0)THEN CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING TIME IS ', FINISH-START + WRITE(*,*)' SAVING SINGLE PARALELL IO FILE TIME IS ', FINISH-START END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! @@ -123,10 +124,24 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0)THEN CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING TIME IS ', FINISH-START + WRITE(*,*)' SAVING N-M MODLE TIME IS ', FINISH-START END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + +! +! SAVING INDIVIDUAL FILES +! + IF(WORLD_RANK == 0)CALL CPU_TIME(START) + + CALL SAVE_INDIVID_FILES(PDATA_SET,WORLD_RANK) + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START + END IF + + IF(WORLD_RANK == 0) THEN CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) END IF diff --git a/examples/Example_MPI-IO/Save_inivid_files.f90 b/examples/Example_MPI-IO/Save_inivid_files.f90 new file mode 100644 index 0000000..9ea5733 --- /dev/null +++ b/examples/Example_MPI-IO/Save_inivid_files.f90 @@ -0,0 +1,69 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: Saves individual files +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE SAVE_INDIVID_FILES_M +CONTAINS + + SUBROUTINE SAVE_INDIVID_FILES(PNODE,RANK) + + USE FLL_MODS_M + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE +! +! Local declarations +! + CHARACTER(LEN=NAME_LENGTH) :: FILENAME + CHARACTER(LEN=6) :: STR + LOGICAL :: OK + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: RANK + + WRITE(STR,'(I6)')RANK + WRITE(FILENAME,'(A16)')"Ifiles_"//TRIM(ADJUSTL(TRIM(STR)))//".bsol" + OK = FLL_WRITE(PNODE,trim(FILENAME),RANK+10,'B',FPAR) + + END SUBROUTINE SAVE_INDIVID_FILES +END MODULE SAVE_INDIVID_FILES_M diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index 144588f..ecf9908 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -1,13 +1,17 @@ # This file is generated automatically. DO NOT EDIT! -Example_mpi-IO.o : \ - ../../data_util/fll_mods.o \ - read_input.o \ - ../../mpi_util/fll_mpi_mods.o \ - create_data_set.o +create_data_set.o : \ + ../../data_util/fll_mods.o -read_input.o : \ +Save_inivid_files.o : \ ../../data_util/fll_mods.o -create_data_set.o : \ +read_input.o : \ ../../data_util/fll_mods.o + +Example_mpi-IO.o : \ + create_data_set.o \ + read_input.o \ + Save_inivid_files.o \ + ../../data_util/fll_mods.o \ + ../../mpi_util/fll_mpi_mods.o diff --git a/mpi_util/Makefile b/mpi_util/Makefile index 26b1b26..12613e0 100644 --- a/mpi_util/Makefile +++ b/mpi_util/Makefile @@ -59,7 +59,7 @@ test: depend: $(FFILES) echo "Making dependencies ..." - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 6c47e42..da3254e 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -230,7 +230,7 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! create name of the file from the stem, number of file, and suffix ! WRITE(STR,'(I5)')J - WRITE(FILENAME,*)ADJUSTL(TRIM(NAME_OF_FILE))//"_",TRIM(ADJUSTL(STR))//".",ADJUSTL(TRIM(EXTENSION)) + WRITE(FILENAME,*)ADJUSTL(TRIM(NAME_OF_FILE))//"_"//TRIM(ADJUSTL(STR))//".",ADJUSTL(TRIM(EXTENSION)) ! ! save it to the IO structure ! diff --git a/mpi_util/project.dep b/mpi_util/project.dep index c839e40..a7e3009 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,47 +1,47 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o - fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_write_nm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_write.o - -fll_mpi_mods.o : \ - fll_mpi_cp.o \ - fll_mpi_proc_struct.o \ - fll_mpi_write_nm.o \ - fll_mpi_write.o \ - fll_mpi_sum.o \ - fll_mpi_mv.o \ - fll_mpi_read.o \ - fll_mpi_cp_all.o - -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o - fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o + fll_mpi_cp_all.o \ + ../data_util/fll_mods.o fll_mpi_mv.o : \ + ../data_util/fll_rm.o \ + ../data_util/fll_type.o \ fll_mpi_cp.o \ + ../data_util/fll_out.o + +fll_mpi_cp.o : \ + ../data_util/fll_mk.o \ ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_rm.o + ../data_util/fll_mv.o + +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o fll_mpi_write.o : \ ../data_util/fll_mods.o \ fll_mpi_sum.o -fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ +fll_mpi_cp_all.o : \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mv.o + +fll_mpi_mods.o : \ + fll_mpi_mv.o \ + fll_mpi_cp_all.o \ + fll_mpi_sum.o \ + fll_mpi_write_nm.o \ + fll_mpi_proc_struct.o \ + fll_mpi_read.o \ + fll_mpi_cp.o \ + fll_mpi_write.o + +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o From 7fa8ed395ddb5218809fd422501160aa59aa79c7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sun, 20 Nov 2016 20:53:41 -0700 Subject: [PATCH 152/325] add saving individual files --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 16 ++++++++++++++-- examples/Example_MPI-IO/project.dep | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 87a9e6d..cd56af8 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -50,6 +50,7 @@ PROGRAM EXAMPLE_MPI_IO USE FLL_MPI_MODS_M USE READ_INPUT_M USE CREATE_DATA_SET_M + USE SAVE_INDIVID_FILES_M IMPLICIT NONE ! @@ -110,7 +111,7 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0)THEN CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING TIME IS ', FINISH-START + WRITE(*,*)' SAVING PARALELL IO TIME IS ', FINISH-START END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! @@ -141,7 +142,18 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0)THEN CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING TIME IS ', FINISH-START + WRITE(*,*)' SAVING N-M MODEL TIME IS ', FINISH-START + END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + + IF(WORLD_RANK == 0)CALL CPU_TIME(START) + + OK = SAVE_INDIVID_FILES(PDATA_SET,FPAR) + + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(FINISH) + WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index ecf9908..17abaf5 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -3,15 +3,15 @@ create_data_set.o : \ ../../data_util/fll_mods.o -Save_inivid_files.o : \ +read_input.o : \ ../../data_util/fll_mods.o -read_input.o : \ +Save_inivid_files.o : \ ../../data_util/fll_mods.o Example_mpi-IO.o : \ - create_data_set.o \ read_input.o \ Save_inivid_files.o \ + create_data_set.o \ ../../data_util/fll_mods.o \ ../../mpi_util/fll_mpi_mods.o From 912f807f36a06a5e06e1ef0d1c069ae326dbb8dc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 09:55:53 -0700 Subject: [PATCH 153/325] fix bug in writing FFA format files --- data_util/fll_write_ffa.f90 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 5538a37..583ad9b 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -316,10 +316,10 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) LTYPE = PNODE%LTYPE IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN IF(PNODE%NLINK > 0)THEN - WRITE(IOUNIT, *)TRIM(PNODE%LNAME),",",TRIM(PNODE%FTYPE),' ,1, 1,',PNODE%NDIM + WRITE(IOUNIT, *)TRIM(PNODE%LNAME)," ",TRIM(PNODE%FTYPE),' 1 1 ',PNODE%NDIM LTYPE = PNODE%FTYPE ELSE - WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',N, 0, 0,',PNODE%NDIM + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),' N 0 0 ',PNODE%NDIM RETURN END IF ELSE @@ -330,9 +330,10 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) LTYPE ='L' END IF ELSE IF(TRIM(LTYPE) == 'L') THEN - LTYPE ='J' + LTYPE ='I' END IF - LTYPE = PNODE%FTYPE + + IF(PNODE%FTYPE /= '') LTYPE = PNODE%FTYPE IF( (PNODE%NSIZE * PNODE%NDIM > 1) )THEN SELECT CASE(LTYPE) @@ -341,7 +342,8 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) END SELECT END IF - WRITE(IOUNIT, *)TRIM(PNODE%LNAME),',', TRIM(LTYPE),',', PNODE%NSIZE, ',',PNODE%NDIM,',',0 + write(*,*)' LTYPE is ', ltype + WRITE(IOUNIT, *)TRIM(PNODE%LNAME),' ', TRIM(LTYPE),' ', PNODE%NSIZE, ' ',PNODE%NDIM,' ',0 END IF ! ! 1 D ARRAYS @@ -495,7 +497,7 @@ SUBROUTINE FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) ELSE IF(TRIM(LTYPE) == 'L') THEN LTYPE ='J' END IF - LTYPE = PNODE%FTYPE + IF(PNODE%FTYPE /= '') LTYPE = PNODE%FTYPE IF( (PNODE%NSIZE * PNODE%NDIM > 1) )THEN SELECT CASE(LTYPE) From ba9499ca1ae3f18f2af4188e423d927b38c7a92d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 09:56:31 -0700 Subject: [PATCH 154/325] add test with writing single merged file --- data_util/project.dep | 8 +- examples/Example_MPI-IO/Example_mpi-IO.f90 | 74 ++++++++++---- examples/Example_MPI-IO/project.dep | 20 ++-- ...nivid_files.f90 => save_individ_files.f90} | 6 +- .../Example_MPI-IO/save_root_part_file.f90 | 97 +++++++++++++++++++ mpi_util/project.dep | 58 +++++------ 6 files changed, 202 insertions(+), 61 deletions(-) rename examples/Example_MPI-IO/{Save_inivid_files.f90 => save_individ_files.f90} (91%) create mode 100644 examples/Example_MPI-IO/save_root_part_file.f90 diff --git a/data_util/project.dep b/data_util/project.dep index e518aee..3723677 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -72,15 +72,15 @@ fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_locate.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mk.o \ fll_out.o \ fll_type.o diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index cd56af8..0183e80 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -51,6 +51,7 @@ PROGRAM EXAMPLE_MPI_IO USE READ_INPUT_M USE CREATE_DATA_SET_M USE SAVE_INDIVID_FILES_M + USE SAVE_ROOT_PART_FILE_M IMPLICIT NONE ! @@ -70,6 +71,9 @@ PROGRAM EXAMPLE_MPI_IO REAL :: START, FINISH TYPE(DNODE), POINTER ::PIOSTR,PSUBPROC,PIO + + REAL :: CPUE,CPUS + INTEGER :: VALS(8) ! ! Initialize MPI ! @@ -96,36 +100,56 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 1000000 !+ 100*WORLD_RANK + NSIZE = 100000 !+ 100*WORLD_RANK + +! CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) +! IF(WORLD_RANK == 0) OK = FLL_WRITE_FFA(PDATA_SET,'test.bcs',10,'B',FPAR) + PDATA_SET => FLL_READ_FFA('test.bcase',8,'B',FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) - BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) - WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN +! PDATA_SET => FLL_READ_FFA('BSCW_Mesh.bmsh',8,'B',FPAR) +! BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) +! WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN ! ! save to one file, all partitions at the same time ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)CALL CPU_TIME(START) +! IF(WORLD_RANK == 0)CALL CPU_TIME(START) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING PARALELL IO TIME IS ', FINISH-START +! CALL CPU_TIME(FINISH) +! WRITE(*,*)'Time writing paralell to single file (N-1 model):', FINISH-START + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)' Time writing paralell to single file (N-1 model):',CPUE-CPUS END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! ! save to several separate files ! all partitions at the same time ! - IF(WORLD_RANK == 0)CALL CPU_TIME(START) + IF(WORLD_RANK == 0)THEN +! CALL CPU_TIME(START) + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING TIME IS ', FINISH-START +! CALL CPU_TIME(FINISH) +! WRITE(*,*)'Time writing paralell to a 2 file file (N-M model):', FINISH-START + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)"Time writing paralell to a 2 file file (N-M model):",CPUE-CPUS END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0) THEN @@ -136,27 +160,43 @@ PROGRAM EXAMPLE_MPI_IO PMPI => FLL_MPI_PROC_STRUCT(FPAR) CALL FLL_IO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) - IF(WORLD_RANK == 0)CALL CPU_TIME(START) + IF(WORLD_RANK == 0)THEN + CALL CPU_TIME(START) + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING N-M MODEL TIME IS ', FINISH-START +! CALL CPU_TIME(FINISH) +! WRITE(*,*)'Time writing paralell to a 4 file file (N-M model)', FINISH-START + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)' Time writing paralell to a 4 file file (N-M model):',CPUE-CPUS END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)CALL CPU_TIME(START) +! IF(WORLD_RANK == 0)CALL CPU_TIME(START) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF - OK = SAVE_INDIVID_FILES(PDATA_SET,FPAR) + CALL SAVE_INDIVID_FILES(PDATA_SET,WORLD_RANK,FPAR) IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(FINISH) - WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START +! CALL CPU_TIME(FINISH) +! WRITE(*,*)'Time writing to individual files (N-N model):', FINISH-START + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)' Time writing to individual files (N-N model):',CPUE-CPUS END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + IF(WORLD_RANK == 0)CALL SAVE_ROOT_PART_FILE(PDATA_SET,FPAR) ! ! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc ! to all other partitions diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/project.dep index 17abaf5..5e2ba4a 100644 --- a/examples/Example_MPI-IO/project.dep +++ b/examples/Example_MPI-IO/project.dep @@ -1,17 +1,21 @@ # This file is generated automatically. DO NOT EDIT! -create_data_set.o : \ +Example_mpi-IO.o : \ + ../../data_util/fll_mods.o \ + save_root_part_file.o \ + create_data_set.o \ + save_individ_files.o \ + read_input.o \ + ../../mpi_util/fll_mpi_mods.o + +save_individ_files.o : \ ../../data_util/fll_mods.o read_input.o : \ ../../data_util/fll_mods.o -Save_inivid_files.o : \ +create_data_set.o : \ ../../data_util/fll_mods.o -Example_mpi-IO.o : \ - read_input.o \ - Save_inivid_files.o \ - create_data_set.o \ - ../../data_util/fll_mods.o \ - ../../mpi_util/fll_mpi_mods.o +save_root_part_file.o : \ + ../../data_util/fll_mods.o diff --git a/examples/Example_MPI-IO/Save_inivid_files.f90 b/examples/Example_MPI-IO/save_individ_files.f90 similarity index 91% rename from examples/Example_MPI-IO/Save_inivid_files.f90 rename to examples/Example_MPI-IO/save_individ_files.f90 index 9ea5733..d32882d 100644 --- a/examples/Example_MPI-IO/Save_inivid_files.f90 +++ b/examples/Example_MPI-IO/save_individ_files.f90 @@ -46,7 +46,7 @@ MODULE SAVE_INDIVID_FILES_M CONTAINS - SUBROUTINE SAVE_INDIVID_FILES(PNODE,RANK) + SUBROUTINE SAVE_INDIVID_FILES(PNODE,RANK,FPAR) USE FLL_MODS_M IMPLICIT NONE @@ -61,9 +61,9 @@ SUBROUTINE SAVE_INDIVID_FILES(PNODE,RANK) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: RANK - WRITE(STR,'(I6)')RANK + WRITE(STR,'(I6)')RANK+1 WRITE(FILENAME,'(A16)')"Ifiles_"//TRIM(ADJUSTL(TRIM(STR)))//".bsol" - OK = FLL_WRITE(PNODE,trim(FILENAME),RANK+10,'B',FPAR) + OK = FLL_WRITE(PNODE,ADJUSTL(TRIM(FILENAME)),RANK+10,'B',FPAR) END SUBROUTINE SAVE_INDIVID_FILES END MODULE SAVE_INDIVID_FILES_M diff --git a/examples/Example_MPI-IO/save_root_part_file.f90 b/examples/Example_MPI-IO/save_root_part_file.f90 new file mode 100644 index 0000000..7c21c7f --- /dev/null +++ b/examples/Example_MPI-IO/save_root_part_file.f90 @@ -0,0 +1,97 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: Saves individual files +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE SAVE_ROOT_PART_FILE_M +CONTAINS + + SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,FPAR) + + USE MPI + USE FLL_MODS_M + IMPLICIT NONE + + TYPE(DNODE), POINTER :: PNODE,PMAIN,PTMP +! +! Local declarations +! + CHARACTER(LEN=NAME_LENGTH) :: FILENAME + CHARACTER(LEN=6) :: STR + LOGICAL :: OK + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: RANK, NPROC,IERR,WORLD_RANK,I + + REAL :: FINISH,START + REAL :: CPUE,CPUS + INTEGER :: VALS(8) + + CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, IERR ) + CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) + + FILENAME = 'Commsofile.bsol' + + PMAIN => FLL_MKDIR('partitioned_file',FPAR) + + DO I=1,NPROC + PTMP => FLL_CP(PNODE, PMAIN, FPAR) + END DO + + IF(WORLD_RANK == 0)THEN +! CALL CPU_TIME(START) + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + + OK = FLL_WRITE(PMAIN,ADJUSTL(TRIM(FILENAME)),10,'B',FPAR) + +! CALL CPU_TIME(FINISH) +! WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)'Time writing parallel to single file :',CPUE-CPUS + END IF + + CALL FLL_RM(PMAIN, FPAR) + + END SUBROUTINE SAVE_ROOT_PART_FILE +END MODULE SAVE_ROOT_PART_FILE_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index a7e3009..3625741 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,47 +1,47 @@ # This file is generated automatically. DO NOT EDIT! +fll_mpi_mods.o : \ + fll_mpi_cp.o \ + fll_mpi_proc_struct.o \ + fll_mpi_write_nm.o \ + fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o + fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_read.o : \ - fll_mpi_cp_all.o \ - ../data_util/fll_mods.o +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o -fll_mpi_mv.o : \ - ../data_util/fll_rm.o \ +fll_mpi_cp_all.o : \ + ../data_util/fll_mv.o \ ../data_util/fll_type.o \ - fll_mpi_cp.o \ - ../data_util/fll_out.o - -fll_mpi_cp.o : \ ../data_util/fll_mk.o \ - ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mv.o + ../data_util/fll_out.o fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o -fll_mpi_write.o : \ +fll_mpi_read.o : \ ../data_util/fll_mods.o \ - fll_mpi_sum.o + fll_mpi_cp_all.o -fll_mpi_cp_all.o : \ - ../data_util/fll_mk.o \ +fll_mpi_mv.o : \ + fll_mpi_cp.o \ ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_mv.o + ../data_util/fll_rm.o -fll_mpi_mods.o : \ - fll_mpi_mv.o \ - fll_mpi_cp_all.o \ - fll_mpi_sum.o \ - fll_mpi_write_nm.o \ - fll_mpi_proc_struct.o \ - fll_mpi_read.o \ - fll_mpi_cp.o \ - fll_mpi_write.o - -fll_mpi_write_nm.o : \ +fll_mpi_write.o : \ ../data_util/fll_mods.o \ - fll_mpi_write.o + fll_mpi_sum.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o From ca8bf6c91b0d33531ec788c407c7cbec5d9f2c8b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 10:02:45 -0700 Subject: [PATCH 155/325] write size of data set --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 0183e80..1c57203 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -107,9 +107,8 @@ PROGRAM EXAMPLE_MPI_IO PDATA_SET => FLL_READ_FFA('test.bcase',8,'B',FPAR) CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) -! PDATA_SET => FLL_READ_FFA('BSCW_Mesh.bmsh',8,'B',FPAR) -! BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) -! WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN + BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) + WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN ! ! save to one file, all partitions at the same time ! From 3e7107f48701fec928e290b4d5fb25c7e3718fb4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 11:55:34 -0700 Subject: [PATCH 156/325] add ffa format to fll_cat --- accessories/fll_cat/fll_cat.f90 | 11 +++++++++-- accessories/fll_cat/fll_cat.py | 21 ++++++++++++++------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index bb9e551..1c3aa1b 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -54,14 +54,21 @@ PROGRAM FLL_CATU TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: FMT, SCAN + CHARACTER(LEN=3) :: EFMT ! ! read a file and print on screen ! READ(*,*)FILE READ(*,*)FMT + READ(*,'(A3)')EFMT READ(*,*)SCAN - - PNODE => FLL_READ(FILE,8,FMT,FPAR,SCAN = SCAN) + + SELECT CASE(EFMT) + CASE('fll') + PNODE => FLL_READ(FILE,8,FMT,FPAR,SCAN = SCAN) + CASE('ffa') + PNODE => FLL_READ_FFA(FILE,8,FMT,FPAR) + END SELECT ! ! print node on the screen ! diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 145842e..4a8cbb1 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -11,7 +11,7 @@ #Definitions -def run(file,fmt,scan): +def run(file,fmt,efmt,scan): # # execute # @@ -44,10 +44,10 @@ def run(file,fmt,scan): if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt, scan])) + p.communicate(os.linesep.join([file, fmt, efmt, scan])) else: p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here - p.communicate(os.linesep.join( [file, fmt, scan])) + p.communicate(os.linesep.join( [file, fmt, efmt, scan])) def print_header(): print(" ") @@ -77,12 +77,14 @@ def check_path(path): parser.add_argument('-i','--file',nargs=1,help='Files to process') parser.add_argument('-f','--format',nargs=1,help='Format of the file') parser.add_argument('-s','--scan',action='store_true',help='Scan file only',required=False) + parser.add_argument('-e','--external_format',nargs=1,help='External format of the file') # Parse the command line arguments args = parser.parse_args() file = args.file[0] if args.file else None format = args.format[0] if args.format else None + eformat = args.external_format[0] if args.external_format else None scan = args.scan if not scan: @@ -97,11 +99,16 @@ def check_path(path): if not format: print ("\033[031mError: \033[039m missing file format\033[031m-c \033[032m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") - print ("\033[031m \033[039m \033[032m b - binary\033[039m") + print ("\033[031m \033[039m \033[032m b - binary format\033[039m") sys.exit() + + if not eformat: + eformat = 'fll' else: - if not('a') or not('A') or not('b') or not('B'): - print ("\033[031mError: \033[039m wrong specified file format\033[031m-c \033[032m") + if not('fll') or not('ffa'): + print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") + print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() - run(file=file,fmt=format, scan=scan) + run(file=file,fmt=format, efmt = eformat, scan=scan) From 46bf8052d8b6c326ee66da277948211b576df464 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 12:18:06 -0700 Subject: [PATCH 157/325] add scan option to FFA format read --- accessories/fll_cat/fll_cat.f90 | 2 +- data_util/fll_read_ffa.f90 | 189 ++++++++++++++++++++++++++------ 2 files changed, 155 insertions(+), 36 deletions(-) diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index 1c3aa1b..e8c9600 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -67,7 +67,7 @@ PROGRAM FLL_CATU CASE('fll') PNODE => FLL_READ(FILE,8,FMT,FPAR,SCAN = SCAN) CASE('ffa') - PNODE => FLL_READ_FFA(FILE,8,FMT,FPAR) + PNODE => FLL_READ_FFA(FILE,8,FMT,FPAR,SCAN = SCAN) END SELECT ! ! print node on the screen diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 346ca6c..b698d90 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -30,7 +30,7 @@ MODULE FLL_READ_FFA_M ! External Modules used ! CONTAINS - FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -57,6 +57,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! IOUNIT In Number of unit ! FMT In Format - a,A ASCII, b,B - Binary, * not specified ! FPAR In/Out structure containing function specific data +! SCAN In Optional parameter - scan only file ! ! Arguments declaration ! @@ -65,6 +66,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT + CHARACTER, OPTIONAL :: SCAN ! ! Local declarations ! @@ -72,6 +74,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS + CHARACTER :: SCAN_LOC INQUIRE (FILE=TRIM(FILE), EXIST=OK) @@ -82,6 +85,8 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) PNODE => NULL() RETURN END IF + + POS = 1 ! ! DETERMINE RORMAT' ! @@ -99,6 +104,12 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) PNODE => NULL() RETURN END SELECT + + IF(PRESENT(SCAN))THEN + SCAN_LOC = SCAN + ELSE + SCAN_LOC = 'N' + END IF ! ! OPEN THE FILE ! @@ -121,7 +132,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! READ INITIAL NODE ! - PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,FPAR) + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -136,7 +147,7 @@ END FUNCTION FLL_READ_FFA ! ! READS NODE ! - RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) + RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -165,6 +176,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) ! FMT In Format - a,A ASCII, b,B - Binary ! POS In/Out Position in binary file ! FPAR In/Out structure containing function specific data +! SCAN In scan only ! ! Arguments declaration ! @@ -173,6 +185,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT + CHARACTER :: SCAN ! ! Local declarations ! @@ -221,12 +234,12 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CASE('A') CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) CASE('B') - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,POS,FPAR_H) END SELECT END IF DO NNODES = 1,NDIM - PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) + PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' ! ! ATTACH TO PNODE @@ -243,7 +256,16 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,FPAR) RESULT(PNODE) CASE('A') CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) CASE('B') - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + IF(SCAN /= 'Y')THEN + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + ELSE + IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + ELSE + POS = POS + GET_NEW_FFA_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END IF + END IF + END SELECT END IF @@ -289,15 +311,15 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! NSIZE0 In original value of NSIZE from FFA format ! EXTRALINE In/Out If node node N but has NSUB > 0 read extra line ! FPAR In/Out structure containing function specific data +! POS In position in file ! ! Arguments declaration ! - INTEGER(LINT) :: POS CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT LOGICAL :: EXTRALINE - INTEGER(LINT) :: NDIM, NSIZE,NLINK,NDIMO,NSIZEO + INTEGER(LINT) :: NDIM, NSIZE,NLINK,NDIMO,NSIZEO,POS CHARACTER(*) :: LTYPE CHARACTER(*) :: NAME ! @@ -432,7 +454,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! CASE('B') NSIZE = 0 - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)NAME,LTYPE,NSIZE,NDIM,NLINK IF(TRIM(NAME) == 'FFA-format-v2')THEN ! @@ -443,6 +465,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM READ(IOUNIT,IOSTAT=IOSTAT)VER READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK END IF + INQUIRE(UNIT = IOUNIT, POS=POS) LTYPE(2:) = ' ' FTYPE = LTYPE @@ -628,7 +651,7 @@ END SUBROUTINE READ_DATA_FFA_ASCII - SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) ! ! Description: Function reads data contained in Pnode, binary file ! @@ -656,12 +679,13 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! NDIM In 1st dimension of array in the node ! NSIZE In 2nd dimension of array in the node ! FPAR In/Out structure containing function specific data +! POS In Position in file ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT - INTEGER(LINT) :: NDIM,NSIZE,NINTEG + INTEGER(LINT) :: NDIM,NSIZE,NINTEG,POS CHARACTER(*) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR ! @@ -679,30 +703,38 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('R') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%R1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%R0 + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,PNODE%R0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%R1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%R1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%R2(I,J),I=1,NDIM),J=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,((PNODE%R2(I,J),I=1,NDIM),J=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF CASE('D') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%D1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%D1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%D0 + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,PNODE%D0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%D1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%D1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%D2(I,J),I=1,NDIM),J=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,((PNODE%D2(I,J),I=1,NDIM),J=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -710,15 +742,19 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('I') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%I1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%I1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%I0 + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,PNODE%I0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%I1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%I1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%I2(I,J),I=1,NDIM),J=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,((PNODE%I2(I,J),I=1,NDIM),J=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -726,41 +762,48 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE('J') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%L1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%L1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%L0 + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,PNODE%L0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%L1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%L1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%L2(I,J),I=1,NDIM),J=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,((PNODE%L2(I,J),I=1,NDIM),J=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF CASE('S') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG DO I=1,NSIZE READ(IOUNIT,IOSTAT=IOSTAT)T PNODE%S1(I) = ' ' PNODE%S1(I) = T END DO + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,T + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,T + INQUIRE(UNIT = IOUNIT, POS=POS) PNODE%S0 = T END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG DO I=1,NDIM READ(IOUNIT,IOSTAT=IOSTAT)T PNODE%S1(I) = ' ' PNODE%S1(I) = T END DO + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG DO J=1,NSIZE DO I=1,NDIM READ(IOUNIT,IOSTAT=IOSTAT)T @@ -768,21 +811,26 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) PNODE%S2(I,J) = T END DO END DO + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF CASE('L') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%S1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%S1(I),I=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,PNODE%S0 + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,PNODE%S0 + INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE IF(NSIZE == 1)THEN - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,(PNODE%S1(I),I=1,NDIM) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,(PNODE%S1(I),I=1,NDIM) + INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,IOSTAT=IOSTAT)NINTEG,((PNODE%S2(I,J),I=1,NDIM),J=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,((PNODE%S2(I,J),I=1,NDIM),J=1,NSIZE) + INQUIRE(UNIT = IOUNIT, POS=POS) END IF END IF @@ -801,5 +849,76 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) RETURN END SUBROUTINE READ_DATA_FFA_BIN + + + FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) +! +! Description: Function gets new position for reading bindary file without allocating arrays +! used for scanning files +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! POS In Position in file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER(LINT) :: NDIM, NSIZE, POS + CHARACTER(LEN=*) :: LTYPE +! +! Local declaration +! + INTEGER :: LENGTH +! +! BODY +! + SELECT CASE(LTYPE) + CASE('R', 'I') + LENGTH = 4 + + CASE('D', 'L') + LENGTH = 8 + + + CASE('S') + LENGTH = LSTRING_LENGTH + + CASE('C') + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + POS = (NDIM * NSIZE ) *LENGTH + 8 + + RETURN + + END FUNCTION GET_NEW_FFA_POS END MODULE FLL_READ_FFA_M From 7386ed5b6fea0b312e81232aadcee9391e1e7ff5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Nov 2016 14:11:19 -0700 Subject: [PATCH 158/325] fix bindir definition --- Makefile | 4 +++- accessories/fll_cat/Makefile | 6 ++--- configure.py | 30 ++++++++++++++++++++++--- examples/Example_MPI-IO/Makefile | 4 ---- examples/Simple_data_operation/Makefile | 4 ---- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 2438e91..c5be3f8 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,8 @@ mpi_util \ accessories\ examples\ +SUBCLEAN=$(SUBDIRS) + ########################################################################### all: $(SUBDIRS:%=%.all) @@ -57,7 +59,7 @@ init: data_util.all: test.all: data_util.all -clean: $(SUBDIRS:%=%.clean) +clean: $(SUBCLEAN:%=%.clean) depend: $(SUBDIRS:%=%.depend) diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index dbbe3b7..58d30e0 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -61,8 +61,8 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -install: $(EXE).x $(EXE) - $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) - $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x +install: $(EXE).x $(EXE).py + $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x + $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py -include $(srcdir)/project.dep diff --git a/configure.py b/configure.py index 63300ee..f7a082a 100755 --- a/configure.py +++ b/configure.py @@ -52,7 +52,17 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= print(" ") print("\033[031mDIAG:\033[039m creating configure file \033[032m \033[039m") print(" ") - ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=cwd) + + if build == '': + print(" ") + print("\033[031mDIAG:\033[039m Bild directory not specified, setting it to \033[032m "+cwd+platform.machine()+"/bin\033[039m") + print(" ") + bin_dir=cwd+platform.machine()+'/bin' + else: + bin_dir=build + + + ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=bin_dir) # # create structure and link necessary files # @@ -64,6 +74,11 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= print("\033[031mDIAG:\033[039m Subdirectories .... \033[032m \033[039m") ok=mkdir_structure(root_path=path, cwd=cwd, exclude=exclude, linkfiles=linkfiles) + print(" ") + print("\033[031mNOTE:\033[039m Bild directory is set to \033[032m "+bin_dir+"\033[039m") + print("\033[031m------------------------------------------------------------------------\033[039m") + print(" ") + print(" ") print("\033[031mSUCCESS:\033[039m Setup was succesful \033[032m \033[039m") print(" ") @@ -208,7 +223,7 @@ def mkconfigfile(path, cwd,version, bin_dir): sys.exit() - exec_dir=bin_dir+"/bin/" + exec_dir=bin_dir confname = 'config.mk' @@ -237,7 +252,7 @@ def mkconfigfile(path, cwd,version, bin_dir): fconfig.write("#\n") fconfig.write("# bin_dir is the base directory where executables will be installed\n") fconfig.write("#\n") - fconfig.write('bin_dir='+exec_dir) + fconfig.write('bin_dir='+exec_dir+"\n") fconfig.write("#\n") fconfig.write("#\n") fconfig.write("# MACHINE identifies the host machine type") @@ -253,6 +268,15 @@ def mkconfigfile(path, cwd,version, bin_dir): f.close() fconfig.close() +# +# make exec directory +# + if not os.path.isdir(exec_dir): + print(" ") + print("\033[031mERROR:\033[039m Creating exec directory \033[032m"+exec_dir+"\033[039m .... ") + os.makedirs(exec_dir) + + cwd = check_path(path=cwd) class file_obj: def __init__(self): diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index 3733a7b..b59e0c5 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -65,8 +65,4 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -install: $(EXE).x $(EXE) - $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) - $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x - -include $(srcdir)/project.dep diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index 289024e..34e8397 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -60,8 +60,4 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -install: $(EXE).x $(EXE) - $(INSTALL) $(EXE) $(bindir)/bin/$(EXE)$(POSTFIX) - $(INSTALL) $(EXE).x $(bindir)/bin/$(EXE)$(POSTFIX).x - -include $(srcdir)/project.dep From acc80c816faa651dec91322e02d5ceebffb92f84 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 22 Nov 2016 08:52:07 -0700 Subject: [PATCH 159/325] rename function --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 6 +++--- mpi_util/fll_mpi_proc_struct.f90 | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 1c57203..507e929 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -89,7 +89,7 @@ PROGRAM EXAMPLE_MPI_IO ! ! define how to save files for N-M saving model ! - CALL FLL_IO_STRUCT(PMPI,'ada','bmpi',2_LINT, FPAR) + CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',2_LINT, FPAR) ! ! print the strucute on the screen and save into ASCII file ! @@ -113,7 +113,7 @@ PROGRAM EXAMPLE_MPI_IO ! save to one file, all partitions at the same time ! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) -! IF(WORLD_RANK == 0)CALL CPU_TIME(START) + IF(WORLD_RANK == 0)THEN CALL DATE_AND_TIME(VALUES=VALS) CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 @@ -157,7 +157,7 @@ PROGRAM EXAMPLE_MPI_IO CALL FLL_RM(PMPI,FPAR) PMPI => FLL_MPI_PROC_STRUCT(FPAR) - CALL FLL_IO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) + CALL FLL_NMIO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) IF(WORLD_RANK == 0)THEN CALL CPU_TIME(START) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index da3254e..a232220 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -141,7 +141,7 @@ END FUNCTION FLL_MPI_PROC_STRUCT - SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) + SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! ! Description: Contains function prepiring MPI I/O structure ! @@ -310,7 +310,7 @@ SUBROUTINE FLL_IO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) RETURN - END SUBROUTINE FLL_IO_STRUCT + END SUBROUTINE FLL_NMIO_STRUCT From 0aee4faa15115126d3d2c9d2cbf3641a467b58b4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 22 Nov 2016 12:03:46 -0700 Subject: [PATCH 160/325] add S-N-M model --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 66 +++-- mpi_util/fll_mpi_mods.f90 | 1 + mpi_util/fll_mpi_proc_struct.f90 | 279 +++++++++++++++++++-- mpi_util/fll_mpi_write_nm.f90 | 10 +- mpi_util/fll_mpi_write_snm.f90 | 190 ++++++++++++++ mpi_util/project.dep | 27 +- 6 files changed, 520 insertions(+), 53 deletions(-) create mode 100644 mpi_util/fll_mpi_write_snm.f90 diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 507e929..0e55bd6 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -90,6 +90,7 @@ PROGRAM EXAMPLE_MPI_IO ! define how to save files for N-M saving model ! CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',2_LINT, FPAR) + CALL FLL_SNMIO_STRUCT(PMPI,'ceda','bmpi',2_LINT, 'I', FPAR) ! ! print the strucute on the screen and save into ASCII file ! @@ -100,15 +101,15 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 100000 !+ 100*WORLD_RANK + NSIZE = 10000 !+ 100*WORLD_RANK -! CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) + CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) ! IF(WORLD_RANK == 0) OK = FLL_WRITE_FFA(PDATA_SET,'test.bcs',10,'B',FPAR) - PDATA_SET => FLL_READ_FFA('test.bcase',8,'B',FPAR) +! PDATA_SET => FLL_READ_FFA('test.bcase',8,'B',FPAR) CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) - WRITE(*,*)' Partition created data set size of ', WORLD_RANK,BYTESN + IF(WORLD_RANK == 0) WRITE(*,*)' Partitions created data set size of ', WORLD_RANK,BYTESN ! ! save to one file, all partitions at the same time ! @@ -119,46 +120,65 @@ PROGRAM EXAMPLE_MPI_IO CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 END IF - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) +! OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(FINISH) -! WRITE(*,*)'Time writing paralell to single file (N-1 model):', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 WRITE(*,*)' Time writing paralell to single file (N-1 model):',CPUE-CPUS END IF +! +! save to 2 separate files in S-N-M mode +! + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF + + OK = FLL_MPI_WRITE_SNM(PDATA_SET,PMPI,FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + WRITE(*,*)"Time writing serial to 2 files (S-N-M model):",CPUE-CPUS + END IF + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) +stop + ! -! save to several separate files -! all partitions at the same time +! save to 2 separate files all partitions at the same time ! IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(START) CALL DATE_AND_TIME(VALUES=VALS) CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 END IF OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(FINISH) -! WRITE(*,*)'Time writing paralell to a 2 file file (N-M model):', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)"Time writing paralell to a 2 file file (N-M model):",CPUE-CPUS + WRITE(*,*)"Time writing paralell to 2 partitions file (N-M model):",CPUE-CPUS END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0) THEN CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) END IF CALL FLL_RM(PMPI,FPAR) +! +! save to 4 separate files all partitions at the same time +! PMPI => FLL_MPI_PROC_STRUCT(FPAR) CALL FLL_NMIO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN CALL CPU_TIME(START) CALL DATE_AND_TIME(VALUES=VALS) @@ -167,17 +187,20 @@ PROGRAM EXAMPLE_MPI_IO OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN ! CALL CPU_TIME(FINISH) ! WRITE(*,*)'Time writing paralell to a 4 file file (N-M model)', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)' Time writing paralell to a 4 file file (N-M model):',CPUE-CPUS + WRITE(*,*)' Time writing paralell to 4 partitions file (N-M model):',CPUE-CPUS END IF + + +! +! write to individual files +! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - - -! IF(WORLD_RANK == 0)CALL CPU_TIME(START) IF(WORLD_RANK == 0)THEN CALL DATE_AND_TIME(VALUES=VALS) CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 @@ -185,16 +208,17 @@ PROGRAM EXAMPLE_MPI_IO CALL SAVE_INDIVID_FILES(PDATA_SET,WORLD_RANK,FPAR) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(FINISH) -! WRITE(*,*)'Time writing to individual files (N-N model):', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 WRITE(*,*)' Time writing to individual files (N-N model):',CPUE-CPUS END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - +! +! save entire data set from too partiton: 1-1 model +! IF(WORLD_RANK == 0)CALL SAVE_ROOT_PART_FILE(PDATA_SET,FPAR) ! ! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc diff --git a/mpi_util/fll_mpi_mods.f90 b/mpi_util/fll_mpi_mods.f90 index 9d2123d..fe16cf5 100644 --- a/mpi_util/fll_mpi_mods.f90 +++ b/mpi_util/fll_mpi_mods.f90 @@ -42,5 +42,6 @@ MODULE FLL_MPI_MODS_M USE FLL_MPI_WRITE_NM_M USE FLL_MPI_READ_M USE FLL_MPI_PROC_STRUCT_M + USE FLL_MPI_WRITE_SNM_M END MODULE FLL_MPI_MODS_M diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index a232220..289181f 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -125,15 +125,23 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) RETURN END IF ! -! add to is IO_struct -! - PTMP => FLL_MKDIR('IO_struct',FPAR) - IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN - WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO_struct' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - RETURN - END IF +! add to IO_struct structs +! +! PTMP => FLL_MKDIR('IO-NM_struct',FPAR) +! IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN +! WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' +! CALL FLL_OUT('ALL',FPAR) +! FPAR%SUCCESS = .FALSE. +! RETURN +! END IF + +! PTMP => FLL_MKDIR('IO-SNM_struct',FPAR) +! IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN +! WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' +! CALL FLL_OUT('ALL',FPAR) +! FPAR%SUCCESS = .FALSE. +! RETURN +! END IF FPAR%SUCCESS = .TRUE. RETURN @@ -143,7 +151,18 @@ END FUNCTION FLL_MPI_PROC_STRUCT SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! -! Description: Contains function prepiring MPI I/O structure +! Description: Contains function prepiring MPI I/O structure for NM model +! It splits all world_processes to NFILES groups +! which will simultaniously write to their own file +! The processes in groups are defined as: +! group 1: 1,world_size,nfiles +! group 2: 1,world_size,nfiles +! group 3: 1,world_size,nfiles +! group 4: 1,world_size,nfiles +! group 5: 1,world_size,nfiles +! ... +! ... +! group n: n,world_size,nfiles ! ! History: ! Version Date Patch number CLA Comment @@ -183,15 +202,31 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) CHARACTER(LEN=5) :: STR INTEGER, ALLOCATABLE :: EVEN_RANK(:) ! -! In MPI_prc_str find MPI_prc_str -> Subprocs -> IO_struct -! - PSUBPROC => FLL_LOCATE(PNODE,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) - PIOSTR => FLL_LOCATE(PSUBPROC,'IO_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) -! ! get number of processors and world group ! CALL MPI_Comm_size( MPI_COMM_WORLD, NPROC, IERR ) CALL MPI_Comm_group( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) + + IF(MOD(NPROC,NFILES) /= 0)THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - NPROC is not multiplication of NFILES' + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF +! +! In MPI_prc_str find MPI_prc_str -> Subprocs -> IO-NM_struct +! + PSUBPROC => FLL_LOCATE(PNODE,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) +! +! add to IO_struct structs +! + PIOSTR => FLL_MKDIR('IO-NM_struct',FPAR) + IF(.NOT.FLL_MV(PIOSTR, PSUBPROC, FPAR))THEN + WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF ! ! group processes ! there will be NFILES group @@ -204,7 +239,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) IF(NFILES == NPROC)THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A)')' fll_mpi_write_nm - error witing files, nfiles == npart ' + WRITE(FPAR%MESG,'(A)')' FLL_NMIO_STRUCT - error witing files, nfiles == npart ' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -276,7 +311,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) CALL MPI_Group_incl(WORLD_GROUP_ID, INT(NSTEP, KIND = SINT), EVEN_RANK, GROUP_ID, IERR ) CALL MPI_Comm_create(MPI_COMM_WORLD, GROUP_ID, COMM_ID, IERR ) ! -! save comminicator +! save communicator ! PTMP => FLL_MK('communicator','I', 1_LINT, 1_LINT, FPAR) PTMP%I0 = COMM_ID @@ -314,4 +349,214 @@ END SUBROUTINE FLL_NMIO_STRUCT + + + SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) +! +! Description: Contains function prepiring MPI I/O structure for NM model +! It splits all world_processes to NFILES groups +! which will then choose their first process as a master process +! to which they send the data. The master process then +! writes the data on the disc to its own designated file +! The processes in groups are defined as: +! +! mode - cross-node MODE = 'C' +! group 1: 1,world_size,nfiles +! group 2: 1,world_size,nfiles +! group 3: 1,world_size,nfiles +! group 4: 1,world_size,nfiles +! group 5: 1,world_size,nfiles +! ... +! ... +! group n: n,world_size,nfiles +! +! mode - in-node MODE = 'I' +! group 1: 1,nfiles +! group 2: nfiles+1,2*nfiles +! group 3: 2*nfiles+1, 3*nfiles +! ... +! ... +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to MPI structure +! NAME_OF_FILE In Name of output file +! EXTENSION In File extension (suffix) +! NFILES In Number of files +! FPAR In/Out Structure containing function specific data +! MODE In mode for grouping processors +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=*) :: NAME_OF_FILE,EXTENSION + INTEGER(LINT) :: NFILES + CHARACTER :: MODE +! +! Local declarations +! + TYPE(DNODE), POINTER :: PTMP,PSUBPROC,PIOSTR,PDIR + INTEGER(LINT) :: I,J, COUNT,NSTEP + INTEGER :: IERR,NPROC,WORLD_GROUP_ID,GROUP_ID, COMM_ID,IOUNIT,LOC_RANK + CHARACTER(LEN=NAME_LENGTH) :: FILENAME + CHARACTER(LEN=5) :: STR + INTEGER, ALLOCATABLE :: EVEN_RANK(:) +! +! get number of processors and world group +! + CALL MPI_Comm_size( MPI_COMM_WORLD, NPROC, IERR ) + CALL MPI_Comm_group( MPI_COMM_WORLD, WORLD_GROUP_ID, IERR ) + + IF(MOD(NPROC,NFILES) /= 0)THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - NPROC is not multiplication of NFILES' + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF +! +! In MPI_prc_str find MPI_prc_str -> Subprocs -> IO-SNM_struct +! + PSUBPROC => FLL_LOCATE(PNODE,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) + PIOSTR => FLL_MKDIR('IO-SNM_struct',FPAR) + IF(.NOT.FLL_MV(PIOSTR, PSUBPROC, FPAR))THEN + WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF +! +! group processes +! there will be NFILES group +! each group would have max NPROC/NFILES partitions and the increment +! between them is NFILES +! +! in this way, each file should be associated to one partition from each node +! + NSTEP = NPROC/NFILES + + IF(NFILES == NPROC)THEN + FPAR%SUCCESS = .FALSE. + WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - error witing files, nfiles == npart ' + CALL FLL_OUT('ALL',FPAR) + RETURN + END IF + + ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' +! +! loop over number of separate files, define which partition is going to be +! saving in what file (defined by EVEN_RANK array +! + DO J=1,NFILES +! +! define IOunit - so that user does not have to do it and they +! do not collide +! + IOUNIT = 10+J +! +! create node for name of the I/O file and add it to the main structure +! + PDIR => FLL_MKDIR('IO', FPAR) + IF(.NOT.FLL_MV(PDIR, PIOSTR, FPAR))STOP' ERROR MOVING NODE' +! +! create name of the file from the stem, number of file, and suffix +! + WRITE(STR,'(I5)')J + WRITE(FILENAME,*)ADJUSTL(TRIM(NAME_OF_FILE))//"_"//TRIM(ADJUSTL(STR))//".",ADJUSTL(TRIM(EXTENSION)) +! +! save it to the IO structure +! + PTMP => FLL_MK('name-of-file','S', 1_LINT, 1_LINT, FPAR) + PTMP%S0 = ADJUSTL(TRIM(FILENAME)) + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! save number of IO desrciptor +! + PTMP => FLL_MK('io-descrpt','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = IOUNIT + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! create node with number processors the job will run at +! + PTMP => FLL_MK('proc','L', NSTEP, 1_LINT, FPAR) + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! group processes +! there will be NFILES group +! each group would have max NPROC/NFILES partitions and the increment +! between them is NFILES +! +! in this way, each file should be associated to one partition from each node +! + COUNT = 1 + DO I=1+(J-1)*NSTEP,J*NSTEP +! +! fill partition numbers +! + PTMP%L1(COUNT) = I +! +! Partition is always +1 larger than rank of the process +! + EVEN_RANK(COUNT) = I-1 + COUNT = COUNT + 1 + + END DO +! +! create group and communicator +! group will contain processes in EVEN_RANK array +! + CALL MPI_Group_incl(WORLD_GROUP_ID, INT(NSTEP, KIND = SINT), EVEN_RANK, GROUP_ID, IERR ) + CALL MPI_Comm_create(MPI_COMM_WORLD, GROUP_ID, COMM_ID, IERR ) +! +! save communicator +! + PTMP => FLL_MK('communicator','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = COMM_ID + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! if in the group, get local rank of the process and save it +! if not in the group, set process local rank to -1 +! + IF(COMM_ID /= MPI_COMM_NULL)THEN + CALL MPI_Comm_rank(COMM_ID, LOC_RANK, IERR ) + ELSE + LOC_RANK = -1 + END IF + + PTMP => FLL_MK('loc_prc_rank','I', 1_LINT, 1_LINT, FPAR) + PTMP%I0 = LOC_RANK + IF(.NOT.FLL_MV(PTMP, PDIR, FPAR))STOP' ERROR MOVING NODE' +! +! free group, will not be needed +! + CALL MPI_GROUP_FREE(GROUP_ID, IERR) +! +! print node on the screen and save to files +! + END DO +! +! free memory +! + DEALLOCATE(EVEN_RANK, STAT = IERR) + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + + RETURN + + END SUBROUTINE FLL_SNMIO_STRUCT + END MODULE FLL_MPI_PROC_STRUCT_M diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index 0c49825..72602a9 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -80,10 +80,10 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) ! -! find MPI_prc_str -> Subprocs -> IO_struct +! find MPI_prc_str -> Subprocs -> IO-NM_struct ! PSUBPROC => FLL_LOCATE(PMPI,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) - PIOSTR => FLL_LOCATE(PSUBPROC,'IO_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) + PIOSTR => FLL_LOCATE(PSUBPROC,'IO-NM_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) ! ! loop over IO subsets ! @@ -93,17 +93,19 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! ! find: communicator ! name of file to save into -! desrcriptor for the file +! descriptor for the file ! local process rank, for each group of processes it will start with 0 ! COMM = FLL_GETNDATA_I0(PIO,'communicator',1_LINT,FPAR) + IF(COMM /= MPI_COMM_NULL)RETURN + NAME_OF_FILE = FLL_GETNDATA_S0(PIO,'name-of-file',1_LINT,FPAR) IOUNIT = FLL_GETNDATA_I0(PIO,'io-descrpt', 1_LINT, FPAR) LOC_RANK = FLL_GETNDATA_I0(PIO,'loc_prc_rank', 1_LINT, FPAR) ! ! Print some info ! - IF(COMM /= MPI_COMM_NULL)write(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) + WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) ! ! save file, ROOT_RANK is always 0, use local rank ! diff --git a/mpi_util/fll_mpi_write_snm.f90 b/mpi_util/fll_mpi_write_snm.f90 new file mode 100644 index 0000000..ee82ab2 --- /dev/null +++ b/mpi_util/fll_mpi_write_snm.f90 @@ -0,0 +1,190 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! +MODULE FLL_MPI_WRITE_SNM_M +! +! Description: contains subroutine writing file in paralell mode from N processors to M files +! in serial mode +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 22/11/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) +! +! Description: contains subroutine writing file in paralell mode from N processors to M files +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE MPI + USE FLL_MODS_M + USE FLL_MPI_CP_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE In Node to be written +! IOUNIT In Number of unit +! FILE_TAB In Specifies which partition saves to which file +! FPAR In/Out structure containing function specific data +! OK Out Success or fail +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE,PMPI + TYPE(FUNC_DATA_SET) :: FPAR + LOGICAL OK +! +! Local declarations +! + TYPE(DNODE), POINTER :: PSUBPROC,PIOSTR,PIO,PDISPL,PMAIN,PTMP + INTEGER :: COMM,IOUNIT,WORLD_RANK,IERR,ISTAT,LOCRANK,TMPINT + INTEGER(LINT) :: I,J + CHARACTER(LEN=NAME_LENGTH) :: NAME_OF_FILE + INTEGER(LINT), POINTER :: PROC_NUM(:) + + INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) + INTEGER(LINT) :: POS1,NPROC + + OK = .FALSE. +! +! get processor rank in world group +! + CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) +! +! find MPI_prc_str -> Subprocs -> IO-SNM_struct +! + PSUBPROC => FLL_LOCATE(PMPI,'Subprocs','*',-1_LINT,1_LINT,.FALSE.,FPAR) + PIOSTR => FLL_LOCATE(PSUBPROC,'IO-SNM_struct','*',-1_LINT,1_LINT,.FALSE.,FPAR) +! +! loop over IO subsets +! + DO I=1,PIOSTR%NDIM + + PIO => FLL_LOCATE(PIOSTR,'IO','*',-1_LINT,I,.FALSE.,FPAR) +! +! find: communicator +! name of file to save into +! descriptor for the file +! local process rank, for each group of processes it will start with 0 +! + COMM = FLL_GETNDATA_I0(PIO,'communicator',1_LINT,FPAR) + IF(COMM == MPI_COMM_NULL)CYCLE + + CALL MPI_Comm_rank ( COMM, LOCRANK, IERR ) + + NAME_OF_FILE = FLL_GETNDATA_S0(PIO,'name-of-file',1_LINT,FPAR) + IOUNIT = FLL_GETNDATA_I0(PIO,'io-descrpt', 1_LINT, FPAR) + PROC_NUM => FLL_GETNDATA_L1(PIO,'proc', 1_LINT, FPAR) + NPROC = SIZE(PROC_NUM, DIM = 1, KIND = LINT) +! +! if first partition in group get data from other partitions and +! save the file +! + IF(LOCRANK == 0)THEN +! +! Create header for the file +! + PMAIN => FLL_MKDIR('partitioned_file', FPAR) + PMAIN%NDIM = NPROC + 1 ! Number of partitioned solutions and displacement vector + PDISPL => FLL_MK('displacements','L', NPROC+1_LINT, 1_LINT, FPAR) + OK = FLL_MV(PDISPL, PMAIN, FPAR) +! +! ADD ROOT PARTITION SOLUTION +! + PTMP => FLL_CP(PNODE, PMAIN, FPAR) + + ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:144 ' +! +! get length of each data subset of actual data +! + POS = 0 +! +! the first subset is a header +! header = 16 + 4 + 8 + 8 (name, type, ndim, nsize) +! +! header + long int array +! + POS(1) = 36 + 36 + (NPROC+1)*8 + POS(2) = FLL_GETNBYTES(PNODE,FPAR) +! +! get solutions from associated partitions and add it to the main tree +! + DO J=2,NPROC + TMPINT = J-1 + PTMP => FLL_MPI_CP(PNODE,COMM,TMPINT,0,FPAR) + OK = FLL_MV(PTMP, PMAIN,FPAR) + POS(J+1) = FLL_GETNBYTES(PTMP,FPAR) + END DO +! +! Calculate displacement, ie where each subset starts +! +! the first subset will start always at position 1 +! ie. beginning of the file +! + DISPL(1) = 1 + + DO J=2,NPROC+1 + DISPL(J) = DISPL(J-1) + POS(J-1) + END DO + + PDISPL%L1 = DISPL + + WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) + IF(.NOT.FLL_WRITE(PMAIN,TRIM(NAME_OF_FILE), IOUNIT, 'B', FPAR))STOP'Error writing file' +! WRITE(*,*)' Partition ',WORLD_RANK,' done saving to :',trim(NAME_OF_FILE) +! +! Clean memory +! + CALL FLL_RM(PMAIN, FPAR) + RETURN + + ELSE +! +! Other then group root partition, copy data set to root partition +! + PTMP => FLL_MPI_CP(PNODE,COMM,LOCRANK,0,FPAR) + + RETURN + + END IF + + END DO + + END FUNCTION FLL_MPI_WRITE_SNM + +END MODULE FLL_MPI_WRITE_SNM_M diff --git a/mpi_util/project.dep b/mpi_util/project.dep index 3625741..e32f87f 100644 --- a/mpi_util/project.dep +++ b/mpi_util/project.dep @@ -1,6 +1,20 @@ # This file is generated automatically. DO NOT EDIT! +fll_mpi_cp_all.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o + +fll_mpi_sum.o : \ + ../data_util/fll_mods.o + +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o + fll_mpi_mods.o : \ + fll_mpi_write_snm.o \ fll_mpi_cp.o \ fll_mpi_proc_struct.o \ fll_mpi_write_nm.o \ @@ -10,18 +24,9 @@ fll_mpi_mods.o : \ fll_mpi_read.o \ fll_mpi_cp_all.o -fll_mpi_sum.o : \ - ../data_util/fll_mods.o - -fll_mpi_write_nm.o : \ +fll_mpi_write_snm.o : \ ../data_util/fll_mods.o \ - fll_mpi_write.o - -fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o + fll_mpi_cp.o fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o From edf482b18c4081f9f2080fa8bbb892b8283c9a55 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 22 Nov 2016 12:16:21 -0700 Subject: [PATCH 161/325] bug fix in fll_mpi_write_nm model --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 7 ++----- mpi_util/fll_mpi_write_nm.f90 | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 0e55bd6..5a87e51 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -101,7 +101,7 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 10000 !+ 100*WORLD_RANK + NSIZE = 5000000 !+ 100*WORLD_RANK CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) ! IF(WORLD_RANK == 0) OK = FLL_WRITE_FFA(PDATA_SET,'test.bcs',10,'B',FPAR) @@ -120,7 +120,7 @@ PROGRAM EXAMPLE_MPI_IO CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 END IF -! OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF(WORLD_RANK == 0)THEN @@ -146,8 +146,6 @@ PROGRAM EXAMPLE_MPI_IO END IF CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) -stop - ! ! save to 2 separate files all partitions at the same time ! @@ -165,7 +163,6 @@ PROGRAM EXAMPLE_MPI_IO WRITE(*,*)"Time writing paralell to 2 partitions file (N-M model):",CPUE-CPUS END IF - IF(WORLD_RANK == 0) THEN CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) END IF diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index 72602a9..1be22b2 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -97,7 +97,7 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! local process rank, for each group of processes it will start with 0 ! COMM = FLL_GETNDATA_I0(PIO,'communicator',1_LINT,FPAR) - IF(COMM /= MPI_COMM_NULL)RETURN + IF(COMM == MPI_COMM_NULL)CYCLE NAME_OF_FILE = FLL_GETNDATA_S0(PIO,'name-of-file',1_LINT,FPAR) IOUNIT = FLL_GETNDATA_I0(PIO,'io-descrpt', 1_LINT, FPAR) From f6c9a478af6173a0caef5bbc2e1da8166ca49e06 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 22 Nov 2016 13:19:55 -0700 Subject: [PATCH 162/325] correct typo --- examples/Example_MPI-IO/save_root_part_file.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Example_MPI-IO/save_root_part_file.f90 b/examples/Example_MPI-IO/save_root_part_file.f90 index 7c21c7f..1184bca 100644 --- a/examples/Example_MPI-IO/save_root_part_file.f90 +++ b/examples/Example_MPI-IO/save_root_part_file.f90 @@ -88,7 +88,7 @@ SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,FPAR) ! WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)'Time writing parallel to single file :',CPUE-CPUS + WRITE(*,*)'Time writing single to single file :',CPUE-CPUS END IF CALL FLL_RM(PMAIN, FPAR) From 2f78b62d62ca2eb6e4200301d27668343688f214 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 23 Nov 2016 14:43:28 -0700 Subject: [PATCH 163/325] change SEND to SSEND --- accessories/Makefile | 3 +- accessories/fll_cat/fll_cat.f90 | 11 ++++- examples/Example_MPI-IO/Example_mpi-IO.f90 | 51 +++++++++++----------- mpi_util/fll_mpi_cp.f90 | 34 +++++++-------- 4 files changed, 54 insertions(+), 45 deletions(-) diff --git a/accessories/Makefile b/accessories/Makefile index 86bb1b3..2f54e35 100644 --- a/accessories/Makefile +++ b/accessories/Makefile @@ -37,7 +37,8 @@ DEP_FILE=project.dep #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ - fll_cat + fll_cat\ + fll_convert diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index e8c9600..cd427af 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -48,7 +48,16 @@ PROGRAM FLL_CATU USE FLL_MODS_M IMPLICIT NONE ! -! SUBROUTINE MOVES NODE +! Description: cat file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 5a87e51..7cc8b19 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -167,32 +167,31 @@ PROGRAM EXAMPLE_MPI_IO CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) END IF - CALL FLL_RM(PMPI,FPAR) -! -! save to 4 separate files all partitions at the same time -! - PMPI => FLL_MPI_PROC_STRUCT(FPAR) - CALL FLL_NMIO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) - - - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL CPU_TIME(START) - CALL DATE_AND_TIME(VALUES=VALS) - CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - END IF - - OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) - - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(FINISH) -! WRITE(*,*)'Time writing paralell to a 4 file file (N-M model)', FINISH-START - CALL DATE_AND_TIME(VALUES=VALS) - CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)' Time writing paralell to 4 partitions file (N-M model):',CPUE-CPUS - END IF - +! CALL FLL_RM(PMPI,FPAR) +! ! +! ! save to 4 separate files all partitions at the same time +! ! +! PMPI => FLL_MPI_PROC_STRUCT(FPAR) +! CALL FLL_NMIO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) +! +! +! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) +! IF(WORLD_RANK == 0)THEN +! CALL CPU_TIME(START) +! CALL DATE_AND_TIME(VALUES=VALS) +! CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! END IF +! +! OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) +! +! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) +! IF(WORLD_RANK == 0)THEN +! ! CALL CPU_TIME(FINISH) +! ! WRITE(*,*)'Time writing paralell to a 4 file file (N-M model)', FINISH-START +! CALL DATE_AND_TIME(VALUES=VALS) +! CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! WRITE(*,*)' Time writing paralell to 4 partitions file (N-M model):',CPUE-CPUS +! END IF ! ! write to individual files diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index dcdfa66..7ec49ca 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -319,8 +319,8 @@ SUBROUTINE NODE_SEND(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ! ! Send node header ! - CALL MPI_SEND(IARR, 3, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) - CALL MPI_SEND(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(IARR, 3, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) IF(CODE == 0) RETURN IF(NDIM*NSIZE > 1) THEN @@ -328,46 +328,46 @@ SUBROUTINE NODE_SEND(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ! 1D ARRAYS ! IF(ASSOCIATED(PNODE%R1))THEN - CALL MPI_SEND(PNODE%R1, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%R1, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D1))THEN - CALL MPI_SEND(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%D1, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I1))THEN - CALL MPI_SEND(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%I1, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L1))THEN - CALL MPI_SEND(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%L1, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S1))THEN - CALL MPI_SEND(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%S1, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF ! ! 2D ARRAYS ! IF(ASSOCIATED(PNODE%R2))THEN - CALL MPI_SEND(PNODE%R2, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%R2, NDIM*NSIZE, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%D2))THEN - CALL MPI_SEND(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%D2, NDIM*NSIZE, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%I2))THEN - CALL MPI_SEND(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%I2, NDIM*NSIZE, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%L2))THEN - CALL MPI_SEND(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%L2, NDIM*NSIZE, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF IF(ASSOCIATED(PNODE%S2))THEN - CALL MPI_SEND(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%S2, NDIM*NSIZE*NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) RETURN END IF ! @@ -376,15 +376,15 @@ SUBROUTINE NODE_SEND(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ELSE IF(NDIM*NSIZE == 1 )THEN SELECT CASE(CODE) CASE(1) - CALL MPI_SEND(PNODE%R0, 1, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%R0, 1, MPI_REAL, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(2) - CALL MPI_SEND(PNODE%D0, 1, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%D0, 1, MPI_DOUBLE, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(3) - CALL MPI_SEND(PNODE%I0, 1, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%I0, 1, MPI_INTEGER, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(4) - CALL MPI_SEND(PNODE%L0, 1, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%L0, 1, MPI_INTEGER8, RECPART, SENDPART, COMMUNICATOR, IERR ) CASE(5) - CALL MPI_SEND(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) + CALL MPI_SSEND(PNODE%S0, NAME_LENGTH, MPI_CHARACTER, RECPART, SENDPART, COMMUNICATOR, IERR ) END SELECT END IF From 5977a4f4d134082084ecb6a69a0793ceceb7d825 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 23 Nov 2016 14:43:42 -0700 Subject: [PATCH 164/325] add fll_convert --- accessories/fll_convert/Makefile | 68 +++++++++++++ accessories/fll_convert/fll_convert.f90 | 95 ++++++++++++++++++ accessories/fll_convert/fll_convert.py | 123 ++++++++++++++++++++++++ accessories/fll_convert/project.dep | 4 + accessories/fll_convert/src_dir_path.mk | 2 + 5 files changed, 292 insertions(+) create mode 100644 accessories/fll_convert/Makefile create mode 100644 accessories/fll_convert/fll_convert.f90 create mode 100755 accessories/fll_convert/fll_convert.py create mode 100644 accessories/fll_convert/project.dep create mode 100644 accessories/fll_convert/src_dir_path.mk diff --git a/accessories/fll_convert/Makefile b/accessories/fll_convert/Makefile new file mode 100644 index 0000000..3a85e1e --- /dev/null +++ b/accessories/fll_convert/Makefile @@ -0,0 +1,68 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_convert + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=project.dep + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + + +install: $(EXE).x $(EXE).py + $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x + $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py + +-include $(srcdir)/project.dep diff --git a/accessories/fll_convert/fll_convert.f90 b/accessories/fll_convert/fll_convert.f90 new file mode 100644 index 0000000..cb010a4 --- /dev/null +++ b/accessories/fll_convert/fll_convert.f90 @@ -0,0 +1,95 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: prints file on screen +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM FLL_CONVERT + + USE FLL_MODS_M + IMPLICIT NONE +! +! Description: conversion utility +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE,OUTFILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER :: FMT, SCAN + CHARACTER(LEN=3) :: EFMT,OFMT + LOGICAL :: OK +! +! read a file and save it +! + READ(*,*)FILE + READ(*,*)FMT + READ(*,'(A3)')EFMT + READ(*,*)OUTFILE + READ(*,'(A3)')OFMT + + SELECT CASE(EFMT) + CASE('fll') + PNODE => FLL_READ(FILE,8,FMT,FPAR) + CASE('ffa') + PNODE => FLL_READ_FFA(FILE,8,FMT,FPAR) + END SELECT + + SELECT CASE(OFMT) + CASE('fll') + OK = FLL_WRITE(PNODE,OUTFILE,8,FMT,FPAR) + CASE('ffa') + OK = FLL_WRITE_FFA(PNODE, OUTFILE,8,FMT,FPAR) + END SELECT + + + CALL FLL_RM(PNODE,FPAR) + + +END PROGRAM diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py new file mode 100755 index 0000000..2f86a3e --- /dev/null +++ b/accessories/fll_convert/fll_convert.py @@ -0,0 +1,123 @@ +#!/usr/bin/python +# +# +# this is a python script +# +import os +import sys +from subprocess import Popen, PIPE +import unicodedata +import ast + +#Definitions + +def run(file,fmt,efmt,ofile,ofmt): +# +# execute +# + print_header() +# + path = os.path.dirname(os.path.abspath(__file__)) + cwd = os.getcwd() + + path = check_path(path=path) + cwd = check_path(path=cwd) + + executable = path+"fll_convert.x" + + if not os.path.isfile(file): + print(" ") + print("\033[031mERROR:\033[039m specified file \033[032m"+file+"\033[039m does not exist, terminating .... ") + sys.exit() + + print(" ") + print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + if fmt == 'b' or fmt == 'B': + print("\033[039m Specified file format is: \033[032mbinary\033[039m") + else: + print("\033[039m Specified file format is: \033[032mASCII \033[039m") + + if sys.version_info < (3,0): + p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here + p.communicate(os.linesep.join([file, fmt, efmt, ofile,ofmt])) + else: + p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here + p.communicate(os.linesep.join( [file, fmt, efmt, ofile,ofmt])) + +def print_header(): + print(" ") + print ("\033[031m************************************************************************************ \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m fll_convert - v1.1 \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m prints content of file on screen \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m************************************************************************************ \033[039m") + + +def check_path(path): + if not(path.endswith("/")): + path=path + "/" + + return path + + + +#Script +if __name__ == "__main__": + import argparse + + # Add command line arguments + parser = argparse.ArgumentParser(description='FLL configure script') + parser.add_argument('-i','--file',nargs=1,help='Input file') + parser.add_argument('-f','--format',nargs=1,help='Format of the file') + parser.add_argument('-o','--output_file',nargs=1,help='Output file') + parser.add_argument('-e','--format_input',nargs=1,help='Input file format') + parser.add_argument('-g','--format_output',nargs=1,help='Output file format') + + + # Parse the command line arguments + args = parser.parse_args() + + file = args.file[0] if args.file else None + format = args.format[0] if args.format else None + eformat = args.format_input[0] if args.format_input else None + oformat = args.format_output[0] if args.format_output else None + output = args.output_file[0] if args.output_file else None + + if not file: + print ("\033[031mError: \033[039m missing name of file\033[031m-c \033[032m") + sys.exit() + + if not format: + print ("\033[031mError: \033[039m missing file format\033[031m-c \033[032m") + print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") + print ("\033[031m \033[039m \033[032m b - binary format\033[039m") + sys.exit() + + if not output: + print ("\033[031mError: \033[039m missing output file \033[031m-o \033[032m") + sys.exit() + + if not eformat: + eformat = 'fll' + else: + + if not('fll') or not('ffa'): + print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") + print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") + sys.exit() + + + if not oformat: + oformat = 'fll' + else: + + if not('fll') or not('ffa'): + print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") + print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") + sys.exit() + + run(file=file,fmt=format, efmt = eformat, ofile=output, ofmt = oformat) diff --git a/accessories/fll_convert/project.dep b/accessories/fll_convert/project.dep new file mode 100644 index 0000000..41e91bd --- /dev/null +++ b/accessories/fll_convert/project.dep @@ -0,0 +1,4 @@ +# This file is generated automatically. DO NOT EDIT! + +fll_convert.o : \ + ../../data_util/fll_mods.o diff --git a/accessories/fll_convert/src_dir_path.mk b/accessories/fll_convert/src_dir_path.mk new file mode 100644 index 0000000..dc71e04 --- /dev/null +++ b/accessories/fll_convert/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/accessories/fll_convert + From 9f605f36c9666a1f7d8b2b531cd2333ba7dc8817 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 23 Nov 2016 15:16:01 -0700 Subject: [PATCH 165/325] add printout --- accessories/fll_convert/fll_convert.py | 27 +++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 2f86a3e..769ef78 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -31,12 +31,29 @@ def run(file,fmt,efmt,ofile,ofmt): sys.exit() print(" ") - print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + print("\033[039m Specified input file is: \033[032m"+file+"\033[039m") if fmt == 'b' or fmt == 'B': - print("\033[039m Specified file format is: \033[032mbinary\033[039m") + print("\033[039m Specified input file format is: \033[032mbinary\033[039m") else: - print("\033[039m Specified file format is: \033[032mASCII \033[039m") - + print("\033[039m Specified input file format is: \033[032mASCII \033[039m") + + if efmt == 'fll': + print("\033[039m Specified input file type is: \033[032mFLL \033[039m") + else: + print("\033[039m Specified input file type is: \033[032mFFA \033[039m") + + print(" ") + print("\033[039m Specified outpu file is: \033[032m"+ofile+"\033[039m") + if fmt == 'b' or fmt == 'B': + print("\033[039m Specified input file format is: \033[032mbinary\033[039m") + else: + print("\033[039m Specified input file format is: \033[032mASCII \033[039m") + + if ofmt == 'fll': + print("\033[039m Specified output file type is: \033[032mFLL \033[039m") + else: + print("\033[039m Specified output file type is: \033[032mFFA \033[039m") + if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here p.communicate(os.linesep.join([file, fmt, efmt, ofile,ofmt])) @@ -50,7 +67,7 @@ def print_header(): print ("\033[031m \033[039m") print ("\033[031m \033[039m fll_convert - v1.1 \033[031m \033[039m") print ("\033[031m \033[039m") - print ("\033[031m \033[039m prints content of file on screen \033[031m \033[039m") + print ("\033[031m \033[039m conversion utility \033[031m \033[039m") print ("\033[031m \033[039m") print ("\033[031m************************************************************************************ \033[039m") From 580fc72db63113a729e4cca4e663c7189d1dcd81 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Dec 2016 11:33:04 -0700 Subject: [PATCH 166/325] cleanup colors in fll_convert python script --- accessories/fll_convert/fll_convert.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 769ef78..23b505e 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -87,7 +87,7 @@ def check_path(path): # Add command line arguments parser = argparse.ArgumentParser(description='FLL configure script') parser.add_argument('-i','--file',nargs=1,help='Input file') - parser.add_argument('-f','--format',nargs=1,help='Format of the file') + parser.add_argument('-f','--format',nargs=1,help='Format of the file - ASCII, binary') parser.add_argument('-o','--output_file',nargs=1,help='Output file') parser.add_argument('-e','--format_input',nargs=1,help='Input file format') parser.add_argument('-g','--format_output',nargs=1,help='Output file format') @@ -103,7 +103,7 @@ def check_path(path): output = args.output_file[0] if args.output_file else None if not file: - print ("\033[031mError: \033[039m missing name of file\033[031m-c \033[032m") + print ("\033[031mError: \033[039m missing name of file \033[031m-i \033[039m") sys.exit() if not format: From cba004097b02d1638a636a969ee30c45a1bb5531 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Dec 2016 12:18:42 -0700 Subject: [PATCH 167/325] fix bu reading/writing strings --- accessories/fll_convert/fll_convert.f90 | 4 ++-- data_util/fll_read.f90 | 5 +++-- data_util/fll_write.f90 | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/accessories/fll_convert/fll_convert.f90 b/accessories/fll_convert/fll_convert.f90 index cb010a4..d643fe1 100644 --- a/accessories/fll_convert/fll_convert.f90 +++ b/accessories/fll_convert/fll_convert.f90 @@ -83,9 +83,9 @@ PROGRAM FLL_CONVERT SELECT CASE(OFMT) CASE('fll') - OK = FLL_WRITE(PNODE,OUTFILE,8,FMT,FPAR) + OK = FLL_WRITE(PNODE,OUTFILE,9,FMT,FPAR) CASE('ffa') - OK = FLL_WRITE_FFA(PNODE, OUTFILE,8,FMT,FPAR) + OK = FLL_WRITE_FFA(PNODE, OUTFILE,9,FMT,FPAR) END SELECT diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index b64980b..71b86d1 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -419,6 +419,7 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) READ(IOUNIT,IOSTAT=IOSTAT,POS = POS)NAME,LTYPE,NDIM,NSIZE INQUIRE(UNIT = IOUNIT, POS=POS) FPAR%SUCCESS = .TRUE. + RETURN END SELECT @@ -721,10 +722,10 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) CASE('S') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN - READ(IOUNIT,*,IOSTAT=IOSTAT, POS=POS)(PNODE%S1(I),I=1,NSIZE) + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)(PNODE%S1(I),I=1,NSIZE) INQUIRE(UNIT = IOUNIT, POS=POS) ELSE - READ(IOUNIT,*,IOSTAT=IOSTAT, POS=POS)PNODE%S0 + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)PNODE%S0 INQUIRE(UNIT = IOUNIT, POS=POS) END IF ELSE diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 38a1671..3d697a7 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -454,7 +454,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) ELSE IF(ASSOCIATED(PNODE%S1))THEN NDIM = SIZE(PNODE%S1, DIM =1, KIND = LINT) DO I = 1,NDIM - WRITE(IOUNIT)"'",PNODE%S1(I),"'" + WRITE(IOUNIT)PNODE%S1(I) END DO SAVED = .TRUE. ! @@ -488,7 +488,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) NDIM = SIZE(PNODE%S2, DIM =1, KIND = LINT) NSIZE = SIZE(PNODE%S2, DIM =2, KIND = LINT) DO J=1,NSIZE - WRITE(IOUNIT)("'",PNODE%S2(I,J),"' ", I = 1,NDIM) + WRITE(IOUNIT)(PNODE%S2(I,J), I = 1,NDIM) END DO SAVED = .TRUE. END IF @@ -506,7 +506,7 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) CASE('L') WRITE(IOUNIT)PNODE%L0 CASE('S') - WRITE(IOUNIT)"'",PNODE%S0,"'" + WRITE(IOUNIT)PNODE%S0 CASE DEFAULT From af3d844fe2d10849399eb348f1a9aaeb6e358977 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 5 Dec 2016 13:57:19 -0700 Subject: [PATCH 168/325] do not use --convert big endian Do not use compillation lag --convert big_endian for FFA files, specify in OPEN statement --- config/compset.x86_64 | 4 ++-- config/compset.x86_64_debug | 4 ++-- data_util/fll_read_ffa.f90 | 2 +- data_util/fll_write.f90 | 3 ++- data_util/fll_write_ffa.f90 | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/config/compset.x86_64 b/config/compset.x86_64 index cd299c3..1e8507b 100644 --- a/config/compset.x86_64 +++ b/config/compset.x86_64 @@ -5,8 +5,8 @@ # Fortran compiler and flags FC='ifort' -FFLAGS='-O2 -msse3 -ip -convert big_endian -r8 -std03 -fpp' -LDFLAGS='-O2 -msse3 -ip -convert big_endian -r8 -std03 -i-static' +FFLAGS='-O2 -msse3 -ip -r8 -std03 -fpp' +LDFLAGS='-O2 -msse3 -ip -r8 -std03 -i-static' # C compiler CC='icc' diff --git a/config/compset.x86_64_debug b/config/compset.x86_64_debug index 5fb3d0c..476c0ac 100644 --- a/config/compset.x86_64_debug +++ b/config/compset.x86_64_debug @@ -5,8 +5,8 @@ # Fortran compiler and flags FC='ifort' -FFLAGS='-msse3 -g -traceback -check -warn -convert big_endian -r8 -std03 -fpe0 -ftrapuv' -LDFLAGS='-msse3 -g -traceback -check -warn -convert big_endian -r8 -std03 -i-static -fpe0 -ftrapuv' +FFLAGS='-msse3 -g -traceback -check -warn -r8 -std03 -fpe0 -ftrapuv' +LDFLAGS='-msse3 -g -traceback -check -warn -r8 -std03 -i-static -fpe0 -ftrapuv' # C compiler CC='icc' diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index b698d90..2ba8834 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -116,7 +116,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) SELECT CASE(FMT_LOC) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& - ACCESS='STREAM',IOSTAT=ISTAT) + ACCESS='STREAM',CONVERT='big_endian',IOSTAT=ISTAT) CASE('A') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& IOSTAT=ISTAT, ACTION = 'READ') diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 3d697a7..7f09b23 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -433,9 +433,10 @@ SUBROUTINE FLL_SAVE_NODE_B(PNODE, IOUNIT, POS, FPAR) SAVED = .FALSE. ! -! 1D ARRAYS +! Header ! WRITE(IOUNIT)PNODE%LNAME,PNODE%LTYPE, PNODE%NDIM,PNODE%NSIZE + IF(TRIM(PNODE%LNAME) == 'DIR' .OR. TRIM(PNODE%LNAME) == 'N')RETURN ! ! 1 D ARRAYS ! diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 583ad9b..eca4cc4 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -98,7 +98,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) SELECT CASE(FMT_LOC) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& - ACCESS='STREAM',IOSTAT=ISTAT) + ACCESS='STREAM',CONVERT='big_endian', IOSTAT=ISTAT) WRITE(IOUNIT)FFVERSION CASE('A') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& From 8570e9111f413aac97031af780ecd175f0083d11 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 5 Dec 2016 21:56:39 -0700 Subject: [PATCH 169/325] get rid of big endian --- config/compset.gfortran | 10 +++++----- config/compset.gfortran_debug | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/compset.gfortran b/config/compset.gfortran index d90cbbe..b060249 100644 --- a/config/compset.gfortran +++ b/config/compset.gfortran @@ -1,12 +1,12 @@ FC = gfortran FCMODINCFLAG = -I -FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp -x f95-cpp-input -FFFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fopenmp -cpp -x f95-cpp-input +FFFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -ffixed-form -frecord-marker=4 -fopenmp -cpp UPPER_MODFILE_NAME = -LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 +LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 CC = gcc CFLAGS = -O2 -fopenmp C_LDFLAGS = -O2 -fopenmp MPI_FC = mpif90 -MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp -MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fopenmp -cpp +MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fopenmp -cpp +MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fopenmp -cpp diff --git a/config/compset.gfortran_debug b/config/compset.gfortran_debug index 1e3a207..8ea9118 100644 --- a/config/compset.gfortran_debug +++ b/config/compset.gfortran_debug @@ -1,13 +1,13 @@ FC = gfortran FCMODINCFLAG = -I -FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +FFFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input UPPER_MODFILE_NAME = -LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp +LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp CC = gcc -fopenmp CFLAGS = -g -fopenmp C_LDFLAGS = -g -fopenmp MPI_FC = mpif90 -MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input -MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -fconvert=big-endian -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp +MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input +MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp From 39c4f27f91b36f1409a2740c085493604adb4809 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 8 Dec 2016 08:38:43 -0700 Subject: [PATCH 170/325] clear comment in fll_locate --- data_util/fll_locate.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 6db1d93..82c654b 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -54,8 +54,8 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU ! NUMBER In position of node in list ! LTYPE In type of node - can be * ! DATADIM In dimensions of data the node should contain -! can be 0 - scalar), 1 -1D array, 2 -2D array -! any other number (prefer -1) - do not care about dimensions +! can be 0 - scalar, 1 -1D array, 2 -2D array +! if any other number specified (preferrable -1) - do not care about dimensions ! RECURSE In search recursively ! PFIND Out return pointer to located node ! FPAR In/Out structure containing function specific data From 4b26c6645eb83dd1223a4f1783844640c0930b4b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 9 Dec 2016 20:10:55 -0700 Subject: [PATCH 171/325] add name to diag --- data_util/fll_getndata.f90 | 46 +++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 4307544..9988bb5 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -83,7 +83,8 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -146,7 +147,8 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R1 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -208,7 +210,8 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_R2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R2 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -272,7 +275,8 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -336,7 +340,8 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D1 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -399,7 +404,8 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_D2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D2 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -463,7 +469,8 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -526,7 +533,8 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I1 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -587,7 +595,8 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_I2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I2 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -650,8 +659,8 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' - CALL FLL_OUT('ALL',FPAR) + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME RETURN END IF @@ -703,7 +712,8 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L1 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L1 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -764,7 +774,8 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L2 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L2 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -825,7 +836,8 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -886,7 +898,8 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -947,7 +960,8 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A)')'FLL_GETNDATA_L0 - Node ',TRIM(PNODE%LNAME),' does not contain specified data' + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN END IF From 733143b96d3e7a655f319e76b5a5b57c2b0c54bc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 10 Dec 2016 17:52:27 -0700 Subject: [PATCH 172/325] remove absolete stdout statement --- data_util/fll_write_ffa.f90 | 1 - 1 file changed, 1 deletion(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index eca4cc4..082299f 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -86,7 +86,6 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) CALL FLL_OUT('ALL',FPAR) - CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. From 46f20daa3b008aa3da84d611a6d75dd7231659a4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 15 Dec 2016 13:33:54 -0700 Subject: [PATCH 173/325] add check if ffa-v2 format --- data_util/fll_locate.f90 | 2 +- data_util/fll_read_ffa.f90 | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 82c654b..e6e0be9 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -35,7 +35,7 @@ MODULE FLL_LOCATE_M RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PFIND) ! ! Description: function finds node identified by name, type, position in list, dimensions of data it contains -! serach can be done recursively +! search can be done recursively ! ! External Modules used ! diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 2ba8834..368cc8d 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -464,6 +464,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM REWIND(IOUNIT) READ(IOUNIT,IOSTAT=IOSTAT)VER READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK + ELSE + WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading ffa file ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF INQUIRE(UNIT = IOUNIT, POS=POS) From a9d416788639b839d3ba8f71a4acee0c5deace3b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 27 Dec 2016 15:27:46 -0700 Subject: [PATCH 174/325] fix problem with FFA files --- data_util/fll_read_ffa.f90 | 39 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 368cc8d..f6a7a97 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -79,7 +79,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN - WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Read-ffa - file does not exist ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -98,7 +98,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) CASE('U','u','*') FMT_LOC = 'U' CASE DEFAULT - WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + WRITE(FPAR%MESG,'(A,A)')' Read-ffa - unknown format',TRIM(FMT) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -123,7 +123,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) END SELECT IF(ISTAT/=0) THEN - WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error opening file ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -136,7 +136,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error opening file ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -202,7 +202,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,NDIMO,NSIZEO,EXTRALINE,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN - WRITE(FPAR%MESG,'(A)')' Read - error reading header ' + WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading header ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -216,7 +216,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) END IF IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' + WRITE(FPAR%MESG,'(A)')' Read-ffa - error allocating node ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() @@ -456,20 +456,24 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM NSIZE = 0 READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)NAME,LTYPE,NSIZE,NDIM,NLINK - IF(TRIM(NAME) == 'FFA-format-v2')THEN + IF(POS == 1)THEN + + IF(TRIM(NAME) == 'FFA-format-v2')THEN ! ! DISREGARD, THIS IS JUST INFO ABOUT VERSION ! CONSIDER HAVING VERSION ONLY AT THE BEGINING OF THE FILE ! - REWIND(IOUNIT) - READ(IOUNIT,IOSTAT=IOSTAT)VER - READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK - ELSE - WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading ffa file ' - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - RETURN + REWIND(IOUNIT) + READ(IOUNIT,IOSTAT=IOSTAT)VER + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK + ELSE + WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading ffa header ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + RETURN + END IF + END IF INQUIRE(UNIT = IOUNIT, POS=POS) @@ -496,15 +500,16 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM END IF FPAR%SUCCESS = .TRUE. + RETURN END SELECT - WRITE(FPAR%MESG,'(A)')' Read - reading header error ' + WRITE(FPAR%MESG,'(A)')' Read-ffa - reading header error ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN - WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' + WRITE(FPAR%MESG,'(A)')' Read-ffa - reading header error, reached end of file ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN From 7243aca452d1a5286c41dd086256c44f96a55c0c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 28 Dec 2016 11:03:18 -0700 Subject: [PATCH 175/325] some additional fixes --- Makefile | 5 ++++- accessories/fll_cat/fll_cat.py | 6 +++--- accessories/fll_convert/fll_convert.py | 10 +++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index c5be3f8..f23bed1 100644 --- a/Makefile +++ b/Makefile @@ -33,10 +33,13 @@ include src_dir_path.mk SUBDIRS= \ data_util\ -mpi_util \ accessories\ examples\ +ifneq ($(strip $(MPI_FC)),) + SUBDIRS+= mpi_util +endif + SUBCLEAN=$(SUBDIRS) ########################################################################### diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 4a8cbb1..cfbb45f 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -93,11 +93,11 @@ def check_path(path): scan = 'Y' if not file: - print ("\033[031mError: \033[039m missing name of file\033[031m-c \033[032m") + print ("\033[031mError: \033[039m missing name of file, option\033[031m -i \033[039m") sys.exit() if not format: - print ("\033[031mError: \033[039m missing file format\033[031m-c \033[032m") + print ("\033[031mError: \033[039m missing file format, option\033[031m -f \033[039m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") print ("\033[031m \033[039m \033[032m b - binary format\033[039m") sys.exit() @@ -106,7 +106,7 @@ def check_path(path): eformat = 'fll' else: if not('fll') or not('ffa'): - print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031mError: \033[039m wrong file format, option\033[031m -e \033[039m") print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 23b505e..03ab093 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -103,17 +103,17 @@ def check_path(path): output = args.output_file[0] if args.output_file else None if not file: - print ("\033[031mError: \033[039m missing name of file \033[031m-i \033[039m") + print ("\033[031mError: \033[039m missing name of file, option \033[031m -i \033[039m") sys.exit() if not format: - print ("\033[031mError: \033[039m missing file format\033[031m-c \033[032m") + print ("\033[031mError: \033[039m missing file format, option\033[031m -c \033[039m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") print ("\033[031m \033[039m \033[032m b - binary format\033[039m") sys.exit() if not output: - print ("\033[031mError: \033[039m missing output file \033[031m-o \033[032m") + print ("\033[031mError: \033[039m missing output file, option \033[031m -o \033[039m") sys.exit() if not eformat: @@ -121,7 +121,7 @@ def check_path(path): else: if not('fll') or not('ffa'): - print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031mError: \033[039m wrong input file format, option \033[031m -e \033[039m") print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() @@ -132,7 +132,7 @@ def check_path(path): else: if not('fll') or not('ffa'): - print ("\033[031mError: \033[039m wrong file format\033[031m-e \033[032m") + print ("\033[031mError: \033[039m wrong output file format, option\033[031m -g \033[032m") print ("\033[031m \033[039m available options are: \033[032m fll - fll native format\033[039m") print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() From 06720505bc16df6bf0b313560010ab26ffd8417c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 24 Feb 2017 11:33:07 -0700 Subject: [PATCH 176/325] add A as a single char --- data_util/fll_read_ffa.f90 | 65 +++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index f6a7a97..bc20e4e 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -208,7 +208,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) PNODE => NULL() RETURN END IF - + IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) ELSE @@ -433,11 +433,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN NDIM = NLINK ELSE - IF(TRIM(LTYPE) == 'L')THEN LTYPE ='S' ELSE IF(TRIM(LTYPE) == 'J')THEN LTYPE ='L' + ELSE IF(TRIM(LTYPE) == 'A')THEN + LTYPE ='S' END IF IF(NLINK > 0 )THEN @@ -490,6 +491,8 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM LTYPE ='S' ELSE IF(TRIM(LTYPE(1:1)) == 'J')THEN LTYPE ='L' + ELSE IF(TRIM(LTYPE) == 'A')THEN + LTYPE ='S' END IF IF(NLINK > 0 )THEN @@ -644,7 +647,20 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END IF END IF - CASE('C') + CASE('A') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%C,I=1,NSIZE) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)PNODE%C + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,*,IOSTAT=IOSTAT)(PNODE%C,I=1,NDIM) + ELSE + READ(IOUNIT,*,IOSTAT=IOSTAT)((PNODE%C,I=1,NDIM),J=1,NSIZE) + END IF + END IF CASE('N','DIR') RETURN @@ -703,6 +719,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) ! Local declarations ! CHARACTER(LEN=SSTRING_LENGTH) :: T + CHARACTER :: ST INTEGER(LINT) :: I,J INTEGER :: IOSTAT LOGICAL :: OK @@ -826,6 +843,44 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END IF END IF + + CASE('A') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG + DO I=1,NSIZE + READ(IOUNIT,IOSTAT=IOSTAT)ST + PNODE%S1(I) = ' ' + PNODE%S1(I) = ST + END DO + INQUIRE(UNIT = IOUNIT, POS=POS) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG,ST + INQUIRE(UNIT = IOUNIT, POS=POS) + PNODE%S0 = ST + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' + PNODE%S1(I) = ST + END DO + INQUIRE(UNIT = IOUNIT, POS=POS) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT,POS=POS)NINTEG + DO J=1,NSIZE + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)ST + PNODE%S2(I,J) = ' ' + PNODE%S2(I,J) = ST + END DO + END DO + INQUIRE(UNIT = IOUNIT, POS=POS) + END IF + END IF + CASE('L') IF(NDIM == 1)THEN IF(NSIZE > 1)THEN @@ -845,7 +900,6 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END IF END IF - CASE('C') CASE('N','DIR') RETURN @@ -916,7 +970,8 @@ FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) CASE('S') LENGTH = LSTRING_LENGTH - CASE('C') + CASE('A') + LENGTH = 1 CASE('N','DIR') RETURN From 6f886ecdbbe2be7616b2ce54d474466f3bde063e Mon Sep 17 00:00:00 2001 From: Kostas Tsigaridis Date: Sat, 18 Mar 2017 15:44:13 -0400 Subject: [PATCH 177/325] Adding -i (--ignore) option to list modules which are found in dependencies but should be ignored. This is useful when the code is linked to external libraries. --- fort_depend.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 60484dc..70579f9 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -3,11 +3,11 @@ import re #Definitions -def run(files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(files=None,ignore=None,verbose=True,overwrite=None,output=None,macros={},build=''): l=create_file_objs(files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) - depends=get_depends(fob=l,m2f=mod2fil) + depends=get_depends(fob=l,m2f=mod2fil,ignore=ignore) if verbose: for i in depends.keys(): @@ -124,11 +124,12 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(fob=[],m2f=[]): +def get_depends(fob=[],m2f=[],ignore=[]): deps={} for i in fob: tmp=[] for j in i.uses: + if ignore and (j in ignore): continue try: tmp.append(m2f[j.lower()]) except: @@ -153,6 +154,7 @@ def __init__(self): # Add command line arguments parser = argparse.ArgumentParser(description='Generate Fortran dependencies') parser.add_argument('-f','--files',nargs='+',help='Files to process') + parser.add_argument('-i','--ignore',nargs='+',help='Modules to ignore') parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', help="""The macro NAME is replaced by DEFINITION in 'use' statements""") parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', @@ -175,4 +177,4 @@ def __init__(self): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' - run(files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(files=args.files, ignore=args.ignore, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From cc8b0014cbbcf2f930f176ef96f17d312bcc72a3 Mon Sep 17 00:00:00 2001 From: Kostas Tsigaridis Date: Sat, 18 Mar 2017 16:50:37 -0400 Subject: [PATCH 178/325] Check for included files while building depepdencies, not only used modules --- fort_depend.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 70579f9..a78ee2c 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -44,7 +44,11 @@ def write_depend(outfile="makefile.dep",dep=[],overwrite=False,build=''): stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") for j in dep[i]: tmp,fil=os.path.split(j) - stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") + ext=fil.split(".")[1] + if (ext == "inc"): + stri=stri+" \\\n\t"+os.path.join(build, fil) + else: + stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") stri=stri+"\n" f.write(stri) f.close() @@ -69,6 +73,7 @@ def create_file_objs(files=None, macros={}): source_file.file_name = i source_file.uses = get_uses(i,macros) + source_file.includes = get_includes(i,macros) source_file.contains = get_contains(i) l.append(source_file) @@ -99,6 +104,30 @@ def get_uses(infile=None, macros={}): return uniq_mods +def get_includes(infile=None, macros={}): + "Return which modules are included in infile after expanding macros" + p=re.compile("\#include\s*\"(?P\w*).inc\"$",re.IGNORECASE).match + + includes=[] + + with open(infile,'r') as f: + t=f.readlines() + + for i in t: + tmp=p(i) + if tmp: + includes.append(tmp.group('incfile').strip()+".inc") + + # Remove duplicates + uniq_includes = list(set(includes)) + + for i, mod in enumerate(uniq_includes): + for k, v in macros.items(): + if re.match(k, mod, re.IGNORECASE): + uniq_includes[i] = mod.replace(k,v) + + return uniq_includes + def get_contains(infile=None): "Return all the modules that are in infile" p=re.compile("^\s*module\s*(?P\w*)",re.IGNORECASE).match @@ -125,6 +154,7 @@ def file_objs_to_mod_dict(file_objs=[]): return dic def get_depends(fob=[],m2f=[],ignore=[]): + import os.path deps={} for i in fob: tmp=[] @@ -134,6 +164,12 @@ def get_depends(fob=[],m2f=[],ignore=[]): tmp.append(m2f[j.lower()]) except: print "\033[031mError\033[039m module \033[032m"+j+"\033[039m not defined in any files. Skipping..." + for j in i.includes: + try: + os.path.isfile(j) + tmp.append(j) + except: + print "\033[031mError\033[039m include file \033[032m"+j+"\033[039m does not exist. Skipping..." deps[i.file_name]=tmp @@ -143,6 +179,7 @@ class file_obj: def __init__(self): self.file_name=None self.uses=None + self.includes=None self.contains=None self.depends_on=None From b2b7201d48f48a294340765c49d23b7aa9d68b22 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 24 Apr 2017 07:04:51 -0600 Subject: [PATCH 179/325] remove absolete lines --- mpi_util/fll_mpi_proc_struct.f90 | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 289181f..258dd23 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -124,24 +124,6 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) FPAR%SUCCESS = .FALSE. RETURN END IF -! -! add to IO_struct structs -! -! PTMP => FLL_MKDIR('IO-NM_struct',FPAR) -! IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN -! WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' -! CALL FLL_OUT('ALL',FPAR) -! FPAR%SUCCESS = .FALSE. -! RETURN -! END IF - -! PTMP => FLL_MKDIR('IO-SNM_struct',FPAR) -! IF(.NOT.FLL_MV(PTMP, PSUBPROC, FPAR))THEN -! WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' -! CALL FLL_OUT('ALL',FPAR) -! FPAR%SUCCESS = .FALSE. -! RETURN -! END IF FPAR%SUCCESS = .TRUE. RETURN From 9bd074fefef231ca81714ea50d112edc150b90c9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 24 Apr 2017 07:06:02 -0600 Subject: [PATCH 180/325] correct err statement --- data_util/fll_read_ffa.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index bc20e4e..95a5bdc 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -136,7 +136,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN - WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error opening file ',TRIM(FILE) + WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error reading file ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. END IF From d596f05d7bc4a2ab9bca1c85f87f9179d1f7dbd3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 2 May 2017 10:00:59 -0600 Subject: [PATCH 181/325] add reading old format for pointwise --- data_util/fll_read_ffa.f90 | 264 +++++++++++++++++++++++++++++++++++-- 1 file changed, 250 insertions(+), 14 deletions(-) diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 95a5bdc..8e5a004 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -72,7 +72,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! LOGICAL :: OK CHARACTER :: FMT_LOC - INTEGER :: ISTAT + INTEGER :: ISTAT,FMTS INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC @@ -132,9 +132,21 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! ! READ INITIAL NODE ! - PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) - - CLOSE(IOUNIT) + FMTS = 0 + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR) + + IF(FMTS == 1)THEN + WRITE(*,*)' Reopening as old format' + FMTS = 2 + CLOSE(IOUNIT) + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + CONVERT='big_endian',IOSTAT=ISTAT) + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR) + CLOSE(IOUNIT) + ELSE + CLOSE(IOUNIT) + END IF + IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error reading file ',TRIM(FILE) CALL FLL_OUT('ALL',FPAR) @@ -147,7 +159,7 @@ END FUNCTION FLL_READ_FFA ! ! READS NODE ! - RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) + RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -184,7 +196,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) TYPE(DNODE), POINTER :: PNODE CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT + INTEGER :: IOUNIT,FMTS CHARACTER :: SCAN ! ! Local declarations @@ -199,7 +211,8 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) ! ! READ HEADER ! - CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,NDIMO,NSIZEO,EXTRALINE,FPAR_H) + CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,NDIMO,NSIZEO,& + EXTRALINE,FMTS,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading header ' @@ -234,12 +247,16 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) CASE('A') CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) CASE('B') - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,POS,FPAR_H) + IF(FMTS == 0)THEN + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,POS,FPAR_H) + ELSE + CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) + END IF END SELECT END IF DO NNODES = 1,NDIM - PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) + PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' ! ! ATTACH TO PNODE @@ -257,9 +274,14 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) CASE('B') IF(SCAN /= 'Y')THEN - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + IF(FMTS == 0)THEN + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + ELSE + CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + END IF ELSE IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN + IF(FMTS /= 0)STOP' Cannot use scan == y with old format' CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) ELSE POS = POS + GET_NEW_FFA_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) @@ -276,7 +298,7 @@ END FUNCTION READ_NODE_FFA ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIMO,NSIZEO,EXTRALINE,FPAR) + SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIMO,NSIZEO,EXTRALINE,FMTS,FPAR) ! ! Description: Reads header of each node ! @@ -312,12 +334,13 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! EXTRALINE In/Out If node node N but has NSUB > 0 read extra line ! FPAR In/Out structure containing function specific data ! POS In position in file +! FMTPS In format specification ! ! Arguments declaration ! CHARACTER :: FMT TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: IOUNIT + INTEGER :: IOUNIT,FMTS LOGICAL :: EXTRALINE INTEGER(LINT) :: NDIM, NSIZE,NLINK,NDIMO,NSIZEO,POS CHARACTER(*) :: LTYPE @@ -331,6 +354,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM CHARACTER*32 :: VER INTEGER :: IOSTAT LOGICAL :: OK + INTEGER(SINT) :: NDIM_S, NSIZE_S,NLINK_S EXTRALINE = .FALSE. @@ -455,9 +479,16 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM ! CASE('B') NSIZE = 0 - READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)NAME,LTYPE,NSIZE,NDIM,NLINK + IF(FMTS == 0)THEN + READ(IOUNIT,IOSTAT=IOSTAT, POS=POS)NAME,LTYPE,NSIZE,NDIM,NLINK + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE_S,NDIM_S,NLINK_S + NDIM = NDIM_S + NSIZE = NSIZE_S + NLINK = NLINK_S + END IF - IF(POS == 1)THEN + IF(POS == 1 .AND. FMTS == 0)THEN IF(TRIM(NAME) == 'FFA-format-v2')THEN ! @@ -471,6 +502,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading ffa header ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. + FMTS = 1 RETURN END IF @@ -916,6 +948,210 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) END SUBROUTINE READ_DATA_FFA_BIN + + SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) +! +! Description: Function reads data contained in Pnode, binary file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_FUNC_PRT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE In Pointer to node +! IOUNIT In Number of unit +! LTYPE In type of node +! NDIM In 1st dimension of array in the node +! NSIZE In 2nd dimension of array in the node +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + INTEGER :: IOUNIT + INTEGER(LINT) :: NDIM,NSIZE + CHARACTER(*) :: LTYPE + TYPE(FUNC_DATA_SET) :: FPAR +! +! Local declarations +! + CHARACTER(LEN=SSTRING_LENGTH) :: T + CHARACTER :: ST + INTEGER(LINT) :: I,J + INTEGER :: IOSTAT + LOGICAL :: OK +! +! BODY +! + IF(NDIM*NSIZE == 0)RETURN + SELECT CASE(LTYPE(1:1)) + CASE('R') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%R0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%R1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%R2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF + + CASE('D') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%D0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%D1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%D2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF + + + CASE('I') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%I0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%I1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%I2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF + + + CASE('J') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%L0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%L1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%L2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF + + CASE('S') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + DO I=1,NSIZE + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' + PNODE%S1(I) = T + END DO + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S0 = T + END IF + ELSE + IF(NSIZE == 1)THEN + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' + PNODE%S1(I) = T + END DO + ELSE + DO J=1,NSIZE + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S2(I,J) = ' ' + PNODE%S2(I,J) = T + END DO + END DO + END IF + END IF + + + CASE('A') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + DO I=1,NSIZE + READ(IOUNIT,IOSTAT=IOSTAT)ST + PNODE%S1(I) = ' ' + PNODE%S1(I) = ST + END DO + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)ST + PNODE%S0 = ST + END IF + ELSE + IF(NSIZE == 1)THEN + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)T + PNODE%S1(I) = ' ' + PNODE%S1(I) = ST + END DO + ELSE + DO J=1,NSIZE + DO I=1,NDIM + READ(IOUNIT,IOSTAT=IOSTAT)ST + PNODE%S2(I,J) = ' ' + PNODE%S2(I,J) = ST + END DO + END DO + END IF + END IF + + CASE('L') + IF(NDIM == 1)THEN + IF(NSIZE > 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NSIZE) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)PNODE%S0 + END IF + ELSE + IF(NSIZE == 1)THEN + READ(IOUNIT,IOSTAT=IOSTAT)(PNODE%S1(I),I=1,NDIM) + ELSE + READ(IOUNIT,IOSTAT=IOSTAT)((PNODE%S2(I,J),I=1,NDIM),J=1,NSIZE) + END IF + END IF + + + CASE('N','DIR') + RETURN + + CASE DEFAULT + WRITE(*,*)' WRONG TYPE' + + END SELECT + + OK = TEST_IOSTAT(IOSTAT,FPAR) + + RETURN + + END SUBROUTINE READ_DATA_FFA_BIN_OLD + + FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) ! ! Description: Function gets new position for reading bindary file without allocating arrays From c31b6b6c47462bad63fa714eb41c4bfe8e9b3cb4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 17 May 2017 14:15:29 -0600 Subject: [PATCH 182/325] Add link to fll --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d98394f..7e7b970 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,10 @@ Original script by D. Dickinson Usage ===== -Here's an example of how to use `fort_depend.py` in your makefiles: +Here's an example of how to use `fort_depend.py` in your makefiles. +For bigger project example, look at Makefiles, rule.mk and other files into fll project at +https://github.com/libm3l/fll which is a linked list library written in Fortran and which uses this +script to get dependencies # Script to generate the dependencies # for example - look into www.github.com/libm3l/fll project From 9a4e67c5aa3e459dc515c5a78fef4266e6cb401e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 17 May 2017 14:32:42 -0600 Subject: [PATCH 183/325] adding paragraph to README.md --- README.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e7e1a1..c12976e 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,38 @@ x86_64 are settings for Intel fortran compiler To compile, type -gmake +gmake + +3. Development: +==================================================== + + +3.1 Adding a new file to existing subdirectory + +if adding new file to already existing directory, after adding it type + +gmake depend + +to update the dependencies. If the file depends on files in different subdirectories then specified in FMODIR in the Makefile, add this subdirectory to FMODIR list + +3.2 Adding a new subdirectory + + +When adding new directory to the project, copy a Makefile and src_dir_path.mk from one of already existing directories for example from mpi_util. src_dir_path.mk is not to change. In Makefile the only item which is to be likely edited is +FMODIR array which contains list of directories with files which are used by newly added files. + +For example in mpi_util Makfile, the FMODIR array contains ../data_util specifying that fortran source file in mpi_util directory depends on files contained in ../data_util directory and when making dependencies python dependency script will look into this directory + +if FMODIR is not specified, the fortran dependency script will search all directories specified in PROJ_ROOT_PATH which is specified in config.mk file in root direcotry of the project. This file is created automatically upon initialization of the project by invoking command + +gmake init + +in root directory of the fll project + + + + +Edit array [![Analytics](https://ga-beacon.appspot.com/UA-86532469-1/libm3l/fll)](https://github.com/igrigorik/ga-beacon) From 348a67540dbbaf55482ca09bf4f3531530ced1ee Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 17 May 2017 14:36:42 -0600 Subject: [PATCH 184/325] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c12976e..a150ea2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# fll is a fortran linked list library +# fll is a fortran linked list library with possibility of paralell IO The library enables operations with linked list. For more information see attached ppt or pdf file in the project root directory From 4ea47bb89ac51de1573eee873cff1f4b7992d815 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 19 May 2017 08:47:32 -0600 Subject: [PATCH 185/325] add type of verbose complete readme file --- README.md | 56 ++++++++++++++++++--------- fort_depend.py | 100 +++++++++++++++++++++++++++++++------------------ 2 files changed, 102 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 7e7b970..c9c922d 100644 --- a/README.md +++ b/README.md @@ -9,40 +9,62 @@ Usage ===== Here's an example of how to use `fort_depend.py` in your makefiles. -For bigger project example, look at Makefiles, rule.mk and other files into fll project at + +Input parameters: + + + -f --files Files to process + -o --output Output file + -v -vv -vvv Different level of verbosity contained in standard output + -w --overwrite Overwrite output file without warning + -r --root_dir Project root directory + -d --dep_dir List of selected dependecy directories + +For bigger project example, look at Makefiles, rule.mk, src_dir_path.mk and other files in fll project at https://github.com/libm3l/fll which is a linked list library written in Fortran and which uses this -script to get dependencies +script to get fortran project dependencies + +========================= MAKEFILE EXAMPLE =================== # Script to generate the dependencies # for example - look into www.github.com/libm3l/fll project # # specify location of fort_depend.py script # - MAKEDEPEND=/path/to/fort_depend.py + MAKEDEPEND=/path_to/fort_depend.py # + # The PROJ_ROOT_PATH specifies the common directory for all the project subdirectories # specify location of fortran project root directory # the script can now make dependencies for project with source - # files located in different directories. The script the search in each of them - # for fortran modules - # The PROJ_ROOT_PATH specifies the common directory for all the project subdirevtories + # files located in different subdirectories directories in the project root directory. + # The script lops over all of them finding dependencies for all fortran files + # use option --root_dir # PROJ_ROOT_PATH =/path/to_proj_root_dir # - # specify preferre path, ie. for big projects, rather then seaarch all directories in PROJ_ROOT_PATH - # you can specify those directories where the module are located - # if not specified, the script will be searching through entire tree + # specify selected path for dependency search, ie. for big projects, rather then search through all directories in PROJ_ROOT_PATH + # you can specify those directories which will be searched for dependencies are located + # if not specified, the script will be searching through entire tree. For bigger projects this may lead to longer time while + # looking for dependencies + # use option --dep_dir # - FMODDIRS= \ - ../common \ - ../../util \ - # $(DEP_FILE) is a .dep file generated by fort_depend.py DEP_FILE = my_project.dep # Source files to compile - OBJECTS = mod_file1.f90 \ - mod_file2.f90 + # You can specify all .f90 files + FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + # or you can specify names of the files directly + FFILES = mod_file1.f90 \ + mod_file2.f90 + + # + # files specified in FFILES are dependent on files located in directory ../data_util and ../../util + # if not specified, the sript looks for all files in PROJ_ROOT_PATH + FMODDIRS= \ + ../data_util \ + ../../util \ # Make sure everything depends on the .dep file all: $(actual_executable) $(DEP_FILE) @@ -55,6 +77,6 @@ script to get dependencies # when you change your source $(DEP_FILE): $(OBJECTS) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -v w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) - include $(DEP_FILE) + -include $(DEP_FILE) diff --git a/fort_depend.py b/fort_depend.py index 20dbc55..e83e7df 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -19,16 +19,17 @@ #Definitions -def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() path = check_path(path=path) cwd = check_path(path=cwd) - print(" ") - print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") - print(" ") + if int(verbose) > 0: + print(" ") + print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") + print(" ") # # get rid of ../ in deps # @@ -42,18 +43,19 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= # ff=get_all_files(path=path, dep=dep) - print(" ") - print("\033[031m Looking for modules in files:\033[039m") - print(ff) + if int(verbose) > 2: + print(" ") + print("\033[031m Looking for modules in files:\033[039m") + print(ff) - l=create_file_objs(files,macros) + l=create_file_objs( (verbose) ,files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) # # make dependencies # depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) - if verbose: + if int(verbose) == 3 : for i in depends.keys(): print ("\033[032m"+i+"\033[039m depends on :\033[034m") for j in depends[i]: print( "\t"+j) @@ -62,11 +64,11 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= if output is None: output = "makefile.dep" - tmp=write_depend(path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) + tmp=write_depend(verbose=verbose,path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) return depends -def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): +def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): "Write the dependencies to outfile" # #Test file doesn't exist @@ -84,15 +86,19 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' # #Open file # - print(" ") - print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") - print(" ") + if int(verbose) > 1: + print(" ") + print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") + print(" ") f=open(outfile,'w') f.write('# This file is generated automatically. DO NOT EDIT!\n') + for i in dep.keys(): tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") - print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") + if int(verbose) > 1: + print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") + if not(dep[i] == ""): for j in dep[i]: @@ -117,8 +123,11 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' f.write(stri) f.close() - print("\033[031m Finished ... \033[039m") - print(" ") + + if int(verbose) > 1: + print("\033[031m Finished ... \033[039m") + print(" ") + return def get_source(ext=[".f90",".F90",".f",".F"]): @@ -170,7 +179,8 @@ def check_if_there(use,file): else: with open(file) as f: with open(file, errors='ignore') as f: - if "module" in line.lower(): + for line in f: + if "module" in line.lower(): extrline = line.lower() extrline = extrline.replace("module", "") if use.lower().strip() == extrline.strip(): @@ -181,7 +191,7 @@ def check_if_there(use,file): return 0 -def create_file_objs(files=None, macros={}): +def create_file_objs(verbose, files=None, macros={}): l=[] if files is None: @@ -189,23 +199,25 @@ def create_file_objs(files=None, macros={}): files = get_source() - print(" ") - print("\033[031m Looking for modules for files:\033[039m") - print(" ") + if int(verbose) > 1 : + print(" ") + print("\033[031m Looking for modules for files:\033[039m") + print(" ") for i in files: source_file = file_obj() - - print(i) + if int(verbose) > 1 : + print(i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.contains = get_contains(i) l.append(source_file) - print(" ") + if int(verbose) > 1 : + print(" ") return l @@ -271,8 +283,9 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 0 for i in fob: - print("") - print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") + if int(verbose) > 1 : + print("") + print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: try: @@ -298,15 +311,16 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + if int(verbose) > 1 : + print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") + print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") if istat== 0 and not(j == ""): - print("") - print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print("") + if int(verbose) > 1 : + print("") + print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") if not(istat == 0): deps[i.file_name]=tmp @@ -317,9 +331,10 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): def check_path(path): if path.endswith("/"): - print("Path correct") +# print(" ") + return path else: - print( "adding / to the path in "+path) +# print( "adding / to the path in "+path) path=path + "/" return path @@ -361,6 +376,8 @@ def __init__(self): default='') parser.add_argument('-o','--output',nargs=1,help='Output file') parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') + parser.add_argument('-vv','--vverbose',action='store_true',help='explain what is done') + parser.add_argument('-vvv','--vvverbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') parser.add_argument('-d','--dep_dir',nargs='+',action='append',help='Preferred dependecy directory') @@ -385,4 +402,13 @@ def __init__(self): print ("\033[031mError: \033[039m missing path to project root directory \033[032m") sys.exit() - run(path=root_dir, dep=dep_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + verbose = 0 + if(args.verbose): + verbose = 1 + if(args.vverbose): + verbose = 2 + if(args.vvverbose): + verbose = 3 + + + run(path=root_dir, dep=dep_dir, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From 0bde16137b0be70ab3c444a9804fbd11c8eddc22 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 19 May 2017 12:40:56 -0600 Subject: [PATCH 186/325] update verbosity of output during depend phase --- Makefile | 1 + accessories/fll_cat/Makefile | 2 +- accessories/fll_convert/Makefile | 2 +- data_util/Makefile | 2 +- data_util/project.dep | 8 +- examples/Example_MPI-IO/Makefile | 2 +- examples/Makefile | 1 + examples/Simple_data_operation/Makefile | 2 +- examples/Simple_data_operation/project.dep | 4 +- mpi_util/Makefile | 2 +- python_dep/fort_depend.py | 101 +++++++++++++-------- 11 files changed, 77 insertions(+), 50 deletions(-) diff --git a/Makefile b/Makefile index f23bed1..2cf66ef 100644 --- a/Makefile +++ b/Makefile @@ -58,6 +58,7 @@ init: echo PROJ_ROOT_PATH=$(PWD) > config.mk echo MAKEDEPEND=$(PWD)/python_dep/fort_depend.py >> config.mk echo MPI_FC=YES >> config.mk + echo VERBOSE=v data_util.all: test.all: data_util.all diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index 58d30e0..5b7c52d 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -58,7 +58,7 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) install: $(EXE).x $(EXE).py diff --git a/accessories/fll_convert/Makefile b/accessories/fll_convert/Makefile index 3a85e1e..e4412db 100644 --- a/accessories/fll_convert/Makefile +++ b/accessories/fll_convert/Makefile @@ -58,7 +58,7 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) install: $(EXE).x $(EXE).py diff --git a/data_util/Makefile b/data_util/Makefile index 061c2a5..77d1cd6 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -53,7 +53,7 @@ test: depend: $(FFILES) echo "Making dependencies ..." - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) diff --git a/data_util/project.dep b/data_util/project.dep index 3723677..e518aee 100644 --- a/data_util/project.dep +++ b/data_util/project.dep @@ -72,15 +72,15 @@ fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mk.o \ fll_out.o \ fll_type.o -fll_locate.o : \ +fll_read_ffa.o : \ + fll_mv.o \ fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index b59e0c5..bab4c3c 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -63,6 +63,6 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/project.dep diff --git a/examples/Makefile b/examples/Makefile index f506216..542c2be 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -41,6 +41,7 @@ DEP_FILE=project.dep #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ Simple_data_operation \ + Extra \ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= Example_MPI-IO diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index 34e8397..6263f0a 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -58,6 +58,6 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH)$(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/project.dep diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/project.dep index 4b1a81c..84ecddc 100644 --- a/examples/Simple_data_operation/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -1,8 +1,6 @@ # This file is generated automatically. DO NOT EDIT! -fll_test_subr.o : \ - ../../data_util/fll_mods.o +fll_test_subr.o : fll_test.o : \ - ../../data_util/fll_mods.o \ fll_test_subr.o diff --git a/mpi_util/Makefile b/mpi_util/Makefile index 12613e0..2acb8db 100644 --- a/mpi_util/Makefile +++ b/mpi_util/Makefile @@ -59,7 +59,7 @@ test: depend: $(FFILES) echo "Making dependencies ..." - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 541dc4b..67d86aa 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -19,16 +19,17 @@ #Definitions -def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() path = check_path(path=path) cwd = check_path(path=cwd) - print(" ") - print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") - print(" ") + if int(verbose) > 0: + print(" ") + print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") + print(" ") # # get rid of ../ in deps # @@ -42,31 +43,32 @@ def run(path,dep=None,files=None,verbose=True,overwrite=None,output=None,macros= # ff=get_all_files(path=path, dep=dep) - print(" ") - print("\033[031m Looking for modules in files:\033[039m") - print(ff) + if int(verbose) > 2: + print(" ") + print("\033[031m Searching for modules in files:\033[039m") + print(ff) - l=create_file_objs(files,macros) + l=create_file_objs( (verbose) ,files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) # # make dependencies # depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) - if verbose: + if int(verbose) == 3 : for i in depends.keys(): - print ("\033[032m"+i+"\033[039m depends on :\033[034m") + print ("\033[032m "+i+"\033[039m depends on:\033[034m") for j in depends[i]: print( "\t"+j) print ("\033[039m") if output is None: output = "makefile.dep" - tmp=write_depend(path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) + tmp=write_depend(verbose=verbose,path=path,cwd=cwd,outfile=output,dep=depends,overwrite=overwrite,build=build) return depends -def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): +def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build=''): "Write the dependencies to outfile" # #Test file doesn't exist @@ -84,15 +86,19 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' # #Open file # - print(" ") - print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") - print(" ") + if int(verbose) > 1: + print(" ") + print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") + print(" ") f=open(outfile,'w') f.write('# This file is generated automatically. DO NOT EDIT!\n') + for i in dep.keys(): tmp,fil=os.path.split(i) stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") - print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") + if int(verbose) > 1: + print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") + if not(dep[i] == ""): for j in dep[i]: @@ -117,8 +123,11 @@ def write_depend(path,cwd,outfile="makefile.dep",dep=[],overwrite=False,build='' f.write(stri) f.close() - print("\033[031m Finished ... \033[039m") - print(" ") + + if int(verbose) > 1: + print("\033[031m Finished ... \033[039m") + print(" ") + return def get_source(ext=[".f90",".F90",".f",".F"]): @@ -182,7 +191,7 @@ def check_if_there(use,file): return 0 -def create_file_objs(files=None, macros={}): +def create_file_objs(verbose, files=None, macros={}): l=[] if files is None: @@ -190,23 +199,25 @@ def create_file_objs(files=None, macros={}): files = get_source() - print(" ") - print("\033[031m Looking for modules for files:\033[039m") - print(" ") + if int(verbose) > 1 : + print(" ") + print("\033[031m Searching modules for files:\033[039m") + print(" ") for i in files: source_file = file_obj() - - print(i) + if int(verbose) > 1 : + print(" " + i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.contains = get_contains(i) l.append(source_file) - print(" ") + if int(verbose) > 1 : + print(" ") return l @@ -272,8 +283,9 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 0 for i in fob: - print("") - print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") + if int(verbose) > 1 : +# print("") + print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: try: @@ -299,15 +311,18 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + if int(verbose) > 2 : + print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") + print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + print(" ") if istat== 0 and not(j == ""): - print("") - print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print("") + if int(verbose) > 2 : + print("") + print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print(" ") if not(istat == 0): deps[i.file_name]=tmp @@ -318,9 +333,10 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): def check_path(path): if path.endswith("/"): - print("Path correct") +# print(" ") + return path else: - print( "adding / to the path in "+path) +# print( "adding / to the path in "+path) path=path + "/" return path @@ -362,6 +378,8 @@ def __init__(self): default='') parser.add_argument('-o','--output',nargs=1,help='Output file') parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') + parser.add_argument('-vv','--vverbose',action='store_true',help='explain what is done') + parser.add_argument('-vvv','--vvverbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') parser.add_argument('-r','--root_dir',nargs=1,help='Project root directory') parser.add_argument('-d','--dep_dir',nargs='+',action='append',help='Preferred dependecy directory') @@ -386,4 +404,13 @@ def __init__(self): print ("\033[031mError: \033[039m missing path to project root directory \033[032m") sys.exit() - run(path=root_dir, dep=dep_dir, files=args.files, verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + verbose = 0 + if(args.verbose): + verbose = 1 + if(args.vverbose): + verbose = 2 + if(args.vvverbose): + verbose = 3 + + + run(path=root_dir, dep=dep_dir, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From 957eb58d3cb0ee3a6e5a618e1e7c1d64942aef3e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 19 May 2017 12:41:44 -0600 Subject: [PATCH 187/325] update output verbosity details --- fort_depend.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index e83e7df..67d86aa 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -45,7 +45,7 @@ def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros= if int(verbose) > 2: print(" ") - print("\033[031m Looking for modules in files:\033[039m") + print("\033[031m Searching for modules in files:\033[039m") print(ff) l=create_file_objs( (verbose) ,files,macros) @@ -57,7 +57,7 @@ def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros= if int(verbose) == 3 : for i in depends.keys(): - print ("\033[032m"+i+"\033[039m depends on :\033[034m") + print ("\033[032m "+i+"\033[039m depends on:\033[034m") for j in depends[i]: print( "\t"+j) print ("\033[039m") @@ -201,7 +201,7 @@ def create_file_objs(verbose, files=None, macros={}): if int(verbose) > 1 : print(" ") - print("\033[031m Looking for modules for files:\033[039m") + print("\033[031m Searching modules for files:\033[039m") print(" ") @@ -209,7 +209,7 @@ def create_file_objs(verbose, files=None, macros={}): source_file = file_obj() if int(verbose) > 1 : - print(i) + print(" " + i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.contains = get_contains(i) @@ -284,8 +284,8 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): for i in fob: if int(verbose) > 1 : - print("") - print("\033[031mChecking dependency for file: \033[032m"+i.file_name+"\033[039m") +# print("") + print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: try: @@ -311,16 +311,18 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) - if int(verbose) > 1 : - print ("\033[031mNote: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m..... \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + if int(verbose) > 2 : + print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") + print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + print(" ") if istat== 0 and not(j == ""): - if int(verbose) > 1 : + if int(verbose) > 2 : print("") - print ("\033[031mNote!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") - print ("\033[031m..... \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") + print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") + print(" ") if not(istat == 0): deps[i.file_name]=tmp From ed03a62b6bb25cfd033eb55b56dc461bffe30199 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 19 May 2017 12:44:58 -0600 Subject: [PATCH 188/325] fix readme file --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index c9c922d..98dc092 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,18 @@ Input parameters: -f --files Files to process + -o --output Output file + -v -vv -vvv Different level of verbosity contained in standard output + -w --overwrite Overwrite output file without warning + -r --root_dir Project root directory + -d --dep_dir List of selected dependecy directories + For bigger project example, look at Makefiles, rule.mk, src_dir_path.mk and other files in fll project at https://github.com/libm3l/fll which is a linked list library written in Fortran and which uses this script to get fortran project dependencies From 0623210cf64f305c0fd6fce9d8e90726a5a45138 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 22 May 2017 07:34:49 -0600 Subject: [PATCH 189/325] update fort_depend --- python_dep/fort_depend.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 67d86aa..a1ce8ea 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -19,7 +19,7 @@ #Definitions -def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() @@ -53,7 +53,7 @@ def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros= # # make dependencies # - depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) + depends=get_depends(ignore=ignore,verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) if int(verbose) == 3 : for i in depends.keys(): @@ -212,6 +212,7 @@ def create_file_objs(verbose, files=None, macros={}): print(" " + i) source_file.file_name = i source_file.uses = get_uses(i,macros) + source_file.includes = get_includes(i,macros) source_file.contains = get_contains(i) l.append(source_file) @@ -249,6 +250,30 @@ def get_uses(infile=None, macros={}): return uniq_mods +def get_includes(infile=None, macros={}): + "Return which modules are included in infile after expanding macros" + p=re.compile("\#include\s*\"(?P\w*).inc\"$",re.IGNORECASE).match + + includes=[] + + with open(infile,'r') as f: + t=f.readlines() + + for i in t: + tmp=p(i) + if tmp: + includes.append(tmp.group('incfile').strip()+".inc") + + # Remove duplicates + uniq_includes = list(set(includes)) + + for i, mod in enumerate(uniq_includes): + for k, v in macros.items(): + if re.match(k, mod, re.IGNORECASE): + uniq_includes[i] = mod.replace(k,v) + + return uniq_includes + def get_contains(infile=None): "Return all the modules that are in infile" p=re.compile("^\s*module\s*(?P\w*)",re.IGNORECASE).match @@ -278,7 +303,7 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): +def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} istat = 0 @@ -288,6 +313,7 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: + if ignore and (j in ignore): continue try: # # module is in the same directory, include it @@ -361,6 +387,7 @@ class file_obj: def __init__(self): self.file_name=None self.uses=None + self.includes=None self.contains=None self.depends_on=None @@ -372,6 +399,7 @@ def __init__(self): # Add command line arguments parser = argparse.ArgumentParser(description='Generate Fortran dependencies') parser.add_argument('-f','--files',nargs='+',help='Files to process') + parser.add_argument('-i','--ignore',nargs='+',help='Modules to ignore') parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', help="""The macro NAME is replaced by DEFINITION in 'use' statements""") parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', @@ -413,4 +441,4 @@ def __init__(self): verbose = 3 - run(path=root_dir, dep=dep_dir, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(path=root_dir, dep=dep_dir, ignore=args.ignore, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From 19c20b98d212f7f134be356f7661192d3b7d74c3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 22 May 2017 07:35:17 -0600 Subject: [PATCH 190/325] implement latest changes from tsigarid/fort_depend.py branch --- fort_depend.py | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 67d86aa..a1ce8ea 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -19,7 +19,7 @@ #Definitions -def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): +def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() @@ -53,7 +53,7 @@ def run(path,dep=None,files=None,verbose=None,overwrite=None,output=None,macros= # # make dependencies # - depends=get_depends(verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) + depends=get_depends(ignore=ignore,verbose=verbose,cwd=cwd,fob=l,m2f=mod2fil,ffiles=ff) if int(verbose) == 3 : for i in depends.keys(): @@ -212,6 +212,7 @@ def create_file_objs(verbose, files=None, macros={}): print(" " + i) source_file.file_name = i source_file.uses = get_uses(i,macros) + source_file.includes = get_includes(i,macros) source_file.contains = get_contains(i) l.append(source_file) @@ -249,6 +250,30 @@ def get_uses(infile=None, macros={}): return uniq_mods +def get_includes(infile=None, macros={}): + "Return which modules are included in infile after expanding macros" + p=re.compile("\#include\s*\"(?P\w*).inc\"$",re.IGNORECASE).match + + includes=[] + + with open(infile,'r') as f: + t=f.readlines() + + for i in t: + tmp=p(i) + if tmp: + includes.append(tmp.group('incfile').strip()+".inc") + + # Remove duplicates + uniq_includes = list(set(includes)) + + for i, mod in enumerate(uniq_includes): + for k, v in macros.items(): + if re.match(k, mod, re.IGNORECASE): + uniq_includes[i] = mod.replace(k,v) + + return uniq_includes + def get_contains(infile=None): "Return all the modules that are in infile" p=re.compile("^\s*module\s*(?P\w*)",re.IGNORECASE).match @@ -278,7 +303,7 @@ def file_objs_to_mod_dict(file_objs=[]): dic[j.lower()]=i.file_name return dic -def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): +def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} istat = 0 @@ -288,6 +313,7 @@ def get_depends(verbose,cwd,fob=[],m2f=[], ffiles=[]): print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") tmp=[] for j in i.uses: + if ignore and (j in ignore): continue try: # # module is in the same directory, include it @@ -361,6 +387,7 @@ class file_obj: def __init__(self): self.file_name=None self.uses=None + self.includes=None self.contains=None self.depends_on=None @@ -372,6 +399,7 @@ def __init__(self): # Add command line arguments parser = argparse.ArgumentParser(description='Generate Fortran dependencies') parser.add_argument('-f','--files',nargs='+',help='Files to process') + parser.add_argument('-i','--ignore',nargs='+',help='Modules to ignore') parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', help="""The macro NAME is replaced by DEFINITION in 'use' statements""") parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', @@ -413,4 +441,4 @@ def __init__(self): verbose = 3 - run(path=root_dir, dep=dep_dir, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(path=root_dir, dep=dep_dir, ignore=args.ignore, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From ef4fb6024c1f0961a6a8c8abbae826392477ed83 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 08:20:37 -0600 Subject: [PATCH 191/325] update dependency files --- examples/Simple_data_operation/Makefile | 2 +- examples/Simple_data_operation/project.dep | 4 +++- python_dep/fort_depend.py | 9 ++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index 6263f0a..b9f4180 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -58,6 +58,6 @@ clean: depend: $(FFILES) @echo "Making dependencies!" - cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH)$(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/project.dep diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/project.dep index 84ecddc..4b1a81c 100644 --- a/examples/Simple_data_operation/project.dep +++ b/examples/Simple_data_operation/project.dep @@ -1,6 +1,8 @@ # This file is generated automatically. DO NOT EDIT! -fll_test_subr.o : +fll_test_subr.o : \ + ../../data_util/fll_mods.o fll_test.o : \ + ../../data_util/fll_mods.o \ fll_test_subr.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index a1ce8ea..a207819 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -209,7 +209,7 @@ def create_file_objs(verbose, files=None, macros={}): source_file = file_obj() if int(verbose) > 1 : - print(" " + i) + print("\033[031m -- \033[039m" + i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.includes = get_includes(i,macros) @@ -341,20 +341,23 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") - print(" ") +# print(" ") if istat== 0 and not(j == ""): if int(verbose) > 2 : print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print(" ") +# print(" ") if not(istat == 0): deps[i.file_name]=tmp else: deps[i.file_name]="" + if int(verbose) > 1 : + print("\033[031m Done ... \033[032m") + return deps def check_path(path): From 5c5248c9fd6ba0dbc518a1bb04b23dbcff8e2a3b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 08:44:18 -0600 Subject: [PATCH 192/325] fix makefile --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 2cf66ef..bf73e37 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ include src_dir_path.mk SUBDIRS= \ data_util\ accessories\ +mpi_util\ examples\ ifneq ($(strip $(MPI_FC)),) From 08e50150dea6577705adcc0c828a5b453eb726bb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 08:50:21 -0600 Subject: [PATCH 193/325] updated stdout --- fort_depend.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index a1ce8ea..a207819 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -209,7 +209,7 @@ def create_file_objs(verbose, files=None, macros={}): source_file = file_obj() if int(verbose) > 1 : - print(" " + i) + print("\033[031m -- \033[039m" + i) source_file.file_name = i source_file.uses = get_uses(i,macros) source_file.includes = get_includes(i,macros) @@ -341,20 +341,23 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") - print(" ") +# print(" ") if istat== 0 and not(j == ""): if int(verbose) > 2 : print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") - print(" ") +# print(" ") if not(istat == 0): deps[i.file_name]=tmp else: deps[i.file_name]="" + if int(verbose) > 1 : + print("\033[031m Done ... \033[032m") + return deps def check_path(path): From c81011f8b640c456862b3120aa2f500083ee2ef5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 12:42:21 -0600 Subject: [PATCH 194/325] fix in dep script --- python_dep/fort_depend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index a207819..dd45bab 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -17,6 +17,7 @@ import os import sys + #Definitions def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): @@ -224,7 +225,7 @@ def create_file_objs(verbose, files=None, macros={}): def get_uses(infile=None, macros={}): "Return which modules are used in infile after expanding macros" - p=re.compile("^\s*use\s*(?P\w*)\s*(,)?\s*(only)?\s*(:)?.*?$",re.IGNORECASE).match + p=re.compile("^\s*use\s+(?P\w*)\s*(,)?\s*(only)?\s*(:)?.*?$",re.IGNORECASE).match uses=[] From c16145142072261b2668134ff5bb03ca12c0ef73 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 14:59:09 -0600 Subject: [PATCH 195/325] remove mpif90 --- config/compset.gfortran | 2 +- config/compset.gfortran_debug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/compset.gfortran b/config/compset.gfortran index b060249..07289e9 100644 --- a/config/compset.gfortran +++ b/config/compset.gfortran @@ -7,6 +7,6 @@ LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 CC = gcc CFLAGS = -O2 -fopenmp C_LDFLAGS = -O2 -fopenmp -MPI_FC = mpif90 +MPI_FC = MPI_FFLAGS = -O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fopenmp -cpp MPI_LDFLAGS =-O2 -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fopenmp -cpp diff --git a/config/compset.gfortran_debug b/config/compset.gfortran_debug index 8ea9118..2bb8833 100644 --- a/config/compset.gfortran_debug +++ b/config/compset.gfortran_debug @@ -8,6 +8,6 @@ LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefa CC = gcc -fopenmp CFLAGS = -g -fopenmp C_LDFLAGS = -g -fopenmp -MPI_FC = mpif90 +MPI_FC = MPI_FFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp -x f95-cpp-input MPI_LDFLAGS = -g -ffpe-trap=invalid,zero,overflow -fdefault-real-8 -fdefault-double-8 -frecord-marker=4 -fbounds-check -Wall -Wextra -fopenmp From da62ed00dd2dc0488440408f1e5fc5e04a8a1bd1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 23 May 2017 15:03:36 -0600 Subject: [PATCH 196/325] fix intel config files --- config/compset.x86_64 | 20 +++++++++++--------- config/compset.x86_64_debug | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/config/compset.x86_64 b/config/compset.x86_64 index 1e8507b..384445c 100644 --- a/config/compset.x86_64 +++ b/config/compset.x86_64 @@ -4,17 +4,19 @@ # # Fortran compiler and flags -FC='ifort' -FFLAGS='-O2 -msse3 -ip -r8 -std03 -fpp' -LDFLAGS='-O2 -msse3 -ip -r8 -std03 -i-static' - -# C compiler -CC='icc' -CFLAGS='-O2 -msse3 -ip' -C_LDFLAGS='-O2 -msse3 -ip -i-static' +FC = ifort +FCMODINCFLAG = -I +FFLAGS = -O2 -msse3 -ip -r8 -std03 -fpp +FFFLAGS = -O2 -msse3 -ip -r8 -std03 -fpp +UPPER_MODFILE_NAME = +LDFLAGS = -O2 -msse3 -ip -r8 -std03 -i-static +CC = icc +CFLAGS = -O2 -msse3 -ip +C_LDFLAGS = -O2 -msse3 -ip -i-static # MPI fortran compiler and flags. -# Set MPI_FC empty if you don't have/need MPI. +# # Set MPI_FC empty if you don't have/need MPI. MPI_FC= MPI_FFLAGS="$FFLAGS" MPI_LDFLAGS="$LDFLAGS" + diff --git a/config/compset.x86_64_debug b/config/compset.x86_64_debug index 476c0ac..38ea6c4 100644 --- a/config/compset.x86_64_debug +++ b/config/compset.x86_64_debug @@ -4,17 +4,19 @@ # # Fortran compiler and flags -FC='ifort' -FFLAGS='-msse3 -g -traceback -check -warn -r8 -std03 -fpe0 -ftrapuv' -LDFLAGS='-msse3 -g -traceback -check -warn -r8 -std03 -i-static -fpe0 -ftrapuv' - -# C compiler -CC='icc' -CFLAGS='-msse3 -g -Wall -traceback' -C_LDFLAGS='-msse3 -w -Wall -traceback -i-static' +FC = ifort +FCMODINCFLAG = -I +FFLAGS = -msse3 -g -traceback -check -warn -r8 -std03 -fpe0 -ftrapuv +FFFLAGS = -msse3 -g -traceback -check -warn -r8 -std03 -fpe0 -ftrapuv +UPPER_MODFILE_NAME = +LDFLAGS = -msse3 -g -traceback -check -warn -r8 -std03 -i-static -fpe0 -ftrapuv +CC = icc +CFLAGS = -msse3 -g -Wall -traceback +C_LDFLAGS = -msse3 -w -Wall -traceback -i-static # MPI fortran compiler and flags. -# Set MPI_FC empty if you don't have/need MPI. +# # Set MPI_FC empty if you don't have/need MPI. MPI_FC= MPI_FFLAGS="$FFLAGS" MPI_LDFLAGS="$LDFLAGS" + From fba84001a820534dcc1b33fa8be14d62fef0df67 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 11:37:16 -0600 Subject: [PATCH 197/325] cpecify for intel debug and add comments to configure.py --- config/compset.x86_64_debug | 22 +++++++++++ configure.py | 77 +++++++++++++++++++++++++++++++------ 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/config/compset.x86_64_debug b/config/compset.x86_64_debug index 38ea6c4..41f718b 100644 --- a/config/compset.x86_64_debug +++ b/config/compset.x86_64_debug @@ -20,3 +20,25 @@ MPI_FC= MPI_FFLAGS="$FFLAGS" MPI_LDFLAGS="$LDFLAGS" +# -*-sh-*- +# +# For intel ifort 12 compiler. +# + +# Fortran compiler and flags +FC = ifort +FCMODINCFLAG = -I +FFLAGS = -O2 -msse3 -ip -r8 -std03 -fpp +FFFLAGS = -O2 -msse3 -ip -r8 -std03 -fpp +UPPER_MODFILE_NAME = +LDFLAGS = -O2 -msse3 -ip -r8 -std03 -i-static +CC = icc +CFLAGS = -O2 -msse3 -ip +C_LDFLAGS = -O2 -msse3 -ip -i-static + +# MPI fortran compiler and flags. +# # Set MPI_FC empty if you don't have/need MPI. +MPI_FC= +MPI_FFLAGS="$FFLAGS" +MPI_LDFLAGS="$LDFLAGS" + diff --git a/configure.py b/configure.py index f7a082a..61ad94a 100755 --- a/configure.py +++ b/configure.py @@ -1,7 +1,44 @@ #!/usr/bin/python +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: python configuration script. It loops over all subdirectories in source directories +# in the project and links: +# src_dir_path.mk - specifies source directory withe source files +# Makefike +# project.dep - project depenency file with source code dependencies +# .py - all .py scritps which may be present +# +# avoid links for these directories: +# pyhon_dep - contains python script for making dependencies, it is used in source directory +# config - contains files with settings specific to compiler +# .git - any .git repository specific files +# .svn - any .svn repository specific files +# # +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# # -# this is a python script wj # import os import re @@ -21,13 +58,19 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= # print_header() linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep']) - exclude =(['python_dep', 'config', '.git']) + exclude =(['python_dep', 'config', '.git', '.svn']) +# +# get path of the source files, found from location of this script which is located in the root +# directory of the source code # -# path = os.path.dirname(os.path.abspath(__file__)) +# +# get current directory # cwd = os.getcwd() - +# +# if path for source does not exit, terminate +# path = check_path(path=path) if not os.path.isdir(path): print(" ") @@ -39,7 +82,10 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= print(" ") print("\033[031mDIAG:\033[039m project location is \033[032m"+path+"\033[039m") print("\033[031mDIAG:\033[039m Intended location of compillation is \033[032m"+cwd+"\033[039m") - +# +# if pathe to source and path to location of compilation directory are the same +# terminate, do not allow compilation in the source code directory +# if cwd == path: print(".....") print ("\033[031mError:\033[039m project location is the same as inteded location of compillation \033[032m"+path+"\033[039m") @@ -52,7 +98,9 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= print(" ") print("\033[031mDIAG:\033[039m creating configure file \033[032m \033[039m") print(" ") - +# +# specify build directory where all executables will be located +# if build == '': print(" ") print("\033[031mDIAG:\033[039m Bild directory not specified, setting it to \033[032m "+cwd+platform.machine()+"/bin\033[039m") @@ -60,11 +108,13 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= bin_dir=cwd+platform.machine()+'/bin' else: bin_dir=build - - +# +# create configuration file config.mk +# ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=bin_dir) # # create structure and link necessary files +# ie. create the same tree structure as source files and link "linkfiles" specified above # print(" ") print("\033[031mDIAG:\033[039m Recreating project tree structure and linking files \033[032m \033[039m .....") @@ -160,6 +210,10 @@ def mkdir_structure(root_path,cwd, exclude, linkfiles): for subdir, dirs, files in os.walk(cwd): for dir in dirs: subdir = check_path(path=subdir) +# +# dirtmp is a source directory +# newdir is a target directory +# newdir = subdir+dir print ("\033[031mDIAG: \033[039m processing directory \033[032m"+newdir+"\033[039m ....") dirtmp = subdir.replace(subdir[:length], '') @@ -167,7 +221,9 @@ def mkdir_structure(root_path,cwd, exclude, linkfiles): dirtmp = root_path + dirtmp+dir os.chdir(newdir) - +# +# link over list of files specified in linkfiels and link them +# for word in linkfiles: try: os.remove(word) @@ -180,9 +236,8 @@ def mkdir_structure(root_path,cwd, exclude, linkfiles): if os.path.exists(source): print ("\033[031mDIAG: \033[039m linking file \033[032m"+source+"\033[039m ....") linkfile = os.symlink( source, dest) - # -# check if python script +# check if python script, link it too # if os.path.isdir(dirtmp): for file in os.listdir(dirtmp): From 6fdfc798cb1ef53513154f84af34ae6157c2fad0 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 12:08:05 -0600 Subject: [PATCH 198/325] remove absolete file --- template_v1.Sourcef90 | 65 ------------------------------------------- 1 file changed, 65 deletions(-) delete mode 100644 template_v1.Sourcef90 diff --git a/template_v1.Sourcef90 b/template_v1.Sourcef90 deleted file mode 100644 index c4ec892..0000000 --- a/template_v1.Sourcef90 +++ /dev/null @@ -1,65 +0,0 @@ -! -! Header for svn -! -MODULE Convection -! -! Description: -! -! -! History: -! Version Date Comment -! ------- -------- ------- -! 1.1 24/03/16 Update of ... -! -! - -! External Modules used - USE FFAType - USE FFAData - -! Declarations - IMPLICIT NONE - PRIVATE - PUBLIC ConvectionMean - -CONTAINS - - SUBROUTINE ConvectionMean(pglob,preg,nnodes) - -! Description: Computes convective mean flow -! Fluxes computed and added to residuals -! - -! Declarations - IMPLICIT NONE - -! Arguments description -! Name In/Out Function -! pglob In/Out Pointer to all data -! preg In/Out Pointer to region data -! nnodes In Number of nodes - -! Arguments declaration - TYPE(DATA_SET), POINTER :: pglob - TYPE(DATA_SET), POINTER :: pdom - INTEGER, INTENT(IN) :: nnodes - -! Local variables declaration - INTEGER ndim,ncol,iupwin,irot,nsc,nedges - REAL :: gom1 - -! -! Global data -! - iupwin = Get_Child_I0(pglob,'IUPWIN') - -!... - - END SUBROUTINE ConvectionMean - - SUBROUTINE ConvectionTurbulence(pglob,preg,nnodes) -!... - -END MODULE Convection - -END MODULE GCONEU_M From 48d0a9239fc27994cf186bf74410d1122d6ed7a0 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 13:02:39 -0600 Subject: [PATCH 199/325] rename project.dep to depend.mk --- accessories/Makefile | 2 +- accessories/fll_cat/Makefile | 2 +- accessories/fll_cat/{project.dep => depend.mk} | 0 accessories/fll_convert/Makefile | 2 +- accessories/fll_convert/{project.dep => depend.mk} | 0 configure.py | 4 ++-- examples/Example_MPI-IO/Makefile | 2 +- examples/Example_MPI-IO/{project.dep => depend.mk} | 0 examples/Makefile | 2 +- examples/Simple_data_operation/Makefile | 2 +- examples/Simple_data_operation/{project.dep => depend.mk} | 0 11 files changed, 8 insertions(+), 8 deletions(-) rename accessories/fll_cat/{project.dep => depend.mk} (100%) rename accessories/fll_convert/{project.dep => depend.mk} (100%) rename examples/Example_MPI-IO/{project.dep => depend.mk} (100%) rename examples/Simple_data_operation/{project.dep => depend.mk} (100%) diff --git a/accessories/Makefile b/accessories/Makefile index 2f54e35..4ea10df 100644 --- a/accessories/Makefile +++ b/accessories/Makefile @@ -31,7 +31,7 @@ include src_dir_path.mk include ../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk #FMODDIRS= ../../data_util diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index 5b7c52d..013867d 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -34,7 +34,7 @@ EXE = fll_cat include src_dir_path.mk include ../../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk FMODDIRS= ../../data_util diff --git a/accessories/fll_cat/project.dep b/accessories/fll_cat/depend.mk similarity index 100% rename from accessories/fll_cat/project.dep rename to accessories/fll_cat/depend.mk diff --git a/accessories/fll_convert/Makefile b/accessories/fll_convert/Makefile index e4412db..aa5bd82 100644 --- a/accessories/fll_convert/Makefile +++ b/accessories/fll_convert/Makefile @@ -34,7 +34,7 @@ EXE = fll_convert include src_dir_path.mk include ../../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk FMODDIRS= ../../data_util diff --git a/accessories/fll_convert/project.dep b/accessories/fll_convert/depend.mk similarity index 100% rename from accessories/fll_convert/project.dep rename to accessories/fll_convert/depend.mk diff --git a/configure.py b/configure.py index 61ad94a..53a5d04 100755 --- a/configure.py +++ b/configure.py @@ -57,7 +57,7 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= # definition of parameters # print_header() - linkfiles =(['src_dir_path.mk', 'Makefile', 'project.dep']) + linkfiles =(['src_dir_path.mk', 'Makefile', 'depend.mk']) exclude =(['python_dep', 'config', '.git', '.svn']) # # get path of the source files, found from location of this script which is located in the root @@ -166,7 +166,7 @@ def prepare_compiler(root_path,cwd, linkfiles): # linknew = copy.copy(linkfiles) linknew.append('rules.mk') - linknew.remove('project.dep') + linknew.remove('depend.mk') for word in linknew: try: diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index bab4c3c..7abb0a3 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -34,7 +34,7 @@ EXE = MPI_Test include src_dir_path.mk include ../../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk # Use MPI compilation in this file FC =$(MPI_FC) diff --git a/examples/Example_MPI-IO/project.dep b/examples/Example_MPI-IO/depend.mk similarity index 100% rename from examples/Example_MPI-IO/project.dep rename to examples/Example_MPI-IO/depend.mk diff --git a/examples/Makefile b/examples/Makefile index 542c2be..2583461 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -34,7 +34,7 @@ EXE = fll_test include src_dir_path.mk include ../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk #FMODDIRS= ../../data_util diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index b9f4180..7e464e5 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -34,7 +34,7 @@ EXE = fll_test include src_dir_path.mk include ../../config.mk -DEP_FILE=project.dep +DEP_FILE=depend.mk FMODDIRS= ../../data_util diff --git a/examples/Simple_data_operation/project.dep b/examples/Simple_data_operation/depend.mk similarity index 100% rename from examples/Simple_data_operation/project.dep rename to examples/Simple_data_operation/depend.mk From 4f0bedd730a353dc9aa3bcff99b02efaff96a280 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 13:12:16 -0600 Subject: [PATCH 200/325] fix Makefiles for new depend.mk name --- accessories/fll_cat/Makefile | 3 ++- accessories/fll_convert/Makefile | 3 ++- data_util/Makefile | 2 +- examples/Example_MPI-IO/Makefile | 3 ++- examples/Simple_data_operation/Makefile | 3 ++- mpi_util/Makefile | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index 013867d..d2d8c77 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -65,4 +65,5 @@ install: $(EXE).x $(EXE).py $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py --include $(srcdir)/project.dep +include $(srcdir)/$(DEP_FILE) + diff --git a/accessories/fll_convert/Makefile b/accessories/fll_convert/Makefile index aa5bd82..7c402f1 100644 --- a/accessories/fll_convert/Makefile +++ b/accessories/fll_convert/Makefile @@ -65,4 +65,5 @@ install: $(EXE).x $(EXE).py $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py --include $(srcdir)/project.dep +include $(srcdir)/$(DEP_FILE) + diff --git a/data_util/Makefile b/data_util/Makefile index 77d1cd6..9bef2fa 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -56,5 +56,5 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) --include $(srcdir)/$(DEP_FILE) +include $(srcdir)/$(DEP_FILE) diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index 7abb0a3..03daf82 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -65,4 +65,5 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) --include $(srcdir)/project.dep +include $(srcdir)/$(DEP_FILE) + diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index 7e464e5..e78c1a2 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -60,4 +60,5 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) --include $(srcdir)/project.dep +include $(srcdir)/$(DEP_FILE) + diff --git a/mpi_util/Makefile b/mpi_util/Makefile index 2acb8db..b9506a6 100644 --- a/mpi_util/Makefile +++ b/mpi_util/Makefile @@ -62,5 +62,5 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) --include $(srcdir)/$(DEP_FILE) +include $(srcdir)/$(DEP_FILE) From bfde8223ec215d9fd90ae232c24c62bb47ea8768 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 13:28:57 -0600 Subject: [PATCH 201/325] fix some additional errors --- accessories/fll_cat/Makefile | 2 +- accessories/fll_convert/Makefile | 2 +- data_util/Makefile | 4 ++-- data_util/{project.dep => depend.mk} | 0 examples/Example_MPI-IO/Makefile | 2 +- examples/Simple_data_operation/Makefile | 2 +- mpi_util/Makefile | 4 ++-- mpi_util/{project.dep => depend.mk} | 0 rules.mk | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) rename data_util/{project.dep => depend.mk} (100%) rename mpi_util/{project.dep => depend.mk} (100%) diff --git a/accessories/fll_cat/Makefile b/accessories/fll_cat/Makefile index d2d8c77..34065a7 100644 --- a/accessories/fll_cat/Makefile +++ b/accessories/fll_cat/Makefile @@ -65,5 +65,5 @@ install: $(EXE).x $(EXE).py $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/accessories/fll_convert/Makefile b/accessories/fll_convert/Makefile index 7c402f1..2f77b9b 100644 --- a/accessories/fll_convert/Makefile +++ b/accessories/fll_convert/Makefile @@ -65,5 +65,5 @@ install: $(EXE).x $(EXE).py $(INSTALL) $(EXE).x $(bin_dir)/$(EXE)$(POSTFIX).x $(INSTALL) $(EXE).py $(bin_dir)/$(EXE)$(POSTFIX).py -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/data_util/Makefile b/data_util/Makefile index 9bef2fa..0b988e2 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -32,7 +32,7 @@ include src_dir_path.mk include ../config.mk # $(DEP_FILE) is a .dep file generated by fort_depend.py -DEP_FILE = project.dep +DEP_FILE = depend.mk FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) @@ -56,5 +56,5 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/data_util/project.dep b/data_util/depend.mk similarity index 100% rename from data_util/project.dep rename to data_util/depend.mk diff --git a/examples/Example_MPI-IO/Makefile b/examples/Example_MPI-IO/Makefile index 03daf82..1d96649 100644 --- a/examples/Example_MPI-IO/Makefile +++ b/examples/Example_MPI-IO/Makefile @@ -65,5 +65,5 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/examples/Simple_data_operation/Makefile b/examples/Simple_data_operation/Makefile index e78c1a2..d01f142 100644 --- a/examples/Simple_data_operation/Makefile +++ b/examples/Simple_data_operation/Makefile @@ -60,5 +60,5 @@ depend: $(FFILES) @echo "Making dependencies!" cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/mpi_util/Makefile b/mpi_util/Makefile index b9506a6..f75bdfe 100644 --- a/mpi_util/Makefile +++ b/mpi_util/Makefile @@ -32,7 +32,7 @@ include src_dir_path.mk include ../config.mk # $(DEP_FILE) is a .dep file generated by fort_depend.py -DEP_FILE = project.dep +DEP_FILE = depend.mk # Use MPI compilation in this file FC =$(MPI_FC) @@ -62,5 +62,5 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) -d $(FMODDIRS) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) -include $(srcdir)/$(DEP_FILE) +-include $(srcdir)/$(DEP_FILE) diff --git a/mpi_util/project.dep b/mpi_util/depend.mk similarity index 100% rename from mpi_util/project.dep rename to mpi_util/depend.mk diff --git a/rules.mk b/rules.mk index 88403bc..d2731d2 100644 --- a/rules.mk +++ b/rules.mk @@ -37,7 +37,7 @@ HANDLE_UPPER_CASE_MOD_NAMES = ! [ "$(UPPER_MODFILE_NAME)" ] || ! [[ $* = *_m ]] @cd $* && $(MAKE) clean %.depend: %.mkdir - @cd $* && $(MAKE) depend + @cd $* && $(MAKE) depend %.install: %.mkdir @cd $* && $(MAKE) install From d90ef215802bd07b4938c2128bdf1ce178f0c2bd Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 13:56:45 -0600 Subject: [PATCH 202/325] Fix err lines, sync with current implementation --- Makefile | 2 +- mpi_util/fll_mpi_proc_struct.f90 | 8 ++++---- mpi_util/fll_mpi_write.f90 | 4 ++-- mpi_util/fll_mpi_write_snm.f90 | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index bf73e37..695bfe3 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ init: echo PROJ_ROOT_PATH=$(PWD) > config.mk echo MAKEDEPEND=$(PWD)/python_dep/fort_depend.py >> config.mk echo MPI_FC=YES >> config.mk - echo VERBOSE=v + echo VERBOSE=-vvv >> config.mk data_util.all: test.all: data_util.all diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 258dd23..5cb787c 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -227,7 +227,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) END IF ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:230 ' ! ! loop over number of separate files, define which partition is going to be ! saving in what file (defined by EVEN_RANK array @@ -323,7 +323,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! free memory ! DEALLOCATE(EVEN_RANK, STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:326 ' RETURN @@ -439,7 +439,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) END IF ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:442 ' ! ! loop over number of separate files, define which partition is going to be ! saving in what file (defined by EVEN_RANK array @@ -535,7 +535,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) ! free memory ! DEALLOCATE(EVEN_RANK, STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:538 ' RETURN diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index ef31a0e..9813012 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -145,7 +145,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! subsets #2: are actual data from each partition ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:144 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:148 ' ! ! get length of each data subset of actual data ! @@ -218,7 +218,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! free memory ! DEALLOCATE(POS, DISPL, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:203 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:221 ' OK = .TRUE. RETURN diff --git a/mpi_util/fll_mpi_write_snm.f90 b/mpi_util/fll_mpi_write_snm.f90 index ee82ab2..cf752d5 100644 --- a/mpi_util/fll_mpi_write_snm.f90 +++ b/mpi_util/fll_mpi_write_snm.f90 @@ -128,7 +128,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) PTMP => FLL_CP(PNODE, PMAIN, FPAR) ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:144 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write_snm ERR:131 ' ! ! get length of each data subset of actual data ! From a7b7c3eb7b9ce46203bec8b4f8e7fc1af96d669e Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 25 May 2017 14:00:26 -0600 Subject: [PATCH 203/325] add notice about installation to INSTALL file --- INSTALLATION | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INSTALLATION b/INSTALLATION index fec62ef..816fec6 100644 --- a/INSTALLATION +++ b/INSTALLATION @@ -71,6 +71,12 @@ To compile, type gmake +and then + +gmake install + +This install all files to specified bin directory + 3. DEVELOPERS: ==================================================== From 6ee34ef04c8ebc66bbf611904a92eaf1e6ba1741 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 26 May 2017 11:04:30 -0600 Subject: [PATCH 204/325] specify lenght of file name at rading --- Makefile | 11 ----------- accessories/fll_cat/fll_cat.f90 | 2 +- accessories/fll_convert/fll_convert.f90 | 4 ++-- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 695bfe3..949e2c8 100644 --- a/Makefile +++ b/Makefile @@ -70,14 +70,3 @@ depend: $(SUBDIRS:%=%.depend) install: $(SUBDIRS:%=%.all) $(SUBDIRS:%=%.install) -test: $(SUBDIRS:%=%.test) - -# -# The following target checks all .f90 files against -# some of the sourcecode standard rules. -# -CHK_SUBDIRS:=$(filter-out adaption lapack,$(SUBDIRS)) -chk: $(CHK_SUBDIRS:%=%.chk) -# -# -.PHONY: path diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index cd427af..02eb398 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -67,7 +67,7 @@ PROGRAM FLL_CATU ! ! read a file and print on screen ! - READ(*,*)FILE + READ(*,'(A1024)')FILE READ(*,*)FMT READ(*,'(A3)')EFMT READ(*,*)SCAN diff --git a/accessories/fll_convert/fll_convert.f90 b/accessories/fll_convert/fll_convert.f90 index d643fe1..ac6e231 100644 --- a/accessories/fll_convert/fll_convert.f90 +++ b/accessories/fll_convert/fll_convert.f90 @@ -68,10 +68,10 @@ PROGRAM FLL_CONVERT ! ! read a file and save it ! - READ(*,*)FILE + READ(*,'(A1024)')FILE READ(*,*)FMT READ(*,'(A3)')EFMT - READ(*,*)OUTFILE + READ(*,'(A1024)')OUTFILE READ(*,'(A3)')OFMT SELECT CASE(EFMT) From a001c14fa77beb3f2d5747ce5cf2f8821f86a5fb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 27 May 2017 17:17:14 -0600 Subject: [PATCH 205/325] tmp commit --- fort_depend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 20dbc55..541dc4b 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -170,7 +170,8 @@ def check_if_there(use,file): else: with open(file) as f: with open(file, errors='ignore') as f: - if "module" in line.lower(): + for line in f: + if "module" in line.lower(): extrline = line.lower() extrline = extrline.replace("module", "") if use.lower().strip() == extrline.strip(): From 36bb8c1d0d4c93ce6755122275a9d27e8aace05d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 27 May 2017 17:20:25 -0600 Subject: [PATCH 206/325] commit latest changes --- data_util/depend.mk | 140 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 10 +- examples/Simple_data_operation/depend.mk | 4 +- mpi_util/depend.mk | 60 +++++----- python_dep/fort_depend.py | 6 +- 5 files changed, 110 insertions(+), 110 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index e518aee..27faad2 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,121 +1,114 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ +fll_duplicate.o : \ fll_out.o \ + fll_type.o \ + fll_mk.o \ + fll_mv.o + +fll_out.o : \ fll_type.o -fll_nnodes.o : \ - fll_funct_prt.o \ +fll_mods.o : \ + fll_mkdir.o \ + fll_read.o \ + fll_rm.o \ + fll_stich.o \ + fll_getnbytes.o \ + fll_sweep.o \ fll_out.o \ - fll_type.o + fll_read_ffa.o \ + fll_funct_prt.o \ + fll_write.o \ + fll_match_pattern.o \ + fll_mv.o \ + fll_cp.o \ + fll_duplicate.o \ + fll_mk.o \ + fll_locate.o \ + fll_type.o \ + fll_nnodes.o \ + fll_cat.o \ + fll_deattach.o \ + fll_getndata.o \ + fll_write_ffa.o -fll_getnbytes.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_out.o \ fll_type.o fll_mkdir.o : \ - fll_mk.o \ - fll_type.o + fll_type.o \ + fll_mk.o -fll_cat.o : \ +fll_deattach.o : \ fll_out.o \ - fll_type.o - -fll_type.o : + fll_type.o \ + fll_stich.o fll_stich.o : \ fll_out.o \ fll_type.o -fll_funct_prt.o : \ +fll_cat.o : \ fll_out.o \ fll_type.o -fll_sweep.o : \ - fll_match_pattern.o \ +fll_funct_prt.o : \ fll_out.o \ fll_type.o fll_read.o : \ - fll_mv.o \ + fll_out.o \ fll_funct_prt.o \ + fll_type.o \ fll_mk.o \ - fll_out.o \ - fll_type.o - -fll_cp.o : \ - fll_mv.o \ - fll_cat.o \ - fll_out.o \ - fll_duplicate.o \ - fll_rm.o \ - fll_stich.o \ - fll_type.o + fll_mv.o -fll_mv.o : \ - fll_stich.o \ +fll_sweep.o : \ fll_out.o \ - fll_rm.o \ + fll_match_pattern.o \ fll_type.o -fll_write.o : \ - fll_out.o \ - fll_type.o +fll_type.o : -fll_getndata.o : \ - fll_locate.o \ +fll_rm.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_stich.o fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_locate.o : \ - fll_funct_prt.o \ +fll_mv.o : \ + fll_rm.o \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_stich.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ +fll_getnbytes.o : \ fll_out.o \ fll_type.o -fll_duplicate.o : \ - fll_mv.o \ - fll_mk.o \ +fll_cp.o : \ fll_out.o \ - fll_type.o - -fll_mods.o : \ + fll_type.o \ fll_mv.o \ + fll_duplicate.o \ + fll_cat.o \ + fll_rm.o \ + fll_stich.o + +fll_read_ffa.o : \ fll_out.o \ fll_funct_prt.o \ - fll_stich.o \ - fll_match_pattern.o \ fll_type.o \ - fll_mkdir.o \ - fll_cat.o \ - fll_write.o \ - fll_write_ffa.o \ - fll_getnbytes.o \ fll_mk.o \ - fll_deattach.o \ - fll_duplicate.o \ - fll_sweep.o \ - fll_rm.o \ - fll_nnodes.o \ - fll_getndata.o \ - fll_read_ffa.o \ - fll_locate.o \ - fll_cp.o \ - fll_read.o + fll_mv.o -fll_rm.o : \ - fll_stich.o \ +fll_write_ffa.o : \ fll_out.o \ fll_type.o @@ -123,9 +116,16 @@ fll_mk.o : \ fll_out.o \ fll_type.o -fll_out.o : \ +fll_locate.o : \ + fll_funct_prt.o \ + fll_out.o \ fll_type.o -fll_write_ffa.o : \ +fll_write.o : \ fll_out.o \ fll_type.o + +fll_getndata.o : \ + fll_out.o \ + fll_type.o \ + fll_locate.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 5e2ba4a..ec5638e 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically. DO NOT EDIT! Example_mpi-IO.o : \ - ../../data_util/fll_mods.o \ - save_root_part_file.o \ create_data_set.o \ save_individ_files.o \ read_input.o \ + ../../data_util/fll_mods.o \ + save_root_part_file.o \ ../../mpi_util/fll_mpi_mods.o -save_individ_files.o : \ - ../../data_util/fll_mods.o - read_input.o : \ ../../data_util/fll_mods.o create_data_set.o : \ ../../data_util/fll_mods.o +save_individ_files.o : \ + ../../data_util/fll_mods.o + save_root_part_file.o : \ ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 4b1a81c..248c2d0 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -4,5 +4,5 @@ fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - ../../data_util/fll_mods.o \ - fll_test_subr.o + fll_test_subr.o \ + ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index e32f87f..7775b94 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o - -fll_mpi_sum.o : \ +fll_mpi_write_snm.o : \ + fll_mpi_cp.o \ ../data_util/fll_mods.o -fll_mpi_write_nm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_write.o +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_type.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_out.o fll_mpi_mods.o : \ - fll_mpi_write_snm.o \ - fll_mpi_cp.o \ - fll_mpi_proc_struct.o \ - fll_mpi_write_nm.o \ fll_mpi_write.o \ fll_mpi_sum.o \ + fll_mpi_write_nm.o \ + fll_mpi_cp_all.o \ fll_mpi_mv.o \ fll_mpi_read.o \ - fll_mpi_cp_all.o - -fll_mpi_write_snm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp.o + fll_mpi_cp.o \ + fll_mpi_proc_struct.o \ + fll_mpi_write_snm.o -fll_mpi_proc_struct.o : \ +fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o - -fll_mpi_mv.o : \ - fll_mpi_cp.o \ +fll_mpi_cp.o : \ ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_rm.o + ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_out.o + +fll_mpi_read.o : \ + fll_mpi_cp_all.o \ + ../data_util/fll_mods.o fll_mpi_write.o : \ ../data_util/fll_mods.o \ fll_mpi_sum.o -fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ +fll_mpi_write_nm.o : \ + fll_mpi_write.o \ + ../data_util/fll_mods.o + +fll_mpi_cp_all.o : \ ../data_util/fll_type.o \ ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ ../data_util/fll_out.o + +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index dd45bab..bb69cbc 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -438,11 +438,11 @@ def __init__(self): verbose = 0 if(args.verbose): - verbose = 1 + verbose = 1 if(args.vverbose): - verbose = 2 + verbose = 2 if(args.vvverbose): - verbose = 3 + verbose = 3 run(path=root_dir, dep=dep_dir, ignore=args.ignore, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From ed4ec0a35ef9582166071a48985049beb744ad52 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 27 May 2017 17:22:40 -0600 Subject: [PATCH 207/325] fix bug with inconsisten use of tab and spaces --- fort_depend.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 85055fa..bb69cbc 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # # # this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py @@ -438,11 +438,11 @@ def __init__(self): verbose = 0 if(args.verbose): - verbose = 1 + verbose = 1 if(args.vverbose): - verbose = 2 + verbose = 2 if(args.vvverbose): - verbose = 3 + verbose = 3 run(path=root_dir, dep=dep_dir, ignore=args.ignore, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From ab7db500a52d98d18eb2a0aa5d0fa30be1018ccd Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 29 May 2017 19:03:05 -0600 Subject: [PATCH 208/325] fix utf-8 file reading problem --- fort_depend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index bb69cbc..4f7e4a9 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -257,7 +257,7 @@ def get_includes(infile=None, macros={}): includes=[] - with open(infile,'r') as f: + with open(infile,'r',encoding = "ISO-8859-1") as f: t=f.readlines() for i in t: @@ -310,8 +310,8 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): for i in fob: if int(verbose) > 1 : -# print("") print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") + tmp=[] for j in i.uses: if ignore and (j in ignore): continue From 1e97890dd6679d99ded4876bfc6c29884b6c0937 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 29 May 2017 19:05:54 -0600 Subject: [PATCH 209/325] fix fort depend for utf-8 files --- data_util/Makefile | 1 + data_util/depend.mk | 140 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 14 +-- examples/Simple_data_operation/depend.mk | 4 +- mpi_util/depend.mk | 60 +++++----- python_dep/fort_depend.py | 4 +- 6 files changed, 112 insertions(+), 111 deletions(-) diff --git a/data_util/Makefile b/data_util/Makefile index 0b988e2..f1724ca 100644 --- a/data_util/Makefile +++ b/data_util/Makefile @@ -56,5 +56,6 @@ depend: $(FFILES) cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + -include $(srcdir)/$(DEP_FILE) diff --git a/data_util/depend.mk b/data_util/depend.mk index 27faad2..7188b5b 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,131 +1,131 @@ # This file is generated automatically. DO NOT EDIT! -fll_duplicate.o : \ +fll_match_pattern.o : \ fll_out.o \ - fll_type.o \ - fll_mk.o \ - fll_mv.o + fll_type.o -fll_out.o : \ +fll_cat.o : \ + fll_out.o \ fll_type.o -fll_mods.o : \ - fll_mkdir.o \ - fll_read.o \ - fll_rm.o \ - fll_stich.o \ - fll_getnbytes.o \ - fll_sweep.o \ +fll_read.o : \ + fll_mk.o \ fll_out.o \ - fll_read_ffa.o \ - fll_funct_prt.o \ - fll_write.o \ - fll_match_pattern.o \ fll_mv.o \ - fll_cp.o \ - fll_duplicate.o \ - fll_mk.o \ - fll_locate.o \ fll_type.o \ - fll_nnodes.o \ - fll_cat.o \ - fll_deattach.o \ - fll_getndata.o \ - fll_write_ffa.o + fll_funct_prt.o -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_out.o \ +fll_out.o : \ fll_type.o -fll_mkdir.o : \ - fll_type.o \ - fll_mk.o - -fll_deattach.o : \ +fll_nnodes.o : \ fll_out.o \ fll_type.o \ - fll_stich.o + fll_funct_prt.o fll_stich.o : \ fll_out.o \ fll_type.o -fll_cat.o : \ +fll_locate.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_funct_prt.o fll_funct_prt.o : \ fll_out.o \ fll_type.o -fll_read.o : \ - fll_out.o \ - fll_funct_prt.o \ - fll_type.o \ +fll_mkdir.o : \ fll_mk.o \ - fll_mv.o - -fll_sweep.o : \ - fll_out.o \ - fll_match_pattern.o \ fll_type.o -fll_type.o : - fll_rm.o : \ + fll_stich.o \ fll_out.o \ - fll_type.o \ - fll_stich.o + fll_type.o -fll_match_pattern.o : \ +fll_duplicate.o : \ + fll_mk.o \ fll_out.o \ + fll_mv.o \ fll_type.o fll_mv.o : \ - fll_rm.o \ + fll_stich.o \ fll_out.o \ fll_type.o \ - fll_stich.o + fll_rm.o -fll_getnbytes.o : \ +fll_write_ffa.o : \ fll_out.o \ fll_type.o -fll_cp.o : \ +fll_write.o : \ fll_out.o \ - fll_type.o \ + fll_type.o + +fll_mods.o : \ fll_mv.o \ - fll_duplicate.o \ + fll_locate.o \ fll_cat.o \ + fll_type.o \ + fll_funct_prt.o \ + fll_stich.o \ fll_rm.o \ - fll_stich.o + fll_mk.o \ + fll_nnodes.o \ + fll_write.o \ + fll_getnbytes.o \ + fll_duplicate.o \ + fll_out.o \ + fll_mkdir.o \ + fll_deattach.o \ + fll_write_ffa.o \ + fll_getndata.o \ + fll_read.o \ + fll_cp.o \ + fll_sweep.o \ + fll_read_ffa.o \ + fll_match_pattern.o -fll_read_ffa.o : \ +fll_getndata.o : \ fll_out.o \ - fll_funct_prt.o \ fll_type.o \ - fll_mk.o \ - fll_mv.o + fll_locate.o -fll_write_ffa.o : \ +fll_sweep.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_match_pattern.o -fll_mk.o : \ +fll_type.o : + +fll_getnbytes.o : \ fll_out.o \ fll_type.o -fll_locate.o : \ - fll_funct_prt.o \ +fll_read_ffa.o : \ + fll_mk.o \ fll_out.o \ - fll_type.o + fll_mv.o \ + fll_type.o \ + fll_funct_prt.o -fll_write.o : \ +fll_mk.o : \ fll_out.o \ fll_type.o -fll_getndata.o : \ +fll_deattach.o : \ + fll_stich.o \ fll_out.o \ + fll_type.o + +fll_cp.o : \ + fll_mv.o \ + fll_cat.o \ fll_type.o \ - fll_locate.o + fll_stich.o \ + fll_duplicate.o \ + fll_out.o \ + fll_rm.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index ec5638e..920e8cf 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically. DO NOT EDIT! Example_mpi-IO.o : \ + read_input.o \ + ../../mpi_util/fll_mpi_mods.o \ create_data_set.o \ save_individ_files.o \ - read_input.o \ - ../../data_util/fll_mods.o \ save_root_part_file.o \ - ../../mpi_util/fll_mpi_mods.o - -read_input.o : \ ../../data_util/fll_mods.o -create_data_set.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o -save_individ_files.o : \ +read_input.o : \ ../../data_util/fll_mods.o save_root_part_file.o : \ ../../data_util/fll_mods.o + +create_data_set.o : \ + ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 248c2d0..4b1a81c 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -4,5 +4,5 @@ fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - fll_test_subr.o \ - ../../data_util/fll_mods.o + ../../data_util/fll_mods.o \ + fll_test_subr.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 7775b94..12a1747 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_write_snm.o : \ - fll_mpi_cp.o \ - ../data_util/fll_mods.o +fll_mpi_read.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o fll_mpi_mv.o : \ - fll_mpi_cp.o \ - ../data_util/fll_type.o \ ../data_util/fll_rm.o \ - ../data_util/fll_out.o + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + fll_mpi_cp.o + +fll_mpi_write_snm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp.o + +fll_mpi_cp_all.o : \ + ../data_util/fll_mk.o \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mv.o fll_mpi_mods.o : \ - fll_mpi_write.o \ - fll_mpi_sum.o \ - fll_mpi_write_nm.o \ - fll_mpi_cp_all.o \ - fll_mpi_mv.o \ fll_mpi_read.o \ + fll_mpi_write_snm.o \ + fll_mpi_mv.o \ fll_mpi_cp.o \ + fll_mpi_sum.o \ + fll_mpi_write.o \ + fll_mpi_write_nm.o \ fll_mpi_proc_struct.o \ - fll_mpi_write_snm.o + fll_mpi_cp_all.o fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_cp.o : \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o - -fll_mpi_read.o : \ - fll_mpi_cp_all.o \ - ../data_util/fll_mods.o - fll_mpi_write.o : \ - ../data_util/fll_mods.o \ - fll_mpi_sum.o + fll_mpi_sum.o \ + ../data_util/fll_mods.o fll_mpi_write_nm.o : \ fll_mpi_write.o \ ../data_util/fll_mods.o -fll_mpi_cp_all.o : \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o - fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o + +fll_mpi_cp.o : \ + ../data_util/fll_mk.o \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mv.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index bb69cbc..4f7e4a9 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -257,7 +257,7 @@ def get_includes(infile=None, macros={}): includes=[] - with open(infile,'r') as f: + with open(infile,'r',encoding = "ISO-8859-1") as f: t=f.readlines() for i in t: @@ -310,8 +310,8 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): for i in fob: if int(verbose) > 1 : -# print("") print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") + tmp=[] for j in i.uses: if ignore and (j in ignore): continue From 3ade0c5e5467ebcdbb42accb5f95abceed98488b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 30 May 2017 09:25:33 -0600 Subject: [PATCH 210/325] disable stdio, distracting --- mpi_util/fll_mpi_write_nm.f90 | 2 +- mpi_util/fll_mpi_write_snm.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index 1be22b2..5ab4183 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -105,7 +105,7 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! ! Print some info ! - WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) +! WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) ! ! save file, ROOT_RANK is always 0, use local rank ! diff --git a/mpi_util/fll_mpi_write_snm.f90 b/mpi_util/fll_mpi_write_snm.f90 index cf752d5..b63fa18 100644 --- a/mpi_util/fll_mpi_write_snm.f90 +++ b/mpi_util/fll_mpi_write_snm.f90 @@ -164,7 +164,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) PDISPL%L1 = DISPL - WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) +! WRITE(*,*)' Partition ',WORLD_RANK,' saving to :',trim(NAME_OF_FILE) IF(.NOT.FLL_WRITE(PMAIN,TRIM(NAME_OF_FILE), IOUNIT, 'B', FPAR))STOP'Error writing file' ! WRITE(*,*)' Partition ',WORLD_RANK,' done saving to :',trim(NAME_OF_FILE) ! From d3afa723b0f9c30037ba88a0a39c8c0b3ce55b86 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 30 May 2017 09:25:48 -0600 Subject: [PATCH 211/325] update MIP-IO example --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 303 ++++++++++++------ examples/Example_MPI-IO/read_input.f90 | 2 +- .../Example_MPI-IO/save_root_part_file.f90 | 8 +- examples/Makefile | 2 + 4 files changed, 211 insertions(+), 104 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 7cc8b19..bdefe87 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -61,7 +61,7 @@ PROGRAM EXAMPLE_MPI_IO TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IERR,WORLD_RANK,world_group_id,NPROC,ISTAT - INTEGER(LINT) :: NFILES,BYTESN,NSIZE,I + INTEGER(LINT) :: NFILES,BYTESN,NSIZE,I,J integer :: EVEN_COMM_ID,EVEN_P,EVEN_GROUP_ID,ODD_GROUP_ID,ODD_COMM_ID CHARACTER(LEN=FILE_NAME_LENGTH) :: NAME_OF_FILE LOGICAL :: OK @@ -72,36 +72,24 @@ PROGRAM EXAMPLE_MPI_IO TYPE(DNODE), POINTER ::PIOSTR,PSUBPROC,PIO - REAL :: CPUE,CPUS + REAL :: CPUE,CPUS,CPUAVE,CPTIMERMS(100),BYTESIZE,BYTESPEED INTEGER :: VALS(8) + + INTEGER :: NCYC + NCYC = 20 ! ! Initialize MPI ! CALL MPI_INIT(IERR) CALL MPI_Comm_rank ( MPI_COMM_WORLD, WORLD_RANK, IERR ) - CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) + CALL MPI_Comm_size ( MPI_COMM_WORLD, NPROC, ierr ) FLL_MPI_STRUCT => NULL() ! -! initiate MPI structure with all info -! - PMPI => FLL_MPI_PROC_STRUCT(FPAR) -! -! define how to save files for N-M saving model -! - CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',2_LINT, FPAR) - CALL FLL_SNMIO_STRUCT(PMPI,'ceda','bmpi',2_LINT, 'I', FPAR) -! -! print the strucute on the screen and save into ASCII file -! - IF(WORLD_RANK == 0)THEN - CALL FLL_CAT(PMPI,6,.FALSE., FPAR) - IF(.NOT.FLL_WRITE(PMPI,"io.str", 9, 'A', FPAR))STOP'Error writing file' - END IF -! ! create sample data se ! - NSIZE = 5000000 !+ 100*WORLD_RANK + NSIZE = 100000 !+ 100*WORLD_RANK + BYTESIZE = NSIZE*8*NPROC*5 CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) ! IF(WORLD_RANK == 0) OK = FLL_WRITE_FFA(PDATA_SET,'test.bcs',10,'B',FPAR) @@ -112,112 +100,225 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0) WRITE(*,*)' Partitions created data set size of ', WORLD_RANK,BYTESN ! ! save to one file, all partitions at the same time -! - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) +! + IF(WORLD_RANK == 0)THEN + WRITE(*,*)'==============================================' + write(*,*)' Saving to single file' + WRITE(*,*)'==============================================' + END IF + CPUAVE = 0 + DO J=1,NCYC + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - END IF + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF - OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) + OK = FLL_MPI_WRITE(PDATA_SET,'PartitionedFile',10,0, world_rank, MPI_COMM_WORLD, 'A', FPAR) - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)' Time writing paralell to single file (N-1 model):',CPUE-CPUS - END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! WRITE(*,*)' Time writing paralell to single file (N-1 model):',CPUE-CPUS + CPTIMERMS(J) = CPUE-CPUS + CPUAVE = CPUAVE + CPUE-CPUS + END IF + + END DO + + IF(WORLD_RANK == 0)THEN + CPUAVE = CPUAVE/FLOAT(NCYC) + DO J=1,NCYC + CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 + END DO + write(*,*)' >>>>>>>>>>>>> average time of saving (N-1 model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + BYTESPEED = BYTESIZE/CPUAVE/1048576 + write(*,*)' >>>>>>>>>>>>> average speed of saving (N-1 model) is ',& + BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + write(*,*) + END IF + + + + + + + DO I=2,NPROC/2,2 + + IF(WORLD_RANK == 0)THEN + WRITE(*,*)'==============================================' + write(*,*)' Saving to ',I,' files' + WRITE(*,*)'==============================================' + END IF +! +! initiate MPI structure with all info +! + PMPI => FLL_MPI_PROC_STRUCT(FPAR) +! +! define how to save files for N-M saving model +! + CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',I, FPAR) + CALL FLL_SNMIO_STRUCT(PMPI,'ceda','bmpi',I, 'I', FPAR) +! +! print the strucute on the screen and save into ASCII file +! + IF(WORLD_RANK == 0)THEN +! CALL FLL_CAT(PMPI,6,.FALSE., FPAR) +! IF(.NOT.FLL_WRITE(PMPI,"io.str", 9, 'A', FPAR))STOP'Error writing file' + END IF + + CPUAVE = 0 + DO J=1,NCYC ! ! save to 2 separate files in S-N-M mode ! - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - END IF + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF - OK = FLL_MPI_WRITE_SNM(PDATA_SET,PMPI,FPAR) + OK = FLL_MPI_WRITE_SNM(PDATA_SET,PMPI,FPAR) - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)"Time writing serial to 2 files (S-N-M model):",CPUE-CPUS - END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! WRITE(*,*)"Time writing serial to files (S-N-M model):",CPUE-CPUS + CPTIMERMS(J) = CPUE-CPUS + CPUAVE = CPUAVE + CPUE-CPUS + END IF + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + END DO + + IF(WORLD_RANK == 0)THEN + CPUAVE = CPUAVE/FLOAT(NCYC) + DO J=1,NCYC + CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 + END DO + write(*,*)' >>>>>>>>>>>>> average time of saving (S-N-M model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + BYTESPEED = BYTESIZE/CPUAVE/1048576 + write(*,*)' >>>>>>>>>>>>> average speed of saving (S-N-M model) is ',& + BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + write(*,*) + END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) ! ! save to 2 separate files all partitions at the same time ! - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - END IF + CPUAVE = 0 + DO J=1,NCYC - OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)"Time writing paralell to 2 partitions file (N-M model):",CPUE-CPUS - END IF - - IF(WORLD_RANK == 0) THEN - CALL READ_INPUT(NAME_OF_FILE,NFILES,1_LINT*NPROC) - END IF - -! CALL FLL_RM(PMPI,FPAR) -! ! -! ! save to 4 separate files all partitions at the same time -! ! -! PMPI => FLL_MPI_PROC_STRUCT(FPAR) -! CALL FLL_NMIO_STRUCT(PMPI,'beda','bmpi',4_LINT, FPAR) -! -! -! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) -! IF(WORLD_RANK == 0)THEN -! CALL CPU_TIME(START) -! CALL DATE_AND_TIME(VALUES=VALS) -! CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 -! END IF -! -! OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) -! -! CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) -! IF(WORLD_RANK == 0)THEN -! ! CALL CPU_TIME(FINISH) -! ! WRITE(*,*)'Time writing paralell to a 4 file file (N-M model)', FINISH-START -! CALL DATE_AND_TIME(VALUES=VALS) -! CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 -! WRITE(*,*)' Time writing paralell to 4 partitions file (N-M model):',CPUE-CPUS -! END IF + OK = FLL_MPI_WRITE_NM(PDATA_SET,PMPI,FPAR) + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! WRITE(*,*)"Time writing paralell to partitions file (N-M model):",CPUE-CPUS + CPTIMERMS(J) = CPUE-CPUS + CPUAVE = CPUAVE + CPUE-CPUS + END IF + + END DO + IF(WORLD_RANK == 0)THEN + CPUAVE = CPUAVE/FLOAT(NCYC) + DO J=1,NCYC + CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 + END DO + write(*,*)' >>>>>>>>>>>>> average time of saving (N-M model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + BYTESPEED = BYTESIZE/CPUAVE/1048576 + write(*,*)' >>>>>>>>>>>>> average speed of saving (N-M model) is ',& + BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + write(*,*) + END IF + + CALL FLL_RM(PMPI,FPAR) + + END DO + + + + + IF(WORLD_RANK == 0)THEN + WRITE(*,*)'==============================================' + write(*,*)' Saving to individual files' + WRITE(*,*)'==============================================' + END IF ! ! write to individual files ! - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN - CALL DATE_AND_TIME(VALUES=VALS) - CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - END IF + CPUAVE = 0 - CALL SAVE_INDIVID_FILES(PDATA_SET,WORLD_RANK,FPAR) + DO J=1,NCYC - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF(WORLD_RANK == 0)THEN + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN CALL DATE_AND_TIME(VALUES=VALS) - CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)' Time writing to individual files (N-N model):',CPUE-CPUS - END IF - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + CPUS = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 + END IF + + CALL SAVE_INDIVID_FILES(PDATA_SET,WORLD_RANK,FPAR) + + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + IF(WORLD_RANK == 0)THEN + CALL DATE_AND_TIME(VALUES=VALS) + CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 +! WRITE(*,*)' Time writing to individual files (N-N model):',CPUE-CPUS + CPTIMERMS(J) = CPUE-CPUS + CPUAVE = CPUAVE + CPUE-CPUS + END IF + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + + END DO + + IF(WORLD_RANK == 0)THEN + CPUAVE = CPUAVE/FLOAT(NCYC) + DO J=1,NCYC + CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 + END DO + write(*,*)' >>>>>>>>>>>>> average time of saving (N-N model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + BYTESPEED = BYTESIZE/CPUAVE/1048576 + write(*,*)' >>>>>>>>>>>>> average speed of saving (N-N model) is ',& + BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + write(*,*) + END IF ! ! save entire data set from too partiton: 1-1 model ! - IF(WORLD_RANK == 0)CALL SAVE_ROOT_PART_FILE(PDATA_SET,FPAR) -! -! Copy FLL_MPI_STRUCT date set which now exists on root partition onlyc + IF(WORLD_RANK == 0)THEN + WRITE(*,*)'==============================================' + write(*,*)' Saving to concentanated file' + WRITE(*,*)'==============================================' + END IF + + DO J=1,NCYC + IF(WORLD_RANK == 0)CALL SAVE_ROOT_PART_FILE(PDATA_SET,J,CPTIMERMS,FPAR) + END DO + + IF(WORLD_RANK == 0)THEN + CPUAVE = SUM(CPTIMERMS(1:NCYC))/FLOAT(NCYC) + DO J=1,NCYC + CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 + END DO + write(*,*)' >>>>>>>>>>>>> average time of saving (1-1 model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + BYTESPEED = BYTESIZE/CPUAVE/1048576 + write(*,*)' >>>>>>>>>>>>> average speed of saving (1-1 model) is ',& + BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) + write(*,*) + END IF +! +! Copy FLL_MPI_STRUCT date set which now exists on root partition only ! to all other partitions ! Upon return, the function will return pointer to newly allocated data ! for all other partition then root partition diff --git a/examples/Example_MPI-IO/read_input.f90 b/examples/Example_MPI-IO/read_input.f90 index c9bdc02..cd42108 100644 --- a/examples/Example_MPI-IO/read_input.f90 +++ b/examples/Example_MPI-IO/read_input.f90 @@ -63,7 +63,7 @@ SUBROUTINE READ_INPUT(NAME_OF_FILE,NFILES,NPROC) WRITE(*,*)' Name of file without suffix' READ(*,*)NAME_OF_FILE - WRITE(*,*)' Hom many files' + WRITE(*,*)' How many files' READ(*,*)NFILES WRITE(*,*)' How many processors' diff --git a/examples/Example_MPI-IO/save_root_part_file.f90 b/examples/Example_MPI-IO/save_root_part_file.f90 index 1184bca..0831118 100644 --- a/examples/Example_MPI-IO/save_root_part_file.f90 +++ b/examples/Example_MPI-IO/save_root_part_file.f90 @@ -46,7 +46,7 @@ MODULE SAVE_ROOT_PART_FILE_M CONTAINS - SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,FPAR) + SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,J,CPURMS,FPAR) USE MPI USE FLL_MODS_M @@ -62,6 +62,9 @@ SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: RANK, NPROC,IERR,WORLD_RANK,I + INTEGER(LINT) :: J + REAL :: CPURMS(:) + REAL :: FINISH,START REAL :: CPUE,CPUS INTEGER :: VALS(8) @@ -88,7 +91,8 @@ SUBROUTINE SAVE_ROOT_PART_FILE(PNODE,FPAR) ! WRITE(*,*)' SAVING INDIVIDUAL FILES TIME IS ', FINISH-START CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 - WRITE(*,*)'Time writing single to single file :',CPUE-CPUS + CPURMS(J) = CPUE-CPUS +! WRITE(*,*)'Time writing single to single file :',CPUE-CPUS END IF CALL FLL_RM(PMAIN, FPAR) diff --git a/examples/Makefile b/examples/Makefile index 2583461..c7838a3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -42,6 +42,8 @@ DEP_FILE=depend.mk SUBDIRS= \ Simple_data_operation \ Extra \ + Example_MPI-IO\ + ExtractSurface\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= Example_MPI-IO From 8a8e7cf53906e94f6a4ee7556338e095833bddbc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 30 May 2017 12:18:41 -0600 Subject: [PATCH 212/325] tweak with number of files --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index bdefe87..b4b4f89 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -88,7 +88,9 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 100000 !+ 100*WORLD_RANK + NSIZE = 1000000 !+ 10000*SIN(2*3.145926*world_rank/nproc) +! write(*,*)nsize + BYTESIZE = NSIZE*8*NPROC*5 CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) @@ -143,13 +145,17 @@ PROGRAM EXAMPLE_MPI_IO + NFILES = 1 + + DO I=1,NPROC - DO I=2,NPROC/2,2 + NFILES = NFILES*2 + IF(NFILES > NPROC-1)EXIT IF(WORLD_RANK == 0)THEN WRITE(*,*)'==============================================' - write(*,*)' Saving to ',I,' files' + write(*,*)' Saving to ',NFILES,' files' WRITE(*,*)'==============================================' END IF ! @@ -159,8 +165,8 @@ PROGRAM EXAMPLE_MPI_IO ! ! define how to save files for N-M saving model ! - CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',I, FPAR) - CALL FLL_SNMIO_STRUCT(PMPI,'ceda','bmpi',I, 'I', FPAR) + CALL FLL_NMIO_STRUCT(PMPI,'ada','bmpi',NFILES, FPAR) + CALL FLL_SNMIO_STRUCT(PMPI,'ceda','bmpi',NFILES, 'I', FPAR) ! ! print the strucute on the screen and save into ASCII file ! From f1242c075be5136cc1e91aca493f84285957d680 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 30 May 2017 15:06:27 -0600 Subject: [PATCH 213/325] add --dir -d option to fll_cat --- accessories/fll_cat/fll_cat.f90 | 9 +++++++-- accessories/fll_cat/fll_cat.py | 20 ++++++++++++++++---- data_util/fll_cat.f90 | 33 +++++++++++++++++++++++---------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index 02eb398..fd5e33c 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -62,7 +62,7 @@ PROGRAM FLL_CATU CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER :: FMT, SCAN + CHARACTER :: FMT, SCAN, DIR CHARACTER(LEN=3) :: EFMT ! ! read a file and print on screen @@ -71,6 +71,7 @@ PROGRAM FLL_CATU READ(*,*)FMT READ(*,'(A3)')EFMT READ(*,*)SCAN + READ(*,*)DIR SELECT CASE(EFMT) CASE('fll') @@ -81,7 +82,11 @@ PROGRAM FLL_CATU ! ! print node on the screen ! - CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN) + IF(DIR == 'Y')THEN + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN, SDIR = DIR) + ELSE + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN) + END IF WRITE(*,*) CALL FLL_RM(PNODE,FPAR) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index cfbb45f..1a0c4ce 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -11,7 +11,7 @@ #Definitions -def run(file,fmt,efmt,scan): +def run(file,fmt,efmt,scan,dir): # # execute # @@ -37,6 +37,11 @@ def run(file,fmt,efmt,scan): else: print("\033[039m Specified file format is: \033[032mASCII \033[039m") + if dir == 'Y': + print(" ") + print("\033[035m ... printing DIR structure only ... \033[039m") + if fmt == 'b' or fmt == 'B': scan = 'Y' + if scan == 'Y': print(" ") print("\033[035m ... running in scan only mode ... \033[039m") @@ -44,10 +49,10 @@ def run(file,fmt,efmt,scan): if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt, efmt, scan])) + p.communicate(os.linesep.join([file, fmt, efmt, scan, dir])) else: p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here - p.communicate(os.linesep.join( [file, fmt, efmt, scan])) + p.communicate(os.linesep.join( [file, fmt, efmt, scan, dir])) def print_header(): print(" ") @@ -77,6 +82,7 @@ def check_path(path): parser.add_argument('-i','--file',nargs=1,help='Files to process') parser.add_argument('-f','--format',nargs=1,help='Format of the file') parser.add_argument('-s','--scan',action='store_true',help='Scan file only',required=False) + parser.add_argument('-D','--dir',action='store_true',help='Print DIR only',required=False) parser.add_argument('-e','--external_format',nargs=1,help='External format of the file') # Parse the command line arguments @@ -86,12 +92,18 @@ def check_path(path): format = args.format[0] if args.format else None eformat = args.external_format[0] if args.external_format else None scan = args.scan + dir = args.dir if not scan: scan = 'n' else: scan = 'Y' + if not dir: + dir = 'n' + else: + dir = 'Y' + if not file: print ("\033[031mError: \033[039m missing name of file, option\033[031m -i \033[039m") sys.exit() @@ -111,4 +123,4 @@ def check_path(path): print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() - run(file=file,fmt=format, efmt = eformat, scan=scan) + run(file=file,fmt=format, efmt = eformat, scan=scan, dir=dir) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 06e0ed6..146214a 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -34,7 +34,7 @@ MODULE FLL_CAT_M ! CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -52,6 +52,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) ! IOUNIR In pointer which is to be copied ! PARENT In parameter, if .TRUE. write information about PNODE parent node ! FPAR In/Out structure containing function specific data +! SDIR In if present, print DIRs only ! ! Arguments declaration ! @@ -59,13 +60,14 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT LOGICAL :: PARENT - CHARACTER, OPTIONAL :: SCAN + CHARACTER, OPTIONAL :: SCAN,SDIR ! ! Local types ! TYPE(DNODE), POINTER :: PCHILD INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC + INTEGER :: DIR ! ! body of subroutine ! @@ -75,6 +77,12 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) SCAN_LOC = 'N' END IF + IF(PRESENT(SDIR))THEN + DIR = 1 + ELSE + DIR = 0 + END IF + POS = 1 FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN @@ -90,11 +98,11 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is: ', PNODE%PPAR%LNAME WRITE(*,*) END IF - CALL FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) + CALL FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,DIR,FPAR) FPAR%SUCCESS = .TRUE. @@ -102,7 +110,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN) END SUBROUTINE FLL_CAT ! ! - RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -119,13 +127,14 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,FPAR) ! IOUNIR In pointer which is to be copied ! PARENT In parameter, if .TRUE. write information about PNODE parent node ! FPAR In/Out structure containing function specific data +! DIR In = 0 print entire list, = 1 print DIR types only ! ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS - INTEGER :: IOUNIT + INTEGER :: IOUNIT,DIR CHARACTER :: SCAN ! ! Local variables @@ -141,12 +150,12 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,FPAR) ! DO WHILE(ASSOCIATED(PCURR)) - CALL FLL_PRINT(PCURR, IOUNIT, POS, SCAN, FPAR) + CALL FLL_PRINT(PCURR, IOUNIT, POS, SCAN, DIR, FPAR) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN,FPAR) + CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN,DIR,FPAR) END IF PCURR => PNEXT @@ -161,7 +170,7 @@ END SUBROUTINE FLL_CAT_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) + SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) ! ! Description: print content of PNODE ! @@ -179,6 +188,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! PARENT In parameter, if .TRUE. write information about PNODE parent node ! FPAR In/Out structure containing function specific data ! POS In level in linked list +! DIR In = 0 print entire list, = 1 print DIR types only ! ! Arguments declaration ! @@ -191,6 +201,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) ! Local variables ! INTEGER(LINT) :: I,J,NDIM,NSIZE + INTEGER :: DIR LOGICAL :: SAVED CHARACTER*2048 :: TEXT,TEXT1 CHARACTER*72 :: NDSTR,NSSTR @@ -223,7 +234,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) achar(27),"[32m",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' WRITE(IOUNIT, *)TRIM(TEXT1) RETURN - ELSE + ELSE IF(DIR == 0) THEN WRITE(TEXT1,'(A,A3,A,A,A,A,A,A16)')& "-",TRIM(PNODE%LTYPE),"- ",TRIM(NDSTR),'x',ADJUSTL(TRIM(NSSTR)),SPACE,NAME IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN @@ -231,6 +242,8 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, FPAR) RETURN END IF END IF + + IF(DIR == 1)RETURN ! ! print 1D arrays ! From 73f8b76c87d75160e373c6336b915adeb10ce899 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Jun 2017 09:50:40 -0600 Subject: [PATCH 214/325] update dep script for pyhton2.x --- data_util/depend.mk | 140 +++++++++++++++--------------- examples/Example_MPI-IO/depend.mk | 12 +-- examples/Makefile | 2 - mpi_util/depend.mk | 66 +++++++------- python_dep/fort_depend.py | 8 +- 5 files changed, 116 insertions(+), 112 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 7188b5b..e518aee 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,131 +1,131 @@ # This file is generated automatically. DO NOT EDIT! -fll_match_pattern.o : \ +fll_deattach.o : \ + fll_stich.o \ fll_out.o \ fll_type.o -fll_cat.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_out.o \ fll_type.o -fll_read.o : \ - fll_mk.o \ +fll_getnbytes.o : \ fll_out.o \ - fll_mv.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o -fll_out.o : \ +fll_mkdir.o : \ + fll_mk.o \ fll_type.o -fll_nnodes.o : \ +fll_cat.o : \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o + +fll_type.o : fll_stich.o : \ fll_out.o \ fll_type.o -fll_locate.o : \ - fll_out.o \ - fll_type.o \ - fll_funct_prt.o - fll_funct_prt.o : \ fll_out.o \ fll_type.o -fll_mkdir.o : \ - fll_mk.o \ - fll_type.o - -fll_rm.o : \ - fll_stich.o \ +fll_sweep.o : \ + fll_match_pattern.o \ fll_out.o \ fll_type.o -fll_duplicate.o : \ +fll_read.o : \ + fll_mv.o \ + fll_funct_prt.o \ fll_mk.o \ fll_out.o \ + fll_type.o + +fll_cp.o : \ fll_mv.o \ + fll_cat.o \ + fll_out.o \ + fll_duplicate.o \ + fll_rm.o \ + fll_stich.o \ fll_type.o fll_mv.o : \ fll_stich.o \ fll_out.o \ - fll_type.o \ - fll_rm.o - -fll_write_ffa.o : \ - fll_out.o \ + fll_rm.o \ fll_type.o fll_write.o : \ fll_out.o \ fll_type.o -fll_mods.o : \ - fll_mv.o \ +fll_getndata.o : \ fll_locate.o \ - fll_cat.o \ - fll_type.o \ - fll_funct_prt.o \ - fll_stich.o \ - fll_rm.o \ - fll_mk.o \ - fll_nnodes.o \ - fll_write.o \ - fll_getnbytes.o \ - fll_duplicate.o \ fll_out.o \ - fll_mkdir.o \ - fll_deattach.o \ - fll_write_ffa.o \ - fll_getndata.o \ - fll_read.o \ - fll_cp.o \ - fll_sweep.o \ - fll_read_ffa.o \ - fll_match_pattern.o + fll_type.o -fll_getndata.o : \ +fll_match_pattern.o : \ fll_out.o \ - fll_type.o \ - fll_locate.o + fll_type.o -fll_sweep.o : \ +fll_locate.o : \ + fll_funct_prt.o \ fll_out.o \ - fll_type.o \ - fll_match_pattern.o - -fll_type.o : + fll_type.o -fll_getnbytes.o : \ +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ +fll_duplicate.o : \ + fll_mv.o \ fll_mk.o \ fll_out.o \ + fll_type.o + +fll_mods.o : \ fll_mv.o \ + fll_out.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_match_pattern.o \ fll_type.o \ - fll_funct_prt.o + fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ + fll_write_ffa.o \ + fll_getnbytes.o \ + fll_mk.o \ + fll_deattach.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o -fll_mk.o : \ +fll_rm.o : \ + fll_stich.o \ fll_out.o \ fll_type.o -fll_deattach.o : \ - fll_stich.o \ +fll_mk.o : \ fll_out.o \ fll_type.o -fll_cp.o : \ - fll_mv.o \ - fll_cat.o \ - fll_type.o \ - fll_stich.o \ - fll_duplicate.o \ +fll_out.o : \ + fll_type.o + +fll_write_ffa.o : \ fll_out.o \ - fll_rm.o + fll_type.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 920e8cf..5e2ba4a 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,12 +1,12 @@ # This file is generated automatically. DO NOT EDIT! Example_mpi-IO.o : \ - read_input.o \ - ../../mpi_util/fll_mpi_mods.o \ + ../../data_util/fll_mods.o \ + save_root_part_file.o \ create_data_set.o \ save_individ_files.o \ - save_root_part_file.o \ - ../../data_util/fll_mods.o + read_input.o \ + ../../mpi_util/fll_mpi_mods.o save_individ_files.o : \ ../../data_util/fll_mods.o @@ -14,8 +14,8 @@ save_individ_files.o : \ read_input.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ +create_data_set.o : \ ../../data_util/fll_mods.o -create_data_set.o : \ +save_root_part_file.o : \ ../../data_util/fll_mods.o diff --git a/examples/Makefile b/examples/Makefile index c7838a3..93e79c8 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -41,9 +41,7 @@ DEP_FILE=depend.mk #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ Simple_data_operation \ - Extra \ Example_MPI-IO\ - ExtractSurface\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= Example_MPI-IO diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 12a1747..e32f87f 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o - -fll_mpi_mv.o : \ - ../data_util/fll_rm.o \ +fll_mpi_cp_all.o : \ + ../data_util/fll_mv.o \ ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - fll_mpi_cp.o + ../data_util/fll_mk.o \ + ../data_util/fll_out.o -fll_mpi_write_snm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp.o +fll_mpi_sum.o : \ + ../data_util/fll_mods.o -fll_mpi_cp_all.o : \ - ../data_util/fll_mk.o \ - ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mv.o +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o fll_mpi_mods.o : \ - fll_mpi_read.o \ fll_mpi_write_snm.o \ - fll_mpi_mv.o \ fll_mpi_cp.o \ - fll_mpi_sum.o \ - fll_mpi_write.o \ - fll_mpi_write_nm.o \ fll_mpi_proc_struct.o \ + fll_mpi_write_nm.o \ + fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ fll_mpi_cp_all.o -fll_mpi_sum.o : \ - ../data_util/fll_mods.o +fll_mpi_write_snm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp.o -fll_mpi_write.o : \ - fll_mpi_sum.o \ +fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o -fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o +fll_mpi_read.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o +fll_mpi_mv.o : \ + fll_mpi_cp.o \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_rm.o + +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o fll_mpi_cp.o : \ - ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mv.o + ../data_util/fll_mk.o \ + ../data_util/fll_out.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 4f7e4a9..245c562 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -257,8 +257,14 @@ def get_includes(infile=None, macros={}): includes=[] - with open(infile,'r',encoding = "ISO-8859-1") as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r',errors='ignore') as f: t=f.readlines() +# with open(infile,'r',encoding = "ISO-8859-1") as f: +# t=f.readlines() for i in t: tmp=p(i) From 4d4c1ba2bfc3ba1f427156278c7c601d4fce1791 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Jun 2017 09:52:11 -0600 Subject: [PATCH 215/325] update for python2.x --- fort_depend.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 85055fa..245c562 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # # # this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py @@ -257,8 +257,14 @@ def get_includes(infile=None, macros={}): includes=[] - with open(infile,'r') as f: + if sys.version_info < (3,0): + with open(infile,'r') as f: + t=f.readlines() + else: + with open(infile,'r',errors='ignore') as f: t=f.readlines() +# with open(infile,'r',encoding = "ISO-8859-1") as f: +# t=f.readlines() for i in t: tmp=p(i) @@ -310,8 +316,8 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): for i in fob: if int(verbose) > 1 : -# print("") print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") + tmp=[] for j in i.uses: if ignore and (j in ignore): continue @@ -438,11 +444,11 @@ def __init__(self): verbose = 0 if(args.verbose): - verbose = 1 + verbose = 1 if(args.vverbose): - verbose = 2 + verbose = 2 if(args.vvverbose): - verbose = 3 + verbose = 3 run(path=root_dir, dep=dep_dir, ignore=args.ignore, files=args.files, verbose=verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) From a5850381bd96d27b4b03c551356fbd922176e8ec Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Jun 2017 10:13:48 -0600 Subject: [PATCH 216/325] fix declarations for older version of fortran CONTIGUOUS not defined for older versions --- data_util/fll_type.f90 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 0be32a0..4163950 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -110,13 +110,22 @@ MODULE FLL_TYPE_M PNEXT =>NULL(),& ! Pointer to next list PPREV =>NULL(),& ! Pointer to previous list PLINK =>NULL() ! Pointer to link target - + +#ifdef f2008 REAL(RSINGLE) , POINTER, CONTIGUOUS :: R1(:) =>NULL(), R2(:,:) => NULL() ! real arrays REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) => NULL() ! double arrays INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) => NULL() ! integer arrays INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) => NULL() ! long integer arrays CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S1(:) => NULL() ! 1D array of strings CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S2(:,:)=> NULL() ! 2D array of strings +#else + REAL(RSINGLE) , POINTER :: R1(:) =>NULL(), R2(:,:) => NULL() + REAL(RDOUBLE) , POINTER :: D1(:) =>NULL(), D2(:,:) => NULL() + INTEGER(SINT) , POINTER :: I1(:) =>NULL(), I2(:,:) => NULL() + INTEGER(LINT) , POINTER :: L1(:) =>NULL(), L2(:,:) => NULL() + CHARACTER(LEN=LSTRING_LENGTH), POINTER :: S1(:) => NULL() + CHARACTER(LEN=LSTRING_LENGTH), POINTER :: S2(:,:)=> NULL() +#endif REAL(RSINGLE) :: R0 ! real REAL(RDOUBLE) :: D0 ! double From a81b4580321fee8cfa7a3911bf55b2f21b168b26 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 2 Jun 2017 20:43:03 -0600 Subject: [PATCH 217/325] updated depend files --- data_util/depend.mk | 138 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 22 ++-- examples/Makefile | 1 - examples/Simple_data_operation/depend.mk | 6 +- mpi_util/depend.mk | 68 +++++------ 5 files changed, 117 insertions(+), 118 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 7188b5b..0c6ad7d 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,131 +1,131 @@ # This file is generated automatically. DO NOT EDIT! -fll_match_pattern.o : \ - fll_out.o \ - fll_type.o - -fll_cat.o : \ - fll_out.o \ - fll_type.o - -fll_read.o : \ - fll_mk.o \ +fll_duplicate.o : \ fll_out.o \ fll_mv.o \ fll_type.o \ - fll_funct_prt.o + fll_mk.o -fll_out.o : \ +fll_mk.o : \ + fll_out.o \ fll_type.o -fll_nnodes.o : \ +fll_mv.o : \ fll_out.o \ fll_type.o \ - fll_funct_prt.o - -fll_stich.o : \ - fll_out.o \ - fll_type.o + fll_rm.o \ + fll_stich.o -fll_locate.o : \ +fll_read.o : \ fll_out.o \ + fll_funct_prt.o \ + fll_mv.o \ fll_type.o \ - fll_funct_prt.o + fll_mk.o -fll_funct_prt.o : \ +fll_cat.o : \ fll_out.o \ fll_type.o -fll_mkdir.o : \ - fll_mk.o \ - fll_type.o - -fll_rm.o : \ - fll_stich.o \ +fll_stich.o : \ fll_out.o \ fll_type.o -fll_duplicate.o : \ - fll_mk.o \ +fll_read_ffa.o : \ fll_out.o \ + fll_funct_prt.o \ fll_mv.o \ - fll_type.o - -fll_mv.o : \ - fll_stich.o \ - fll_out.o \ fll_type.o \ - fll_rm.o + fll_mk.o -fll_write_ffa.o : \ - fll_out.o \ - fll_type.o - -fll_write.o : \ +fll_deattach.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_stich.o fll_mods.o : \ - fll_mv.o \ - fll_locate.o \ - fll_cat.o \ - fll_type.o \ fll_funct_prt.o \ - fll_stich.o \ + fll_read_ffa.o \ + fll_getnbytes.o \ + fll_duplicate.o \ + fll_cp.o \ + fll_getndata.o \ fll_rm.o \ + fll_locate.o \ + fll_type.o \ + fll_write.o \ fll_mk.o \ fll_nnodes.o \ - fll_write.o \ - fll_getnbytes.o \ - fll_duplicate.o \ - fll_out.o \ - fll_mkdir.o \ fll_deattach.o \ + fll_match_pattern.o \ fll_write_ffa.o \ - fll_getndata.o \ fll_read.o \ - fll_cp.o \ + fll_mv.o \ + fll_out.o \ + fll_mkdir.o \ fll_sweep.o \ - fll_read_ffa.o \ - fll_match_pattern.o + fll_cat.o \ + fll_stich.o + +fll_write_ffa.o : \ + fll_out.o \ + fll_type.o fll_getndata.o : \ + fll_locate.o \ fll_out.o \ - fll_type.o \ - fll_locate.o + fll_type.o fll_sweep.o : \ fll_out.o \ fll_type.o \ fll_match_pattern.o -fll_type.o : +fll_out.o : \ + fll_type.o -fll_getnbytes.o : \ +fll_funct_prt.o : \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mk.o \ +fll_write.o : \ fll_out.o \ - fll_mv.o \ + fll_type.o + +fll_mkdir.o : \ fll_type.o \ - fll_funct_prt.o + fll_mk.o -fll_mk.o : \ +fll_locate.o : \ fll_out.o \ + fll_funct_prt.o \ fll_type.o -fll_deattach.o : \ - fll_stich.o \ +fll_nnodes.o : \ + fll_out.o \ + fll_funct_prt.o \ + fll_type.o + +fll_match_pattern.o : \ fll_out.o \ fll_type.o +fll_type.o : + fll_cp.o : \ - fll_mv.o \ + fll_out.o \ fll_cat.o \ fll_type.o \ - fll_stich.o \ fll_duplicate.o \ - fll_out.o \ + fll_stich.o \ + fll_mv.o \ fll_rm.o + +fll_rm.o : \ + fll_out.o \ + fll_type.o \ + fll_stich.o + +fll_getnbytes.o : \ + fll_out.o \ + fll_type.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 920e8cf..85f58f4 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically. DO NOT EDIT! -Example_mpi-IO.o : \ - read_input.o \ - ../../mpi_util/fll_mpi_mods.o \ - create_data_set.o \ - save_individ_files.o \ - save_root_part_file.o \ +create_data_set.o : \ ../../data_util/fll_mods.o -save_individ_files.o : \ +save_root_part_file.o : \ ../../data_util/fll_mods.o -read_input.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ - ../../data_util/fll_mods.o +Example_mpi-IO.o : \ + ../../mpi_util/fll_mpi_mods.o \ + save_individ_files.o \ + create_data_set.o \ + ../../data_util/fll_mods.o \ + read_input.o \ + save_root_part_file.o -create_data_set.o : \ +read_input.o : \ ../../data_util/fll_mods.o diff --git a/examples/Makefile b/examples/Makefile index c7838a3..1c95533 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -43,7 +43,6 @@ SUBDIRS= \ Simple_data_operation \ Extra \ Example_MPI-IO\ - ExtractSurface\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= Example_MPI-IO diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 4b1a81c..0bbc702 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! -fll_test_subr.o : \ - ../../data_util/fll_mods.o - fll_test.o : \ ../../data_util/fll_mods.o \ fll_test_subr.o + +fll_test_subr.o : \ + ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 12a1747..ad10aec 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o -fll_mpi_mv.o : \ - ../data_util/fll_rm.o \ +fll_mpi_cp_all.o : \ ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - fll_mpi_cp.o + ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_out.o -fll_mpi_write_snm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp.o +fll_mpi_mv.o : \ + ../data_util/fll_type.o \ + fll_mpi_cp.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_out.o -fll_mpi_cp_all.o : \ - ../data_util/fll_mk.o \ +fll_mpi_cp.o : \ ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mv.o + ../data_util/fll_mk.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_out.o fll_mpi_mods.o : \ - fll_mpi_read.o \ - fll_mpi_write_snm.o \ - fll_mpi_mv.o \ - fll_mpi_cp.o \ - fll_mpi_sum.o \ + fll_mpi_cp_all.o \ + fll_mpi_proc_struct.o \ fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_write_snm.o \ fll_mpi_write_nm.o \ - fll_mpi_proc_struct.o \ - fll_mpi_cp_all.o + fll_mpi_cp.o \ + fll_mpi_read.o \ + fll_mpi_mv.o fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_write.o : \ - fll_mpi_sum.o \ - ../data_util/fll_mods.o +fll_mpi_write_snm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp.o -fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o +fll_mpi_read.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o -fll_mpi_cp.o : \ - ../data_util/fll_mk.o \ - ../data_util/fll_type.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mv.o +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o From ce8632841750d29f99392b4d04dce1e18bce83fc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 16 Jun 2017 11:55:21 -0600 Subject: [PATCH 218/325] fix locate bug --- data_util/fll_locate.f90 | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index e6e0be9..0244959 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -88,11 +88,14 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU RETURN END IF - - PCURR => PNODE%PCHILD - IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN - WRITE(*,*)' NODE NOT DIR NODE' - RETURN + IF(.NOT.RECURSE)THEN + PCURR => PNODE%PCHILD + IF(.NOT.ASSOCIATED(PNODE%PCHILD))THEN + WRITE(*,*)' NODE NOT DIR NODE' + RETURN + END IF + ELSE + PCURR => PNODE END IF LOCNUM = 1 @@ -102,7 +105,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - PFIND => FLL_LOCATE(PCHLD,NAME,LTYPE,DATADIM,1_LINT,RECURSE,FPAR) + PFIND => FLL_LOCATE(PCHLD,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN @@ -111,7 +114,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU ! ! LOOK FOR NODE ! - IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(PCURR%LNAME) == '*') .AND. & + IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(PCURR%LNAME) == '*') .AND. & (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN NDIM = PCURR%NDIM @@ -152,7 +155,8 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU END IF END IF - PCURR => PCURR%PNEXT + + PCURR => PCURR%PNEXT END DO ! @@ -160,8 +164,8 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU ! PFIND => NULL() FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) - CALL FLL_OUT('ALL',FPAR) +! WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) +! CALL FLL_OUT('ALL',FPAR) RETURN END FUNCTION FLL_LOCATE From 9b5ba56f06fc866839523a45cdfa60e3f20dfca7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 16 Jun 2017 11:58:38 -0600 Subject: [PATCH 219/325] add read record function --- data_util/depend.mk | 9 + data_util/fll_mods.f90 | 1 + data_util/fll_read.f90 | 11 +- data_util/fll_read_record.f90 | 213 +++++++++++++++++++++ data_util/fll_type.f90 | 2 +- examples/Example_MPI-IO/Example_mpi-IO.f90 | 3 +- examples/Makefile | 1 + examples/Read_Record/Makefile | 64 +++++++ examples/Read_Record/fll_read_record.f90 | 74 +++++++ examples/Read_Record/src_dir_path.mk | 2 + 10 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 data_util/fll_read_record.f90 create mode 100644 examples/Read_Record/Makefile create mode 100644 examples/Read_Record/fll_read_record.f90 create mode 100644 examples/Read_Record/src_dir_path.mk diff --git a/data_util/depend.mk b/data_util/depend.mk index e518aee..ca788cc 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -37,6 +37,14 @@ fll_sweep.o : \ fll_out.o \ fll_type.o +fll_read_record.o : \ + fll_out.o \ + fll_locate.o \ + fll_rm.o \ + fll_mk.o \ + fll_type.o \ + fll_read.o + fll_read.o : \ fll_mv.o \ fll_funct_prt.o \ @@ -100,6 +108,7 @@ fll_mods.o : \ fll_mkdir.o \ fll_cat.o \ fll_write.o \ + fll_read_record.o \ fll_write_ffa.o \ fll_getnbytes.o \ fll_mk.o \ diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index c5e3632..d957fe7 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -45,6 +45,7 @@ MODULE FLL_MODS_M USE FLL_MV_M USE FLL_NNODES_M USE FLL_READ_M + USE FLL_READ_RECORD_M USE FLL_READ_FFA_M USE FLL_RM_M USE FLL_STICH_M diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 71b86d1..4e49e45 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -220,9 +220,11 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) CHARACTER(LEN=TYPE_LENGTH) :: LTYPE INTEGER(LINT) :: NDIM, NSIZE,NNODES LOGICAL :: OK + INTEGER(LINT):: POSOLD ! ! READ HEADER ! + POSOLD = POS CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H) IF(.NOT.FPAR_H%SUCCESS)THEN @@ -246,8 +248,13 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) PNODE => NULL() RETURN END IF - - +! +! SAVE BYTE POSITION OF THE RECORD IN THE FILE +! + PNODE%FP = POSOLD +! +! IF DIR NODE, READ WHAT IS IN THERE +! IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN DO NNODES = 1,NDIM PNEW => READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 new file mode 100644 index 0000000..f9148d3 --- /dev/null +++ b/data_util/fll_read_record.f90 @@ -0,0 +1,213 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine FLL_READ_RECORD +! +! Date: 2017-06-16 +! +! +! +! +! Description: reads a file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_READ_RECORD_M +! +! Description: Contains functions reading record from FLL native format binary file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PNODE) +! +! Description: main function opening, reading and closing file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_RM_M + USE FLL_READ_M + USE FLL_OUT_M + USE FLL_MK_M + USE FLL_MV_M + USE FLL_LOCATE_M + USE FLL_CAT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! NAME In name of node +! NUMBER In position of node in list +! LTYPE In type of node - can be * +! DATADIM In dimensions of data the node should contain +! can be 0 - scalar, 1 -1D array, 2 -2D array +! if any other number specified (preferrable -1) - do not care about dimensions +! RECURSE In search recursively +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER(*) :: NAME + CHARACTER(*) :: LTYPE + INTEGER(LINT) :: NUMBER,DATADIM + LOGICAL :: RECURSE +! +! Local declarations +! + TYPE(DNODE), POINTER :: PLIST,PTMP + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS + CHARACTER :: SCAN_LOC + + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! USE ONLY BINARY FORMAT +! + PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y') + CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR) + + WRITE(*,*)'_++++++++++++++++++++++++++++++++++_______________',NAME,LTYPE,DATADIM,NUMBER + + PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR) + + IF(.NOT.ASSOCIATED(PTMP))THEN + CALL FLL_RM(PLIST, FPAR) + PNODE => NULL() + RETURN + END IF + + POS = PTMP%FP + + write(*,*)' Found record on position ', POS + write(*,*)' name of record is ',ptmp%lname +! +! CLEAN MEMORY +! + CALL FLL_RM(PTMP, FPAR) + CALL FLL_RM(PLIST, FPAR) +! +! OPEN FILE +! + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! DETERMINE RORMAT +! + FMT_LOC = 'B' + SCAN_LOC = 'N' +! +! OPEN THE FILE +! + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',IOSTAT=ISTAT) + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Read_record - error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! READ INITIAL NODE +! + PLIST => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) + IF(.NOT.ASSOCIATED(PLIST)) THEN + WRITE(FPAR%MESG,'(A,A)')' Read_record - error reading specified data set ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! MAKE A HEAD NODE +! + PNODE => FLL_MK('Record','DIR',0_LINT,0_LINT,FPAR) + OK = FLL_MV(PLIST, PNODE, FPAR) +! +! CLOSE FILE +! + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + END IF + + RETURN + + END FUNCTION FLL_READ_RECORD + +END MODULE FLL_READ_RECORD_M diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index 4163950..b202330 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -102,7 +102,7 @@ MODULE FLL_TYPE_M CHARACTER(LEN=TYPE_LENGTH) :: LTYPE = '' ! type of the list CHARACTER(LEN=TYPE_LENGTH) :: FTYPE = '' ! type of the list INTEGER(LINT) :: NDIM = 0, NSIZE = 0, NLINK = 0 - INTEGER(LINT) :: DATA_LENGTH = 0 + INTEGER(LINT) :: FP = 0 ! byte position in file when reading data set TYPE (DNODE), POINTER :: & PPAR =>NULL(),& ! Pointer to parent list diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index b4b4f89..513c1d5 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -88,8 +88,7 @@ PROGRAM EXAMPLE_MPI_IO ! ! create sample data se ! - NSIZE = 1000000 !+ 10000*SIN(2*3.145926*world_rank/nproc) -! write(*,*)nsize + NSIZE = 100000 !+ 10000*SIN(2*3.145926*world_rank/nproc) BYTESIZE = NSIZE*8*NPROC*5 diff --git a/examples/Makefile b/examples/Makefile index 93e79c8..71f9f4c 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -42,6 +42,7 @@ DEP_FILE=depend.mk SUBDIRS= \ Simple_data_operation \ Example_MPI-IO\ + Read_Record\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= Example_MPI-IO diff --git a/examples/Read_Record/Makefile b/examples/Read_Record/Makefile new file mode 100644 index 0000000..17674c6 --- /dev/null +++ b/examples/Read_Record/Makefile @@ -0,0 +1,64 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_read_reacord + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=depend.mk + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +-include $(srcdir)/$(DEP_FILE) + diff --git a/examples/Read_Record/fll_read_record.f90 b/examples/Read_Record/fll_read_record.f90 new file mode 100644 index 0000000..6ccc4e0 --- /dev/null +++ b/examples/Read_Record/fll_read_record.f90 @@ -0,0 +1,74 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2017-06-15 +! +! +! +! +! Description: +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM FLL_TEST + + USE FLL_MODS_M + IMPLICIT NONE +! +! SUBROUTINE MOVES NODE +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE + TYPE(DNODE), POINTER :: PNODE,ptmp + TYPE(FUNC_DATA_SET) :: FPAR +! +! reading record +! + WRITE(*,*)' READING RECORD FROM THE FILE' + PNODE => FLL_READ_RECORD('Mesh.fll',8,'element_group','*',-1_LINT,3_LINT,.TRUE.,FPAR) + + WRITE(*,*)'WRITING RECORD +++++++++++++++++++++' + + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR) + WRITE(*,*) + + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(*,*)' DID NOT FIND RECORD' + STOP + END IF + + CALL FLL_RM(PNODE,FPAR) + +END PROGRAM diff --git a/examples/Read_Record/src_dir_path.mk b/examples/Read_Record/src_dir_path.mk new file mode 100644 index 0000000..6e8d416 --- /dev/null +++ b/examples/Read_Record/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/examples/Read_Record + From a5f95d6b811dc468bd14adb3f73f83307204009d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 16 Jun 2017 12:01:42 -0600 Subject: [PATCH 220/325] cleanup --- data_util/fll_read_record.f90 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index f9148d3..94f5389 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -132,8 +132,6 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RES PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y') CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR) - WRITE(*,*)'_++++++++++++++++++++++++++++++++++_______________',NAME,LTYPE,DATADIM,NUMBER - PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR) IF(.NOT.ASSOCIATED(PTMP))THEN @@ -143,9 +141,6 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RES END IF POS = PTMP%FP - - write(*,*)' Found record on position ', POS - write(*,*)' name of record is ',ptmp%lname ! ! CLEAN MEMORY ! From 50e4b50c85b9122269df85a587fed3c10b7e3ea8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 19 Jun 2017 09:30:24 -0600 Subject: [PATCH 221/325] add scan file function --- data_util/depend.mk | 160 +++++++++++++++++++----------------- data_util/fll_mods.f90 | 1 + data_util/fll_scan_file.f90 | 88 ++++++++++++++++++++ 3 files changed, 172 insertions(+), 77 deletions(-) create mode 100644 data_util/fll_scan_file.f90 diff --git a/data_util/depend.mk b/data_util/depend.mk index 9fb0ed4..93509b9 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,142 +1,148 @@ # This file is generated automatically. DO NOT EDIT! -fll_mods.o : \ - fll_nnodes.o \ - fll_mv.o \ - fll_match_pattern.o \ - fll_rm.o \ - fll_read_record.o \ - fll_read_ffa.o \ +fll_deattach.o : \ fll_stich.o \ - fll_getndata.o \ - fll_read.o \ - fll_write_ffa.o \ - fll_getnbytes.o \ + fll_out.o \ + fll_type.o + +fll_nnodes.o : \ fll_funct_prt.o \ fll_out.o \ - fll_type.o \ - fll_duplicate.o \ - fll_deattach.o \ - fll_cp.o \ - fll_mkdir.o \ - fll_mk.o \ - fll_sweep.o \ - fll_write.o \ - fll_cat.o \ - fll_locate.o + fll_type.o -fll_write_ffa.o : \ +fll_getnbytes.o : \ fll_out.o \ fll_type.o fll_mkdir.o : \ - fll_type.o \ - fll_mk.o + fll_mk.o \ + fll_type.o -fll_mv.o : \ +fll_cat.o : \ fll_out.o \ - fll_type.o \ - fll_rm.o \ - fll_stich.o + fll_type.o -fll_rm.o : \ +fll_type.o : + +fll_stich.o : \ fll_out.o \ - fll_type.o \ - fll_stich.o + fll_type.o -fll_write.o : \ +fll_funct_prt.o : \ fll_out.o \ fll_type.o -fll_read.o : \ +fll_sweep.o : \ + fll_match_pattern.o \ fll_out.o \ - fll_type.o \ - fll_mk.o \ - fll_mv.o \ - fll_funct_prt.o + fll_type.o -fll_deattach.o : \ +fll_read_record.o : \ + fll_mv.o \ + fll_cat.o \ fll_out.o \ + fll_locate.o \ + fll_rm.o \ + fll_mk.o \ fll_type.o \ - fll_stich.o + fll_read.o -fll_duplicate.o : \ +fll_read.o : \ fll_mv.o \ - fll_type.o \ + fll_funct_prt.o \ fll_mk.o \ - fll_out.o + fll_out.o \ + fll_type.o fll_cp.o : \ - fll_duplicate.o \ - fll_stich.o \ fll_mv.o \ - fll_rm.o \ fll_cat.o \ fll_out.o \ + fll_duplicate.o \ + fll_rm.o \ + fll_stich.o \ fll_type.o -fll_match_pattern.o : \ +fll_scan_file.o : \ + fll_read.o \ fll_out.o \ fll_type.o -fll_cat.o : \ +fll_mv.o : \ + fll_stich.o \ fll_out.o \ + fll_rm.o \ fll_type.o -fll_funct_prt.o : \ +fll_write.o : \ fll_out.o \ fll_type.o -fll_out.o : \ +fll_getndata.o : \ + fll_locate.o \ + fll_out.o \ fll_type.o -fll_nnodes.o : \ +fll_match_pattern.o : \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o - -fll_type.o : + fll_type.o -fll_mk.o : \ +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o fll_locate.o : \ + fll_funct_prt.o \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o -fll_getndata.o : \ +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ - fll_type.o \ - fll_locate.o + fll_type.o -fll_read_ffa.o : \ +fll_mods.o : \ + fll_mv.o \ fll_out.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_match_pattern.o \ fll_type.o \ + fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ + fll_read_record.o \ + fll_write_ffa.o \ + fll_getnbytes.o \ fll_mk.o \ - fll_mv.o \ - fll_funct_prt.o + fll_deattach.o \ + fll_scan_file.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o -fll_sweep.o : \ +fll_rm.o : \ + fll_stich.o \ fll_out.o \ - fll_type.o \ - fll_match_pattern.o + fll_type.o -fll_stich.o : \ +fll_mk.o : \ fll_out.o \ fll_type.o -fll_read_record.o : \ - fll_mv.o \ - fll_read.o \ - fll_rm.o \ - fll_cat.o \ - fll_locate.o \ - fll_out.o \ - fll_type.o \ - fll_mk.o +fll_out.o : \ + fll_type.o -fll_getnbytes.o : \ +fll_write_ffa.o : \ fll_out.o \ fll_type.o diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index d957fe7..486e607 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -57,5 +57,6 @@ MODULE FLL_MODS_M USE FLL_OUT_M USE FLL_MATCH_PATTERN_M USE FLL_GETNBYTES_M + USE FLL_SCAN_FILE_M END MODULE FLL_MODS_M diff --git a/data_util/fll_scan_file.f90 b/data_util/fll_scan_file.f90 new file mode 100644 index 0000000..9938314 --- /dev/null +++ b/data_util/fll_scan_file.f90 @@ -0,0 +1,88 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! Subroutine FLL_SCAN_FILE +! +! +MODULE FLL_SCAN_FILE_M +! +! Description: Contains function fll_cp +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR) RESULT(PNODE) +! +! Description: Scan file, returns fll list with data names in file and their +! position in file in bytes +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + USE FLL_READ_M + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out pointer to fll list with data in names in file +! IOUNIR In pointer which is to be copied +! FILENAME In Name of file +! FMT In Format of file +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER(LEN=FILE_NAME_LENGTH) :: FILENAME + CHARACTER :: FMT +! +! Local types +! + LOGICAL :: OK + + INQUIRE (FILE=TRIM(FILENAME), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILENAME) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! GET FILE STRUCTURE +! + PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y') + + RETURN + + END FUNCTION FLL_SCAN_FILE + +END MODULE FLL_SCAN_FILE_M From a8719ff84d441e901f8a3f5c2376ceb2b51e265b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 19 Jun 2017 10:15:54 -0600 Subject: [PATCH 222/325] update fll_read_record fll_read_record can use already existing list from fll_file_scan function. If this points in NULL, fll_read_record will create the list and remove it too --- data_util/fll_read_record.f90 | 42 ++++++++++++++++-------- examples/Read_Record/fll_read_record.f90 | 8 +++-- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index 94f5389..aab72a3 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_RECORD_M ! CONTAINS - FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PNODE) + FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -114,23 +114,32 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RES TYPE(DNODE), POINTER :: PLIST,PTMP LOGICAL :: OK CHARACTER :: FMT_LOC - INTEGER :: ISTAT + INTEGER :: ISTAT,PLISTOK INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC - INQUIRE (FILE=TRIM(FILE), EXIST=OK) - IF(.NOT.OK) THEN - WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) - FPAR%SUCCESS = .FALSE. - PNODE => NULL() - RETURN - END IF + PLISTOK = 0 + + IF(.NOT.ASSOCIATED(PLIST))THEN + PLISTOK = 1 +! +! IF LIST OF ITEMS NOT PROVIDED THEN +! + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF ! ! USE ONLY BINARY FORMAT ! - PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y') - CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR) + PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y') + CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR) +! + END IF PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR) @@ -144,8 +153,13 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RES ! ! CLEAN MEMORY ! - CALL FLL_RM(PTMP, FPAR) - CALL FLL_RM(PLIST, FPAR) +! CALL FLL_RM(PTMP, FPAR) + IF(PLISTOK == 0)THEN +! +! LIST WAS CREATED IN THIS FUNCTION, REMOVE IT +! + CALL FLL_RM(PLIST, FPAR) + END IF ! ! OPEN FILE ! diff --git a/examples/Read_Record/fll_read_record.f90 b/examples/Read_Record/fll_read_record.f90 index 6ccc4e0..b7842ae 100644 --- a/examples/Read_Record/fll_read_record.f90 +++ b/examples/Read_Record/fll_read_record.f90 @@ -51,13 +51,17 @@ PROGRAM FLL_TEST ! SUBROUTINE MOVES NODE ! CHARACTER(LEN=FILE_NAME_LENGTH) FILE - TYPE(DNODE), POINTER :: PNODE,ptmp + TYPE(DNODE), POINTER :: PNODE,PTMP TYPE(FUNC_DATA_SET) :: FPAR ! ! reading record ! WRITE(*,*)' READING RECORD FROM THE FILE' - PNODE => FLL_READ_RECORD('Mesh.fll',8,'element_group','*',-1_LINT,3_LINT,.TRUE.,FPAR) + NULLIFY(PTMP) +! +! PTMP IS NULLIFIED, FUNCTION WILL READ THE CREATE IT +! + PNODE => FLL_READ_RECORD('Mesh.fll',8,PTMP,'element_group','*',-1_LINT,3_LINT,.TRUE.,FPAR) WRITE(*,*)'WRITING RECORD +++++++++++++++++++++' From a27cc1c7536d0f4bb09dd459d84b1e6f6308c50d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 20 Jun 2017 08:47:41 -0600 Subject: [PATCH 223/325] use standard function to get size of data set --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 513c1d5..11e5478 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -72,7 +72,7 @@ PROGRAM EXAMPLE_MPI_IO TYPE(DNODE), POINTER ::PIOSTR,PSUBPROC,PIO - REAL :: CPUE,CPUS,CPUAVE,CPTIMERMS(100),BYTESIZE,BYTESPEED + REAL :: CPUE,CPUS,CPUAVE,CPTIMERMS(100),BYTESPEED INTEGER :: VALS(8) INTEGER :: NCYC @@ -90,8 +90,6 @@ PROGRAM EXAMPLE_MPI_IO ! NSIZE = 100000 !+ 10000*SIN(2*3.145926*world_rank/nproc) - BYTESIZE = NSIZE*8*NPROC*5 - CALL CREATE_DATA_SET(PDATA_SET,NSIZE, WORLD_RANK) ! IF(WORLD_RANK == 0) OK = FLL_WRITE_FFA(PDATA_SET,'test.bcs',10,'B',FPAR) ! PDATA_SET => FLL_READ_FFA('test.bcase',8,'B',FPAR) @@ -135,7 +133,7 @@ PROGRAM EXAMPLE_MPI_IO CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 END DO write(*,*)' >>>>>>>>>>>>> average time of saving (N-1 model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) - BYTESPEED = BYTESIZE/CPUAVE/1048576 + BYTESPEED = BYTESN/CPUAVE/1048576 write(*,*)' >>>>>>>>>>>>> average speed of saving (N-1 model) is ',& BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) write(*,*) @@ -205,7 +203,7 @@ PROGRAM EXAMPLE_MPI_IO CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 END DO write(*,*)' >>>>>>>>>>>>> average time of saving (S-N-M model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) - BYTESPEED = BYTESIZE/CPUAVE/1048576 + BYTESPEED = BYTESN/CPUAVE/1048576 write(*,*)' >>>>>>>>>>>>> average speed of saving (S-N-M model) is ',& BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) write(*,*) @@ -241,7 +239,7 @@ PROGRAM EXAMPLE_MPI_IO CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 END DO write(*,*)' >>>>>>>>>>>>> average time of saving (N-M model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) - BYTESPEED = BYTESIZE/CPUAVE/1048576 + BYTESPEED = BYTESN/CPUAVE/1048576 write(*,*)' >>>>>>>>>>>>> average speed of saving (N-M model) is ',& BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) write(*,*) @@ -292,7 +290,7 @@ PROGRAM EXAMPLE_MPI_IO CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 END DO write(*,*)' >>>>>>>>>>>>> average time of saving (N-N model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) - BYTESPEED = BYTESIZE/CPUAVE/1048576 + BYTESPEED = BYTESN/CPUAVE/1048576 write(*,*)' >>>>>>>>>>>>> average speed of saving (N-N model) is ',& BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) write(*,*) @@ -317,7 +315,7 @@ PROGRAM EXAMPLE_MPI_IO CPTIMERMS(J) = (CPTIMERMS(J)-CPUAVE)**2 END DO write(*,*)' >>>>>>>>>>>>> average time of saving (1-1 model) is ',CPUAVE, SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) - BYTESPEED = BYTESIZE/CPUAVE/1048576 + BYTESPEED = BYTESN/CPUAVE/1048576 write(*,*)' >>>>>>>>>>>>> average speed of saving (1-1 model) is ',& BYTESPEED, BYTESPEED/CPUAVE*SQRT(SUM(CPTIMERMS(1:NCYC)))/FLOAT(NCYC) write(*,*) From 78c9a299b79c01e7ee357c55eb7eec5123a39dea Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 20 Jun 2017 11:11:47 -0600 Subject: [PATCH 224/325] replace partition with process --- examples/Example_MPI-IO/Example_mpi-IO.f90 | 16 ++++----- examples/Example_MPI-IO/create_data_set.f90 | 8 ++--- examples/Example_MPI-IO/read_input.f90 | 2 +- mpi_util/fll_mpi_cp.f90 | 22 ++++++------ mpi_util/fll_mpi_cp_all.f90 | 16 ++++----- mpi_util/fll_mpi_mv.f90 | 8 ++--- mpi_util/fll_mpi_proc_struct.f90 | 24 ++++++------- mpi_util/fll_mpi_read.f90 | 30 ++++++++-------- mpi_util/fll_mpi_write.f90 | 38 ++++++++++----------- mpi_util/fll_mpi_write_nm.f90 | 2 +- mpi_util/fll_mpi_write_snm.f90 | 10 +++--- 11 files changed, 88 insertions(+), 88 deletions(-) diff --git a/examples/Example_MPI-IO/Example_mpi-IO.f90 b/examples/Example_MPI-IO/Example_mpi-IO.f90 index 11e5478..bcdc2b3 100644 --- a/examples/Example_MPI-IO/Example_mpi-IO.f90 +++ b/examples/Example_MPI-IO/Example_mpi-IO.f90 @@ -98,7 +98,7 @@ PROGRAM EXAMPLE_MPI_IO BYTESN = FLL_GETNBYTES(PDATA_SET,FPAR) IF(WORLD_RANK == 0) WRITE(*,*)' Partitions created data set size of ', WORLD_RANK,BYTESN ! -! save to one file, all partitions at the same time +! save to one file, all processes at the same time ! IF(WORLD_RANK == 0)THEN WRITE(*,*)'==============================================' @@ -210,7 +210,7 @@ PROGRAM EXAMPLE_MPI_IO END IF ! -! save to 2 separate files all partitions at the same time +! save to 2 separate files all processes at the same time ! CPUAVE = 0 DO J=1,NCYC @@ -226,7 +226,7 @@ PROGRAM EXAMPLE_MPI_IO IF(WORLD_RANK == 0)THEN CALL DATE_AND_TIME(VALUES=VALS) CPUE = REAL(VALS(5)*3600+VALS(6)*60+VALS(7))+REAL(VALS(8))*0.001 -! WRITE(*,*)"Time writing paralell to partitions file (N-M model):",CPUE-CPUS +! WRITE(*,*)"Time writing paralell to processes file (N-M model):",CPUE-CPUS CPTIMERMS(J) = CPUE-CPUS CPUAVE = CPUAVE + CPUE-CPUS END IF @@ -321,16 +321,16 @@ PROGRAM EXAMPLE_MPI_IO write(*,*) END IF ! -! Copy FLL_MPI_STRUCT date set which now exists on root partition only -! to all other partitions +! Copy FLL_MPI_STRUCT date set which now exists on root process only +! to all other processes ! Upon return, the function will return pointer to newly allocated data -! for all other partition then root partition -! On root partition, the PNEW pointer is pointing on FLL_MPI_STRUCT +! for all other process then root process +! On root process, the PNEW pointer is pointing on FLL_MPI_STRUCT ! ! PNEW => FLL_MPI_CP_ALL(FLL_MPI_STRUCT,MPI_COMM_WORLD,0,FPAR) ! IF(WORLD_RANK /= 0)THEN ! -! make FLL_MPI_STRUCT point to PNEW so that we cane use the same names for all partitions +! make FLL_MPI_STRUCT point to PNEW so that we cane use the same names for all processes ! ! FLL_MPI_STRUCT => PNEW ! END IF diff --git a/examples/Example_MPI-IO/create_data_set.f90 b/examples/Example_MPI-IO/create_data_set.f90 index 0d52dcf..e2f56a1 100644 --- a/examples/Example_MPI-IO/create_data_set.f90 +++ b/examples/Example_MPI-IO/create_data_set.f90 @@ -27,7 +27,7 @@ ! ! ! Description: creates mpi struct defining how many files will be -! saved and which partitions will be saving to each +! saved and which processes will be saving to each ! file ! ! @@ -67,11 +67,11 @@ SUBROUTINE CREATE_DATA_SET(PNODE,NNODES,RANK) ! ! MAKE STRUCTURE ! - PNODE => FLL_MKDIR('partition',FPAR) + PNODE => FLL_MKDIR('process',FPAR) ! -! add number of partition +! add number of process ! - PTMP => FLL_MK('part_number','L', 1_LINT, 1_LINT, FPAR) + PTMP => FLL_MK('process_number','L', 1_LINT, 1_LINT, FPAR) PTMP%L0 = RANK+1 IF(.NOT.FLL_MV(PTMP, PNODE, FPAR))STOP' ERROR MOVING NODE' ! diff --git a/examples/Example_MPI-IO/read_input.f90 b/examples/Example_MPI-IO/read_input.f90 index cd42108..d13782d 100644 --- a/examples/Example_MPI-IO/read_input.f90 +++ b/examples/Example_MPI-IO/read_input.f90 @@ -27,7 +27,7 @@ ! ! ! Description: creates mpi struct defining how many files will be -! saved and which partitions will be saving to each +! saved and which processes will be saving to each ! file ! ! diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index 7ec49ca..7afad5e 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -63,8 +63,8 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! PNODE In node to duplicate ! PNEW Out duplicate node ! COMMUNICATOR In MPI communicatior -! SENDPART In Sending partition -! RECPART In Receiving partition +! SENDPART In Sending process +! RECPART In Receiving process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -89,8 +89,8 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! FPAR%SUCCESS = .FALSE. ! -! If not sending partition, nullify pointer -! owherwise check that sending partition does not send NULL pointer and +! If not sending process, nullify pointer +! owherwise check that sending process does not send NULL pointer and ! associate returning pointer with sending ! CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) @@ -117,7 +117,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ELSE ! -! Sending partition +! Sending process ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' @@ -168,8 +168,8 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR ! Arguments description ! Name In/Out Function ! PNODE In pointer which is to be duplicated -! SENDPART In sending partition rank -! RECPART In receiving partition rank +! SENDPART In sending process rank +! RECPART In receiving process rank ! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! @@ -236,7 +236,7 @@ RECURSIVE SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! Name In/Out Function ! PNODE In pointer which is to be duplicated ! PNEW In recevied pointer -! SENDPART In sending partition rank +! SENDPART In sending process rank ! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! @@ -292,8 +292,8 @@ SUBROUTINE NODE_SEND(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) ! Name In/Out Function ! PNODE In pointer data which is to be duplicated ! COMMUNICATOR In communicator -! SENDPART In sending partition -! RECPART In receiving partition +! SENDPART In sending process +! RECPART In receiving process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -416,7 +416,7 @@ FUNCTION NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) ! Name In/Out Function ! PNODE In pointer data which is to be duplicated ! COMMUNICATOR In communicator -! SENDPART In sending partition +! SENDPART In sending process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index 03a07a4..3e612f5 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -63,7 +63,7 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! PNODE In node to duplicate ! PNEW Out duplicate node ! COMMUNICATOR In MPI communicatior -! SENDPART In Sending partition +! SENDPART In Sending process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -88,8 +88,8 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! FPAR%SUCCESS = .FALSE. ! -! If not sending partition, nullify pointer -! owherwise check that sending partition does not send NULL pointer and +! If not sending process, nullify pointer +! owherwise check that sending process does not send NULL pointer and ! associate returning pointer with sending ! CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) @@ -116,7 +116,7 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ELSE ! -! Sending partition +! Sending process ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' @@ -167,7 +167,7 @@ RECURSIVE SUBROUTINE FLL_SEND_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! Arguments description ! Name In/Out Function ! PNODE In pointer which is to be duplicated -! SENDPART In sending partition rank +! SENDPART In sending process rank ! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! @@ -234,7 +234,7 @@ RECURSIVE SUBROUTINE FLL_RECEIVE_RECURSIVE(PNODE,COMMUNICATOR,SENDPART,FPAR) ! Name In/Out Function ! PNODE In pointer which is to be duplicated ! PNEW In recevied pointer -! SENDPART In sending partition rank +! SENDPART In sending process rank ! COMMUNICATOR In Commuticator ! FPAR In/Out structure containing function specific data ! @@ -290,7 +290,7 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) ! Name In/Out Function ! PNODE In pointer data which is to be duplicated ! COMMUNICATOR In communicator -! SENDPART In sending partition +! SENDPART In sending process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -420,7 +420,7 @@ FUNCTION BROADCAST_NODE_RECEIVE(COMMUNICATOR,SENDPART,FPAR) RESULT(PNODE) ! Name In/Out Function ! PNODE In pointer data which is to be duplicated ! COMMUNICATOR In communicator -! SENDPART In sending partition +! SENDPART In sending process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration diff --git a/mpi_util/fll_mpi_mv.f90 b/mpi_util/fll_mpi_mv.f90 index 7a25e2b..5cfe063 100644 --- a/mpi_util/fll_mpi_mv.f90 +++ b/mpi_util/fll_mpi_mv.f90 @@ -63,8 +63,8 @@ FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! PNODE In node to duplicate ! PNEW Out duplicate node ! COMMUNICATOR In MPI communicatior -! SENDPART In Sending partition -! RECPART In Receiving partition +! SENDPART In Sending process +! RECPART In Receiving process ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -89,8 +89,8 @@ FUNCTION FLL_MPI_MV(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! FPAR%SUCCESS = .FALSE. ! -! If not sending partition, nullify pointer -! owherwise check that sending partition does not send NULL pointer and +! If not sending process, nullify pointer +! owherwise check that sending process does not send NULL pointer and ! associate returning pointer with sending ! CALL MPI_Comm_rank ( COMMUNICATOR, RANK, IERR ) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 5cb787c..4dd0194 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -212,10 +212,10 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! ! group processes ! there will be NFILES group -! each group would have max NPROC/NFILES partitions and the increment +! each group would have max NPROC/NFILES processes and the increment ! between them is NFILES ! -! in this way, each file should be associated to one partition from each node +! in this way, each file should be associated to one process from each node ! NSTEP = NPROC/NFILES @@ -229,7 +229,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:230 ' ! -! loop over number of separate files, define which partition is going to be +! loop over number of separate files, define which process is going to be ! saving in what file (defined by EVEN_RANK array ! DO J=1,NFILES @@ -268,15 +268,15 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) ! ! group processes ! there will be NFILES group -! each group would have max NPROC/NFILES partitions and the increment +! each group would have max NPROC/NFILES processes and the increment ! between them is NFILES ! -! in this way, each file should be associated to one partition from each node +! in this way, each file should be associated to one process from each node ! COUNT = 1 DO I=J,NPROC,NFILES ! -! fill partition numbers +! fill process numbers ! PTMP%L1(COUNT) = I ! @@ -424,10 +424,10 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) ! ! group processes ! there will be NFILES group -! each group would have max NPROC/NFILES partitions and the increment +! each group would have max NPROC/NFILES processes and the increment ! between them is NFILES ! -! in this way, each file should be associated to one partition from each node +! in this way, each file should be associated to one process from each node ! NSTEP = NPROC/NFILES @@ -441,7 +441,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:442 ' ! -! loop over number of separate files, define which partition is going to be +! loop over number of separate files, define which process is going to be ! saving in what file (defined by EVEN_RANK array ! DO J=1,NFILES @@ -480,15 +480,15 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) ! ! group processes ! there will be NFILES group -! each group would have max NPROC/NFILES partitions and the increment +! each group would have max NPROC/NFILES processes and the increment ! between them is NFILES ! -! in this way, each file should be associated to one partition from each node +! in this way, each file should be associated to one process from each node ! COUNT = 1 DO I=1+(J-1)*NSTEP,J*NSTEP ! -! fill partition numbers +! fill process numbers ! PTMP%L1(COUNT) = I ! diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 197363f..413533d 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -47,29 +47,29 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R ! ! the main directory is a partitioned_file ! followed by displacement which is a byte position of each partiton in the file -! each data on patition is in subset partition +! each data on patition is in subset process ! -! this is an example of a file with four partitions +! this is an example of a file with four processes ! ! -DIR- 5\ partitioned_file ! -L- 5x1 displacements 1 113 40000301 -! -DIR- 4\ partition -! -L- 1x1 part_number 1 +! -DIR- 4\ process +! -L- 1x1 process_number 1 ! -D- 1000000x1 pressure ! -D- 1000000x1 density ! -D- 1000000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 2 +! -DIR- 4\ process +! -L- 1x1 process_number 2 ! -D- 1100000x1 pressure ! -D- 1100000x1 density ! -D- 1100000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 3 +! -DIR- 4\ process +! -L- 1x1 process_number 3 ! -D- 1200000x1 pressure ! -D- 1200000x1 density ! -D- 1200000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 4 +! -DIR- 4\ process +! -L- 1x1 process_number 4 ! -D- 1300000x1 pressure ! -D- 1300000x1 density ! -D- 1300000x3 velocity @@ -133,19 +133,19 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R CALL MPI_BARRIER(COMMUNICATOR, IERR) ! -! If root processor, read initial set and -! get positions for each subset, ie. each partition solution +! If root process, read initial set and +! get positions for each subset, ie. each process solution ! IF(RANK == ROOT_RANK)THEN PTMP => FLL_RPART_FILE_HEADER(IOUNIT, FPAR) END IF ! -! distribute that info to all partitions +! distribute that info to all processes ! PTMP1 => FLL_MPI_CP_ALL(PTMP,COMMUNICATOR,ROOT_RANK,FPAR) IF(RANK /= ROOT_RANK) PTMP => PTMP1 ! -! get position in a file for each partition +! get position in a file for each process ! DISPL => PTMP%L1 ! @@ -181,7 +181,7 @@ END FUNCTION FLL_MPI_READ FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) ! -! Description: Reads header of partitione file containing +! Description: Reads header of partitioned file containing ! positions of each record in the file ! ! diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index 9813012..ee3fab6 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -47,29 +47,29 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! ! the main directory is a partitioned_file ! followed by displacement which is a byte position of each partiton in the file -! each data on patition is in subset partition +! each data on patition is in subset process ! -! this is an example of a file with four partitions +! this is an example of a file with four processes ! ! -DIR- 5\ partitioned_file ! -L- 5x1 displacements 1 113 40000301 -! -DIR- 4\ partition -! -L- 1x1 part_number 1 +! -DIR- 4\ process +! -L- 1x1 process_number 1 ! -D- 1000000x1 pressure ! -D- 1000000x1 density ! -D- 1000000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 2 +! -DIR- 4\ process +! -L- 1x1 process_number 2 ! -D- 1100000x1 pressure ! -D- 1100000x1 density ! -D- 1100000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 3 +! -DIR- 4\ process +! -L- 1x1 process_number 3 ! -D- 1200000x1 pressure ! -D- 1200000x1 density ! -D- 1200000x3 velocity -! -DIR- 4\ partition -! -L- 1x1 part_number 4 +! -DIR- 4\ process +! -L- 1x1 process_number 4 ! -D- 1300000x1 pressure ! -D- 1300000x1 density ! -D- 1300000x3 velocity @@ -142,7 +142,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! Get position and length of each data set ! there will be totally n+1 subset, ! subset #1 is a headet of the file -! subsets #2: are actual data from each partition +! subsets #2: are actual data from each process ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:148 ' @@ -161,13 +161,13 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, POS(1) = 36 + 36 + (NPROC+1)*8 END IF ! -! ... and distribute length of each subset to all partitions +! ... and distribute length of each subset to all processes ! CALL FLL_MPI_SUM(COMMUNICATOR, 1_LINT+NPROC,L1=POS) ! ! Calculate displacement, ie where each subset starts ! - PART_NUM = FLL_GETNDATA_L0(PNODE, 'part_number',1_LINT, FPAR) + PART_NUM = FLL_GETNDATA_L0(PNODE, 'process_number',1_LINT, FPAR) ! ! the first subset will start always at position 1 ! ie. beginning of the file @@ -179,8 +179,8 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, LOC_DISPL = LOC_DISPL + POS(I-1) END DO ! -! define subset position for all other partitions -! and propagate this to all partitions +! define subset position for all other processes +! and propagate this to all processes ! DISPL(RANK+2) = LOC_DISPL CALL FLL_MPI_SUM(COMMUNICATOR, NPROC+1_LINT,L1=DISPL) @@ -228,7 +228,7 @@ END FUNCTION FLL_MPI_WRITE FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! -! Description: write header for partitioned file +! Description: write header for processed file ! ! ! History: @@ -247,7 +247,7 @@ FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! Arguments description ! Name In/Out Function ! NPROC In Number of processes -! DISPL In Length of each partition record +! DISPL In Length of each process record ! IOUNIT In Number of unit ! FPAR In/Out structure containing function specific data ! OK Out Success or fail @@ -262,10 +262,10 @@ FUNCTION FLL_PART_FILE_HEADER(IOUNIT, NPROC, DISPL, FPAR) RESULT(POS) ! TYPE(DNODE), POINTER :: PTMP ! -! make a head node and say it contains number of partitions + one subsets +! make a head node and say it contains number of processes + one subsets ! PTMP => FLL_MKDIR('partitioned_file', FPAR) - PTMP%NDIM = NPROC + 1 ! Number of partitioned solutions and displacement vector + PTMP%NDIM = NPROC + 1 ! Number of processed solutions and displacement vector ! ! save it ! diff --git a/mpi_util/fll_mpi_write_nm.f90 b/mpi_util/fll_mpi_write_nm.f90 index 5ab4183..fc366b9 100644 --- a/mpi_util/fll_mpi_write_nm.f90 +++ b/mpi_util/fll_mpi_write_nm.f90 @@ -57,7 +57,7 @@ FUNCTION FLL_MPI_WRITE_NM(PNODE,PMPI,FPAR) RESULT(OK) ! FILE In Name of file ! PNODE In Node to be written ! IOUNIT In Number of unit -! FILE_TAB In Specifies which partition saves to which file +! FILE_TAB In Specifies which process saves to which file ! FPAR In/Out structure containing function specific data ! OK Out Success or fail ! diff --git a/mpi_util/fll_mpi_write_snm.f90 b/mpi_util/fll_mpi_write_snm.f90 index b63fa18..763ed47 100644 --- a/mpi_util/fll_mpi_write_snm.f90 +++ b/mpi_util/fll_mpi_write_snm.f90 @@ -58,7 +58,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) ! FILE In Name of file ! PNODE In Node to be written ! IOUNIT In Number of unit -! FILE_TAB In Specifies which partition saves to which file +! FILE_TAB In Specifies which process saves to which file ! FPAR In/Out structure containing function specific data ! OK Out Success or fail ! @@ -111,7 +111,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) PROC_NUM => FLL_GETNDATA_L1(PIO,'proc', 1_LINT, FPAR) NPROC = SIZE(PROC_NUM, DIM = 1, KIND = LINT) ! -! if first partition in group get data from other partitions and +! if first process in group get data from other processes and ! save the file ! IF(LOCRANK == 0)THEN @@ -119,7 +119,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) ! Create header for the file ! PMAIN => FLL_MKDIR('partitioned_file', FPAR) - PMAIN%NDIM = NPROC + 1 ! Number of partitioned solutions and displacement vector + PMAIN%NDIM = NPROC + 1 ! Number of processed solutions and displacement vector PDISPL => FLL_MK('displacements','L', NPROC+1_LINT, 1_LINT, FPAR) OK = FLL_MV(PDISPL, PMAIN, FPAR) ! @@ -142,7 +142,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) POS(1) = 36 + 36 + (NPROC+1)*8 POS(2) = FLL_GETNBYTES(PNODE,FPAR) ! -! get solutions from associated partitions and add it to the main tree +! get solutions from associated processes and add it to the main tree ! DO J=2,NPROC TMPINT = J-1 @@ -175,7 +175,7 @@ FUNCTION FLL_MPI_WRITE_SNM(PNODE,PMPI,FPAR) RESULT(OK) ELSE ! -! Other then group root partition, copy data set to root partition +! Other then group root process, copy data set to root processes ! PTMP => FLL_MPI_CP(PNODE,COMM,LOCRANK,0,FPAR) From 3f06cb83a4278d2cc82dd15263c16183f2eca3f9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 20 Jun 2017 11:15:41 -0600 Subject: [PATCH 225/325] update documentation --- "fll\342\200\223FortranLinkedListLibrary.pdf" | Bin 442549 -> 195312 bytes ...\342\200\223FortranLinkedListLibrary.pptx" | Bin 83674 -> 97713 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git "a/fll\342\200\223FortranLinkedListLibrary.pdf" "b/fll\342\200\223FortranLinkedListLibrary.pdf" index af434194504381754b7b513815cd4c223e24e73b..84fb07d2dfff0c1c30754582212c88039e818783 100644 GIT binary patch literal 195312 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

5Cr3wQ=$~;qQ&gI%L)Uj( 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 JEQOBt{{Z3G_Kg4l literal 442549 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�t+iIjm>g@ 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

>uCk{*jHl+=c`^PjZ^+y5cs`6z;tTl(zL%fm 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

X>a^6bei&9h?#)^tt|CFv4tn*V*o?M{?@sX3fn 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 jCM>Lr{Oevpd2N*JBj2iRt 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 K-`M}H`2PV(y^Mqa diff --git "a/fll\342\200\223FortranLinkedListLibrary.pptx" "b/fll\342\200\223FortranLinkedListLibrary.pptx" index 7e2b6a1ee4aef8b7e71c99dde7fc50a56e559409..7936e2083f42d5a410d7f9bd684c2771e937b2b2 100644 GIT binary patch delta 56389 zcmZ^~Wl&tvx-E*kLy+L^?(XgyG`PDHtZ@kLPH^|&?(Xhx!QBJACVRho&i!$#sM)<{ zv$~D|5)K9rmqWZU*+ku#WQM^O$r3*c&a}f%7wsIOAQLIJ0>C5S)v*8t^T#->a!U_8;Tz$>jM&#*%P;Q1MeN#9STQ1{m%XlzY@xwuDs6f zu(yPm`L_PHH9bW2!m^E3yC~aLd1VWA9qOP2yCHk0Tf~;WdiK~NXW9N`C{e=1QO

O1;0b<&xCsLYd;cECVgK_u1pl5; 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 delta 45656 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 From 985fbcf5c0034f106e34739d52911107bc97d622 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 3 Jul 2017 13:28:28 -0600 Subject: [PATCH 226/325] fix dependency script --- python_dep/fort_depend.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 245c562..a0ab46c 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -320,6 +320,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: + if ignore and (j in ignore): continue try: # @@ -333,6 +334,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): # these are files found in function get_all_files # for k in ffiles: + dir,fil=os.path.split(k) dir = dir+ "/" retval = 0 @@ -349,6 +351,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") # print(" ") + break #break loop, dependency declared if istat== 0 and not(j == ""): if int(verbose) > 2 : @@ -356,6 +359,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") # print(" ") + break #break loop, dependency declared if not(istat == 0): deps[i.file_name]=tmp From 16fce51cd76e95d34d5b6cdc0004d740fc2e64d4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 3 Jul 2017 13:30:09 -0600 Subject: [PATCH 227/325] add break to for loop --- fort_depend.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 4c6b1a9..a0ab46c 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -257,15 +257,12 @@ def get_includes(infile=None, macros={}): includes=[] - if sys.version_info < (3,0): with open(infile,'r') as f: t=f.readlines() else: with open(infile,'r',errors='ignore') as f: t=f.readlines() - -# with open(infile,'r',encoding = "ISO-8859-1") as f: # with open(infile,'r',encoding = "ISO-8859-1") as f: # t=f.readlines() @@ -323,6 +320,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: + if ignore and (j in ignore): continue try: # @@ -336,6 +334,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): # these are files found in function get_all_files # for k in ffiles: + dir,fil=os.path.split(k) dir = dir+ "/" retval = 0 @@ -352,6 +351,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") # print(" ") + break #break loop, dependency declared if istat== 0 and not(j == ""): if int(verbose) > 2 : @@ -359,6 +359,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") # print(" ") + break #break loop, dependency declared if not(istat == 0): deps[i.file_name]=tmp From b20ced888e8e8eebd0e1d0fcb0bd8f9eafc61eea Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 13 Jul 2017 08:03:34 -0600 Subject: [PATCH 228/325] fix Makefile in examples --- examples/Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/Makefile b/examples/Makefile index 71f9f4c..f9bc514 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -36,20 +36,19 @@ include ../config.mk DEP_FILE=depend.mk -#FMODDIRS= ../../data_util - #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ Simple_data_operation \ - Example_MPI-IO\ Read_Record\ -ifneq ($(strip $(MPI_FC)),) +#ifneq ($(strip $(MPI_FC)),) +ifneq ($(MPI_FC),) SUBDIRS+= Example_MPI-IO endif + ########################################################################### all: $(SUBDIRS:%=%.all) From f37fd368e3f8af94bb544de7fc20933769e9922f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 25 Jul 2017 20:24:33 -0600 Subject: [PATCH 229/325] fix two thigs - module names and fitler files - module names, fix if module name contains word module - add extensions f, f90, F, F90 --- fort_depend.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index a0ab46c..66ec8b4 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -154,20 +154,25 @@ def get_all_files(path,dep): if not(dep == None): for i in dep: if i.strip() in root: - for filename in fnmatch.filter(filenames, '*.f*'): - matches.append(os.path.join(root, filename)) + #for filename in fnmatch.filter(filenames, '*.F*'): + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) # # otherwise include all files from path dir # else: - for filename in fnmatch.filter(filenames, '*.f*'): - matches.append(os.path.join(root, filename)) + #for filename in fnmatch.filter(filenames, '*.f*'): + #matches.append(os.path.join(root, filename)) + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) return matches def check_if_there(use,file): "return if you see module name" - + if sys.version_info < (3,0): with open(file) as f: for line in f: @@ -183,7 +188,7 @@ def check_if_there(use,file): for line in f: if "module" in line.lower(): extrline = line.lower() - extrline = extrline.replace("module", "") + extrline = extrline.replace("module", "",1) if use.lower().strip() == extrline.strip(): f.close() return 1 @@ -320,7 +325,6 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: - if ignore and (j in ignore): continue try: # From 6899cf541ddbf5241fa0fd750c6e2f94d7460ad7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 25 Jul 2017 20:27:07 -0600 Subject: [PATCH 230/325] add fixed depend script --- python_dep/fort_depend.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index a0ab46c..66ec8b4 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -154,20 +154,25 @@ def get_all_files(path,dep): if not(dep == None): for i in dep: if i.strip() in root: - for filename in fnmatch.filter(filenames, '*.f*'): - matches.append(os.path.join(root, filename)) + #for filename in fnmatch.filter(filenames, '*.F*'): + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) # # otherwise include all files from path dir # else: - for filename in fnmatch.filter(filenames, '*.f*'): - matches.append(os.path.join(root, filename)) + #for filename in fnmatch.filter(filenames, '*.f*'): + #matches.append(os.path.join(root, filename)) + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) return matches def check_if_there(use,file): "return if you see module name" - + if sys.version_info < (3,0): with open(file) as f: for line in f: @@ -183,7 +188,7 @@ def check_if_there(use,file): for line in f: if "module" in line.lower(): extrline = line.lower() - extrline = extrline.replace("module", "") + extrline = extrline.replace("module", "",1) if use.lower().strip() == extrline.strip(): f.close() return 1 @@ -320,7 +325,6 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): tmp=[] for j in i.uses: - if ignore and (j in ignore): continue try: # From 92be0d3ceeaf008a9c5c2983f5ae1700a30d8ab8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 27 Jul 2017 13:00:33 -0600 Subject: [PATCH 231/325] fix module replacement for v2 --- fort_depend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 66ec8b4..4c3c486 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -43,6 +43,8 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= # list all file in path dir # ff=get_all_files(path=path, dep=dep) + + if int(verbose) > 2: print(" ") @@ -178,7 +180,7 @@ def check_if_there(use,file): for line in f: if "module" in line.lower(): extrline = line.lower() - extrline = extrline.replace("module", "") + extrline = extrline.replace("module", "",1) if use.lower().strip() == extrline.strip(): f.close() return 1 From 86b0f3d2e2a1e327a357f136454351765dc820d7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 27 Jul 2017 13:02:14 -0600 Subject: [PATCH 232/325] update to new dependency script --- examples/Example_MPI-IO/depend.mk | 14 +++--- examples/Simple_data_operation/depend.mk | 6 +-- mpi_util/depend.mk | 60 ++++++++++++------------ python_dep/fort_depend.py | 4 +- 4 files changed, 43 insertions(+), 41 deletions(-) diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 8e8b65a..5e2ba4a 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -3,19 +3,19 @@ Example_mpi-IO.o : \ ../../data_util/fll_mods.o \ save_root_part_file.o \ - read_input.o \ create_data_set.o \ - ../../mpi_util/fll_mpi_mods.o \ - save_individ_files.o + save_individ_files.o \ + read_input.o \ + ../../mpi_util/fll_mpi_mods.o -create_data_set.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o -save_individ_files.o : \ +read_input.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ +create_data_set.o : \ ../../data_util/fll_mods.o -read_input.o : \ +save_root_part_file.o : \ ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 0bbc702..4b1a81c 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -1,8 +1,8 @@ # This file is generated automatically. DO NOT EDIT! +fll_test_subr.o : \ + ../../data_util/fll_mods.o + fll_test.o : \ ../../data_util/fll_mods.o \ fll_test_subr.o - -fll_test_subr.o : \ - ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index f5d7ad7..f9a4577 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o +fll_mpi_mods.o : \ + fll_mpi_write_snm.o \ + fll_mpi_cp.o \ + fll_mpi_proc_struct.o \ + fll_mpi_write_nm.o \ + fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_cp_all.o : \ - ../data_util/fll_type.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mk.o - fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_write.o -fll_mpi_cp.o : \ - ../data_util/fll_type.o \ +fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mk.o + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o fll_mpi_write_snm.o : \ - fll_mpi_cp.o \ + ../data_util/fll_mods.o \ + fll_mpi_cp.o + +fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o fll_mpi_read.o : \ - fll_mpi_cp_all.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o fll_mpi_mv.o : \ - ../data_util/fll_type.o \ fll_mpi_cp.o \ + ../data_util/fll_type.o \ ../data_util/fll_out.o \ ../data_util/fll_rm.o fll_mpi_write.o : \ - fll_mpi_sum.o \ - ../data_util/fll_mods.o - -fll_mpi_mods.o : \ - fll_mpi_proc_struct.o \ - fll_mpi_write_snm.o \ - fll_mpi_write_nm.o \ - fll_mpi_mv.o \ - fll_mpi_cp.o \ - fll_mpi_read.o \ - fll_mpi_write.o \ - fll_mpi_cp_all.o \ + ../data_util/fll_mods.o \ fll_mpi_sum.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 66ec8b4..4c3c486 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -43,6 +43,8 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= # list all file in path dir # ff=get_all_files(path=path, dep=dep) + + if int(verbose) > 2: print(" ") @@ -178,7 +180,7 @@ def check_if_there(use,file): for line in f: if "module" in line.lower(): extrline = line.lower() - extrline = extrline.replace("module", "") + extrline = extrline.replace("module", "",1) if use.lower().strip() == extrline.strip(): f.close() return 1 From c92a820eda34429cdf105a2533a5bb0f4a02e491 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 10:46:38 -0600 Subject: [PATCH 233/325] modify dep list when specified list of preferred dirs with files, find its absolute path and loop only those --- fort_depend.py | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 4c3c486..65bf4c9 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -32,19 +32,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") # -# get rid of ../ in deps -# - if not(dep == None): - dep = [w.replace('../', ' ') for w in dep] -# # get files where to look for modules # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir # ff=get_all_files(path=path, dep=dep) - - if int(verbose) > 2: print(" ") @@ -145,30 +138,36 @@ def get_source(ext=[".f90",".F90",".f",".F"]): def get_all_files(path,dep): # -# list all fortran files +# list all fortran files where to look for possible module # matches = [] - for root, dirnames, filenames in os.walk(path): # # specified list of preferred directories -# list only those +# list only files located in those +# + if not(dep == None): + for i in dep: # - if not(dep == None): - for i in dep: - if i.strip() in root: - #for filename in fnmatch.filter(filenames, '*.F*'): - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) +# use basolute path ie.: os.path.abspath(i) +# + for root, dirnames, filenames in os.walk(os.path.abspath(i)): +# +# list all files and check if they end up with given suffix, if yes, add to the list +# + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) # # otherwise include all files from path dir # - else: - #for filename in fnmatch.filter(filenames, '*.f*'): - #matches.append(os.path.join(root, filename)) - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) + else: +# +# path is a root dorectory of the entire project, loop all file in it +# + for root, dirnames, filenames in os.walk(path): + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) return matches From d94488e535a8e3c3524072e9dfa308602500334c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 10:47:48 -0600 Subject: [PATCH 234/325] add improved dependency script --- python_dep/fort_depend.py | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 4c3c486..65bf4c9 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -32,19 +32,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") # -# get rid of ../ in deps -# - if not(dep == None): - dep = [w.replace('../', ' ') for w in dep] -# # get files where to look for modules # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir # ff=get_all_files(path=path, dep=dep) - - if int(verbose) > 2: print(" ") @@ -145,30 +138,36 @@ def get_source(ext=[".f90",".F90",".f",".F"]): def get_all_files(path,dep): # -# list all fortran files +# list all fortran files where to look for possible module # matches = [] - for root, dirnames, filenames in os.walk(path): # # specified list of preferred directories -# list only those +# list only files located in those +# + if not(dep == None): + for i in dep: # - if not(dep == None): - for i in dep: - if i.strip() in root: - #for filename in fnmatch.filter(filenames, '*.F*'): - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) +# use basolute path ie.: os.path.abspath(i) +# + for root, dirnames, filenames in os.walk(os.path.abspath(i)): +# +# list all files and check if they end up with given suffix, if yes, add to the list +# + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) # # otherwise include all files from path dir # - else: - #for filename in fnmatch.filter(filenames, '*.f*'): - #matches.append(os.path.join(root, filename)) - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) + else: +# +# path is a root dorectory of the entire project, loop all file in it +# + for root, dirnames, filenames in os.walk(path): + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + matches.append(os.path.join(root, filename)) return matches From 0d26780006d8f0cf923e35aab716e33b92a535bc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 17:07:28 -0600 Subject: [PATCH 235/325] udated dependency script --- python_dep/fort_depend.py | 108 ++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 28 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 4c3c486..adee9a1 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -32,19 +32,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") # -# get rid of ../ in deps -# - if not(dep == None): - dep = [w.replace('../', ' ') for w in dep] -# # get files where to look for modules # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir # ff=get_all_files(path=path, dep=dep) - - if int(verbose) > 2: print(" ") @@ -98,30 +91,45 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, for i in dep.keys(): tmp,fil=os.path.split(i) +# +# get name of file for which you write dependencies with .o +# stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") if int(verbose) > 1: print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") if not(dep[i] == ""): - +# +# add module name to stri and separate by new line and tab +# for j in dep[i]: +# stri=stri+" \\\n\t" +j.split(".")[0]+".o" + npathseg = j.count('/') if npathseg == 0: # # module is in the file located in the same directory # tmp,fil=os.path.split(j) +# +# replace suffix with .o +# + fil= os.path.splitext(j)[0]+'.o' else: # # module is in file located in different directory # - fil = get_relative_path_name(j,path=path,cwd=cwd) +# fil = get_relative_path_name(j,path=path,cwd=cwd) + fil = j if "../" in fil: stri = stri + " \\\n\t" + fil else: stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") - + +# +# add the last new line and write to a file +# stri=stri+"\n" f.write(stri) @@ -145,30 +153,74 @@ def get_source(ext=[".f90",".F90",".f",".F"]): def get_all_files(path,dep): # -# list all fortran files +# list all fortran files where to look for possible module +# once found add their relative path from this directory to project root directory +# it is important to do so when the project is compiled in a different directory +# the path of all modules should be relatie # matches = [] - for root, dirnames, filenames in os.walk(path): # # specified list of preferred directories -# list only those +# list only files located in those +# + if not(dep == None): + for i in dep: # - if not(dep == None): - for i in dep: - if i.strip() in root: - #for filename in fnmatch.filter(filenames, '*.F*'): - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) +# use basolute path to preferred directories ie.: os.path.abspath(i) +# + for root, dirnames, filenames in os.walk(os.path.abspath(i)): +# +# list all files and check if they end up with given suffix, if yes, add to the list +# + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): +# matches.append(os.path.join(root, filename)) +# +# add specified dependency directory location (i) rather then aboslute path +# + matches.append(os.path.join(i, filename)) # # otherwise include all files from path dir # - else: - #for filename in fnmatch.filter(filenames, '*.f*'): - #matches.append(os.path.join(root, filename)) - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) + else: +# +# path is a root dorectory of the entire project, loop all file in it +# get how many ../ you have to go up to reach the project root directory +# + currdirr = os.getcwd() + relapth = currdirr + relapth=relapth.replace(path,'') + relapth = relapth + "/" + slsh_count = relapth.count('/') + relapth = '' + for isl in range(0, slsh_count): + relapth += "../" +# +# loop over all file in project root path directory +# + for root, dirnames, filenames in os.walk(path): + + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + # matches.append(os.path.join(root, filename)) + + if(root == currdirr): +# +# file is in this directory add juts its name +# + matches.append(filename) + else: +# +# file is different directory, +# sybstract project root parth from the file path +# add trailing / and then add ../ to get to project root path +# + cwurrdirr = root + cwurrdirr=cwurrdirr.replace(path,'') + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) + + return matches @@ -202,8 +254,8 @@ def check_if_there(use,file): def create_file_objs(verbose, files=None, macros={}): l=[] - if files is None: - files = get_source() +# if files is None: +# files = get_source() files = get_source() From 44fad34a5c76530b2de357ca355df0794b54e218 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 17:07:39 -0600 Subject: [PATCH 236/325] updated dependency files --- data_util/depend.mk | 204 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 20 +-- examples/Simple_data_operation/depend.mk | 4 +- mpi_util/depend.mk | 62 +++---- 4 files changed, 145 insertions(+), 145 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 93509b9..4709376 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,148 +1,148 @@ # This file is generated automatically. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o +fll_scan_file.o : \ + fll_type.o \ + fll_read.o \ + fll_out.o -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_out.o \ - fll_type.o +fll_type.o : -fll_getnbytes.o : \ - fll_out.o \ - fll_type.o +fll_match_pattern.o : \ + fll_type.o \ + fll_out.o -fll_mkdir.o : \ - fll_mk.o \ - fll_type.o +fll_write.o : \ + fll_type.o \ + fll_out.o -fll_cat.o : \ +fll_rm.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_stich.o -fll_type.o : +fll_getnbytes.o : \ + fll_type.o \ + fll_out.o fll_stich.o : \ - fll_out.o \ - fll_type.o - -fll_funct_prt.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o fll_sweep.o : \ fll_match_pattern.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_read_record.o : \ - fll_mv.o \ - fll_cat.o \ +fll_mk.o : \ + fll_type.o \ + fll_out.o + +fll_deattach.o : \ fll_out.o \ - fll_locate.o \ - fll_rm.o \ - fll_mk.o \ fll_type.o \ - fll_read.o + fll_stich.o -fll_read.o : \ +fll_duplicate.o : \ fll_mv.o \ - fll_funct_prt.o \ + fll_type.o \ fll_mk.o \ - fll_out.o \ - fll_type.o + fll_out.o -fll_cp.o : \ +fll_mods.o : \ + fll_getnbytes.o \ + fll_type.o \ + fll_write_ffa.o \ + fll_duplicate.o \ fll_mv.o \ + fll_sweep.o \ + fll_mkdir.o \ + fll_write.o \ + fll_locate.o \ fll_cat.o \ - fll_out.o \ - fll_duplicate.o \ fll_rm.o \ + fll_scan_file.o \ + fll_match_pattern.o \ + fll_funct_prt.o \ + fll_read_record.o \ fll_stich.o \ - fll_type.o - -fll_scan_file.o : \ - fll_read.o \ - fll_out.o \ - fll_type.o - -fll_mv.o : \ - fll_stich.o \ + fll_mk.o \ + fll_read_ffa.o \ fll_out.o \ - fll_rm.o \ - fll_type.o + fll_nnodes.o \ + fll_read.o \ + fll_cp.o \ + fll_getndata.o \ + fll_deattach.o -fll_write.o : \ - fll_out.o \ - fll_type.o +fll_mkdir.o : \ + fll_type.o \ + fll_mk.o -fll_getndata.o : \ +fll_read_record.o : \ + fll_type.o \ fll_locate.o \ - fll_out.o \ - fll_type.o - -fll_match_pattern.o : \ - fll_out.o \ - fll_type.o + fll_read.o \ + fll_cat.o \ + fll_rm.o \ + fll_mv.o \ + fll_mk.o \ + fll_out.o fll_read_ffa.o : \ - fll_mv.o \ fll_funct_prt.o \ + fll_mv.o \ + fll_type.o \ fll_mk.o \ - fll_out.o \ - fll_type.o + fll_out.o -fll_locate.o : \ - fll_funct_prt.o \ - fll_out.o \ +fll_out.o : \ fll_type.o -fll_duplicate.o : \ - fll_mv.o \ - fll_mk.o \ +fll_cat.o : \ + fll_type.o \ + fll_out.o + +fll_nnodes.o : \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_funct_prt.o -fll_mods.o : \ - fll_mv.o \ +fll_getndata.o : \ + fll_type.o \ + fll_locate.o \ + fll_out.o + +fll_locate.o : \ fll_out.o \ + fll_type.o \ + fll_funct_prt.o + +fll_read.o : \ fll_funct_prt.o \ - fll_stich.o \ - fll_match_pattern.o \ + fll_mv.o \ fll_type.o \ - fll_mkdir.o \ - fll_cat.o \ - fll_write.o \ - fll_read_record.o \ - fll_write_ffa.o \ - fll_getnbytes.o \ fll_mk.o \ - fll_deattach.o \ - fll_scan_file.o \ - fll_duplicate.o \ - fll_sweep.o \ - fll_rm.o \ - fll_nnodes.o \ - fll_getndata.o \ - fll_read_ffa.o \ - fll_locate.o \ - fll_cp.o \ - fll_read.o + fll_out.o -fll_rm.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o +fll_write_ffa.o : \ + fll_type.o \ + fll_out.o -fll_mk.o : \ - fll_out.o \ - fll_type.o +fll_funct_prt.o : \ + fll_type.o \ + fll_out.o -fll_out.o : \ - fll_type.o +fll_cp.o : \ + fll_type.o \ + fll_duplicate.o \ + fll_cat.o \ + fll_stich.o \ + fll_rm.o \ + fll_mv.o \ + fll_out.o -fll_write_ffa.o : \ +fll_mv.o : \ + fll_rm.o \ fll_out.o \ - fll_type.o + fll_type.o \ + fll_stich.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 5e2ba4a..61cd574 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,20 +1,20 @@ # This file is generated automatically. DO NOT EDIT! +read_input.o : \ + ../../data_util/fll_mods.o + Example_mpi-IO.o : \ - ../../data_util/fll_mods.o \ - save_root_part_file.o \ - create_data_set.o \ - save_individ_files.o \ + ../../mpi_util/fll_mpi_mods.o \ read_input.o \ - ../../mpi_util/fll_mpi_mods.o - -save_individ_files.o : \ - ../../data_util/fll_mods.o + create_data_set.o \ + save_root_part_file.o \ + ../../data_util/fll_mods.o \ + save_individ_files.o -read_input.o : \ +create_data_set.o : \ ../../data_util/fll_mods.o -create_data_set.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o save_root_part_file.o : \ diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 4b1a81c..248c2d0 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -4,5 +4,5 @@ fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - ../../data_util/fll_mods.o \ - fll_test_subr.o + fll_test_subr.o \ + ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index f9a4577..9648dc7 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_mods.o : \ - fll_mpi_write_snm.o \ - fll_mpi_cp.o \ - fll_mpi_proc_struct.o \ - fll_mpi_write_nm.o \ - fll_mpi_write.o \ - fll_mpi_sum.o \ - fll_mpi_mv.o \ - fll_mpi_read.o \ - fll_mpi_cp_all.o - -fll_mpi_sum.o : \ - ../data_util/fll_mods.o - -fll_mpi_write_nm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_write.o - fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ + ../data_util/fll_out.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o + ../data_util/fll_type.o -fll_mpi_write_snm.o : \ +fll_mpi_read.o : \ ../data_util/fll_mods.o \ - fll_mpi_cp.o + fll_mpi_cp_all.o fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o -fll_mpi_read.o : \ +fll_mpi_sum.o : \ + ../data_util/fll_mods.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_type.o + +fll_mpi_write_nm.o : \ ../data_util/fll_mods.o \ - fll_mpi_cp_all.o + fll_mpi_write.o fll_mpi_mv.o : \ - fll_mpi_cp.o \ - ../data_util/fll_type.o \ ../data_util/fll_out.o \ + ../data_util/fll_type.o \ + fll_mpi_cp.o \ ../data_util/fll_rm.o fll_mpi_write.o : \ ../data_util/fll_mods.o \ fll_mpi_sum.o -fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o +fll_mpi_write_snm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp.o + +fll_mpi_mods.o : \ + fll_mpi_write.o \ + fll_mpi_write_nm.o \ + fll_mpi_write_snm.o \ + fll_mpi_cp_all.o \ + fll_mpi_cp.o \ + fll_mpi_read.o \ + fll_mpi_mv.o \ + fll_mpi_proc_struct.o \ + fll_mpi_sum.o From f610e12f331cf27da54cee07b08bbd98feb285b5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 17:16:07 -0600 Subject: [PATCH 237/325] all files should have relatie path --- fort_depend.py | 109 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 4c3c486..ef94579 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -10,6 +10,7 @@ # if fortran source uses module from other directory the script will add the module too # the project root directory is specified as an input parameter with an option -r # +# import os import re import glob @@ -32,19 +33,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") # -# get rid of ../ in deps -# - if not(dep == None): - dep = [w.replace('../', ' ') for w in dep] -# # get files where to look for modules # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir # ff=get_all_files(path=path, dep=dep) - - if int(verbose) > 2: print(" ") @@ -98,30 +92,45 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, for i in dep.keys(): tmp,fil=os.path.split(i) +# +# get name of file for which you write dependencies with .o +# stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") if int(verbose) > 1: print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") if not(dep[i] == ""): - +# +# add module name to stri and separate by new line and tab +# for j in dep[i]: +# stri=stri+" \\\n\t" +j.split(".")[0]+".o" + npathseg = j.count('/') if npathseg == 0: # # module is in the file located in the same directory # tmp,fil=os.path.split(j) +# +# replace suffix with .o +# + fil= os.path.splitext(j)[0]+'.o' else: # # module is in file located in different directory # - fil = get_relative_path_name(j,path=path,cwd=cwd) +# fil = get_relative_path_name(j,path=path,cwd=cwd) + fil = j if "../" in fil: stri = stri + " \\\n\t" + fil else: stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") - + +# +# add the last new line and write to a file +# stri=stri+"\n" f.write(stri) @@ -145,30 +154,74 @@ def get_source(ext=[".f90",".F90",".f",".F"]): def get_all_files(path,dep): # -# list all fortran files +# list all fortran files where to look for possible module +# once found add their relative path from this directory to project root directory +# it is important to do so when the project is compiled in a different directory +# the path of all modules should be relatie # matches = [] - for root, dirnames, filenames in os.walk(path): # # specified list of preferred directories -# list only those +# list only files located in those +# + if not(dep == None): + for i in dep: +# +# use basolute path to preferred directories ie.: os.path.abspath(i) +# + for root, dirnames, filenames in os.walk(os.path.abspath(i)): +# +# list all files and check if they end up with given suffix, if yes, add to the list +# + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): +# matches.append(os.path.join(root, filename)) # - if not(dep == None): - for i in dep: - if i.strip() in root: - #for filename in fnmatch.filter(filenames, '*.F*'): - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) +# add specified dependency directory location (i) rather then aboslute path +# + matches.append(os.path.join(i, filename)) # # otherwise include all files from path dir # - else: - #for filename in fnmatch.filter(filenames, '*.f*'): - #matches.append(os.path.join(root, filename)) - for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): - matches.append(os.path.join(root, filename)) + else: +# +# path is a root dorectory of the entire project, loop all file in it +# get how many ../ you have to go up to reach the project root directory +# + currdirr = os.getcwd() + relapth = currdirr + relapth=relapth.replace(path,'') + relapth = relapth + "/" + slsh_count = relapth.count('/') + relapth = '' + for isl in range(0, slsh_count): + relapth += "../" +# +# loop over all file in project root path directory +# + for root, dirnames, filenames in os.walk(path): + + for filename in filenames: + if filename.endswith(('.f', '.f90', '.F', '.F90')): + # matches.append(os.path.join(root, filename)) + + if(root == currdirr): +# +# file is in this directory add juts its name +# + matches.append(filename) + else: +# +# file is different directory, +# sybstract project root parth from the file path +# add trailing / and then add ../ to get to project root path +# + cwurrdirr = root + cwurrdirr=cwurrdirr.replace(path,'') + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) + + return matches @@ -202,8 +255,8 @@ def check_if_there(use,file): def create_file_objs(verbose, files=None, macros={}): l=[] - if files is None: - files = get_source() +# if files is None: +# files = get_source() files = get_source() From 80248650a3bdd863c4d7b2fd155579de1801313b Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 19:26:51 -0600 Subject: [PATCH 238/325] update to different search algoritm Update so that in -d you an spedicy subdirectory containing directories with source files --- fort_depend.py | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 7865195..5a52af7 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -161,6 +161,18 @@ def get_all_files(path,dep): # matches = [] # +# path is a root dorectory of the entire project, loop all file in it +# get how many ../ you have to go up to reach the project root directory +# + currdirr = os.getcwd() + relapth = currdirr + relapth=relapth.replace(path,'') + relapth = relapth + "/" + slsh_count = relapth.count('/') + relapth = '' + for isl in range(0, slsh_count): + relapth += "../" +# # specified list of preferred directories # list only files located in those # @@ -174,29 +186,33 @@ def get_all_files(path,dep): # list all files and check if they end up with given suffix, if yes, add to the list # for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): -# matches.append(os.path.join(root, filename)) + if filename.endswith(('.f', '.f90', '.F', '.F90')): +## matches.append(os.path.join(root, filename)) +## +## add specified dependency directory location (i) rather then aboslute path +## + #matches.append(os.path.join(i, filename)) + + if(root == currdirr): # -# add specified dependency directory location (i) rather then aboslute path +# file is in this directory add juts its name # - matches.append(os.path.join(i, filename)) + matches.append(filename) + else: +# +# file is different directory, +# sybstract project root parth from the file path +# add trailing / and then add ../ to get to project root path +# + cwurrdirr = root + cwurrdirr=cwurrdirr.replace(path,'') + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) # # otherwise include all files from path dir # else: # -# path is a root dorectory of the entire project, loop all file in it -# get how many ../ you have to go up to reach the project root directory -# - currdirr = os.getcwd() - relapth = currdirr - relapth=relapth.replace(path,'') - relapth = relapth + "/" - slsh_count = relapth.count('/') - relapth = '' - for isl in range(0, slsh_count): - relapth += "../" -# # loop over all file in project root path directory # for root, dirnames, filenames in os.walk(path): From 8d7d21b5a012d1a78a6ac030f0416318edbe4145 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 28 Jul 2017 19:28:54 -0600 Subject: [PATCH 239/325] Update to improved dependency script --- data_util/depend.mk | 146 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 20 ++-- examples/Simple_data_operation/depend.mk | 4 +- mpi_util/depend.mk | 66 +++++----- python_dep/fort_depend.py | 49 +++++--- 5 files changed, 150 insertions(+), 135 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 4709376..b8ba2f8 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -5,31 +5,36 @@ fll_scan_file.o : \ fll_read.o \ fll_out.o -fll_type.o : - -fll_match_pattern.o : \ - fll_type.o \ - fll_out.o +fll_out.o : \ + fll_type.o -fll_write.o : \ +fll_sweep.o : \ + fll_match_pattern.o \ fll_type.o \ fll_out.o -fll_rm.o : \ +fll_read_record.o : \ + fll_read.o \ + fll_mk.o \ fll_out.o \ + fll_locate.o \ + fll_rm.o \ fll_type.o \ - fll_stich.o + fll_cat.o \ + fll_mv.o -fll_getnbytes.o : \ +fll_read_ffa.o : \ + fll_funct_prt.o \ fll_type.o \ - fll_out.o + fll_mk.o \ + fll_out.o \ + fll_mv.o -fll_stich.o : \ +fll_cat.o : \ fll_type.o \ fll_out.o -fll_sweep.o : \ - fll_match_pattern.o \ +fll_write_ffa.o : \ fll_type.o \ fll_out.o @@ -38,111 +43,106 @@ fll_mk.o : \ fll_out.o fll_deattach.o : \ - fll_out.o \ fll_type.o \ - fll_stich.o + fll_stich.o \ + fll_out.o fll_duplicate.o : \ - fll_mv.o \ fll_type.o \ fll_mk.o \ - fll_out.o + fll_out.o \ + fll_mv.o fll_mods.o : \ - fll_getnbytes.o \ - fll_type.o \ + fll_out.o \ fll_write_ffa.o \ - fll_duplicate.o \ - fll_mv.o \ - fll_sweep.o \ - fll_mkdir.o \ - fll_write.o \ - fll_locate.o \ - fll_cat.o \ - fll_rm.o \ fll_scan_file.o \ fll_match_pattern.o \ - fll_funct_prt.o \ - fll_read_record.o \ fll_stich.o \ + fll_read_record.o \ + fll_cat.o \ + fll_getndata.o \ + fll_locate.o \ fll_mk.o \ - fll_read_ffa.o \ - fll_out.o \ - fll_nnodes.o \ + fll_deattach.o \ + fll_rm.o \ + fll_write.o \ + fll_mkdir.o \ + fll_mv.o \ fll_read.o \ + fll_sweep.o \ + fll_getnbytes.o \ + fll_duplicate.o \ fll_cp.o \ - fll_getndata.o \ - fll_deattach.o + fll_type.o \ + fll_read_ffa.o \ + fll_nnodes.o \ + fll_funct_prt.o + +fll_match_pattern.o : \ + fll_type.o \ + fll_out.o fll_mkdir.o : \ fll_type.o \ fll_mk.o -fll_read_record.o : \ +fll_stich.o : \ fll_type.o \ - fll_locate.o \ - fll_read.o \ - fll_cat.o \ - fll_rm.o \ - fll_mv.o \ - fll_mk.o \ fll_out.o -fll_read_ffa.o : \ +fll_locate.o : \ fll_funct_prt.o \ - fll_mv.o \ - fll_type.o \ - fll_mk.o \ - fll_out.o - -fll_out.o : \ - fll_type.o - -fll_cat.o : \ fll_type.o \ fll_out.o -fll_nnodes.o : \ +fll_cp.o : \ fll_out.o \ + fll_rm.o \ + fll_duplicate.o \ fll_type.o \ - fll_funct_prt.o + fll_stich.o \ + fll_cat.o \ + fll_mv.o -fll_getndata.o : \ +fll_mv.o : \ + fll_rm.o \ fll_type.o \ - fll_locate.o \ + fll_stich.o \ fll_out.o -fll_locate.o : \ - fll_out.o \ +fll_funct_prt.o : \ fll_type.o \ - fll_funct_prt.o + fll_out.o -fll_read.o : \ - fll_funct_prt.o \ - fll_mv.o \ +fll_rm.o : \ fll_type.o \ - fll_mk.o \ + fll_stich.o \ fll_out.o -fll_write_ffa.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_type.o \ fll_out.o -fll_funct_prt.o : \ +fll_write.o : \ fll_type.o \ fll_out.o -fll_cp.o : \ +fll_type.o : + +fll_getnbytes.o : \ fll_type.o \ - fll_duplicate.o \ - fll_cat.o \ - fll_stich.o \ - fll_rm.o \ - fll_mv.o \ fll_out.o -fll_mv.o : \ - fll_rm.o \ +fll_read.o : \ + fll_funct_prt.o \ + fll_type.o \ + fll_mk.o \ fll_out.o \ + fll_mv.o + +fll_getndata.o : \ fll_type.o \ - fll_stich.o + fll_locate.o \ + fll_out.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 61cd574..064b42a 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -3,19 +3,19 @@ read_input.o : \ ../../data_util/fll_mods.o +save_individ_files.o : \ + ../../data_util/fll_mods.o + +save_root_part_file.o : \ + ../../data_util/fll_mods.o + Example_mpi-IO.o : \ - ../../mpi_util/fll_mpi_mods.o \ - read_input.o \ create_data_set.o \ - save_root_part_file.o \ + ../../mpi_util/fll_mpi_mods.o \ ../../data_util/fll_mods.o \ - save_individ_files.o + read_input.o \ + save_individ_files.o \ + save_root_part_file.o create_data_set.o : \ ../../data_util/fll_mods.o - -save_individ_files.o : \ - ../../data_util/fll_mods.o - -save_root_part_file.o : \ - ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 248c2d0..4b1a81c 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -4,5 +4,5 @@ fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - fll_test_subr.o \ - ../../data_util/fll_mods.o + ../../data_util/fll_mods.o \ + fll_test_subr.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 9648dc7..ba33483 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! fll_mpi_cp_all.o : \ + ../data_util/fll_type.o \ ../data_util/fll_mv.o \ ../data_util/fll_out.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_type.o + ../data_util/fll_mk.o -fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o - -fll_mpi_proc_struct.o : \ +fll_mpi_write.o : \ + fll_mpi_sum.o \ ../data_util/fll_mods.o fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_type.o - -fll_mpi_write_nm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_write.o - -fll_mpi_mv.o : \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o \ - fll_mpi_cp.o \ - ../data_util/fll_rm.o - -fll_mpi_write.o : \ - ../data_util/fll_mods.o \ - fll_mpi_sum.o +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o fll_mpi_write_snm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp.o + fll_mpi_cp.o \ + ../data_util/fll_mods.o fll_mpi_mods.o : \ - fll_mpi_write.o \ fll_mpi_write_nm.o \ - fll_mpi_write_snm.o \ - fll_mpi_cp_all.o \ - fll_mpi_cp.o \ fll_mpi_read.o \ + fll_mpi_cp.o \ + fll_mpi_write.o \ + fll_mpi_write_snm.o \ fll_mpi_mv.o \ + fll_mpi_sum.o \ fll_mpi_proc_struct.o \ - fll_mpi_sum.o + fll_mpi_cp_all.o + +fll_mpi_read.o : \ + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o + +fll_mpi_write_nm.o : \ + fll_mpi_write.o \ + ../data_util/fll_mods.o + +fll_mpi_cp.o : \ + ../data_util/fll_type.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mk.o + +fll_mpi_mv.o : \ + ../data_util/fll_type.o \ + fll_mpi_cp.o \ + ../data_util/fll_rm.o \ + ../data_util/fll_out.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index ef94579..5a52af7 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -161,6 +161,18 @@ def get_all_files(path,dep): # matches = [] # +# path is a root dorectory of the entire project, loop all file in it +# get how many ../ you have to go up to reach the project root directory +# + currdirr = os.getcwd() + relapth = currdirr + relapth=relapth.replace(path,'') + relapth = relapth + "/" + slsh_count = relapth.count('/') + relapth = '' + for isl in range(0, slsh_count): + relapth += "../" +# # specified list of preferred directories # list only files located in those # @@ -174,29 +186,33 @@ def get_all_files(path,dep): # list all files and check if they end up with given suffix, if yes, add to the list # for filename in filenames: - if filename.endswith(('.f', '.f90', '.F', '.F90')): -# matches.append(os.path.join(root, filename)) + if filename.endswith(('.f', '.f90', '.F', '.F90')): +## matches.append(os.path.join(root, filename)) +## +## add specified dependency directory location (i) rather then aboslute path +## + #matches.append(os.path.join(i, filename)) + + if(root == currdirr): +# +# file is in this directory add juts its name +# + matches.append(filename) + else: # -# add specified dependency directory location (i) rather then aboslute path +# file is different directory, +# sybstract project root parth from the file path +# add trailing / and then add ../ to get to project root path # - matches.append(os.path.join(i, filename)) + cwurrdirr = root + cwurrdirr=cwurrdirr.replace(path,'') + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) # # otherwise include all files from path dir # else: # -# path is a root dorectory of the entire project, loop all file in it -# get how many ../ you have to go up to reach the project root directory -# - currdirr = os.getcwd() - relapth = currdirr - relapth=relapth.replace(path,'') - relapth = relapth + "/" - slsh_count = relapth.count('/') - relapth = '' - for isl in range(0, slsh_count): - relapth += "../" -# # loop over all file in project root path directory # for root, dirnames, filenames in os.walk(path): @@ -221,7 +237,6 @@ def get_all_files(path,dep): cwurrdirr = relapth + cwurrdirr + "/" matches.append(os.path.join(cwurrdirr, filename)) - return matches From 4b79c9e77b2278c673f7930edd970ee2bb1ad26f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 29 Jul 2017 14:26:42 -0600 Subject: [PATCH 240/325] add some comments to the script --- fort_depend.py | 73 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 5a52af7..f995a45 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -1,9 +1,30 @@ #!/usr/bin/python +#The MIT License (MIT) + +#Copyright (c) 2014 David Dickinson, Peter Hill + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. # # # this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py -# -# the modified version used here can be found @https://github.com/libm3l/fort_depend.py +# done by Adam Jirasek +# the modified version can be found @https://github.com/libm3l/fort_depend.py # # this is a script which maked fortran project dependecies # it is executed in each directory separately and creates a project.dep file with fortran dependencies @@ -37,6 +58,9 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir +# +# files paths is relative to projet root directory path so that if the compillation is done in different directory then +# where the source files are located, there are no any prolems with it # ff=get_all_files(path=path, dep=dep) @@ -98,18 +122,19 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") if int(verbose) > 1: print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") - +# +# now write down all files containing modules +# the list contains file names with .f or f90 suffix, replace by .o suffix if not(dep[i] == ""): # # add module name to stri and separate by new line and tab # for j in dep[i]: -# stri=stri+" \\\n\t" +j.split(".")[0]+".o" npathseg = j.count('/') if npathseg == 0: # -# module is in the file located in the same directory +# module is in the file located in the same directory as the file for which the dependency is written # tmp,fil=os.path.split(j) # @@ -120,14 +145,12 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, # # module is in file located in different directory # -# fil = get_relative_path_name(j,path=path,cwd=cwd) fil = j if "../" in fil: stri = stri + " \\\n\t" + fil else: stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") - # # add the last new line and write to a file # @@ -143,7 +166,9 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, return def get_source(ext=[".f90",".F90",".f",".F"]): - "Return all files ending with any of ext" +# +# "Return all files ending with any of ext" +# tmp=os.listdir(".") fil=[] @@ -161,8 +186,7 @@ def get_all_files(path,dep): # matches = [] # -# path is a root dorectory of the entire project, loop all file in it -# get how many ../ you have to go up to reach the project root directory +# get relative path of current directory # currdirr = os.getcwd() relapth = currdirr @@ -190,9 +214,7 @@ def get_all_files(path,dep): ## matches.append(os.path.join(root, filename)) ## ## add specified dependency directory location (i) rather then aboslute path -## - #matches.append(os.path.join(i, filename)) - +## if(root == currdirr): # # file is in this directory add juts its name @@ -201,8 +223,8 @@ def get_all_files(path,dep): else: # # file is different directory, -# sybstract project root parth from the file path -# add trailing / and then add ../ to get to project root path +# substract project root parth from the file path +# add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root cwurrdirr=cwurrdirr.replace(path,'') @@ -230,19 +252,20 @@ def get_all_files(path,dep): # # file is different directory, # sybstract project root parth from the file path -# add trailing / and then add ../ to get to project root path +# add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root cwurrdirr=cwurrdirr.replace(path,'') cwurrdirr = relapth + cwurrdirr + "/" matches.append(os.path.join(cwurrdirr, filename)) - return matches def check_if_there(use,file): - "return if you see module name" - +# +# "return if you see module name" +# make routine to consider version of python installation +# if sys.version_info < (3,0): with open(file) as f: for line in f: @@ -432,10 +455,15 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") -# print(" ") +# +# once module found, break the loop +# break #break loop, dependency declared if not(istat == 0): +# +# if file containign module, add to the list +# deps[i.file_name]=tmp else: deps[i.file_name]="" @@ -446,18 +474,15 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): return deps def check_path(path): - if path.endswith("/"): -# print(" ") + if path.endswith("/") return path else: -# print( "adding / to the path in "+path) path=path + "/" return path def get_relative_path_name(file,path,cwd): length = len(path) - #tmp,fil=os.path.split(j) filetmp = file fil = filetmp.replace(filetmp[:length], '') From 782a3e244652469a421382218d4f2aaaeae29c5d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 07:12:41 -0600 Subject: [PATCH 241/325] use updated version of fort_depend script --- data_util/depend.mk | 210 +++++++++++++++--------------- examples/Example_MPI-IO/depend.mk | 22 ++-- mpi_util/depend.mk | 64 ++++----- python_dep/fort_depend.py | 8 +- 4 files changed, 152 insertions(+), 152 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index b8ba2f8..93509b9 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,148 +1,148 @@ # This file is generated automatically. DO NOT EDIT! -fll_scan_file.o : \ - fll_type.o \ - fll_read.o \ - fll_out.o +fll_deattach.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o -fll_out.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ + fll_out.o \ + fll_type.o + +fll_getnbytes.o : \ + fll_out.o \ + fll_type.o + +fll_mkdir.o : \ + fll_mk.o \ + fll_type.o + +fll_cat.o : \ + fll_out.o \ + fll_type.o + +fll_type.o : + +fll_stich.o : \ + fll_out.o \ + fll_type.o + +fll_funct_prt.o : \ + fll_out.o \ fll_type.o fll_sweep.o : \ fll_match_pattern.o \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o fll_read_record.o : \ - fll_read.o \ - fll_mk.o \ + fll_mv.o \ + fll_cat.o \ fll_out.o \ fll_locate.o \ fll_rm.o \ + fll_mk.o \ fll_type.o \ - fll_cat.o \ - fll_mv.o + fll_read.o -fll_read_ffa.o : \ +fll_read.o : \ + fll_mv.o \ fll_funct_prt.o \ - fll_type.o \ fll_mk.o \ fll_out.o \ - fll_mv.o - -fll_cat.o : \ - fll_type.o \ - fll_out.o + fll_type.o -fll_write_ffa.o : \ - fll_type.o \ - fll_out.o +fll_cp.o : \ + fll_mv.o \ + fll_cat.o \ + fll_out.o \ + fll_duplicate.o \ + fll_rm.o \ + fll_stich.o \ + fll_type.o -fll_mk.o : \ - fll_type.o \ - fll_out.o +fll_scan_file.o : \ + fll_read.o \ + fll_out.o \ + fll_type.o -fll_deattach.o : \ - fll_type.o \ +fll_mv.o : \ fll_stich.o \ - fll_out.o - -fll_duplicate.o : \ - fll_type.o \ - fll_mk.o \ fll_out.o \ - fll_mv.o + fll_rm.o \ + fll_type.o -fll_mods.o : \ +fll_write.o : \ fll_out.o \ - fll_write_ffa.o \ - fll_scan_file.o \ - fll_match_pattern.o \ - fll_stich.o \ - fll_read_record.o \ - fll_cat.o \ - fll_getndata.o \ + fll_type.o + +fll_getndata.o : \ fll_locate.o \ - fll_mk.o \ - fll_deattach.o \ - fll_rm.o \ - fll_write.o \ - fll_mkdir.o \ - fll_mv.o \ - fll_read.o \ - fll_sweep.o \ - fll_getnbytes.o \ - fll_duplicate.o \ - fll_cp.o \ - fll_type.o \ - fll_read_ffa.o \ - fll_nnodes.o \ - fll_funct_prt.o + fll_out.o \ + fll_type.o fll_match_pattern.o : \ - fll_type.o \ - fll_out.o - -fll_mkdir.o : \ - fll_type.o \ - fll_mk.o + fll_out.o \ + fll_type.o -fll_stich.o : \ - fll_type.o \ - fll_out.o +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ + fll_type.o fll_locate.o : \ fll_funct_prt.o \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_cp.o : \ +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ - fll_rm.o \ - fll_duplicate.o \ - fll_type.o \ - fll_stich.o \ - fll_cat.o \ - fll_mv.o + fll_type.o -fll_mv.o : \ - fll_rm.o \ - fll_type.o \ +fll_mods.o : \ + fll_mv.o \ + fll_out.o \ + fll_funct_prt.o \ fll_stich.o \ - fll_out.o - -fll_funct_prt.o : \ + fll_match_pattern.o \ fll_type.o \ - fll_out.o + fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ + fll_read_record.o \ + fll_write_ffa.o \ + fll_getnbytes.o \ + fll_mk.o \ + fll_deattach.o \ + fll_scan_file.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o fll_rm.o : \ - fll_type.o \ fll_stich.o \ - fll_out.o - -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_type.o \ - fll_out.o - -fll_write.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_type.o : +fll_mk.o : \ + fll_out.o \ + fll_type.o -fll_getnbytes.o : \ - fll_type.o \ - fll_out.o +fll_out.o : \ + fll_type.o -fll_read.o : \ - fll_funct_prt.o \ - fll_type.o \ - fll_mk.o \ +fll_write_ffa.o : \ fll_out.o \ - fll_mv.o - -fll_getndata.o : \ - fll_type.o \ - fll_locate.o \ - fll_out.o + fll_type.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 064b42a..5e2ba4a 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically. DO NOT EDIT! -read_input.o : \ - ../../data_util/fll_mods.o +Example_mpi-IO.o : \ + ../../data_util/fll_mods.o \ + save_root_part_file.o \ + create_data_set.o \ + save_individ_files.o \ + read_input.o \ + ../../mpi_util/fll_mpi_mods.o save_individ_files.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ +read_input.o : \ ../../data_util/fll_mods.o -Example_mpi-IO.o : \ - create_data_set.o \ - ../../mpi_util/fll_mpi_mods.o \ - ../../data_util/fll_mods.o \ - read_input.o \ - save_individ_files.o \ - save_root_part_file.o - create_data_set.o : \ ../../data_util/fll_mods.o + +save_root_part_file.o : \ + ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index ba33483..f9a4577 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically. DO NOT EDIT! -fll_mpi_cp_all.o : \ - ../data_util/fll_type.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_mk.o - -fll_mpi_write.o : \ +fll_mpi_mods.o : \ + fll_mpi_write_snm.o \ + fll_mpi_cp.o \ + fll_mpi_proc_struct.o \ + fll_mpi_write_nm.o \ + fll_mpi_write.o \ fll_mpi_sum.o \ - ../data_util/fll_mods.o + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o +fll_mpi_write_nm.o : \ + ../data_util/fll_mods.o \ + fll_mpi_write.o + +fll_mpi_cp_all.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o fll_mpi_write_snm.o : \ - fll_mpi_cp.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_cp.o -fll_mpi_mods.o : \ - fll_mpi_write_nm.o \ - fll_mpi_read.o \ - fll_mpi_cp.o \ - fll_mpi_write.o \ - fll_mpi_write_snm.o \ - fll_mpi_mv.o \ - fll_mpi_sum.o \ - fll_mpi_proc_struct.o \ - fll_mpi_cp_all.o +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o fll_mpi_read.o : \ ../data_util/fll_mods.o \ fll_mpi_cp_all.o -fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o - -fll_mpi_cp.o : \ +fll_mpi_mv.o : \ + fll_mpi_cp.o \ ../data_util/fll_type.o \ - ../data_util/fll_mv.o \ ../data_util/fll_out.o \ - ../data_util/fll_mk.o + ../data_util/fll_rm.o -fll_mpi_mv.o : \ +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ ../data_util/fll_type.o \ - fll_mpi_cp.o \ - ../data_util/fll_rm.o \ + ../data_util/fll_mk.o \ ../data_util/fll_out.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 5a52af7..5058723 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -44,7 +44,9 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print(" ") print("\033[031m Searching for modules in files:\033[039m") print(ff) - +# +# loop through all files and look for pattern (use etc and add it to a list) +# l=create_file_objs( (verbose) ,files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) # @@ -424,7 +426,6 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") -# print(" ") break #break loop, dependency declared if istat== 0 and not(j == ""): @@ -432,8 +433,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") -# print(" ") - break #break loop, dependency declared +# break #break loop, dependency declared if not(istat == 0): deps[i.file_name]=tmp From 8da1f5d0f1f4e849a089fce658703fdd3e2c10ae Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 07:20:55 -0600 Subject: [PATCH 242/325] update to recovered dependency script --- python_dep/fort_depend.py | 75 ++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 5058723..5969f80 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -1,9 +1,30 @@ #!/usr/bin/python +#The MIT License (MIT) + +#Copyright (c) 2014 David Dickinson, Peter Hill + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. # # # this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py -# -# the modified version used here can be found @https://github.com/libm3l/fort_depend.py +# done by Adam Jirasek +# the modified version can be found @https://github.com/libm3l/fort_depend.py # # this is a script which maked fortran project dependecies # it is executed in each directory separately and creates a project.dep file with fortran dependencies @@ -37,6 +58,9 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= # if list of preferred directories is specified in dep # list only these files, otherwise # list all file in path dir +# +# files paths is relative to projet root directory path so that if the compillation is done in different directory then +# where the source files are located, there are no any prolems with it # ff=get_all_files(path=path, dep=dep) @@ -44,9 +68,7 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print(" ") print("\033[031m Searching for modules in files:\033[039m") print(ff) -# -# loop through all files and look for pattern (use etc and add it to a list) -# + l=create_file_objs( (verbose) ,files,macros) mod2fil=file_objs_to_mod_dict(file_objs=l) # @@ -100,18 +122,19 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, stri="\n"+os.path.join(build, fil.split(".")[0]+".o"+" : ") if int(verbose) > 1: print("\033[031m Writing dependency info for \033[032m"+i+"\033[039m module") - +# +# now write down all files containing modules +# the list contains file names with .f or f90 suffix, replace by .o suffix if not(dep[i] == ""): # # add module name to stri and separate by new line and tab # for j in dep[i]: -# stri=stri+" \\\n\t" +j.split(".")[0]+".o" npathseg = j.count('/') if npathseg == 0: # -# module is in the file located in the same directory +# module is in the file located in the same directory as the file for which the dependency is written # tmp,fil=os.path.split(j) # @@ -122,14 +145,12 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, # # module is in file located in different directory # -# fil = get_relative_path_name(j,path=path,cwd=cwd) fil = j if "../" in fil: stri = stri + " \\\n\t" + fil else: stri=stri+" \\\n\t"+os.path.join(build, fil.split(".")[0]+".o") - # # add the last new line and write to a file # @@ -145,7 +166,9 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, return def get_source(ext=[".f90",".F90",".f",".F"]): - "Return all files ending with any of ext" +# +# "Return all files ending with any of ext" +# tmp=os.listdir(".") fil=[] @@ -163,8 +186,7 @@ def get_all_files(path,dep): # matches = [] # -# path is a root dorectory of the entire project, loop all file in it -# get how many ../ you have to go up to reach the project root directory +# get relative path of current directory # currdirr = os.getcwd() relapth = currdirr @@ -192,9 +214,7 @@ def get_all_files(path,dep): ## matches.append(os.path.join(root, filename)) ## ## add specified dependency directory location (i) rather then aboslute path -## - #matches.append(os.path.join(i, filename)) - +## if(root == currdirr): # # file is in this directory add juts its name @@ -203,8 +223,8 @@ def get_all_files(path,dep): else: # # file is different directory, -# sybstract project root parth from the file path -# add trailing / and then add ../ to get to project root path +# substract project root parth from the file path +# add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root cwurrdirr=cwurrdirr.replace(path,'') @@ -232,19 +252,20 @@ def get_all_files(path,dep): # # file is different directory, # sybstract project root parth from the file path -# add trailing / and then add ../ to get to project root path +# add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root cwurrdirr=cwurrdirr.replace(path,'') cwurrdirr = relapth + cwurrdirr + "/" matches.append(os.path.join(cwurrdirr, filename)) - return matches def check_if_there(use,file): - "return if you see module name" - +# +# "return if you see module name" +# make routine to consider version of python installation +# if sys.version_info < (3,0): with open(file) as f: for line in f: @@ -426,6 +447,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") +# print(" ") break #break loop, dependency declared if istat== 0 and not(j == ""): @@ -433,9 +455,15 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") print ("\033[031m \033[039m assuming intrinsic module, not adding to dependency tree ... \033[032m\033[039m") +# +# once module found, break the loop +# # break #break loop, dependency declared if not(istat == 0): +# +# if file containign module, add to the list +# deps[i.file_name]=tmp else: deps[i.file_name]="" @@ -447,17 +475,14 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): def check_path(path): if path.endswith("/"): -# print(" ") return path else: -# print( "adding / to the path in "+path) path=path + "/" return path def get_relative_path_name(file,path,cwd): length = len(path) - #tmp,fil=os.path.split(j) filetmp = file fil = filetmp.replace(filetmp[:length], '') From 8d0f7890b938829f7a6f1ffa45c8c22abde92287 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 07:22:07 -0600 Subject: [PATCH 243/325] bug in loop, terminated prematurely --- fort_depend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index f995a45..5969f80 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -458,7 +458,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): # # once module found, break the loop # - break #break loop, dependency declared +# break #break loop, dependency declared if not(istat == 0): # @@ -474,7 +474,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): return deps def check_path(path): - if path.endswith("/") + if path.endswith("/"): return path else: path=path + "/" From 1ab5266e00e7acc598ccb7190b4cb215c85bdccb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 14:12:55 -0600 Subject: [PATCH 244/325] add - to include --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 949e2c8..29fbda3 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ # # # -include src_dir_path.mk +-include src_dir_path.mk -include config.mk SUBDIRS= \ From 0f68b5957dc87f30b14825b7bf63ab6b40804ac3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 14:30:17 -0600 Subject: [PATCH 245/325] fix dep / --- python_dep/fort_depend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 5969f80..e24d35b 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -189,9 +189,9 @@ def get_all_files(path,dep): # get relative path of current directory # currdirr = os.getcwd() + currdirr = check_path(path=currdirr) relapth = currdirr relapth=relapth.replace(path,'') - relapth = relapth + "/" slsh_count = relapth.count('/') relapth = '' for isl in range(0, slsh_count): From a4b3ef6d0a47e90485a1e3419b6c0e8fb13bdafe Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 31 Jul 2017 14:30:36 -0600 Subject: [PATCH 246/325] fix current path slashes --- fort_depend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 5969f80..e24d35b 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -189,9 +189,9 @@ def get_all_files(path,dep): # get relative path of current directory # currdirr = os.getcwd() + currdirr = check_path(path=currdirr) relapth = currdirr relapth=relapth.replace(path,'') - relapth = relapth + "/" slsh_count = relapth.count('/') relapth = '' for isl in range(0, slsh_count): From f089d2fd76539f0d4c3abd33a793733542a10028 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Aug 2017 09:29:58 -0600 Subject: [PATCH 247/325] fix bug in stitch rutine once node is emmpty set PCHILD to NULL --- data_util/fll_mv.f90 | 4 ++-- data_util/fll_stich.f90 | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index f3f14b0..9cd71a7 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -129,7 +129,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! PTNEXT => PWHERE%PNEXT PTPREV => PWHERE%PPREV - PTPAR => PWHERE%PPAR + PTPAR => PWHERE%PPAR PSOURCETMP => PWHAT ! @@ -165,7 +165,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) PCHILD => PCHILD%PNEXT END DO - PLAST%PNEXT => PSOURCETMP + PLAST%PNEXT => PSOURCETMP PWHERE%NDIM = PWHERE%NDIM + 1 PSOURCETMP%PPREV => PLAST diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index 0013e3d..db47b68 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -72,9 +72,9 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) PNEXT => PNODE%PNEXT PPREV => PNODE%PPREV - PPAR => PNODE%PPAR + PPAR => PNODE%PPAR - IF(.NOT.ASSOCIATED(PNEXT) .AND. .NOT.ASSOCIATED(PPREV) .AND. .NOT.ASSOCIATED(PPAR)) RETURN + IF(.NOT.ASSOCIATED(PNEXT) .AND. .NOT.ASSOCIATED(PPREV) .AND. .NOT.ASSOCIATED(PPAR)) RETURN IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' @@ -87,6 +87,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) ! IF(.NOT.ASSOCIATED(PNEXT) .AND. .NOT.ASSOCIATED(PPREV))THEN PPAR%NDIM = 0 + PPAR%PCHILD => NULL() FPAR%SUCCESS = .TRUE. ! ! STICH AND SUBSTRACT FROM PARENT From cd1b956b32a5f8d93d439091d4dda0a8b2378657 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Aug 2017 14:15:37 -0600 Subject: [PATCH 248/325] add current directory to list of specified directories with dependencies --- fort_depend.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fort_depend.py b/fort_depend.py index e24d35b..1667001 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -201,6 +201,10 @@ def get_all_files(path,dep): # list only files located in those # if not(dep == None): +# +# add current directory to list of specified directories with dependencies +# + dep.append(currdirr) for i in dep: # # use basolute path to preferred directories ie.: os.path.abspath(i) From b73285b7d1d0521bfaf233f76b91fd561f0dfdd9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Aug 2017 14:17:37 -0600 Subject: [PATCH 249/325] add updated dep script --- python_dep/fort_depend.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index e24d35b..1667001 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -201,6 +201,10 @@ def get_all_files(path,dep): # list only files located in those # if not(dep == None): +# +# add current directory to list of specified directories with dependencies +# + dep.append(currdirr) for i in dep: # # use basolute path to preferred directories ie.: os.path.abspath(i) From 06a163882c1d0ef068bf40e40a6936422328bfb4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Aug 2017 14:31:43 -0600 Subject: [PATCH 250/325] treat if -d contains external libraries --- fort_depend.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 1667001..4b25bd5 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -112,7 +112,7 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") print(" ") f=open(outfile,'w') - f.write('# This file is generated automatically. DO NOT EDIT!\n') + f.write('# This file is generated automatically by fort_depend.py. DO NOT EDIT!\n') for i in dep.keys(): tmp,fil=os.path.split(i) @@ -201,9 +201,6 @@ def get_all_files(path,dep): # list only files located in those # if not(dep == None): -# -# add current directory to list of specified directories with dependencies -# dep.append(currdirr) for i in dep: # @@ -231,9 +228,13 @@ def get_all_files(path,dep): # add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root - cwurrdirr=cwurrdirr.replace(path,'') - cwurrdirr = relapth + cwurrdirr + "/" - matches.append(os.path.join(cwurrdirr, filename)) + cwurrdirr = cwurrdirr.replace(path,'') +# +# if specified directory is a subdirectory in projet root path then add files +# otherwise not (it is possible then some external library is specified) + if root != cwurrdirr: + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) # # otherwise include all files from path dir # From b1420bc41b989340a2b27d502fbeb145b6708e5c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 1 Aug 2017 14:32:31 -0600 Subject: [PATCH 251/325] updated dep script --- accessories/fll_cat/depend.mk | 2 +- accessories/fll_convert/depend.mk | 2 +- data_util/depend.mk | 2 +- examples/Example_MPI-IO/depend.mk | 2 +- examples/Simple_data_operation/depend.mk | 2 +- mpi_util/depend.mk | 2 +- python_dep/fort_depend.py | 15 ++++++++------- 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/accessories/fll_cat/depend.mk b/accessories/fll_cat/depend.mk index 3cbf9f1..5031f63 100644 --- a/accessories/fll_cat/depend.mk +++ b/accessories/fll_cat/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_cat.o : \ ../../data_util/fll_mods.o diff --git a/accessories/fll_convert/depend.mk b/accessories/fll_convert/depend.mk index 41e91bd..0b8f538 100644 --- a/accessories/fll_convert/depend.mk +++ b/accessories/fll_convert/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_convert.o : \ ../../data_util/fll_mods.o diff --git a/data_util/depend.mk b/data_util/depend.mk index 93509b9..7d224cf 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_deattach.o : \ fll_stich.o \ diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 5e2ba4a..bf0d643 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! Example_mpi-IO.o : \ ../../data_util/fll_mods.o \ diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 4b1a81c..dc58dd3 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_test_subr.o : \ ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index f9a4577..4f8dc7f 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,4 +1,4 @@ -# This file is generated automatically. DO NOT EDIT! +# This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_mpi_mods.o : \ fll_mpi_write_snm.o \ diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 1667001..4b25bd5 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -112,7 +112,7 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, print("\033[031m Opening dependency file \033[032m"+outfile+"\033[039m ...") print(" ") f=open(outfile,'w') - f.write('# This file is generated automatically. DO NOT EDIT!\n') + f.write('# This file is generated automatically by fort_depend.py. DO NOT EDIT!\n') for i in dep.keys(): tmp,fil=os.path.split(i) @@ -201,9 +201,6 @@ def get_all_files(path,dep): # list only files located in those # if not(dep == None): -# -# add current directory to list of specified directories with dependencies -# dep.append(currdirr) for i in dep: # @@ -231,9 +228,13 @@ def get_all_files(path,dep): # add trailing / and then add ../ to get to project root path, ie..file will have relative path # cwurrdirr = root - cwurrdirr=cwurrdirr.replace(path,'') - cwurrdirr = relapth + cwurrdirr + "/" - matches.append(os.path.join(cwurrdirr, filename)) + cwurrdirr = cwurrdirr.replace(path,'') +# +# if specified directory is a subdirectory in projet root path then add files +# otherwise not (it is possible then some external library is specified) + if root != cwurrdirr: + cwurrdirr = relapth + cwurrdirr + "/" + matches.append(os.path.join(cwurrdirr, filename)) # # otherwise include all files from path dir # From 240f16a52948fce35d9f60b42fd40604d055c1e5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Aug 2017 07:29:58 -0600 Subject: [PATCH 252/325] set istat = 0 if retval == 0 --- fort_depend.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 4b25bd5..411139c 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -197,7 +197,6 @@ def get_all_files(path,dep): for isl in range(0, slsh_count): relapth += "../" # -# specified list of preferred directories # list only files located in those # if not(dep == None): @@ -442,6 +441,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): retval = 0 if not(cwd.strip() == dir): + retval=check_if_there(use=j,file=k) if retval > 0: @@ -454,8 +454,10 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") # print(" ") break #break loop, dependency declared + else: + istat = 0 - if istat== 0 and not(j == ""): + if istat== 0 and (j != ""): if int(verbose) > 2 : print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") From c0055d3bf25628c6b011289a39c869d1f2970592 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Aug 2017 07:40:33 -0600 Subject: [PATCH 253/325] new fix --- fort_depend.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 411139c..fd42e91 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -448,14 +448,12 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) + if int(verbose) > 2 : print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") -# print(" ") - break #break loop, dependency declared - else: - istat = 0 + break #break loop, dependency declared if istat== 0 and (j != ""): if int(verbose) > 2 : @@ -466,8 +464,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): # once module found, break the loop # # break #break loop, dependency declared - - if not(istat == 0): + if (istat != 0): # # if file containign module, add to the list # From 8eb16f254a451fe47daa90c96fa5e8b45dfff448 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Aug 2017 07:41:21 -0600 Subject: [PATCH 254/325] updted version of dependency script --- python_dep/fort_depend.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index 4b25bd5..fd42e91 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -197,7 +197,6 @@ def get_all_files(path,dep): for isl in range(0, slsh_count): relapth += "../" # -# specified list of preferred directories # list only files located in those # if not(dep == None): @@ -442,20 +441,21 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): retval = 0 if not(cwd.strip() == dir): + retval=check_if_there(use=j,file=k) if retval > 0: istat = 1 name=os.path.splitext(k)[0]+'.o' tmp.append(name.lower()) + if int(verbose) > 2 : print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") -# print(" ") - break #break loop, dependency declared + break #break loop, dependency declared - if istat== 0 and not(j == ""): + if istat== 0 and (j != ""): if int(verbose) > 2 : print("") print ("\033[031m Note!!!!: \033[039m module \033[032m"+j+"\033[039m not defined in any file") @@ -464,8 +464,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): # once module found, break the loop # # break #break loop, dependency declared - - if not(istat == 0): + if (istat != 0): # # if file containign module, add to the list # From 466eafaccbe24d6160e9e840601b2ba487225db5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Aug 2017 20:51:38 -0600 Subject: [PATCH 255/325] if path not specified, use cwd --- fort_depend.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index fd42e91..a663daf 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -45,7 +45,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() - +# +# if project root path not specified, used current directory +# + if(path == None): + path = os.getcwd() + path = check_path(path=path) cwd = check_path(path=cwd) From 530aeb0ca06241e3e37a55faaa3d410842817594 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 2 Aug 2017 20:54:08 -0600 Subject: [PATCH 256/325] update depend script --- data_util/depend.mk | 202 +++++++++++------------ examples/Example_MPI-IO/depend.mk | 14 +- examples/Simple_data_operation/depend.mk | 6 +- mpi_util/depend.mk | 70 ++++---- python_dep/fort_depend.py | 7 +- 5 files changed, 152 insertions(+), 147 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 7d224cf..2236ab1 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,148 +1,148 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -fll_deattach.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o - -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_out.o \ - fll_type.o - -fll_getnbytes.o : \ - fll_out.o \ - fll_type.o - -fll_mkdir.o : \ - fll_mk.o \ - fll_type.o +fll_type.o : -fll_cat.o : \ - fll_out.o \ - fll_type.o +fll_scan_file.o : \ + fll_read.o \ + fll_type.o \ + fll_out.o -fll_type.o : +fll_write_ffa.o : \ + fll_type.o \ + fll_out.o -fll_stich.o : \ - fll_out.o \ - fll_type.o +fll_rm.o : \ + fll_type.o \ + fll_stich.o \ + fll_out.o -fll_funct_prt.o : \ - fll_out.o \ - fll_type.o +fll_read_ffa.o : \ + fll_funct_prt.o \ + fll_mv.o \ + fll_mk.o \ + fll_type.o \ + fll_out.o fll_sweep.o : \ - fll_match_pattern.o \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_match_pattern.o + +fll_match_pattern.o : \ + fll_type.o \ + fll_out.o fll_read_record.o : \ fll_mv.o \ - fll_cat.o \ fll_out.o \ - fll_locate.o \ - fll_rm.o \ fll_mk.o \ + fll_read.o \ + fll_rm.o \ + fll_locate.o \ fll_type.o \ - fll_read.o + fll_cat.o -fll_read.o : \ +fll_mods.o : \ fll_mv.o \ - fll_funct_prt.o \ + fll_stich.o \ + fll_duplicate.o \ + fll_write_ffa.o \ fll_mk.o \ + fll_read.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_cat.o \ + fll_read_ffa.o \ + fll_read_record.o \ + fll_sweep.o \ + fll_rm.o \ + fll_write.o \ + fll_type.o \ + fll_match_pattern.o \ + fll_funct_prt.o \ + fll_getnbytes.o \ + fll_scan_file.o \ fll_out.o \ - fll_type.o + fll_locate.o \ + fll_mkdir.o \ + fll_cp.o \ + fll_deattach.o fll_cp.o : \ fll_mv.o \ - fll_cat.o \ fll_out.o \ fll_duplicate.o \ fll_rm.o \ - fll_stich.o \ - fll_type.o - -fll_scan_file.o : \ - fll_read.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_cat.o \ + fll_stich.o fll_mv.o : \ - fll_stich.o \ fll_out.o \ + fll_type.o \ fll_rm.o \ - fll_type.o - -fll_write.o : \ - fll_out.o \ - fll_type.o + fll_stich.o -fll_getndata.o : \ - fll_locate.o \ - fll_out.o \ - fll_type.o - -fll_match_pattern.o : \ - fll_out.o \ - fll_type.o +fll_getnbytes.o : \ + fll_type.o \ + fll_out.o -fll_read_ffa.o : \ - fll_mv.o \ +fll_read.o : \ fll_funct_prt.o \ + fll_mv.o \ fll_mk.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o + +fll_stich.o : \ + fll_type.o \ + fll_out.o fll_locate.o : \ fll_funct_prt.o \ - fll_out.o \ - fll_type.o - -fll_duplicate.o : \ - fll_mv.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o -fll_mods.o : \ - fll_mv.o \ - fll_out.o \ - fll_funct_prt.o \ +fll_deattach.o : \ + fll_type.o \ fll_stich.o \ - fll_match_pattern.o \ + fll_out.o + +fll_write.o : \ fll_type.o \ - fll_mkdir.o \ - fll_cat.o \ - fll_write.o \ - fll_read_record.o \ - fll_write_ffa.o \ - fll_getnbytes.o \ - fll_mk.o \ - fll_deattach.o \ - fll_scan_file.o \ - fll_duplicate.o \ - fll_sweep.o \ - fll_rm.o \ - fll_nnodes.o \ - fll_getndata.o \ - fll_read_ffa.o \ - fll_locate.o \ - fll_cp.o \ - fll_read.o + fll_out.o -fll_rm.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o +fll_getndata.o : \ + fll_type.o \ + fll_locate.o \ + fll_out.o fll_mk.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o fll_out.o : \ fll_type.o -fll_write_ffa.o : \ - fll_out.o \ +fll_mkdir.o : \ + fll_mk.o \ fll_type.o + +fll_funct_prt.o : \ + fll_type.o \ + fll_out.o + +fll_cat.o : \ + fll_type.o \ + fll_out.o + +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ + fll_type.o \ + fll_out.o + +fll_nnodes.o : \ + fll_funct_prt.o \ + fll_type.o \ + fll_out.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index bf0d643..7d5891c 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! Example_mpi-IO.o : \ - ../../data_util/fll_mods.o \ - save_root_part_file.o \ - create_data_set.o \ save_individ_files.o \ + create_data_set.o \ read_input.o \ - ../../mpi_util/fll_mpi_mods.o + ../../mpi_util/fll_mpi_mods.o \ + ../../data_util/fll_mods.o \ + save_root_part_file.o -save_individ_files.o : \ +read_input.o : \ ../../data_util/fll_mods.o -read_input.o : \ +save_root_part_file.o : \ ../../data_util/fll_mods.o create_data_set.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index dc58dd3..05db098 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -1,8 +1,8 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -fll_test_subr.o : \ - ../../data_util/fll_mods.o - fll_test.o : \ ../../data_util/fll_mods.o \ fll_test_subr.o + +fll_test_subr.o : \ + ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 4f8dc7f..17502e2 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -fll_mpi_mods.o : \ - fll_mpi_write_snm.o \ - fll_mpi_cp.o \ - fll_mpi_proc_struct.o \ - fll_mpi_write_nm.o \ - fll_mpi_write.o \ - fll_mpi_sum.o \ - fll_mpi_mv.o \ - fll_mpi_read.o \ - fll_mpi_cp_all.o - -fll_mpi_sum.o : \ - ../data_util/fll_mods.o - -fll_mpi_write_nm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_write.o - fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o - -fll_mpi_write_snm.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp.o - -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o + ../data_util/fll_mv.o \ + ../data_util/fll_out.o \ + ../data_util/fll_type.o fll_mpi_read.o : \ - ../data_util/fll_mods.o \ - fll_mpi_cp_all.o + fll_mpi_cp_all.o \ + ../data_util/fll_mods.o fll_mpi_mv.o : \ fll_mpi_cp.o \ - ../data_util/fll_type.o \ ../data_util/fll_out.o \ - ../data_util/fll_rm.o + ../data_util/fll_rm.o \ + ../data_util/fll_type.o + +fll_mpi_write_snm.o : \ + fll_mpi_cp.o \ + ../data_util/fll_mods.o fll_mpi_write.o : \ ../data_util/fll_mods.o \ fll_mpi_sum.o fll_mpi_cp.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_type.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o + ../data_util/fll_mv.o \ + ../data_util/fll_out.o \ + ../data_util/fll_type.o + +fll_mpi_mods.o : \ + fll_mpi_proc_struct.o \ + fll_mpi_write.o \ + fll_mpi_cp.o \ + fll_mpi_write_nm.o \ + fll_mpi_write_snm.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o \ + fll_mpi_sum.o + +fll_mpi_write_nm.o : \ + fll_mpi_write.o \ + ../data_util/fll_mods.o + +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o + +fll_mpi_sum.o : \ + ../data_util/fll_mods.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index fd42e91..a663daf 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -45,7 +45,12 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output=None,macros={},build=''): cwd = os.getcwd() - +# +# if project root path not specified, used current directory +# + if(path == None): + path = os.getcwd() + path = check_path(path=path) cwd = check_path(path=cwd) From d19d638b78951999338e8b76ed51b013d21273e4 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 4 Aug 2017 08:50:40 -0600 Subject: [PATCH 257/325] expand err statements in Cp, Mv --- data_util/fll_cp.f90 | 6 +++--- data_util/fll_mv.f90 | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 570a83a..f5627c5 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -76,7 +76,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' - WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node ' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN @@ -146,7 +146,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' - WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN @@ -155,7 +155,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! check that pwhere is associated ! IF(.NOT.ASSOCIATED(PWHERE))THEN - WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhere null node' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 9cd71a7..db4e4a0 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -114,14 +114,14 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN - WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhat null node' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF IF(.NOT.ASSOCIATED(PWHERE))THEN - WRITE(FPAR%MESG,'(A,A)')' Mv, Cp - null node ' + WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhere null node' CALL FLL_OUT('ALL',FPAR) FPAR%SUCCESS = .FALSE. RETURN From 66cd0641b7f9d4063f55e5cf644086a3ea1035cc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 4 Aug 2017 10:37:38 -0600 Subject: [PATCH 258/325] if data set not found, nullify pointer --- data_util/fll_getndata.f90 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 9988bb5..00481a8 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -149,6 +149,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME + R1=>NULL() CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -213,6 +214,7 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + R2=>NULL() RETURN END IF @@ -343,6 +345,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + R1=>NULL() RETURN END IF @@ -407,6 +410,7 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + R2=>NULL() RETURN END IF @@ -536,6 +540,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + I1=>NULL() RETURN END IF @@ -598,6 +603,7 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + I2=>NULL() RETURN END IF @@ -715,6 +721,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + I1=>NULL() RETURN END IF @@ -777,6 +784,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + I2=>NULL() RETURN END IF @@ -901,6 +909,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + STRING=>NULL() RETURN END IF @@ -963,6 +972,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) + STRING=>NULL() RETURN END IF From e20e712b1de347ee81e0d830605118104b7674dc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Aug 2017 08:42:49 -0600 Subject: [PATCH 259/325] correct parameter err message --- accessories/fll_convert/fll_convert.py | 2 +- data_util/depend.mk | 202 ++++++++++++------------- 2 files changed, 102 insertions(+), 102 deletions(-) diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 03ab093..817634f 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -107,7 +107,7 @@ def check_path(path): sys.exit() if not format: - print ("\033[031mError: \033[039m missing file format, option\033[031m -c \033[039m") + print ("\033[031mError: \033[039m missing file format, option\033[031m -f \033[039m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") print ("\033[031m \033[039m \033[032m b - binary format\033[039m") sys.exit() diff --git a/data_util/depend.mk b/data_util/depend.mk index 2236ab1..7d224cf 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,148 +1,148 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -fll_type.o : - -fll_scan_file.o : \ - fll_read.o \ - fll_type.o \ - fll_out.o - -fll_write_ffa.o : \ - fll_type.o \ - fll_out.o - -fll_rm.o : \ - fll_type.o \ +fll_deattach.o : \ fll_stich.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_read_ffa.o : \ +fll_nnodes.o : \ fll_funct_prt.o \ - fll_mv.o \ + fll_out.o \ + fll_type.o + +fll_getnbytes.o : \ + fll_out.o \ + fll_type.o + +fll_mkdir.o : \ fll_mk.o \ - fll_type.o \ - fll_out.o + fll_type.o -fll_sweep.o : \ - fll_type.o \ +fll_cat.o : \ fll_out.o \ - fll_match_pattern.o + fll_type.o -fll_match_pattern.o : \ - fll_type.o \ - fll_out.o +fll_type.o : + +fll_stich.o : \ + fll_out.o \ + fll_type.o + +fll_funct_prt.o : \ + fll_out.o \ + fll_type.o + +fll_sweep.o : \ + fll_match_pattern.o \ + fll_out.o \ + fll_type.o fll_read_record.o : \ fll_mv.o \ + fll_cat.o \ fll_out.o \ - fll_mk.o \ - fll_read.o \ - fll_rm.o \ fll_locate.o \ + fll_rm.o \ + fll_mk.o \ fll_type.o \ - fll_cat.o + fll_read.o -fll_mods.o : \ +fll_read.o : \ fll_mv.o \ - fll_stich.o \ - fll_duplicate.o \ - fll_write_ffa.o \ - fll_mk.o \ - fll_read.o \ - fll_nnodes.o \ - fll_getndata.o \ - fll_cat.o \ - fll_read_ffa.o \ - fll_read_record.o \ - fll_sweep.o \ - fll_rm.o \ - fll_write.o \ - fll_type.o \ - fll_match_pattern.o \ fll_funct_prt.o \ - fll_getnbytes.o \ - fll_scan_file.o \ + fll_mk.o \ fll_out.o \ - fll_locate.o \ - fll_mkdir.o \ - fll_cp.o \ - fll_deattach.o + fll_type.o fll_cp.o : \ fll_mv.o \ + fll_cat.o \ fll_out.o \ fll_duplicate.o \ fll_rm.o \ - fll_type.o \ - fll_cat.o \ - fll_stich.o + fll_stich.o \ + fll_type.o -fll_mv.o : \ +fll_scan_file.o : \ + fll_read.o \ fll_out.o \ - fll_type.o \ - fll_rm.o \ - fll_stich.o - -fll_getnbytes.o : \ - fll_type.o \ - fll_out.o - -fll_read.o : \ - fll_funct_prt.o \ - fll_mv.o \ - fll_mk.o \ - fll_type.o \ - fll_out.o - -fll_stich.o : \ - fll_type.o \ - fll_out.o - -fll_locate.o : \ - fll_funct_prt.o \ - fll_type.o \ - fll_out.o + fll_type.o -fll_deattach.o : \ - fll_type.o \ +fll_mv.o : \ fll_stich.o \ - fll_out.o + fll_out.o \ + fll_rm.o \ + fll_type.o fll_write.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o fll_getndata.o : \ - fll_type.o \ fll_locate.o \ - fll_out.o - -fll_mk.o : \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_out.o : \ +fll_match_pattern.o : \ + fll_out.o \ fll_type.o -fll_mkdir.o : \ +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ fll_mk.o \ + fll_out.o \ fll_type.o -fll_funct_prt.o : \ - fll_type.o \ - fll_out.o - -fll_cat.o : \ - fll_type.o \ - fll_out.o +fll_locate.o : \ + fll_funct_prt.o \ + fll_out.o \ + fll_type.o fll_duplicate.o : \ fll_mv.o \ fll_mk.o \ - fll_type.o \ - fll_out.o + fll_out.o \ + fll_type.o -fll_nnodes.o : \ +fll_mods.o : \ + fll_mv.o \ + fll_out.o \ fll_funct_prt.o \ + fll_stich.o \ + fll_match_pattern.o \ fll_type.o \ - fll_out.o + fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ + fll_read_record.o \ + fll_write_ffa.o \ + fll_getnbytes.o \ + fll_mk.o \ + fll_deattach.o \ + fll_scan_file.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o + +fll_rm.o : \ + fll_stich.o \ + fll_out.o \ + fll_type.o + +fll_mk.o : \ + fll_out.o \ + fll_type.o + +fll_out.o : \ + fll_type.o + +fll_write_ffa.o : \ + fll_out.o \ + fll_type.o From bd64d1170ef566decd9308f8e997f0eef9e6e679 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Aug 2017 09:12:26 -0600 Subject: [PATCH 260/325] add fll_rename function --- data_util/depend.mk | 5 +++ data_util/fll_mods.f90 | 1 + data_util/fll_rename.f90 | 80 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 data_util/fll_rename.f90 diff --git a/data_util/depend.mk b/data_util/depend.mk index 7d224cf..31248c1 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -68,6 +68,10 @@ fll_scan_file.o : \ fll_out.o \ fll_type.o +fll_rename.o : \ + fll_out.o \ + fll_type.o + fll_mv.o : \ fll_stich.o \ fll_out.o \ @@ -115,6 +119,7 @@ fll_mods.o : \ fll_mkdir.o \ fll_cat.o \ fll_write.o \ + fll_rename.o \ fll_read_record.o \ fll_write_ffa.o \ fll_getnbytes.o \ diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 486e607..0c0204c 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -58,5 +58,6 @@ MODULE FLL_MODS_M USE FLL_MATCH_PATTERN_M USE FLL_GETNBYTES_M USE FLL_SCAN_FILE_M + USE FLL_RENAME_M END MODULE FLL_MODS_M diff --git a/data_util/fll_rename.f90 b/data_util/fll_rename.f90 new file mode 100644 index 0000000..2ab7ff2 --- /dev/null +++ b/data_util/fll_rename.f90 @@ -0,0 +1,80 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! Subroutine FLL_RENAME +! +! +MODULE FLL_RENAME_M +! +! Description: Contains function fll_rename +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/08/17 Initial implementation +! +! +! External Modules used +! + +CONTAINS + FUNCTION FLL_RENAME(PWHAT,NAME,FPAR) RESULT(OK) +! +! Description: Renames node +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PWHAT In pointer which is to be copied +! FPAR In/Out structure containing function specific data +! NAME In New node name +! OK Out Return parameter +! +! Arguments declaration +! + IMPLICIT NONE + TYPE(DNODE), POINTER :: PWHAT + TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=NAME_LENGTH) :: NAME + LOGICAL :: OK +! +! check that PWHAT is not NULL +! + IF(.NOT.ASSOCIATED(PWHAT))THEN + WRITE(*,*)' Rename - SOURCE IS NULL NODE' + WRITE(FPAR%MESG,'(A,A)')' Rename - Pwhat null node ' + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + OK = .FALSE. + RETURN + END IF + + PWHAT%LNAME = ADJUSTL(TRIM(NAME)) + OK = .TRUE. + + RETURN + END FUNCTION FLL_RENAME + +END MODULE FLL_RENAME_M From 7d06120239c32307651d625bbaf1b1aa211919ad Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Aug 2017 11:08:03 -0600 Subject: [PATCH 261/325] fix length of character in declaration --- data_util/fll_rename.f90 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/data_util/fll_rename.f90 b/data_util/fll_rename.f90 index 2ab7ff2..244c14f 100644 --- a/data_util/fll_rename.f90 +++ b/data_util/fll_rename.f90 @@ -34,7 +34,7 @@ MODULE FLL_RENAME_M ! CONTAINS - FUNCTION FLL_RENAME(PWHAT,NAME,FPAR) RESULT(OK) + FUNCTION FLL_RENAME(PWHAT,INAME,FPAR) RESULT(OK) ! ! Description: Renames node ! @@ -57,7 +57,7 @@ FUNCTION FLL_RENAME(PWHAT,NAME,FPAR) RESULT(OK) IMPLICIT NONE TYPE(DNODE), POINTER :: PWHAT TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(LEN=NAME_LENGTH) :: NAME + CHARACTER(LEN=*) :: INAME LOGICAL :: OK ! ! check that PWHAT is not NULL @@ -71,7 +71,8 @@ FUNCTION FLL_RENAME(PWHAT,NAME,FPAR) RESULT(OK) RETURN END IF - PWHAT%LNAME = ADJUSTL(TRIM(NAME)) + PWHAT%LNAME = ADJUSTL(TRIM(INAME)) + OK = .TRUE. RETURN From 619d5242cca01adf40f4f9e32313b554d62177bc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Aug 2017 11:08:15 -0600 Subject: [PATCH 262/325] got to big endian in FLL format --- data_util/fll_read.f90 | 2 +- data_util/fll_write.f90 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 4e49e45..494050a 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -141,7 +141,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) SELECT CASE(FMT_LOC) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& - ACCESS='STREAM',IOSTAT=ISTAT) + ACCESS='STREAM',CONVERT='big_endian',IOSTAT=ISTAT) CASE('A') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& IOSTAT=ISTAT, ACTION = 'READ') diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 7f09b23..6af54c9 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -97,7 +97,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) SELECT CASE(FMT_LOC) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& - ACCESS='STREAM',IOSTAT=ISTAT) + ACCESS='STREAM',CONVERT='big_endian',IOSTAT=ISTAT) CASE('A') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& IOSTAT=ISTAT,ACTION='WRITE') From 0ebb3fee269c6ca00905911bdfcb86c4fba051eb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 10 Aug 2017 13:04:28 -0600 Subject: [PATCH 263/325] fix err statement --- data_util/fll_getndata.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 00481a8..817555e 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -835,7 +835,7 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S0 - Null node ' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -844,7 +844,7 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) RETURN @@ -897,7 +897,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S1 - Null node ' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -906,7 +906,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) STRING=>NULL() @@ -960,7 +960,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' + WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S2 - Null node ' CALL FLL_OUT('ALL',FPAR) RETURN END IF @@ -969,7 +969,7 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. - WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& + WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME CALL FLL_OUT('ALL',FPAR) STRING=>NULL() From f9b0075c68cfefcfbb3b57341247a0bc46ec3cc2 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 12 Aug 2017 16:48:48 -0600 Subject: [PATCH 264/325] fix error in fll_duplicate --- data_util/fll_duplicate.f90 | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index e395d90..a3a0574 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -97,7 +97,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) PNEW => NULL() RETURN END IF - + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' @@ -162,7 +162,6 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) LOGICAL :: OK ! PCURR => PNODE - PCHILD => PNODE%PCHILD ! ! LOOP OVER CHILDREN ! @@ -182,29 +181,25 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) IF(.NOT.ASSOCIATED(PCHILD))THEN CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR) - OK = FLL_MV(PNEW, PDUPL, FPAR) + ELSE ! ! NODE HAS CHILDREN ! - DO WHILE(ASSOCIATED(PCHILD)) - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' - PCHILD => PCHILD%PNEXT - - END DO - END IF ! ! ADD TO PDUPL LIST ! OK = FLL_MV(PNEW,PDUPL,FPAR) + PCURR => PNEXT END DO FPAR%SUCCESS = .TRUE. + RETURN END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE From 9bec704618fd568fe38d52bb75eea8d21aefefb6 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Aug 2017 09:22:41 -0600 Subject: [PATCH 265/325] extend ffa_convert --- accessories/fll_convert/fll_convert.f90 | 15 +++++++------ accessories/fll_convert/fll_convert.py | 30 ++++++++++++++++++------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/accessories/fll_convert/fll_convert.f90 b/accessories/fll_convert/fll_convert.f90 index ac6e231..9edb2aa 100644 --- a/accessories/fll_convert/fll_convert.f90 +++ b/accessories/fll_convert/fll_convert.f90 @@ -62,7 +62,7 @@ PROGRAM FLL_CONVERT CHARACTER(LEN=FILE_NAME_LENGTH) FILE,OUTFILE TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER :: FMT, SCAN + CHARACTER :: FMT, SCAN, FMTO CHARACTER(LEN=3) :: EFMT,OFMT LOGICAL :: OK ! @@ -72,20 +72,21 @@ PROGRAM FLL_CONVERT READ(*,*)FMT READ(*,'(A3)')EFMT READ(*,'(A1024)')OUTFILE - READ(*,'(A3)')OFMT + READ(*,'(A3)')OFMT + READ(*,*)FMTO SELECT CASE(EFMT) - CASE('fll') - PNODE => FLL_READ(FILE,8,FMT,FPAR) CASE('ffa') PNODE => FLL_READ_FFA(FILE,8,FMT,FPAR) + CASE DEFAULT + PNODE => FLL_READ(FILE,8,FMT,FPAR) END SELECT SELECT CASE(OFMT) - CASE('fll') - OK = FLL_WRITE(PNODE,OUTFILE,9,FMT,FPAR) CASE('ffa') - OK = FLL_WRITE_FFA(PNODE, OUTFILE,9,FMT,FPAR) + OK = FLL_WRITE_FFA(PNODE, OUTFILE,9,FMTO,FPAR) + CASE DEFAULT + OK = FLL_WRITE(PNODE,OUTFILE,9,FMTO,FPAR) END SELECT diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 817634f..01ccbff 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -11,7 +11,7 @@ #Definitions -def run(file,fmt,efmt,ofile,ofmt): +def run(file,fmt,efmt,ofile,ofmt,fmto): # # execute # @@ -48,18 +48,24 @@ def run(file,fmt,efmt,ofile,ofmt): print("\033[039m Specified input file format is: \033[032mbinary\033[039m") else: print("\033[039m Specified input file format is: \033[032mASCII \033[039m") + + if fmto == 'b' or fmto == 'B': + print("\033[039m Specified input file format is: \033[032mbinary\033[039m") + else: + print("\033[039m Specified input file format is: \033[032mASCII \033[039m") if ofmt == 'fll': print("\033[039m Specified output file type is: \033[032mFLL \033[039m") else: print("\033[039m Specified output file type is: \033[032mFFA \033[039m") + if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt, efmt, ofile,ofmt])) + p.communicate(os.linesep.join([file, fmt, efmt, ofile,ofmt,fmto])) else: p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here - p.communicate(os.linesep.join( [file, fmt, efmt, ofile,ofmt])) + p.communicate(os.linesep.join( [file, fmt, efmt, ofile,ofmt,fmto])) def print_header(): print(" ") @@ -87,10 +93,11 @@ def check_path(path): # Add command line arguments parser = argparse.ArgumentParser(description='FLL configure script') parser.add_argument('-i','--file',nargs=1,help='Input file') - parser.add_argument('-f','--format',nargs=1,help='Format of the file - ASCII, binary') parser.add_argument('-o','--output_file',nargs=1,help='Output file') - parser.add_argument('-e','--format_input',nargs=1,help='Input file format') - parser.add_argument('-g','--format_output',nargs=1,help='Output file format') + parser.add_argument('-fi','--format_i',nargs=1,help='Format of the input file - ASCII, binary') + parser.add_argument('-ei','--format_input',nargs=1,help='Input file format (fll, ffa)') + parser.add_argument('-fe','--format_o',nargs=1,help='Format of the output file - ASCII, binary') + parser.add_argument('-eo','--format_output',nargs=1,help='Output file format') # Parse the command line arguments @@ -101,13 +108,20 @@ def check_path(path): eformat = args.format_input[0] if args.format_input else None oformat = args.format_output[0] if args.format_output else None output = args.output_file[0] if args.output_file else None + formato = args.format_o[0] if args.format_o else None if not file: print ("\033[031mError: \033[039m missing name of file, option \033[031m -i \033[039m") sys.exit() if not format: - print ("\033[031mError: \033[039m missing file format, option\033[031m -f \033[039m") + print ("\033[031mError: \033[039m missing input file format, option\033[031m -f \033[039m") + print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") + print ("\033[031m \033[039m \033[032m b - binary format\033[039m") + sys.exit() + + if not formato: + print ("\033[031mError: \033[039m missing output file format, option\033[031m -f \033[039m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") print ("\033[031m \033[039m \033[032m b - binary format\033[039m") sys.exit() @@ -137,4 +151,4 @@ def check_path(path): print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() - run(file=file,fmt=format, efmt = eformat, ofile=output, ofmt = oformat) + run(file=file,fmt=format, efmt = eformat, ofile=output, ofmt = oformat, fmto = formato) From c29fe4489129c9a4c333d1cfea944808515fd329 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 17 Aug 2017 09:52:50 -0600 Subject: [PATCH 266/325] add check for input parameters to python wrappers --- accessories/fll_cat/fll_cat.py | 5 +++++ accessories/fll_convert/fll_convert.py | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 1a0c4ce..3f2be7f 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -104,6 +104,11 @@ def check_path(path): else: dir = 'Y' + if not len(sys.argv) > 1: + print("\nfll_cat - prints content of file on standard output\n") + print("usage: fll_cat.py [-h] [-i FILE] [-f FORMAT] [-s] [-D] [-e EXTERNAL_FORMAT]\n") + sys.exit() + if not file: print ("\033[031mError: \033[039m missing name of file, option\033[031m -i \033[039m") sys.exit() diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index 01ccbff..b1ced70 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -104,12 +104,18 @@ def check_path(path): args = parser.parse_args() file = args.file[0] if args.file else None - format = args.format[0] if args.format else None + format_i = args.format[0] if args.format_i else None eformat = args.format_input[0] if args.format_input else None oformat = args.format_output[0] if args.format_output else None output = args.output_file[0] if args.output_file else None formato = args.format_o[0] if args.format_o else None + + if not len(sys.argv) > 1: + print("\nfll_convert - converts files\n") + print("usage: fll_convert.py [-h] [-i FILE] [-o OUTPUT_FILE] [-fi FORMAT_I] \n [-ei FORMAT_INPUT] [-fe FORMAT_O] [-eo FORMAT_OUTPUT]\n") + sys.exit() + if not file: print ("\033[031mError: \033[039m missing name of file, option \033[031m -i \033[039m") sys.exit() From d0549da8b787759941c0f82e9b5e28b35c7042e2 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Aug 2017 15:39:49 -0600 Subject: [PATCH 267/325] add reading of ucd surface mesh files --- data_util/depend.mk | 7 + data_util/fll_mods.f90 | 1 + data_util/fll_read_ucd.f90 | 314 +++++++++++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 data_util/fll_read_ucd.f90 diff --git a/data_util/depend.mk b/data_util/depend.mk index 31248c1..f53c0c0 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -54,6 +54,12 @@ fll_read.o : \ fll_out.o \ fll_type.o +fll_read_ucd.o : \ + fll_mv.o \ + fll_mk.o \ + fll_out.o \ + fll_type.o + fll_cp.o : \ fll_mv.o \ fll_cat.o \ @@ -129,6 +135,7 @@ fll_mods.o : \ fll_duplicate.o \ fll_sweep.o \ fll_rm.o \ + fll_read_ucd.o \ fll_nnodes.o \ fll_getndata.o \ fll_read_ffa.o \ diff --git a/data_util/fll_mods.f90 b/data_util/fll_mods.f90 index 0c0204c..9b61c32 100644 --- a/data_util/fll_mods.f90 +++ b/data_util/fll_mods.f90 @@ -59,5 +59,6 @@ MODULE FLL_MODS_M USE FLL_GETNBYTES_M USE FLL_SCAN_FILE_M USE FLL_RENAME_M + USE FLL_READ_UCD_M END MODULE FLL_MODS_M diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 new file mode 100644 index 0000000..c636a6b --- /dev/null +++ b/data_util/fll_read_ucd.f90 @@ -0,0 +1,314 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Rree Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or RITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Subroutine FLL_READ_UCD +! +! Date: 2016-10-10 +! +! +! +! +! Description: reads a UCD file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! +MODULE FLL_READ_UCD_M +! +! Description: Contains functions reading FLL native format file, ASCII and BINARY +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! +CONTAINS + + FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) +! +! Description: main function opening, reading and closing file +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! FILE In Name of file +! PNODE Out Node to a first node in list from a file +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary, * not specified +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + CHARACTER(*) :: FILE + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! Local declarations +! + LOGICAL :: OK + CHARACTER :: FMT_LOC + INTEGER :: ISTAT + INTEGER(LINT) :: POS + + write(*,*)' here in ther' + + INQUIRE (FILE=TRIM(FILE), EXIST=OK) + IF(.NOT.OK) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! DETERMINE RORMAT +! + write(*,*)' here in ther1' + + SELECT CASE(FMT) + CASE('A','a') + FMT_LOC = 'A' + CASE('B','b') + FMT_LOC = 'B' + CASE('U','u','*') + FMT_LOC = 'U' + CASE DEFAULT + WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END SELECT +! +! OPEN THE FILE +! + write(*,*)' here in ther2' + + SELECT CASE(FMT_LOC) + CASE('B') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& + ACCESS='STREAM',CONVERT='big_endian',IOSTAT=ISTAT) + CASE('A') + OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='FORMATTED',& + IOSTAT=ISTAT, ACTION = 'READ') + END SELECT + + IF(ISTAT/=0) THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + PNODE => NULL() + RETURN + END IF +! +! READ INITIAL NODE +! + write(*,*)' here in ther3' + POS = 1 + PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR) + + CLOSE(IOUNIT) + IF(.NOT.ASSOCIATED(PNODE))THEN + WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) + CALL FLL_OUT('ALL',FPAR) + FPAR%SUCCESS = .FALSE. + END IF + + RETURN + + END FUNCTION FLL_READ_UCD + + + + + FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) +! +! Description: Function reads a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MKDIR_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! Local declarations +! + TYPE(DNODE), POINTER :: PREG,PTMP,PBND,PBELEM + CHARACTER(LEN=NAME_LENGTH) :: TEXT + CHARACTER(LEN=6) :: ETYPE + INTEGER(LINT) :: NPTS,NELEM,A,B,C,I,N3,N4 + REAL(RDOUBLE), POINTER :: COO(:,:) + INTEGER(LINT), ALLOCATABLE :: I4(:,:),I3(:,:) + INTEGER :: ISTAT + LOGICAL :: OK + CHARACTER(LEN = 200)TEXTLONG +! +! disregard all lines starting with # - 3 lines +! + READ(IOUNIT, '(A)')TEXT + READ(IOUNIT, '(A)')TEXT + READ(IOUNIT, '(A)')TEXT +! +! read mesh dimensions +! + READ(IOUNIT,*)NPTS,NELEM,A,B,C +! +! allocate memory for coordinates +! + PNODE => FLL_MKDIR('unstr_grid_data', FPAR) + PREG => FLL_MKDIR('region', FPAR) + OK = FLL_MV(PREG,PNODE,FPAR) + PBND => FLL_MKDIR('boundary', FPAR) + OK = FLL_MV(PBND,PREG,FPAR) + + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR) + OK = FLL_MV(PTMP,PREG,FPAR) + COO => PTMP%D2 + + DO I=1,NPTS + READ(IOUNIT,*)A,COO(I,:) + END DO +! +! add boundary name +! + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR) + PTMP%S0 = 'wall' +! +! read elements +! + N3 = 0 + N4 = 0 +! + ALLOCATE(I3(NELEM,3),I4(NELEM,4), STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:260 ' + + + DO I=1,NELEM + READ(IOUNIT,'(A)')TEXTLONG + READ(TEXTLONG,*)A,B,ETYPE + SELECT CASE(ETYPE) + CASE('tri') + N3 = N3 + 1 + READ(TEXTLONG, *)A,B,ETYPE,I3(N3,:) + CASE('quad') + N4 = N4 + 1 + READ(TEXTLONG, *)A,B,ETYPE,I4(N4,:) + END SELECT + + END DO + + WRITE(*,*)N3,N4,N3+N4 +! +! add it to the structure +! + IF(N3> 0)THEN + + PBELEM => FLL_MKDIR('belem_group', FPAR) + OK = FLL_MV(PBELEM,PBND,FPAR) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR) + PTMP%S0 = 'tria3' + PTMP => FLL_MK('bound_elem_nodes','L',N3,3_LINT,FPAR) + PTMP%L2 = I3(1:N3,:) + OK = FLL_MV(PTMP,PBELEM,FPAR) + END IF + + IF(N4> 0)THEN + + PBELEM => FLL_MKDIR('belem_group', FPAR) + OK = FLL_MV(PBELEM,PBND,FPAR) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR) + PTMP%S0 = 'quad4' + PTMP => FLL_MK('bound_elem_nodes','L',N4,4_LINT,FPAR) + PTMP%L2 = I4(1:N4,:) + OK = FLL_MV(PTMP,PBELEM,FPAR) + + END IF + + + DEALLOCATE(I3,I4, STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:277 ' + + END FUNCTION READ_NODE_UCD + + +END MODULE FLL_READ_UCD_M From 17b7b53f34b2337ae433fe31c06b2414489f96fd Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Aug 2017 15:43:16 -0600 Subject: [PATCH 268/325] cleanup --- data_util/fll_read_ucd.f90 | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index c636a6b..0865ff1 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -101,8 +101,6 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) INTEGER :: ISTAT INTEGER(LINT) :: POS - write(*,*)' here in ther' - INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) @@ -112,10 +110,8 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) RETURN END IF ! -! DETERMINE RORMAT +! DETERMINE FORMAT ! - write(*,*)' here in ther1' - SELECT CASE(FMT) CASE('A','a') FMT_LOC = 'A' @@ -133,8 +129,6 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! OPEN THE FILE ! - write(*,*)' here in ther2' - SELECT CASE(FMT_LOC) CASE('B') OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& @@ -154,7 +148,6 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! READ INITIAL NODE ! - write(*,*)' here in ther3' POS = 1 PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR) @@ -274,8 +267,6 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) END SELECT END DO - - WRITE(*,*)N3,N4,N3+N4 ! ! add it to the structure ! From 99b590bf5e64a4efefb9f96e7aba0c657aaa9357 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 21 Aug 2017 18:56:03 -0600 Subject: [PATCH 269/325] add miscalenuous add miscalenuous --- Makefile | 1 + data_util/depend.mk | 186 +++++++++++++-------------- examples/Example_MPI-IO/depend.mk | 22 ++-- miscellaneous/Forces/Makefile | 64 +++++++++ miscellaneous/Forces/depend.mk | 4 + miscellaneous/Forces/fll_forces.f90 | 148 +++++++++++++++++++++ miscellaneous/Forces/fll_forces.py | 99 ++++++++++++++ miscellaneous/Forces/src_dir_path.mk | 2 + miscellaneous/Makefile | 66 ++++++++++ miscellaneous/src_dir_path.mk | 2 + mpi_util/depend.mk | 62 ++++----- 11 files changed, 521 insertions(+), 135 deletions(-) create mode 100644 miscellaneous/Forces/Makefile create mode 100644 miscellaneous/Forces/depend.mk create mode 100644 miscellaneous/Forces/fll_forces.f90 create mode 100755 miscellaneous/Forces/fll_forces.py create mode 100644 miscellaneous/Forces/src_dir_path.mk create mode 100644 miscellaneous/Makefile create mode 100644 miscellaneous/src_dir_path.mk diff --git a/Makefile b/Makefile index 29fbda3..ebc69ef 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ data_util\ accessories\ mpi_util\ examples\ +miscellaneous\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= mpi_util diff --git a/data_util/depend.mk b/data_util/depend.mk index 31248c1..0a40f81 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,153 +1,153 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! fll_deattach.o : \ - fll_stich.o \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_stich.o -fll_nnodes.o : \ - fll_funct_prt.o \ - fll_out.o \ - fll_type.o +fll_rename.o : \ + fll_type.o \ + fll_out.o -fll_getnbytes.o : \ - fll_out.o \ - fll_type.o +fll_mk.o : \ + fll_type.o \ + fll_out.o fll_mkdir.o : \ fll_mk.o \ fll_type.o -fll_cat.o : \ - fll_out.o \ - fll_type.o +fll_sweep.o : \ + fll_match_pattern.o \ + fll_type.o \ + fll_out.o -fll_type.o : +fll_scan_file.o : \ + fll_type.o \ + fll_read.o \ + fll_out.o + +fll_getnbytes.o : \ + fll_type.o \ + fll_out.o fll_stich.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o fll_funct_prt.o : \ - fll_out.o \ - fll_type.o - -fll_sweep.o : \ - fll_match_pattern.o \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_out.o fll_read_record.o : \ fll_mv.o \ - fll_cat.o \ + fll_read.o \ fll_out.o \ - fll_locate.o \ fll_rm.o \ fll_mk.o \ fll_type.o \ - fll_read.o + fll_cat.o \ + fll_locate.o fll_read.o : \ - fll_mv.o \ - fll_funct_prt.o \ fll_mk.o \ + fll_type.o \ fll_out.o \ - fll_type.o - -fll_cp.o : \ fll_mv.o \ - fll_cat.o \ - fll_out.o \ - fll_duplicate.o \ - fll_rm.o \ - fll_stich.o \ - fll_type.o - -fll_scan_file.o : \ - fll_read.o \ - fll_out.o \ - fll_type.o + fll_funct_prt.o -fll_rename.o : \ +fll_rm.o : \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_stich.o -fll_mv.o : \ +fll_cp.o : \ + fll_mv.o \ fll_stich.o \ fll_out.o \ + fll_duplicate.o \ fll_rm.o \ - fll_type.o - -fll_write.o : \ - fll_out.o \ - fll_type.o + fll_type.o \ + fll_cat.o -fll_getndata.o : \ - fll_locate.o \ - fll_out.o \ - fll_type.o +fll_cat.o : \ + fll_type.o \ + fll_out.o -fll_match_pattern.o : \ - fll_out.o \ - fll_type.o +fll_write.o : \ + fll_type.o \ + fll_out.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ +fll_duplicate.o : \ fll_mk.o \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_mv.o -fll_locate.o : \ - fll_funct_prt.o \ +fll_getndata.o : \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_locate.o -fll_duplicate.o : \ - fll_mv.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o +fll_match_pattern.o : \ + fll_type.o \ + fll_out.o fll_mods.o : \ - fll_mv.o \ - fll_out.o \ - fll_funct_prt.o \ fll_stich.o \ - fll_match_pattern.o \ - fll_type.o \ + fll_out.o \ + fll_locate.o \ fll_mkdir.o \ + fll_getndata.o \ + fll_cp.o \ + fll_getnbytes.o \ + fll_rm.o \ + fll_type.o \ fll_cat.o \ - fll_write.o \ + fll_write_ffa.o \ + fll_duplicate.o \ + fll_match_pattern.o \ fll_rename.o \ + fll_scan_file.o \ fll_read_record.o \ - fll_write_ffa.o \ - fll_getnbytes.o \ - fll_mk.o \ + fll_nnodes.o \ + fll_funct_prt.o \ fll_deattach.o \ - fll_scan_file.o \ - fll_duplicate.o \ + fll_mv.o \ + fll_read.o \ fll_sweep.o \ - fll_rm.o \ - fll_nnodes.o \ - fll_getndata.o \ fll_read_ffa.o \ - fll_locate.o \ - fll_cp.o \ - fll_read.o + fll_write.o \ + fll_mk.o -fll_rm.o : \ - fll_stich.o \ - fll_out.o \ - fll_type.o +fll_nnodes.o : \ + fll_type.o \ + fll_funct_prt.o \ + fll_out.o -fll_mk.o : \ +fll_mv.o : \ + fll_type.o \ + fll_rm.o \ fll_out.o \ - fll_type.o + fll_stich.o + +fll_type.o : fll_out.o : \ fll_type.o -fll_write_ffa.o : \ +fll_locate.o : \ + fll_type.o \ + fll_funct_prt.o \ + fll_out.o + +fll_read_ffa.o : \ + fll_mk.o \ + fll_type.o \ fll_out.o \ - fll_type.o + fll_mv.o \ + fll_funct_prt.o + +fll_write_ffa.o : \ + fll_type.o \ + fll_out.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index 7d5891c..aa7a8a2 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,21 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -Example_mpi-IO.o : \ - save_individ_files.o \ - create_data_set.o \ - read_input.o \ - ../../mpi_util/fll_mpi_mods.o \ - ../../data_util/fll_mods.o \ - save_root_part_file.o - -read_input.o : \ +save_individ_files.o : \ ../../data_util/fll_mods.o save_root_part_file.o : \ ../../data_util/fll_mods.o -create_data_set.o : \ +read_input.o : \ ../../data_util/fll_mods.o -save_individ_files.o : \ +Example_mpi-IO.o : \ + create_data_set.o \ + read_input.o \ + ../../data_util/fll_mods.o \ + save_root_part_file.o \ + ../../mpi_util/fll_mpi_mods.o \ + save_individ_files.o + +create_data_set.o : \ ../../data_util/fll_mods.o diff --git a/miscellaneous/Forces/Makefile b/miscellaneous/Forces/Makefile new file mode 100644 index 0000000..6671125 --- /dev/null +++ b/miscellaneous/Forces/Makefile @@ -0,0 +1,64 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_forces + +include src_dir_path.mk +include ../../config.mk + +DEP_FILE=depend.mk + +FMODDIRS= ../../data_util + +FFILES= $(notdir $(wildcard $(srcdir)/*.f90)) + + +OFILES=$(FFILES:%.f90=%.o) +XOFILES=$(wildcard ../../data_util/*.o) + +########################################################################### + +all: $(EXE).x + +include ../../rules.mk + +$(EXE).x: $(OFILES) $(XOFILES) + $(FC) $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.x *.o *.mod $(EXE) + +depend: $(FFILES) + @echo "Making dependencies!" + cd $(srcdir) && $(MAKEDEPEND) -r $(PROJ_ROOT_PATH) $(VERBOSE) -w -o $(srcdir)/$(DEP_FILE) -f $(FFILES) + +-include $(srcdir)/$(DEP_FILE) + diff --git a/miscellaneous/Forces/depend.mk b/miscellaneous/Forces/depend.mk new file mode 100644 index 0000000..43fce93 --- /dev/null +++ b/miscellaneous/Forces/depend.mk @@ -0,0 +1,4 @@ +# This file is generated automatically by fort_depend.py. DO NOT EDIT! + +fll_forces.o : \ + ../../data_util/fll_mods.o diff --git a/miscellaneous/Forces/fll_forces.f90 b/miscellaneous/Forces/fll_forces.f90 new file mode 100644 index 0000000..9e29225 --- /dev/null +++ b/miscellaneous/Forces/fll_forces.f90 @@ -0,0 +1,148 @@ +! +! Copyright (C) 2016 Adam Jirasek +! +! This program is free software: you can redistribute it and/or modify +! it under the terms of the GNU Lesser General Public License as published by +! the Free Software Foundation, either version 3 of the License, or +! (at your option) any later version. +! +! This program is distributed in the hope that it will be useful, +! but WITHOUT ANY WARRANTY; without even the implied warranty of +! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +! GNU Lesser General Public License for more details. +! +! You should have received a copy of the GNU Lesser General Public License +! along with this program. If not, see . +! +! contact: libm3l@gmail.com +! +! + +! +! Sample program +! +! Date: 2016-10-10 +! +! +! +! +! Description: calculates forces from bedg file and bout file +! +! +! Input parameters: +! +! +! Return value: +! +! +! +! Modifications: +! Date Version Patch number CLA +! +! +! Description +! +! + PROGRAM FLL_FORCES + + USE FLL_MODS_M + IMPLICIT NONE +! +! Description: conversion utility +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/08/17 Initial implementation +! +! +! External Modules used +! + CHARACTER(LEN=FILE_NAME_LENGTH) FILE,OUTFILE,BEDGFILE + TYPE(DNODE), POINTER :: PBEDGE,PBOUT,PNEW,PGRID,PREG,PFX,PFY,PFZ,& + PTIME,PFREE,PTMP + TYPE(FUNC_DATA_SET) :: FPAR + REAL(RDOUBLE), POINTER :: NORMS(:,:),PRESS(:) + INTEGER(LINT) :: I,NNODES + LOGICAL :: OK +! +! read a file and save it +! + WRITE(*,*)' Name of bedg file ' + READ(*,'(A1024)')BEDGFILE + WRITE(*,*)' Name of bout file ' + READ(*,'(A1024)')FILE + WRITE(*,*)' Name of output file ' + READ(*,'(A1024)')OUTFILE +! +! read bedg file +! + WRITE(*,*)' Reading bedg file' + PBEDGE => FLL_READ_FFA(BEDGFILE,8,'B',FPAR) +! +! read bout file +! + WRITE(*,*)' Reading bout file' + PBOUT => FLL_READ_FFA(FILE,8,'B',FPAR) +! +! +! find normals in bedge file +! + PREG => FLL_LOCATE(PBEDGE,'region','*',-1_LINT,1_LINT,.FALSE. ,FPAR) + PGRID => FLL_LOCATE(PREG,'grid','*',-1_LINT,1_LINT,.FALSE. ,FPAR) + NORMS => FLL_GETNDATA_D2(PGRID, 'edge_surfaces', 1_LINT, FPAR) +! +! find pressures in bout file +! + PREG => FLL_LOCATE(PBOUT,'region','*',-1_LINT,1_LINT,.FALSE. ,FPAR) + PFREE => FLL_LOCATE(PBOUT,'free_stream_data','*',-1_LINT,1_LINT,.FALSE. ,FPAR) +! +! look for time, if not found, steady solution +! + PTIME => NULL() + PTIME => FLL_LOCATE(PREG,'time','*',-1_LINT,1_LINT,.FALSE. ,FPAR) + IF(.NOT.ASSOCIATED(PTIME)) PTIME => PREG + + PRESS => FLL_GETNDATA_D1(PTIME, 'pressure', 1_LINT, FPAR) +! +! make new solution pointer +! + PNEW => FLL_MKDIR('solution', FPAR) + PTMP => FLL_CP(PFREE,PNEW, FPAR) +! +! make region and add it +! + PREG => FLL_MKDIR('region', FPAR) + OK = FLL_MV(PREG, PNEW, FPAR) +! +! make three arrays for forces and add it to region +! + NNODES = SIZE(PRESS, DIM =1, KIND = LINT) + PFX => FLL_MK('FX','D', NNODES, 1_LINT, FPAR) + OK = FLL_MV(PFX, PREG, FPAR) + PFY => FLL_MK('FY','D', NNODES, 1_LINT, FPAR) + OK = FLL_MV(PFY, PREG, FPAR) + PFZ => FLL_MK('FZ','D', NNODES, 1_LINT, FPAR) + OK = FLL_MV(PFZ, PREG, FPAR) +! +! calculate forces +! + DO I=1,NNODES + PFX%D1(I) = PRESS(I) * NORMS(I,1) + PFY%D1(I) = PRESS(I) * NORMS(I,2) + PFZ%D1(I) = PRESS(I) * NORMS(I,3) + END DO +! +! write solution +! + OK = FLL_WRITE_FFA(PNEW, OUTFILE,9,'B',FPAR) +! +! cleanup memory +! + CALL FLL_RM(PBEDGE,FPAR) + CALL FLL_RM(PBOUT,FPAR) + CALL FLL_RM(PNEW,FPAR) + + +END PROGRAM diff --git a/miscellaneous/Forces/fll_forces.py b/miscellaneous/Forces/fll_forces.py new file mode 100755 index 0000000..04e4138 --- /dev/null +++ b/miscellaneous/Forces/fll_forces.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +# +# +# this is a python script +# +import os +import sys +from subprocess import Popen, PIPE +import unicodedata +import ast + +#Definitions + +def run(boutfile,bedgefile, outfile): +# +# execute +# + print_header() +# + path = os.path.dirname(os.path.abspath(__file__)) + cwd = os.getcwd() + + path = check_path(path=path) + cwd = check_path(path=cwd) + + executable = path+"fll_forces.x" + + if not os.path.isfile(boutfile): + print(" ") + print("\033[031mERROR:\033[039m bout file \033[032m"+file+"\033[039m does not exist, terminating .... ") + sys.exit() + + if not os.path.isfile(bedgefile): + print(" ") + print("\033[031mERROR:\033[039m bedge file \033[032m"+file+"\033[039m does not exist, terminating .... ") + sys.exit() + + if sys.version_info < (3,0): + p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here + p.communicate(os.linesep.join([bedgefile, boutfile, outfile])) + else: + p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here + p.communicate(os.linesep.join( [bedgefile, boutfile, outfile])) + +def print_header(): + print(" ") + print ("\033[031m************************************************************************************ \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m fll_convert - v1.1 \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m conversion utility \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m************************************************************************************ \033[039m") + + +def check_path(path): + if not(path.endswith("/")): + path=path + "/" + + return path + + + +#Script +if __name__ == "__main__": + import argparse + + # Add command line arguments + parser = argparse.ArgumentParser(description='FLL configure script') + parser.add_argument('-s','--bout_file',nargs=1,help='Solution file') + parser.add_argument('-b','--bedge_file',nargs=1,help='bedge file') + parser.add_argument('-o','--output_file',nargs=1,help='Output file') + + # Parse the command line arguments + args = parser.parse_args() + + bout_file = args.bout_file[0] if args.bout_file else None + bedge_file = args.bedge_file[0] if args.bedge_file else None + output_file = args.output_file[0] if args.output_file else None + + if not len(sys.argv) > 1: + print("\nfll_force - calculates forces from bedg and bout files\n") + print("usage: fll_forces.py [-h] [-s BOUT_FILE] [-b BEDGE_FILE] [-o OUTPUT_FILE]\n") + sys.exit() + + if not bout_file: + print ("\033[031mError: \033[039m missing name of file, option \033[031m -s \033[039m") + sys.exit() + + if not bedge_file: + print ("\033[031mError: \033[039m missing name of file, option \033[031m -b \033[039m") + sys.exit() + + if not output_file: + print ("\033[031mError: \033[039m missing output file, option \033[031m -o \033[039m") + sys.exit() + + + run(boutfile=bout_file,bedgefile=bedge_file, outfile=output_file) diff --git a/miscellaneous/Forces/src_dir_path.mk b/miscellaneous/Forces/src_dir_path.mk new file mode 100644 index 0000000..813d08a --- /dev/null +++ b/miscellaneous/Forces/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/miscellaneous/Forces + diff --git a/miscellaneous/Makefile b/miscellaneous/Makefile new file mode 100644 index 0000000..b11658b --- /dev/null +++ b/miscellaneous/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2016 Adam Jirasek +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# +# contact: libm3l@gmail.com +# +# +# +# Description: Makefile +# +# +# History: +# Version Date Patch number CLA Comment +# ------- -------- -------- --- ------- +# 1.1 10/10/16 Initial implementation +# +# +# + +EXE = fll_test + +include src_dir_path.mk +include ../config.mk + +DEP_FILE=depend.mk + +#SUBDIRS= $(dir $(wildcard $(srcdir)/*)) +SUBDIRS= \ + Forces\ + +#ifneq ($(strip $(MPI_FC)),) +ifneq ($(MPI_FC),) +# SUBDIRS+= Example_MPI-IO +endif + + + + +########################################################################### + +all: $(SUBDIRS:%=%.all) + +include ../rules.mk + +clean: $(SUBDIRS:%=%.clean) + rm -f *.x *.o *.mod + +depend: $(SUBDIRS:%=%.depend) + +install: $(SUBDIRS:%=%.install) + +test: $(SUBDIRS:%=%.test) + +chk: $(SUBDIRS:%=%.chk) diff --git a/miscellaneous/src_dir_path.mk b/miscellaneous/src_dir_path.mk new file mode 100644 index 0000000..fa7c61b --- /dev/null +++ b/miscellaneous/src_dir_path.mk @@ -0,0 +1,2 @@ +srcdir=$(PROJ_ROOT_PATH)/miscellaneous + diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 17502e2..221b205 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,52 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! -fll_mpi_cp_all.o : \ - ../data_util/fll_mk.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o - fll_mpi_read.o : \ fll_mpi_cp_all.o \ ../data_util/fll_mods.o +fll_mpi_sum.o : \ + ../data_util/fll_mods.o + +fll_mpi_proc_struct.o : \ + ../data_util/fll_mods.o + +fll_mpi_cp.o : \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_mk.o + +fll_mpi_write_nm.o : \ + fll_mpi_write.o \ + ../data_util/fll_mods.o + +fll_mpi_cp_all.o : \ + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_mv.o \ + ../data_util/fll_mk.o + fll_mpi_mv.o : \ + ../data_util/fll_type.o \ fll_mpi_cp.o \ - ../data_util/fll_out.o \ ../data_util/fll_rm.o \ - ../data_util/fll_type.o + ../data_util/fll_out.o fll_mpi_write_snm.o : \ fll_mpi_cp.o \ ../data_util/fll_mods.o -fll_mpi_write.o : \ - ../data_util/fll_mods.o \ - fll_mpi_sum.o - -fll_mpi_cp.o : \ - ../data_util/fll_mk.o \ - ../data_util/fll_mv.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o - fll_mpi_mods.o : \ - fll_mpi_proc_struct.o \ - fll_mpi_write.o \ fll_mpi_cp.o \ + fll_mpi_cp_all.o \ fll_mpi_write_nm.o \ + fll_mpi_write.o \ + fll_mpi_read.o \ fll_mpi_write_snm.o \ fll_mpi_mv.o \ - fll_mpi_read.o \ - fll_mpi_cp_all.o \ + fll_mpi_proc_struct.o \ fll_mpi_sum.o -fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o - -fll_mpi_proc_struct.o : \ - ../data_util/fll_mods.o - -fll_mpi_sum.o : \ - ../data_util/fll_mods.o +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o From 6e6d5f65bb90d9c4c9f7d59cee029f965c27b341 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 22 Aug 2017 08:00:10 -0600 Subject: [PATCH 270/325] add type of integer --- data_util/fll_read_ucd.f90 | 157 +++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 7 deletions(-) diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index 0865ff1..8c283b5 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_UCD_M ! CONTAINS - FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -85,6 +85,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! IOUNIT In Number of unit ! FMT In Format - a,A ASCII, b,B - Binary, * not specified ! FPAR In/Out structure containing function specific data +! ITYPE In type of integer (I) or (L) ! ! Arguments declaration ! @@ -92,14 +93,13 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - CHARACTER :: FMT + CHARACTER :: FMT,ITYPE ! ! Local declarations ! LOGICAL :: OK CHARACTER :: FMT_LOC INTEGER :: ISTAT - INTEGER(LINT) :: POS INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN @@ -148,8 +148,14 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! READ INITIAL NODE ! - POS = 1 - PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR) + SELECT CASE(ITYPE) + CASE('I','i') + PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR) + CASE('L','l') + PNODE => READ_NODE_UCD_L(IOUNIT,FMT_LOC,FPAR) + CASE DEFAULT + STOP'WRONG DATA FORMAT FOR UCD DATA SET' + END SELECT CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN @@ -254,6 +260,143 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:260 ' + DO I=1,NELEM + READ(IOUNIT,'(A)')TEXTLONG + READ(TEXTLONG,*)A,B,ETYPE + SELECT CASE(ETYPE) + CASE('tri') + N3 = N3 + 1 + READ(TEXTLONG, *)A,B,ETYPE,I3(N3,:) + CASE('quad') + N4 = N4 + 1 + READ(TEXTLONG, *)A,B,ETYPE,I4(N4,:) + END SELECT + + END DO +! +! add it to the structure +! + IF(N3> 0)THEN + + PBELEM => FLL_MKDIR('belem_group', FPAR) + OK = FLL_MV(PBELEM,PBND,FPAR) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR) + PTMP%S0 = 'tria3' + PTMP => FLL_MK('bound_elem_nodes','I',N3,3_LINT,FPAR) + PTMP%I2 = I3(1:N3,:) + OK = FLL_MV(PTMP,PBELEM,FPAR) + END IF + + IF(N4> 0)THEN + + PBELEM => FLL_MKDIR('belem_group', FPAR) + OK = FLL_MV(PBELEM,PBND,FPAR) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR) + PTMP%S0 = 'quad4' + PTMP => FLL_MK('bound_elem_nodes','I',N4,4_LINT,FPAR) + PTMP%I2 = I4(1:N4,:) + OK = FLL_MV(PTMP,PBELEM,FPAR) + + END IF + + + DEALLOCATE(I3,I4, STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:306 ' + + END FUNCTION READ_NODE_UCD + + + FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) +! +! Description: Function reads a node +! +! +! History: +! Version Date Patch number CLA Comment +! ------- -------- -------- --- ------- +! 1.1 10/10/16 Initial implementation +! +! +! External Modules used +! + USE FLL_TYPE_M + USE FLL_MK_M + USE FLL_MKDIR_M + USE FLL_MV_M + USE FLL_OUT_M + + IMPLICIT NONE +! +! Declarations +! +! Arguments description +! Name In/Out Function +! PNODE Out Pointer to node +! IOUNIT In Number of unit +! FMT In Format - a,A ASCII, b,B - Binary +! FPAR In/Out structure containing function specific data +! +! Arguments declaration +! + TYPE(DNODE), POINTER :: PNODE + TYPE(FUNC_DATA_SET) :: FPAR + INTEGER :: IOUNIT + CHARACTER :: FMT +! +! Local declarations +! + TYPE(DNODE), POINTER :: PREG,PTMP,PBND,PBELEM + CHARACTER(LEN=NAME_LENGTH) :: TEXT + CHARACTER(LEN=6) :: ETYPE + INTEGER(LINT) :: NPTS,NELEM,A,B,C,I,N3,N4 + REAL(RDOUBLE), POINTER :: COO(:,:) + INTEGER(LINT), ALLOCATABLE :: I4(:,:),I3(:,:) + INTEGER :: ISTAT + LOGICAL :: OK + CHARACTER(LEN = 200)TEXTLONG +! +! disregard all lines starting with # - 3 lines +! + READ(IOUNIT, '(A)')TEXT + READ(IOUNIT, '(A)')TEXT + READ(IOUNIT, '(A)')TEXT +! +! read mesh dimensions +! + READ(IOUNIT,*)NPTS,NELEM,A,B,C +! +! allocate memory for coordinates +! + PNODE => FLL_MKDIR('unstr_grid_data', FPAR) + PREG => FLL_MKDIR('region', FPAR) + OK = FLL_MV(PREG,PNODE,FPAR) + PBND => FLL_MKDIR('boundary', FPAR) + OK = FLL_MV(PBND,PREG,FPAR) + + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR) + OK = FLL_MV(PTMP,PREG,FPAR) + COO => PTMP%D2 + + DO I=1,NPTS + READ(IOUNIT,*)A,COO(I,:) + END DO +! +! add boundary name +! + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR) + PTMP%S0 = 'wall' +! +! read elements +! + N3 = 0 + N4 = 0 +! + ALLOCATE(I3(NELEM,3),I4(NELEM,4), STAT=ISTAT) + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:397 ' + + DO I=1,NELEM READ(IOUNIT,'(A)')TEXTLONG READ(TEXTLONG,*)A,B,ETYPE @@ -297,9 +440,9 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) DEALLOCATE(I3,I4, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:277 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:443 ' - END FUNCTION READ_NODE_UCD + END FUNCTION READ_NODE_UCD_L END MODULE FLL_READ_UCD_M From 305dd3aac509d28de733311ebe4f195d2cc47aef Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 6 Sep 2017 07:17:38 -0600 Subject: [PATCH 271/325] fix bug in python wrapper --- accessories/fll_convert/fll_convert.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/accessories/fll_convert/fll_convert.py b/accessories/fll_convert/fll_convert.py index b1ced70..f4f598f 100755 --- a/accessories/fll_convert/fll_convert.py +++ b/accessories/fll_convert/fll_convert.py @@ -59,7 +59,6 @@ def run(file,fmt,efmt,ofile,ofmt,fmto): else: print("\033[039m Specified output file type is: \033[032mFFA \033[039m") - if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here p.communicate(os.linesep.join([file, fmt, efmt, ofile,ofmt,fmto])) @@ -104,7 +103,7 @@ def check_path(path): args = parser.parse_args() file = args.file[0] if args.file else None - format_i = args.format[0] if args.format_i else None + format_i = args.format_i[0] if args.format_i else None eformat = args.format_input[0] if args.format_input else None oformat = args.format_output[0] if args.format_output else None output = args.output_file[0] if args.output_file else None @@ -120,7 +119,7 @@ def check_path(path): print ("\033[031mError: \033[039m missing name of file, option \033[031m -i \033[039m") sys.exit() - if not format: + if not format_i: print ("\033[031mError: \033[039m missing input file format, option\033[031m -f \033[039m") print ("\033[031m \033[039m available options are: \033[032m a - ASCII\033[039m") print ("\033[031m \033[039m \033[032m b - binary format\033[039m") @@ -157,4 +156,4 @@ def check_path(path): print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() - run(file=file,fmt=format, efmt = eformat, ofile=output, ofmt = oformat, fmto = formato) + run(file=file,fmt=format_i, efmt = eformat, ofile=output, ofmt = oformat, fmto = formato) From aab2bf54be9d92d63070985d0fc5d3ec02fe161d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 7 Sep 2017 07:21:23 -0600 Subject: [PATCH 272/325] Update fort_depend.py --- fort_depend.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index a663daf..e9896e7 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -22,14 +22,22 @@ #SOFTWARE. # # -# this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py -# done by Adam Jirasek +# this is a modification of the original script of D Dickinson and Peter Hill +# @https://github.com/ZedThree/fort_depend.py +# +# The modification was done by Adam Jirasek # the modified version can be found @https://github.com/libm3l/fort_depend.py # -# this is a script which maked fortran project dependecies -# it is executed in each directory separately and creates a project.dep file with fortran dependencies -# if fortran source uses module from other directory the script will add the module too -# the project root directory is specified as an input parameter with an option -r +# the major update is that the dependency script can make dependenies +# from files located in different directories, so it is more suitable +# for bigger project +# +# History: +# Version Date Author Patch number CLA Comment +# ------- -------- -------- ------------ --- ------- +# 1.1 01/09/17 Adam Jirasek Rewrite original version +# +# # # import os From e738069845d8a7af9b67585ce9190bda37309ab7 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 7 Sep 2017 09:42:04 -0600 Subject: [PATCH 273/325] add option for building static library --- Makefile | 4 ++++ configure.py | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index ebc69ef..ecaadad 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,9 @@ SUBCLEAN=$(SUBDIRS) ########################################################################### all: $(SUBDIRS:%=%.all) + + ar rcs fll.a data_util/*.o + @echo '************************************************' @echo '*' @echo '* FLL built successfully!' @@ -70,4 +73,5 @@ clean: $(SUBCLEAN:%=%.clean) depend: $(SUBDIRS:%=%.depend) install: $(SUBDIRS:%=%.all) $(SUBDIRS:%=%.install) + $(INSTALL) fll.a $(lib_dir)/fll.a diff --git a/configure.py b/configure.py index 53a5d04..362ec89 100755 --- a/configure.py +++ b/configure.py @@ -52,7 +52,7 @@ #Definitions -def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build=''): +def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build='',lib=''): # # definition of parameters # @@ -106,12 +106,24 @@ def run(comp,files=None,verbose=True,overwrite=None,output=None,macros={},build= print("\033[031mDIAG:\033[039m Bild directory not specified, setting it to \033[032m "+cwd+platform.machine()+"/bin\033[039m") print(" ") bin_dir=cwd+platform.machine()+'/bin' + lib_dir=cwd+platform.machine()+'/lib64' else: bin_dir=build + lib_dir=lib +# +# specify lib directory where all executables will be located +# + if build == '': + print(" ") + print("\033[031mDIAG:\033[039m Library directory not specified, setting it to \033[032m "+cwd+platform.machine()+"/lib64\033[039m") + print(" ") + lib_dir=cwd+platform.machine()+'/lib64' + else: + lib_dir=lib # # create configuration file config.mk # - ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=bin_dir) + ok = mkconfigfile(path=path, cwd=cwd,version=comp, bin_dir=bin_dir, lib_dir=lib_dir) # # create structure and link necessary files # ie. create the same tree structure as source files and link "linkfiles" specified above @@ -266,7 +278,7 @@ def check_path(path): return path -def mkconfigfile(path, cwd,version, bin_dir): +def mkconfigfile(path, cwd,version, bin_dir, lib_dir): filename = path+'/config/compset.'+version if not(os.path.exists(filename)): @@ -305,10 +317,14 @@ def mkconfigfile(path, cwd,version, bin_dir): fconfig.write(line) fconfig.write("#\n") - fconfig.write("# bin_dir is the base directory where executables will be installed\n") + fconfig.write("# bin_dir is the base directory with installed executables\n") fconfig.write("#\n") fconfig.write('bin_dir='+exec_dir+"\n") fconfig.write("#\n") + fconfig.write("# lib_dir is the fll library directory\n") + fconfig.write("#\n") + fconfig.write('lib_dir='+lib_dir+"\n") + fconfig.write("#\n") fconfig.write("#\n") fconfig.write("# MACHINE identifies the host machine type") fconfig.write("#\n") @@ -331,6 +347,14 @@ def mkconfigfile(path, cwd,version, bin_dir): print("\033[031mERROR:\033[039m Creating exec directory \033[032m"+exec_dir+"\033[039m .... ") os.makedirs(exec_dir) +# +# make library directory +# + if not os.path.isdir(lib_dir): + print(" ") + print("\033[031mERROR:\033[039m Creating library directory \033[032m"+lib_dir+"\033[039m .... ") + os.makedirs(lib_dir) + cwd = check_path(path=cwd) class file_obj: @@ -356,8 +380,8 @@ def print_header(): parser.add_argument('-f','--files',nargs='+',help='Files to process') parser.add_argument('-D',nargs='+',action='append',metavar='NAME=DESCRIPTION', help="""The macro NAME is replaced by DEFINITION in 'use' statements""") - parser.add_argument('-b','--build',nargs=1,help='Build Directory (prepended to all files in output', - default='') + parser.add_argument('-b','--build',nargs=1,help='Build directory', default='') + parser.add_argument('-L','--libdir',nargs=1,help='FLL library directory', default='') parser.add_argument('-o','--output',nargs=1,help='Output file') parser.add_argument('-v','--verbose',action='store_true',help='explain what is done') parser.add_argument('-w','--overwrite',action='store_true',help='Overwrite output file without warning') @@ -376,6 +400,7 @@ def print_header(): output = args.output[0] if args.output else None build = args.build[0] if args.build else '' + libdir = args.libdir[0] if args.libdir else '' compiler = args.compiler[0] if args.compiler else None @@ -387,4 +412,4 @@ def print_header(): print ("\033[031m \033[039m \033[032m x86_64_debug\033[039m") sys.exit() - run(comp=compiler,verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build) + run(comp=compiler,verbose=args.verbose, overwrite=args.overwrite, macros=macros, output=output, build=build, lib=libdir) From 29d24dff663a98dbc59431c8dc19a8e96511ec9d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 7 Sep 2017 10:22:29 -0600 Subject: [PATCH 274/325] replace INSTALL by mv --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ecaadad..5921e80 100644 --- a/Makefile +++ b/Makefile @@ -73,5 +73,5 @@ clean: $(SUBCLEAN:%=%.clean) depend: $(SUBDIRS:%=%.depend) install: $(SUBDIRS:%=%.all) $(SUBDIRS:%=%.install) - $(INSTALL) fll.a $(lib_dir)/fll.a + mv fll.a $(lib_dir)/fll.a From 306b8c62059901224edf4314762cde366a182569 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 8 Sep 2017 13:45:21 -0600 Subject: [PATCH 275/325] add date and time to output --- fort_depend.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index a663daf..f4f41ec 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -38,7 +38,8 @@ import fnmatch import os import sys - +from time import gmtime, strftime +import getpass #Definitions @@ -118,6 +119,14 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, print(" ") f=open(outfile,'w') f.write('# This file is generated automatically by fort_depend.py. DO NOT EDIT!\n') +# +# header +# + username = getpass.getuser() + f.write("#\n") + f.write("# Created by: "+username+"\n") + f.write("# Date: "+strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n") + f.write("#\n") for i in dep.keys(): tmp,fil=os.path.split(i) From df6986d0340c4e5ae977a66760696fc66441c834 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 8 Sep 2017 13:46:40 -0600 Subject: [PATCH 276/325] add date and time to dependency script --- accessories/fll_cat/depend.mk | 4 + accessories/fll_convert/depend.mk | 4 + data_util/depend.mk | 180 ++++++++++++----------- examples/Example_MPI-IO/depend.mk | 20 ++- examples/Simple_data_operation/depend.mk | 8 +- miscellaneous/Forces/depend.mk | 4 + mpi_util/depend.mk | 72 ++++----- python_dep/fort_depend.py | 11 +- 8 files changed, 170 insertions(+), 133 deletions(-) diff --git a/accessories/fll_cat/depend.mk b/accessories/fll_cat/depend.mk index 5031f63..129f793 100644 --- a/accessories/fll_cat/depend.mk +++ b/accessories/fll_cat/depend.mk @@ -1,4 +1,8 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# fll_cat.o : \ ../../data_util/fll_mods.o diff --git a/accessories/fll_convert/depend.mk b/accessories/fll_convert/depend.mk index 0b8f538..843e34b 100644 --- a/accessories/fll_convert/depend.mk +++ b/accessories/fll_convert/depend.mk @@ -1,4 +1,8 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# fll_convert.o : \ ../../data_util/fll_mods.o diff --git a/data_util/depend.mk b/data_util/depend.mk index 77c794b..c89262d 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,161 +1,165 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# -fll_sweep.o : \ +fll_deattach.o : \ + fll_stich.o \ fll_out.o \ - fll_match_pattern.o \ fll_type.o -fll_scan_file.o : \ +fll_nnodes.o : \ + fll_funct_prt.o \ fll_out.o \ - fll_read.o \ fll_type.o -fll_nnodes.o : \ +fll_getnbytes.o : \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o -fll_stich.o : \ - fll_out.o \ +fll_mkdir.o : \ + fll_mk.o \ fll_type.o -fll_read_record.o : \ +fll_cat.o : \ fll_out.o \ - fll_mk.o \ - fll_type.o \ - fll_cat.o \ - fll_mv.o \ - fll_read.o \ - fll_rm.o \ - fll_locate.o + fll_type.o -fll_deattach.o : \ +fll_type.o : + +fll_stich.o : \ fll_out.o \ - fll_type.o \ - fll_stich.o + fll_type.o -fll_out.o : \ +fll_funct_prt.o : \ + fll_out.o \ fll_type.o -fll_cat.o : \ +fll_sweep.o : \ + fll_match_pattern.o \ fll_out.o \ fll_type.o -fll_mods.o : \ - fll_funct_prt.o \ - fll_stich.o \ - fll_type.o \ +fll_read_record.o : \ fll_mv.o \ - fll_rm.o \ - fll_write_ffa.o \ - fll_scan_file.o \ - fll_mk.o \ - fll_out.o \ fll_cat.o \ - fll_write.o \ - fll_match_pattern.o \ - fll_sweep.o \ - fll_nnodes.o \ - fll_read_ffa.o \ - fll_rename.o \ - fll_mkdir.o \ - fll_read_ucd.o \ - fll_deattach.o \ - fll_read.o \ - fll_locate.o \ - fll_getndata.o \ - fll_cp.o \ - fll_read_record.o \ - fll_getnbytes.o \ - fll_duplicate.o - -fll_read_ffa.o : \ fll_out.o \ + fll_locate.o \ + fll_rm.o \ fll_mk.o \ - fll_mv.o \ fll_type.o \ - fll_funct_prt.o + fll_read.o fll_read.o : \ - fll_out.o \ - fll_mk.o \ fll_mv.o \ - fll_type.o \ - fll_funct_prt.o - -fll_write_ffa.o : \ + fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_locate.o : \ +fll_read_ucd.o : \ + fll_mkdir.o \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ - fll_type.o \ - fll_funct_prt.o + fll_type.o fll_cp.o : \ - fll_out.o \ - fll_type.o \ - fll_stich.o \ - fll_cat.o \ fll_mv.o \ + fll_cat.o \ + fll_out.o \ + fll_duplicate.o \ fll_rm.o \ - fll_duplicate.o + fll_stich.o \ + fll_type.o -fll_type.o : +fll_scan_file.o : \ + fll_read.o \ + fll_out.o \ + fll_type.o -fll_mkdir.o : \ - fll_mk.o \ +fll_rename.o : \ + fll_out.o \ fll_type.o fll_mv.o : \ fll_stich.o \ fll_out.o \ - fll_type.o \ - fll_rm.o + fll_rm.o \ + fll_type.o -fll_getndata.o : \ +fll_write.o : \ fll_out.o \ - fll_type.o \ - fll_locate.o + fll_type.o -fll_rename.o : \ +fll_getndata.o : \ + fll_locate.o \ fll_out.o \ fll_type.o -fll_rm.o : \ +fll_match_pattern.o : \ fll_out.o \ - fll_type.o \ - fll_stich.o + fll_type.o -fll_duplicate.o : \ - fll_mk.o \ +fll_read_ffa.o : \ fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_funct_prt.o : \ +fll_locate.o : \ + fll_funct_prt.o \ fll_out.o \ fll_type.o -fll_getnbytes.o : \ +fll_duplicate.o : \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ fll_type.o -fll_read_ucd.o : \ - fll_out.o \ - fll_mk.o \ +fll_mods.o : \ fll_mv.o \ + fll_out.o \ + fll_funct_prt.o \ + fll_stich.o \ + fll_match_pattern.o \ fll_type.o \ - fll_mkdir.o + fll_mkdir.o \ + fll_cat.o \ + fll_write.o \ + fll_rename.o \ + fll_read_record.o \ + fll_write_ffa.o \ + fll_getnbytes.o \ + fll_mk.o \ + fll_deattach.o \ + fll_scan_file.o \ + fll_duplicate.o \ + fll_sweep.o \ + fll_rm.o \ + fll_read_ucd.o \ + fll_nnodes.o \ + fll_getndata.o \ + fll_read_ffa.o \ + fll_locate.o \ + fll_cp.o \ + fll_read.o -fll_mk.o : \ +fll_rm.o : \ + fll_stich.o \ fll_out.o \ fll_type.o -fll_write.o : \ +fll_mk.o : \ fll_out.o \ fll_type.o -fll_match_pattern.o : \ +fll_out.o : \ + fll_type.o + +fll_write_ffa.o : \ fll_out.o \ fll_type.o diff --git a/examples/Example_MPI-IO/depend.mk b/examples/Example_MPI-IO/depend.mk index be441f2..c4f1ffb 100644 --- a/examples/Example_MPI-IO/depend.mk +++ b/examples/Example_MPI-IO/depend.mk @@ -1,21 +1,25 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! - -read_input.o : \ - ../../data_util/fll_mods.o +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:17 +# Example_mpi-IO.o : \ + ../../data_util/fll_mods.o \ save_root_part_file.o \ - read_input.o \ create_data_set.o \ - ../../mpi_util/fll_mpi_mods.o \ - ../../data_util/fll_mods.o \ - save_individ_files.o + save_individ_files.o \ + read_input.o \ + ../../mpi_util/fll_mpi_mods.o save_individ_files.o : \ ../../data_util/fll_mods.o -save_root_part_file.o : \ +read_input.o : \ ../../data_util/fll_mods.o create_data_set.o : \ ../../data_util/fll_mods.o + +save_root_part_file.o : \ + ../../data_util/fll_mods.o diff --git a/examples/Simple_data_operation/depend.mk b/examples/Simple_data_operation/depend.mk index 7239864..8042ab0 100644 --- a/examples/Simple_data_operation/depend.mk +++ b/examples/Simple_data_operation/depend.mk @@ -1,8 +1,12 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# fll_test_subr.o : \ ../../data_util/fll_mods.o fll_test.o : \ - fll_test_subr.o \ - ../../data_util/fll_mods.o + ../../data_util/fll_mods.o \ + fll_test_subr.o diff --git a/miscellaneous/Forces/depend.mk b/miscellaneous/Forces/depend.mk index 43fce93..d3118f6 100644 --- a/miscellaneous/Forces/depend.mk +++ b/miscellaneous/Forces/depend.mk @@ -1,4 +1,8 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:17 +# fll_forces.o : \ ../../data_util/fll_mods.o diff --git a/mpi_util/depend.mk b/mpi_util/depend.mk index 3fced21..d7e00c8 100644 --- a/mpi_util/depend.mk +++ b/mpi_util/depend.mk @@ -1,52 +1,56 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# -fll_mpi_mv.o : \ - ../data_util/fll_out.o \ - ../data_util/fll_rm.o \ +fll_mpi_mods.o : \ + fll_mpi_write_snm.o \ fll_mpi_cp.o \ - ../data_util/fll_type.o + fll_mpi_proc_struct.o \ + fll_mpi_write_nm.o \ + fll_mpi_write.o \ + fll_mpi_sum.o \ + fll_mpi_mv.o \ + fll_mpi_read.o \ + fll_mpi_cp_all.o -fll_mpi_proc_struct.o : \ +fll_mpi_sum.o : \ ../data_util/fll_mods.o -fll_mpi_cp_all.o : \ - ../data_util/fll_mv.o \ - ../data_util/fll_mk.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o - fll_mpi_write_nm.o : \ - fll_mpi_write.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_write.o -fll_mpi_cp.o : \ +fll_mpi_cp_all.o : \ ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ ../data_util/fll_mk.o \ - ../data_util/fll_out.o \ - ../data_util/fll_type.o - -fll_mpi_sum.o : \ - ../data_util/fll_mods.o + ../data_util/fll_out.o fll_mpi_write_snm.o : \ - fll_mpi_cp.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_cp.o -fll_mpi_write.o : \ - fll_mpi_sum.o \ +fll_mpi_proc_struct.o : \ ../data_util/fll_mods.o fll_mpi_read.o : \ - fll_mpi_cp_all.o \ - ../data_util/fll_mods.o + ../data_util/fll_mods.o \ + fll_mpi_cp_all.o -fll_mpi_mods.o : \ - fll_mpi_write_nm.o \ - fll_mpi_write.o \ - fll_mpi_mv.o \ - fll_mpi_proc_struct.o \ - fll_mpi_cp_all.o \ +fll_mpi_mv.o : \ fll_mpi_cp.o \ - fll_mpi_read.o \ - fll_mpi_sum.o \ - fll_mpi_write_snm.o + ../data_util/fll_type.o \ + ../data_util/fll_out.o \ + ../data_util/fll_rm.o + +fll_mpi_write.o : \ + ../data_util/fll_mods.o \ + fll_mpi_sum.o + +fll_mpi_cp.o : \ + ../data_util/fll_mv.o \ + ../data_util/fll_type.o \ + ../data_util/fll_mk.o \ + ../data_util/fll_out.o diff --git a/python_dep/fort_depend.py b/python_dep/fort_depend.py index a663daf..f4f41ec 100755 --- a/python_dep/fort_depend.py +++ b/python_dep/fort_depend.py @@ -38,7 +38,8 @@ import fnmatch import os import sys - +from time import gmtime, strftime +import getpass #Definitions @@ -118,6 +119,14 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, print(" ") f=open(outfile,'w') f.write('# This file is generated automatically by fort_depend.py. DO NOT EDIT!\n') +# +# header +# + username = getpass.getuser() + f.write("#\n") + f.write("# Created by: "+username+"\n") + f.write("# Date: "+strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n") + f.write("#\n") for i in dep.keys(): tmp,fil=os.path.split(i) From 4d26e4c61f9bb6c3f699067d9bfba8cbcdab7451 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 8 Sep 2017 14:13:08 -0600 Subject: [PATCH 277/325] fix bug causing SIGSEGV in printout --- data_util/fll_cat.f90 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 146214a..422195e 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -98,7 +98,6 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) IF(ASSOCIATED(PNODE%PPAR))WRITE(*,*)' ===> Node has a parent, its name is: ', PNODE%PPAR%LNAME WRITE(*,*) END IF - CALL FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! @@ -110,7 +109,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) END SUBROUTINE FLL_CAT ! ! - RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN_LOC,DIR,FPAR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! From 68b69549bf90cbfbe7a991881752d2880368b37a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 27 Sep 2017 14:06:07 -0600 Subject: [PATCH 278/325] fix bug --- data_util/fll_cat.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 422195e..711a238 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -109,7 +109,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) END SUBROUTINE FLL_CAT ! ! - RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN_LOC,DIR,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! From 76b8017763f6f7f9ba8eda86cad64d0d239eb579 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 28 Sep 2017 08:03:40 -0600 Subject: [PATCH 279/325] fix Makefile, make .a library at install too --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 5921e80..3500734 100644 --- a/Makefile +++ b/Makefile @@ -73,5 +73,6 @@ clean: $(SUBCLEAN:%=%.clean) depend: $(SUBDIRS:%=%.depend) install: $(SUBDIRS:%=%.all) $(SUBDIRS:%=%.install) + ar rcs fll.a data_util/*.o mv fll.a $(lib_dir)/fll.a From 4e124d2b764607e23ac4c29ce4dee1a8da6405d8 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 28 Sep 2017 08:03:51 -0600 Subject: [PATCH 280/325] print name of header node --- data_util/fll_cat.f90 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 711a238..db4d61d 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -99,6 +99,10 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) WRITE(*,*) END IF ! +! print main node +! + CALL FLL_PRINT(PNODE, IOUNIT, 0_LINT, SCAN, DIR, FPAR) +! ! IF NODE HAS CHILDREN PRINT THEM TOO ! IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,DIR,FPAR) From 7a488e1dad0d8f4f3f2cd6995c3a0065af0e28d5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 6 Nov 2017 08:51:19 -0700 Subject: [PATCH 281/325] fix L and S type for long and short text when exporting to external format --- data_util/fll_write_ffa.f90 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 082299f..7858858 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -323,10 +323,10 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) END IF ELSE IF(TRIM(LTYPE) == 'S') THEN - IF(LTYPE == 'S')THEN - LTYPE = 'S' + IF(TRIM(FTYPE) == 'L') + LTYPE = 'L' ELSE - LTYPE ='L' + LTYPE ='S' END IF ELSE IF(TRIM(LTYPE) == 'L') THEN LTYPE ='I' @@ -340,8 +340,6 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) LTYPE(2:2) = 'F' END SELECT END IF - - write(*,*)' LTYPE is ', ltype WRITE(IOUNIT, *)TRIM(PNODE%LNAME),' ', TRIM(LTYPE),' ', PNODE%NSIZE, ' ',PNODE%NDIM,' ',0 END IF ! @@ -477,7 +475,7 @@ SUBROUTINE FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) SAVED = .FALSE. LTYPE = PNODE%LTYPE - + IF(TRIM(PNODE%LTYPE) == 'DIR' .OR.TRIM(PNODE%LTYPE) == 'N')THEN IF(PNODE%NLINK > 0)THEN WRITE(IOUNIT)PNODE%LNAME,PNODE%FTYPE,1_LINT,1_LINT,PNODE%NDIM @@ -488,10 +486,10 @@ SUBROUTINE FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) END IF ELSE IF(TRIM(LTYPE) == 'S') THEN - IF(LTYPE == 'S')THEN - LTYPE = 'S' + IF(TRIM(FTYPE) == 'L') + LTYPE = 'L' ELSE - LTYPE ='L' + LTYPE ='S' END IF ELSE IF(TRIM(LTYPE) == 'L') THEN LTYPE ='J' From cd155927b0389142f474ad67bbd43496474b49b1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 6 Nov 2017 14:17:28 -0700 Subject: [PATCH 282/325] fix compillation error --- data_util/fll_write_ffa.f90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index 7858858..deece67 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -323,7 +323,7 @@ SUBROUTINE FLL_SAVE_NODE_A_FFA(PNODE, IOUNIT, FPAR) END IF ELSE IF(TRIM(LTYPE) == 'S') THEN - IF(TRIM(FTYPE) == 'L') + IF(TRIM(PNODE%FTYPE) == 'L')THEN LTYPE = 'L' ELSE LTYPE ='S' @@ -486,7 +486,7 @@ SUBROUTINE FLL_SAVE_NODE_B_FFA(PNODE, IOUNIT, POS, FPAR) END IF ELSE IF(TRIM(LTYPE) == 'S') THEN - IF(TRIM(FTYPE) == 'L') + IF(TRIM(PNODE%FTYPE) == 'L')THEN LTYPE = 'L' ELSE LTYPE ='S' From 13991579c32ca9a3c75a2020fca0bf04621efd60 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 8 Nov 2017 11:05:45 -0700 Subject: [PATCH 283/325] fix error in fll_mv --- data_util/fll_mv.f90 | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index db4e4a0..8c907ee 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -107,6 +107,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& PLAST, PSOURCETMP,PCHILD + LOGICAL :: OK ! ! BODY OF SUBROUTINE ! @@ -192,15 +193,21 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! PWHERE WAS THE FIRST NODE IN THE LIST ! PTPAR%PCHILD => PSOURCETMP - PTPAR%NDIM = PTPAR%NDIM + 1 + PTPAR%NDIM = PTPAR%NDIM + 1 - PSOURCETMP%PPAR => PTPAR + PSOURCETMP%PPAR => PTPAR PSOURCETMP%PPREV => NULL() - PSOURCETMP%PPAR => PWHERE - PTPAR%NDIM = PTPAR%NDIM + 1 IF(ASSOCIATED(PTNEXT))THEN - PSOURCETMP%PNEXT => PTNEXT + IF(.NOT.ASSOCIATED(PWHAT, PTNEXT))THEN +! +! if pnext and pwhat are not the same +! associate pnext from pwhere%next +! otherwise leave pwhat%pnext as it is +! the list is just move one step up +! + PSOURCETMP%PNEXT => PTNEXT + END IF ELSE PSOURCETMP%PNEXT => NULL() END IF @@ -214,7 +221,15 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) PSOURCETMP%PPAR => PWHERE IF(ASSOCIATED(PTNEXT))THEN - PSOURCETMP%PNEXT => PTNEXT + IF(.NOT.ASSOCIATED(PWHAT, PTNEXT))THEN +! +! if pnext and pwhat are not the same +! associate pnext from pwhere%next +! otherwise leave pwhat%pnext as it is +! the list is just move one step up +! + PSOURCETMP%PNEXT => PTNEXT + END IF ELSE PSOURCETMP%PNEXT => NULL() END IF From 16890e44f3ca45b3d65e34e7850474d42dca35df Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 11 Nov 2017 19:35:55 -0700 Subject: [PATCH 284/325] fix error when incrementing list count --- data_util/fll_mv.f90 | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 8c907ee..72b8e50 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -106,7 +106,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! Arguments declaration ! TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& - PLAST, PSOURCETMP,PCHILD + PLAST, PSOURCETMP,PCHILD,PWHERPAR LOGICAL :: OK ! ! BODY OF SUBROUTINE @@ -180,6 +180,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN ! DELETE TARGET NODE ! + PWHERPAR => PWHERE%PPAR CALL FLL_RM(PWHERE, FPAR) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM @@ -193,7 +194,9 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! PWHERE WAS THE FIRST NODE IN THE LIST ! PTPAR%PCHILD => PSOURCETMP - PTPAR%NDIM = PTPAR%NDIM + 1 + IF(.NOT.ASSOCIATED(PWHERPAR,PTPAR))THEN + PTPAR%NDIM = PTPAR%NDIM + 1 + END IF PSOURCETMP%PPAR => PTPAR PSOURCETMP%PPREV => NULL() @@ -207,6 +210,8 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! the list is just move one step up ! PSOURCETMP%PNEXT => PTNEXT + ELSE + PTPAR%NDIM = PTPAR%NDIM - 1 END IF ELSE PSOURCETMP%PNEXT => NULL() @@ -216,8 +221,14 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! ! NODE NOT THE FIRST IN THE LINE ! + IF(.NOT.ASSOCIATED(PWHERPAR,PTPAR))THEN + PTPAR%NDIM = PTPAR%NDIM + 1 + END IF + PTPREV%PNEXT => PSOURCETMP - PSOURCETMP%PPREV => PTPREV + IF(.NOT.ASSOCIATED(PWHAT, PTPREV))THEN + PSOURCETMP%PPREV => PTPREV + END IF PSOURCETMP%PPAR => PWHERE IF(ASSOCIATED(PTNEXT))THEN @@ -233,7 +244,6 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ELSE PSOURCETMP%PNEXT => NULL() END IF - PTPAR%NDIM = PTPAR%NDIM + 1 END IF From dc93ef5e2243fd54654dfcff2ca91263c0f31b00 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 11 Nov 2017 20:59:22 -0700 Subject: [PATCH 285/325] take care of situation where list is moved to its predeccesor or succesor --- data_util/fll_mv.f90 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 72b8e50..26ccd4f 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -106,7 +106,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! Arguments declaration ! TYPE(DNODE), POINTER :: PTNEXT, PTPREV,PTPAR,& - PLAST, PSOURCETMP,PCHILD,PWHERPAR + PLAST, PSOURCETMP,PCHILD,PWHERPAR,PWHERENEXT LOGICAL :: OK ! ! BODY OF SUBROUTINE @@ -181,7 +181,15 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DELETE TARGET NODE ! PWHERPAR => PWHERE%PPAR - CALL FLL_RM(PWHERE, FPAR) + PWHERENEXT => PWHERE%PNEXT + + CALL FLL_RM(PWHERE, FPAR) +! +! IF LIST MOVED TO ITS DIRECT PREDECESSOR OR SUCCESSOR +! LEAVE +! + IF(ASSOCIATED(PWHERPAR,PWHAT))RETURN + IF(ASSOCIATED(PWHERENEXT,PWHAT))RETURN ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! From 18efece1dcd710e811d719e2bb9112e256f0f4fa Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Sat, 11 Nov 2017 21:05:12 -0700 Subject: [PATCH 286/325] avoid cp and mv to itself --- data_util/fll_cp.f90 | 1 + data_util/fll_mv.f90 | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index f5627c5..13a2f96 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -93,6 +93,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! + IF(ASSOCIATED(PWHAT,PWHERE))THEN PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) END IF diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 26ccd4f..5df4b00 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -63,7 +63,9 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) ! ! Local declarations ! - TYPE(DNODE), POINTER :: PSOURCETMP + TYPE(DNODE), POINTER :: PSOURCETMP + + IF(ASSOCIATED(PWHAT,PWHERE))THEN PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) OK = FPAR%SUCCESS From 8dff25f8118f74788bee8b6bd908b7707c6bf053 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 10:17:21 -0700 Subject: [PATCH 287/325] fix bugs --- data_util/fll_cp.f90 | 3 +-- data_util/fll_mv.f90 | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 13a2f96..3c6212c 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -93,8 +93,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! - IF(ASSOCIATED(PWHAT,PWHERE))THEN - PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) + IF(ASSOCIATED(PWHAT,PWHERE))PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) END IF RETURN diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 5df4b00..15736e5 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -67,8 +67,10 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) IF(ASSOCIATED(PWHAT,PWHERE))THEN - PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) - OK = FPAR%SUCCESS + PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) + OK = FPAR%SUCCESS + + END IF RETURN END FUNCTION FLL_MV From c8c8086bb1366f691438f38c823c9341cd4b4698 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 10:20:36 -0700 Subject: [PATCH 288/325] fix logical bug --- data_util/fll_cp.f90 | 3 ++- data_util/fll_mv.f90 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 3c6212c..d32f1ac 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -93,7 +93,8 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! - IF(ASSOCIATED(PWHAT,PWHERE))PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) + IF(.NOT.ASSOCIATED(PWHAT,PWHERE))& + PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) END IF RETURN diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 15736e5..164ad78 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -65,7 +65,7 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) ! TYPE(DNODE), POINTER :: PSOURCETMP - IF(ASSOCIATED(PWHAT,PWHERE))THEN + IF(.NOT.ASSOCIATED(PWHAT,PWHERE))THEN PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) OK = FPAR%SUCCESS From 84cc33d905b4518b5dfd11c6c0ce0a478d696551 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 10:48:27 -0700 Subject: [PATCH 289/325] add optional ACTION to locate and getndata --- data_util/fll_getndata.f90 | 273 ++++++++++++++++++++++++++++--------- data_util/fll_locate.f90 | 14 +- data_util/fll_out.f90 | 3 + 3 files changed, 226 insertions(+), 64 deletions(-) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 817555e..a1d5850 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNDATA_M ! External Modules used ! CONTAINS - FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -66,26 +66,37 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE) :: R0 + CHARACTER(*), OPTIONAL :: ACTION ! -! Local declarations +! local declarations +! + TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! - TYPE(DNODE), POINTER :: PFIND! ! check for null nodes ! IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R0 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -96,7 +107,7 @@ END FUNCTION FLL_GETNDATA_R0 - FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -131,26 +142,36 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R1(:) + CHARACTER(*), OPTIONAL :: ACTION ! -! Local declarations +! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME R1=>NULL() - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -159,7 +180,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_R1 - FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -195,10 +216,20 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R2(:,:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. @@ -207,13 +238,13 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'R',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) R2=>NULL() RETURN END IF @@ -225,7 +256,7 @@ END FUNCTION FLL_GETNDATA_R2 ! ! DOUBLE ! - FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) + FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -261,25 +292,35 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR) RESULT(R0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE) :: R0 + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -290,7 +331,7 @@ END FUNCTION FLL_GETNDATA_D0 - FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) + FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -326,25 +367,35 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R1(:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) R1=>NULL() RETURN END IF @@ -355,7 +406,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR) RESULT(R1) END FUNCTION FLL_GETNDATA_D1 - FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) + FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -391,25 +442,35 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR) RESULT(R2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R2(:,:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'D',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) R2=>NULL() RETURN END IF @@ -421,7 +482,7 @@ END FUNCTION FLL_GETNDATA_D2 ! ! INTEGER ! - FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -457,25 +518,35 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT) :: I0 + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -486,7 +557,7 @@ END FUNCTION FLL_GETNDATA_I0 - FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) ! ! Description: returns single real data of the node ! @@ -521,25 +592,35 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I1(:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) I1=>NULL() RETURN END IF @@ -549,7 +630,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_I1 - FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -584,25 +665,35 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I2(:,:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'I',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) I2=>NULL() RETURN END IF @@ -614,7 +705,7 @@ END FUNCTION FLL_GETNDATA_I2 ! ! LONG INTEGER ! - FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) + FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -649,19 +740,29 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR) RESULT(I0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT) :: I0 + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -678,7 +779,7 @@ END FUNCTION FLL_GETNDATA_L0 - FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) + FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) USE FLL_TYPE_M USE FLL_LOCATE_M @@ -702,25 +803,35 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I1(:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) I1=>NULL() RETURN END IF @@ -730,7 +841,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR) RESULT(I1) END FUNCTION FLL_GETNDATA_L1 - FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) + FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -765,25 +876,35 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I2(:,:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'L',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) I2=>NULL() RETURN END IF @@ -793,7 +914,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -828,25 +949,35 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH) :: STRING + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S0 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',0_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -855,7 +986,7 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S0 -FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) +FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -890,25 +1021,35 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S1 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',1_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) STRING=>NULL() RETURN END IF @@ -918,7 +1059,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) END FUNCTION FLL_GETNDATA_S1 - FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) + FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -953,25 +1094,35 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:,:) + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND + CHARACTER(LEN=10) :: LOC_ACT +! +! SET LOCAL ACTION +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S2 - Null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',2_LINT,NUMBER,.FALSE.,FPAR) + PFIND => FLL_LOCATE(PNODE,NAME,'S',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) STRING=>NULL() RETURN END IF diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 0244959..1012bf2 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -32,7 +32,7 @@ MODULE FLL_LOCATE_M ! CONTAINS - RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PFIND) + RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTION) RESULT(PFIND) ! ! Description: function finds node identified by name, type, position in list, dimensions of data it contains ! search can be done recursively @@ -59,6 +59,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU ! RECURSE In search recursively ! PFIND Out return pointer to located node ! FPAR In/Out structure containing function specific data +! ACTION In/Out where to print err messages ! ! Arguments declaration ! @@ -68,22 +69,29 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD INTEGER(LINT) :: LOCNUM,NDIM, NSIZE + CHARACTER(LEN=10) :: LOC_ACT ! ! remove empty spaces ! NULLIFY(PFIND) + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF TLTYPE = ADJUSTL(TRIM(LTYPE(1:))) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -165,7 +173,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESU PFIND => NULL() FPAR%SUCCESS = .FALSE. ! WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) -! CALL FLL_OUT('ALL',FPAR) +! CALL FLL_OUT(LOC_ACT,FPAR) RETURN END FUNCTION FLL_LOCATE diff --git a/data_util/fll_out.f90 b/data_util/fll_out.f90 index ccefd11..1283e4c 100644 --- a/data_util/fll_out.f90 +++ b/data_util/fll_out.f90 @@ -75,6 +75,9 @@ SUBROUTINE FLL_OUT(ACTION,FPAR) ! SELECT CASE(ACTION) + CASE('NONE') + RETURN + CASE('OPEN') OPEN(UNIT=IOLOGFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') From 2a510ed7536ab8cc9ca8c1dfc5a590ad57a1d83d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 10:51:20 -0700 Subject: [PATCH 290/325] define optional ACTION --- data_util/fll_cat.f90 | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index db4d61d..6c4adb1 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -34,7 +34,7 @@ MODULE FLL_CAT_M ! CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -61,6 +61,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) INTEGER :: IOUNIT LOGICAL :: PARENT CHARACTER, OPTIONAL :: SCAN,SDIR + CHARACTER(*), OPTIONAL :: ACTION ! ! Local types ! @@ -68,6 +69,15 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC INTEGER :: DIR + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! body of subroutine ! @@ -88,7 +98,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' CAT - null node ' FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF From cb584f56ac4282983ca4d653f6c09510efc1f57d Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 10:53:27 -0700 Subject: [PATCH 291/325] add optional ACTION to deattach --- data_util/fll_deattach.f90 | 14 ++++++++++++-- data_util/fll_locate.f90 | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/data_util/fll_deattach.f90 b/data_util/fll_deattach.f90 index 57d7ceb..716beb9 100644 --- a/data_util/fll_deattach.f90 +++ b/data_util/fll_deattach.f90 @@ -34,7 +34,7 @@ MODULE FLL_DEATTACH_M ! External Modules used CONTAINS - FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) + FUNCTION FLL_DEATTACH(PWHAT,FPAR,ACTION) RESULT(OK) ! ! Description: Deattach PWHAT node from the list ! upon return, PWHAT parent is set to NULL and @@ -67,13 +67,23 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR) RESULT(OK) TYPE(DNODE), POINTER :: PWHAT TYPE(FUNC_DATA_SET) :: FPAR LOGICAL:: OK + CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! check that PWAT is not null node ! OK = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Deattach - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 1012bf2..b47888c 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -78,7 +78,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO INTEGER(LINT) :: LOCNUM,NDIM, NSIZE CHARACTER(LEN=10) :: LOC_ACT ! -! remove empty spaces +! define LOC_ACT ! NULLIFY(PFIND) IF(.NOT.PRESENT(ACTION))THEN From 8944851e43366fac71bef57703c8678565ee88dc Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 11:04:09 -0700 Subject: [PATCH 292/325] another functions with optional ACTION --- data_util/fll_duplicate.f90 | 84 +++++++++++++++++++++---------------- data_util/fll_mk.f90 | 20 ++++++--- data_util/fll_mv.f90 | 21 +++++++--- data_util/fll_stich.f90 | 16 +++++-- 4 files changed, 92 insertions(+), 49 deletions(-) diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index a3a0574..5335c1b 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -33,7 +33,7 @@ MODULE FLL_DUPLICATE_M ! External Modules used ! CONTAINS - FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) + FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! ! Description: Contains duplicates node to PNEW mode ! the parent, previous and next pointers of PNEW node are NULL @@ -66,10 +66,20 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF SUBROUTINE ! @@ -80,7 +90,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -90,7 +100,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM ! IF(ASSOCIATED(PCHILD))THEN - PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR) + PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. @@ -98,10 +108,10 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) RETURN END IF - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR,LOC_ACT) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN @@ -111,15 +121,15 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR) RESULT(PNEW) ! ! NODE IS A FILE NODE ! - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR) + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR,ACTION=LOC_ACT) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF - CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW,FPAR) + CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW,FPAR,LOC_ACT) END IF @@ -130,7 +140,7 @@ END FUNCTION FLL_DUPLICATE ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) + RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ACT) ! ! Description: makes recursive duplicate of PNODE ! @@ -155,6 +165,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) ! TYPE(DNODE), POINTER :: PNODE,PDUPL TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*) :: LOC_ACT ! ! Local declarations ! @@ -170,29 +181,29 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR) + PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR,ACTION=LOC_ACT) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF IF(.NOT.ASSOCIATED(PCHILD))THEN - CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR) + CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR,LOC_ACT) ELSE ! ! NODE HAS CHILDREN ! - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR,LOC_ACT) IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' END IF ! ! ADD TO PDUPL LIST ! - OK = FLL_MV(PNEW,PDUPL,FPAR) + OK = FLL_MV(PNEW,PDUPL,FPAR,ACTION=LOC_ACT) PCURR => PNEXT @@ -206,7 +217,7 @@ END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE ! ! ! - SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) + SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ! ! Description: duplicated data of the node ! @@ -235,6 +246,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*) :: LOC_ACT ! ! Local declarations ! @@ -245,7 +257,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF ! @@ -270,7 +282,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -278,7 +290,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -293,7 +305,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -301,7 +313,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -317,14 +329,14 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -339,7 +351,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -347,7 +359,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -362,7 +374,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -370,7 +382,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF @@ -388,7 +400,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -396,7 +408,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF @@ -412,7 +424,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -420,7 +432,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF @@ -436,7 +448,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -444,7 +456,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF @@ -460,7 +472,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -468,7 +480,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF @@ -484,7 +496,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -492,7 +504,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF END IF diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index 0b17c13..ebd2d23 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -36,7 +36,7 @@ MODULE FLL_MK_M ! External Modules used ! CONTAINS - FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) + FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) ! ! Description: function creates node specified by name, type and dimensions ! @@ -64,10 +64,20 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NDIM, NSIZE + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! INTEGER :: ISTAT + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF PNEW => NULL() ! @@ -75,19 +85,19 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) ! IF(LEN_TRIM(LTYPE)<1.OR.LEN_TRIM(LTYPE)>TYPE_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF IF(LEN_TRIM(NAME)>NAME_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong name: ',TRIM(NAME) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF IF(.NOT.ANY(LTYPE(1:1)==(/'C','S','I','L','R','D','N'/))) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF @@ -115,7 +125,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR) RESULT(PNEW) IF(NDIM < 1 .OR. NSIZE < 1)THEN WRITE(FPAR%MESG,'(A,A,I5,I5)')' Wrong dimensions for node ',TRIM(NAME), NDIM, NSIZE - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) RETURN END IF ! diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 164ad78..73257b1 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -30,7 +30,7 @@ MODULE FLL_MV_M ! External Modules used ! CONTAINS - FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) + FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) ! ! Description: Module moves PWHAT pointer to PWHERE pointer ! @@ -60,14 +60,24 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR LOGICAL OK + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! TYPE(DNODE), POINTER :: PSOURCETMP + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF IF(.NOT.ASSOCIATED(PWHAT,PWHERE))THEN - PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR) + PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR,LOC_ACT) OK = FPAR%SUCCESS END IF @@ -75,7 +85,7 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR) RESULT(OK) RETURN END FUNCTION FLL_MV - FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) ! ! Description: Module moves or copies PWHAT pointer to PWHERE pointer ! depending on MODE values (C or M) @@ -96,6 +106,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE + CHARACTER(*) :: LOC_ACT ! ! Declarations ! @@ -120,14 +131,14 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhat null node' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhere null node' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index db47b68..e08ea2d 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -30,7 +30,7 @@ MODULE FLL_STICH_M ! External Modules used ! CONTAINS - SUBROUTINE FLL_STICH(PNODE,FPAR) + SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) ! ! Description: subroutine stiches list after PNODE ! is taken away @@ -56,16 +56,26 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! TYPE(DNODE), POINTER :: PNEXT=>NULL(), PPREV=>NULL(),PPAR=>NULL() + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF SUBROUTINE ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Stich - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -78,7 +88,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR) IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF From f5d8a40ee94c52fb388bb78a4b5613d9a67dcabe Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 11:05:58 -0700 Subject: [PATCH 293/325] add optional ACTION to fll_getnbytes --- data_util/fll_getnbytes.f90 | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 index 043cad9..433f1e9 100644 --- a/data_util/fll_getnbytes.f90 +++ b/data_util/fll_getnbytes.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNBYTES_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) + RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) ! ! Description: Get size of linked list in bytes ! @@ -62,10 +62,20 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: BYTES + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD,PNEXT + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF SUBROUTINE ! @@ -75,7 +85,7 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - null node ' - CALL FLL_OUT('LOG',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -92,7 +102,7 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR) RESULT(BYTES) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - error duplicting children nodes ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF From b2a5336575a8057df47836521382dc3469276c9c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 11:07:52 -0700 Subject: [PATCH 294/325] add optional ACTION to fll_funct_prt --- data_util/fll_funct_prt.f90 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/data_util/fll_funct_prt.f90 b/data_util/fll_funct_prt.f90 index aa88bb0..68be43e 100644 --- a/data_util/fll_funct_prt.f90 +++ b/data_util/fll_funct_prt.f90 @@ -71,7 +71,7 @@ FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) RETURN END FUNCTION ERR_MSG - FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) + FUNCTION TEST_IOSTAT(IOSTAT, FPAR,ACTION) RESULT(OK) ! ! Description: tests IOSTAT return parameter from R/W functions ! @@ -91,15 +91,26 @@ FUNCTION TEST_IOSTAT(IOSTAT, FPAR) RESULT(OK) INTEGER :: IOSTAT TYPE(FUNC_DATA_SET) :: FPAR LOGICAL :: OK + CHARACTER(*), OPTIONAL :: ACTION + + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! OK = .FALSE. IF (IOSTAT > 0) THEN WRITE(FPAR%MESG,'(A)')' Read - error readig node data' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. ELSE IF (IOSTAT < 0) THEN WRITE(FPAR%MESG,'(A)')' Read - EOF reached' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. ELSE FPAR%SUCCESS = .TRUE. From 5c91439e5fb5d09af0abab72078a96cc07fdf963 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 11:13:35 -0700 Subject: [PATCH 295/325] add optional ACTION to fll_cp and fll_rm --- data_util/fll_cp.f90 | 34 +++++++++++++++++++++++----------- data_util/fll_rm.f90 | 30 +++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index d32f1ac..5350fb1 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -34,7 +34,7 @@ MODULE FLL_CP_M ! CONTAINS - FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) + FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) ! ! Description: Module copies PWHAT pointer to PWHERE pointer ! If PWHERE pointer == NULL, PWHAT is a duplicate @@ -69,6 +69,17 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW + CHARACTER(*), OPTIONAL :: ACTION + + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! initialize PNEW pointer and check that PWHAT is not NULL ! @@ -77,7 +88,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -87,21 +98,21 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR) RESULT(PNEW) ! IF NOT SPECIFIED WHERE TO COPY ! JUST DUPLICATE NODE ! - PNEW => FLL_DUPLICATE(PWHAT, FPAR) + PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ACT) ELSE ! ! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! IF(.NOT.ASSOCIATED(PWHAT,PWHERE))& - PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR) + PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR,LOC_ACT) END IF RETURN END FUNCTION FLL_CP - FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) + FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) ! ! Description: Module copies PWHAT pointer to PWHERE pointer ! If PWHERE pointer == NULL, PWHAT is a duplicate @@ -132,6 +143,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE + CHARACTER(*) :: LOC_ACT ! ! LOCAL TYPES ! @@ -148,7 +160,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -157,7 +169,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhere null node' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -167,7 +179,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) PTPAR => PWHERE%PPAR IF(MODE == 'C')THEN - PNEW => FLL_DUPLICATE(PWHAT, FPAR) + PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ACT) PSOURCETMP => PNEW ! ! IN CASE NODE IS NOT COPIED ANYWAY, IT IS ONLY DUPLICATED, RETURN @@ -186,7 +198,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL FLL_STICH(PWHAT,FPAR) + IF(MODE == 'M') CALL FLL_STICH(PWHAT,FPAR,LOC_ACT) IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN ! @@ -221,11 +233,11 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR) RESULT(PSOURCETMP) ! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN ! DELETE TARGET NODE ! - CALL FLL_RM(PWHERE, FPAR) + CALL FLL_RM(PWHERE, FPAR,LOC_ACT) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL FLL_STICH(PSOURCETMP,FPAR) + IF(MODE == 'M') CALL FLL_STICH(PSOURCETMP,FPAR,LOC_ACT) ! ! ADD A NEW NODE ! diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index 91d0aaf..5ccbe54 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -30,7 +30,7 @@ MODULE FLL_RM_M ! External Modules used ! CONTAINS - SUBROUTINE FLL_RM(PNODE,FPAR) + SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! ! Description: function removes PNODE ! @@ -60,17 +60,27 @@ SUBROUTINE FLL_RM(PNODE,FPAR) ! TYPE(DNODE), POINTER :: PNODE,PCHILD TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! INTEGER :: ISTAT + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF SUBROUTINE ! FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' RM - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -79,13 +89,13 @@ SUBROUTINE FLL_RM(PNODE,FPAR) ! ! STICH AND SUBSTRACT FROM PARENT ! - CALL FLL_STICH(PNODE,FPAR) + CALL FLL_STICH(PNODE,FPAR,LOC_ACT) ! ! IF NODE HAS CHILDREN, REMOVE ALL OF THEM ! - IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR,LOC_ACT) - CALL FLL_DEALLOC_DATA(PNODE,FPAR) + CALL FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) ! ! NULLIFY NODE ! @@ -100,7 +110,7 @@ END SUBROUTINE FLL_RM ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) + RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) ! ! Description: recursive function removes PNODE ! @@ -128,6 +138,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*) :: LOC_ACT ! ! Local declarations ! @@ -143,12 +154,12 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR) DO WHILE(ASSOCIATED(PCURR)) PNEXT => PCURR%PNEXT IF(ASSOCIATED(PCURR%PCHILD))THEN - CALL FLL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR) + CALL FLL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR,LOC_ACT) END IF IF(TRIM(PCURR%LTYPE) /= 'LINK')THEN - CALL FLL_DEALLOC_DATA(PCURR,FPAR) + CALL FLL_DEALLOC_DATA(PCURR,FPAR,LOC_ACT) IF(ASSOCIATED(PCURR%PLINK))THEN PNODE%PLINK%PCHILD => NULL(); @@ -181,7 +192,7 @@ END SUBROUTINE FLL_RM_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) + SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) ! ! Description: function deallocates data from associated with PNODE ! @@ -208,6 +219,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*) :: LOC_ACT ! ! local declarations ! From 7ba50cbbffabb85985da39de40649ecf6cfc5252 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 11:52:12 -0700 Subject: [PATCH 296/325] add optional ACTION --- data_util/fll_mkdir.f90 | 14 ++++- data_util/fll_nnodes.f90 | 16 +++++- data_util/fll_read.f90 | 12 +++- data_util/fll_read_ucd.f90 | 110 ++++++++++++++++++++---------------- data_util/fll_rename.f90 | 14 ++++- data_util/fll_scan_file.f90 | 18 ++++-- data_util/fll_sweep.f90 | 14 ++++- 7 files changed, 135 insertions(+), 63 deletions(-) diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 index 774440d..f7ba4ed 100644 --- a/data_util/fll_mkdir.f90 +++ b/data_util/fll_mkdir.f90 @@ -31,7 +31,7 @@ MODULE FLL_MKDIR_M ! External Modules used ! CONTAINS - FUNCTION FLL_MKDIR(NAME,FPAR) RESULT(PNEW) + FUNCTION FLL_MKDIR(NAME,FPAR,ACTION) RESULT(PNEW) ! ! Description: function creates node specified by name, type and dimensions ! @@ -54,14 +54,24 @@ FUNCTION FLL_MKDIR(NAME,FPAR) RESULT(PNEW) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW CHARACTER(LEN=*) :: NAME + CHARACTER(LEN=*), OPTIONAL :: ACTION ! ! Local declarations ! + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF PNEW => NULL() ! ! Body ! - PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR) + PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR,ACTION=LOC_ACT) RETURN END FUNCTION FLL_MKDIR diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index a2447d8..4781ca6 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -31,7 +31,7 @@ MODULE FLL_NNODES_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMBER) + RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESULT(NUMBER) ! ! Description: function returns number of nodes specified by ! name, type and dimensions of data @@ -65,12 +65,22 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE + CHARACTER(*), OPTIONAL :: ACTION ! ! local declarations ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD, PFIND INTEGER(LINT) :: I,NDIM,NSIZE + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF FUNCTION ! @@ -85,7 +95,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -103,7 +113,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR) RESULT(NUMB ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,DATADIM,RECURSE,FPAR) + NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,DATADIM,RECURSE,FPAR,LOC_ACT) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 494050a..90a1ab8 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_M ! CONTAINS - FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) + FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -95,6 +95,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER :: FMT CHARACTER, OPTIONAL :: SCAN + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! @@ -103,6 +104,15 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) INTEGER :: ISTAT INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index 8c283b5..01a6611 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_UCD_M ! CONTAINS - FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) + FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -94,17 +94,27 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT,ITYPE + CHARACTER(*), OPTIONAL :: ACTION ! ! Local declarations ! LOGICAL :: OK CHARACTER :: FMT_LOC INTEGER :: ISTAT + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -121,7 +131,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -140,7 +150,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -150,9 +160,9 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) ! SELECT CASE(ITYPE) CASE('I','i') - PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR) + PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR,LOC_ACT) CASE('L','l') - PNODE => READ_NODE_UCD_L(IOUNIT,FMT_LOC,FPAR) + PNODE => READ_NODE_UCD_L(IOUNIT,FMT_LOC,FPAR,LOC_ACT) CASE DEFAULT STOP'WRONG DATA FORMAT FOR UCD DATA SET' END SELECT @@ -160,7 +170,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -171,7 +181,7 @@ END FUNCTION FLL_READ_UCD - FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -207,6 +217,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT + CHARACTER(*) :: LOC_ACT ! ! Local declarations ! @@ -232,14 +243,14 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! allocate memory for coordinates ! - PNODE => FLL_MKDIR('unstr_grid_data', FPAR) - PREG => FLL_MKDIR('region', FPAR) - OK = FLL_MV(PREG,PNODE,FPAR) - PBND => FLL_MKDIR('boundary', FPAR) - OK = FLL_MV(PBND,PREG,FPAR) + PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ACT) + PREG => FLL_MKDIR('region', FPAR,LOC_ACT) + OK = FLL_MV(PREG,PNODE,FPAR,LOC_ACT) + PBND => FLL_MKDIR('boundary', FPAR,LOC_ACT) + OK = FLL_MV(PBND,PREG,FPAR,LOC_ACT) - PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR) - OK = FLL_MV(PTMP,PREG,FPAR) + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PREG,FPAR,LOC_ACT) COO => PTMP%D2 DO I=1,NPTS @@ -248,7 +259,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! add boundary name ! - PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR) + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ACT) PTMP%S0 = 'wall' ! ! read elements @@ -278,26 +289,26 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) ! IF(N3> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR) - OK = FLL_MV(PBELEM,PBND,FPAR) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) - OK = FLL_MV(PTMP,PBELEM,FPAR) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) PTMP%S0 = 'tria3' - PTMP => FLL_MK('bound_elem_nodes','I',N3,3_LINT,FPAR) + PTMP => FLL_MK('bound_elem_nodes','I',N3,3_LINT,FPAR,LOC_ACT) PTMP%I2 = I3(1:N3,:) - OK = FLL_MV(PTMP,PBELEM,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) END IF IF(N4> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR) - OK = FLL_MV(PBELEM,PBND,FPAR) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) - OK = FLL_MV(PTMP,PBELEM,FPAR) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) PTMP%S0 = 'quad4' - PTMP => FLL_MK('bound_elem_nodes','I',N4,4_LINT,FPAR) + PTMP => FLL_MK('bound_elem_nodes','I',N4,4_LINT,FPAR,LOC_ACT) PTMP%I2 = I4(1:N4,:) - OK = FLL_MV(PTMP,PBELEM,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) END IF @@ -308,7 +319,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR) RESULT(PNODE) END FUNCTION READ_NODE_UCD - FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -356,6 +367,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) INTEGER :: ISTAT LOGICAL :: OK CHARACTER(LEN = 200)TEXTLONG + CHARACTER(LEN=*) :: LOC_ACT ! ! disregard all lines starting with # - 3 lines ! @@ -369,14 +381,14 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! allocate memory for coordinates ! - PNODE => FLL_MKDIR('unstr_grid_data', FPAR) - PREG => FLL_MKDIR('region', FPAR) - OK = FLL_MV(PREG,PNODE,FPAR) - PBND => FLL_MKDIR('boundary', FPAR) - OK = FLL_MV(PBND,PREG,FPAR) + PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ACT) + PREG => FLL_MKDIR('region', FPAR,LOC_ACT) + OK = FLL_MV(PREG,PNODE,FPAR,LOC_ACT) + PBND => FLL_MKDIR('boundary', FPAR,LOC_ACT) + OK = FLL_MV(PBND,PREG,FPAR,LOC_ACT) - PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR) - OK = FLL_MV(PTMP,PREG,FPAR) + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PREG,FPAR,LOC_ACT) COO => PTMP%D2 DO I=1,NPTS @@ -385,7 +397,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! add boundary name ! - PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR) + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ACT) PTMP%S0 = 'wall' ! ! read elements @@ -415,26 +427,26 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR) RESULT(PNODE) ! IF(N3> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR) - OK = FLL_MV(PBELEM,PBND,FPAR) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) - OK = FLL_MV(PTMP,PBELEM,FPAR) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) PTMP%S0 = 'tria3' - PTMP => FLL_MK('bound_elem_nodes','L',N3,3_LINT,FPAR) + PTMP => FLL_MK('bound_elem_nodes','L',N3,3_LINT,FPAR,LOC_ACT) PTMP%L2 = I3(1:N3,:) - OK = FLL_MV(PTMP,PBELEM,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) END IF IF(N4> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR) - OK = FLL_MV(PBELEM,PBND,FPAR) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR) - OK = FLL_MV(PTMP,PBELEM,FPAR) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) PTMP%S0 = 'quad4' - PTMP => FLL_MK('bound_elem_nodes','L',N4,4_LINT,FPAR) + PTMP => FLL_MK('bound_elem_nodes','L',N4,4_LINT,FPAR,LOC_ACT) PTMP%L2 = I4(1:N4,:) - OK = FLL_MV(PTMP,PBELEM,FPAR) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) END IF diff --git a/data_util/fll_rename.f90 b/data_util/fll_rename.f90 index 244c14f..8e4aa3b 100644 --- a/data_util/fll_rename.f90 +++ b/data_util/fll_rename.f90 @@ -34,7 +34,7 @@ MODULE FLL_RENAME_M ! CONTAINS - FUNCTION FLL_RENAME(PWHAT,INAME,FPAR) RESULT(OK) + FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ACTION) RESULT(OK) ! ! Description: Renames node ! @@ -59,13 +59,23 @@ FUNCTION FLL_RENAME(PWHAT,INAME,FPAR) RESULT(OK) TYPE(FUNC_DATA_SET) :: FPAR CHARACTER(LEN=*) :: INAME LOGICAL :: OK + CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! check that PWHAT is not NULL ! IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Rename - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Rename - Pwhat null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN diff --git a/data_util/fll_scan_file.f90 b/data_util/fll_scan_file.f90 index 9938314..5af2fc7 100644 --- a/data_util/fll_scan_file.f90 +++ b/data_util/fll_scan_file.f90 @@ -21,7 +21,7 @@ ! MODULE FLL_SCAN_FILE_M ! -! Description: Contains function fll_cp +! Description: Contains function fll_scan_file ! ! ! History: @@ -34,7 +34,7 @@ MODULE FLL_SCAN_FILE_M ! CONTAINS - FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR) RESULT(PNODE) + FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) ! ! Description: Scan file, returns fll list with data names in file and their ! position in file in bytes @@ -63,15 +63,25 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER(LEN=FILE_NAME_LENGTH) :: FILENAME CHARACTER :: FMT + CHARACTER(*), OPTIONAL :: ACTION ! ! Local types ! LOGICAL :: OK + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF INQUIRE (FILE=TRIM(FILENAME), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILENAME) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -79,7 +89,7 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR) RESULT(PNODE) ! ! GET FILE STRUCTURE ! - PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y') + PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y', ACTION=LOC_ACT) RETURN diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 4f4f06d..77f9e6e 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -30,7 +30,7 @@ MODULE FLL_SWEEP_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR) RESULT(OK) + RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) ! ! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! @@ -71,12 +71,22 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR) RESULT(OK) CHARACTER(*) :: LTYPE INTEGER(LINT) :: DIM LOGICAL OK + CHARACTER(*), OPTIONAL :: ACTION ! ! LOCAL TYPES ! CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE INTEGER(LINT) :: I TYPE(DNODE), POINTER :: PNEXT + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! BODY OF FUNCTION ! @@ -91,7 +101,7 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR) RESULT(OK) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Sweep - Null node: ',TRIM(NAME) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF From 42bc7967ddf4c99968b13f26f7496da0dbca1422 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 12:46:32 -0700 Subject: [PATCH 297/325] add optional ACTION to fll_read --- data_util/fll_read.f90 | 51 +++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 90a1ab8..2cedc4f 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -117,7 +117,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -134,7 +134,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -159,7 +159,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -173,7 +173,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -183,7 +183,7 @@ END FUNCTION FLL_READ ! ! READS NODE ! - RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) + RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ACT) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -231,29 +231,30 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) INTEGER(LINT) :: NDIM, NSIZE,NNODES LOGICAL :: OK INTEGER(LINT):: POSOLD + CHARACTER(LEN=*), OPTIONAL :: LOC_ACT ! ! READ HEADER ! POSOLD = POS - CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H) + CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ACT) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN END IF IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H,LOC_ACT) ELSE - PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ACT) END IF IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -272,7 +273,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) ! ! ATTACH TO PNODE ! - OK = FLL_MV(PNEW,PNODE,FPAR) + OK = FLL_MV(PNEW,PNODE,FPAR,LOC_ACT) IF(.NOT.OK) STOP' ERROR MV' END DO @@ -282,15 +283,15 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR) RESULT(PNODE) ! SELECT CASE(FMT) CASE('A') - CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ACT) CASE('B') IF(SCAN /= 'Y')THEN - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ACT) ELSE IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ACT) ELSE - POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ACT) END IF END IF END SELECT @@ -303,7 +304,7 @@ END FUNCTION READ_NODE ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) ! ! Description: Reads header of each node ! @@ -345,6 +346,7 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) CHARACTER(*) :: LTYPE CHARACTER(*) :: NAME INTEGER(LINT) :: NDIM, NSIZE + CHARACTER(LEN=*) :: LOC_ACT ! ! Local declarations ! @@ -441,12 +443,12 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR) END SELECT WRITE(FPAR%MESG,'(A)')' Read - reading header error ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN @@ -454,7 +456,7 @@ END SUBROUTINE READ_HEADER ! ! READ DATA ! - SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) ! ! Description: Reads data contatined in node Pnode - ASCII file ! @@ -491,6 +493,7 @@ SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) INTEGER(LINT) :: NDIM,NSIZE CHARACTER(LEN=TYPE_LENGTH) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=*), OPTIONAL :: LOC_ACT ! ! Local declarations ! @@ -598,7 +601,7 @@ END SUBROUTINE READ_DATA_ASCII ! ! READ DATA ! - SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) + SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR,LOC_ACT) ! ! Description: Function reads data contained in Pnode, bindary file ! @@ -635,6 +638,7 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) INTEGER(LINT) :: NDIM,NSIZE,POS CHARACTER(*) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(LEN=*), OPTIONAL :: LOC_ACT ! ! Local declarations ! @@ -776,7 +780,7 @@ END SUBROUTINE READ_DATA_BIN - FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) + FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR,LOC_ACT) RESULT (POS) ! ! Description: Function gets new position for reading bindary file without allocating arrays ! used for scanning files @@ -792,6 +796,7 @@ FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -812,6 +817,7 @@ FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: NDIM, NSIZE, POS CHARACTER(LEN=*) :: LTYPE + CHARACTER(LEN=*), OPTIONAL :: LOC_ACT ! ! Local declaration ! @@ -837,6 +843,9 @@ FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) CASE DEFAULT WRITE(*,*)' WRONG TYPE' + WRITE(FPAR%MESG,'(A,A)')' GET_NEW_POS - wrong type ' + CALL FLL_OUT(LOC_ACT,FPAR) + FPAR%SUCCESS = .FALSE. END SELECT From 53b7ec0e6179463781f9729b2fbd2ccb28cd6eb5 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 12:51:33 -0700 Subject: [PATCH 298/325] add optional ACTION --- data_util/fll_write.f90 | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 6af54c9..cd24541 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -31,7 +31,7 @@ MODULE FLL_WRITE_M ! External Modules used ! CONTAINS - FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) + FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) ! ! Description: main function opening, writing and closing file ! @@ -67,12 +67,22 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) INTEGER :: IOUNIT CHARACTER :: FMT LOGICAL OK + CHARACTER(LEN=*), OPTIONAL :: ACTION ! ! local declarations ! CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF ! ! DETERMINE RORMAT' ! @@ -85,7 +95,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Write unknown format',TRIM(FMT) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. @@ -105,7 +115,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -113,12 +123,12 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! ! WRITE LINKED LIST ! - CALL FLL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) + CALL FLL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR,LOC_ACT) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -131,7 +141,7 @@ END FUNCTION FLL_WRITE - SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) + SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ACT) ! ! Description: Function writes a list ! @@ -164,7 +174,8 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) TYPE(DNODE), POINTER :: PNODE,PCHILD TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT - CHARACTER :: FMT + CHARACTER :: FMT + CHARACTER(LEN=*) :: LOC_ACT ! ! Local declarations ! @@ -176,7 +187,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Write - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -191,7 +202,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ACT) FPAR%SUCCESS = .TRUE. @@ -200,7 +211,7 @@ END SUBROUTINE FLL_WRITE_LIST ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) + RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR,LOC_ACT) ! ! Description: Function writes a node ! @@ -232,7 +243,8 @@ RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) INTEGER :: IOUNIT TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS - CHARACTER :: FMT + CHARACTER :: FMT + CHARACTER(LEN=*) :: LOC_ACT ! ! Local declarations ! @@ -255,7 +267,7 @@ RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR) + CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ACT) END IF PCURR => PNEXT From d16ea71b03d8872a1cbc4bf5cd943aa37649ebe9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 12:54:05 -0700 Subject: [PATCH 299/325] add optional ACTION to fll_read_record --- data_util/fll_read_record.f90 | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index aab72a3..9efb8dc 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_RECORD_M ! CONTAINS - FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR) RESULT(PNODE) + FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTION) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -108,6 +108,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE + CHARACTER(LEN=*), OPTIONAL :: ACTION ! ! Local declarations ! @@ -117,6 +118,15 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INTEGER :: ISTAT,PLISTOK INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC + CHARACTER(LEN=10) :: LOC_ACT +! +! local action +! + IF(.NOT.PRESENT(ACTION))THEN + LOC_ACT='ALL' + ELSE + LOC_ACT = ACTION + END IF PLISTOK = 0 @@ -128,7 +138,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -136,15 +146,15 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! USE ONLY BINARY FORMAT ! - PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y') - CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR) + PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y',ACTION=LOC_ACT) + CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR,ACTION=LOC_ACT) ! END IF - PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR) + PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR,ACTION=LOC_ACT) IF(.NOT.ASSOCIATED(PTMP))THEN - CALL FLL_RM(PLIST, FPAR) + CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ACT) PNODE => NULL() RETURN END IF @@ -153,12 +163,11 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! CLEAN MEMORY ! -! CALL FLL_RM(PTMP, FPAR) IF(PLISTOK == 0)THEN ! ! LIST WAS CREATED IN THIS FUNCTION, REMOVE IT ! - CALL FLL_RM(PLIST, FPAR) + CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ACT) END IF ! ! OPEN FILE @@ -166,7 +175,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -184,7 +193,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read_record - error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -195,7 +204,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA PLIST => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) IF(.NOT.ASSOCIATED(PLIST)) THEN WRITE(FPAR%MESG,'(A,A)')' Read_record - error reading specified data set ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -211,7 +220,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ACT,FPAR) FPAR%SUCCESS = .FALSE. END IF From 7ddbb1bc71ab3339644dc0a5cb603c7881b35360 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 12:55:10 -0700 Subject: [PATCH 300/325] sync ERR statements --- data_util/fll_mk.f90 | 32 ++++++++++++++++---------------- data_util/fll_read_ucd.f90 | 8 ++++---- data_util/fll_rm.f90 | 26 +++++++++++++------------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index ebd2d23..d2ae65e 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -102,7 +102,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) END IF ALLOCATE(PNEW, STAT = ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:95 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:105 ' PNEW%LNAME = TRIM(NAME) PNEW%LTYPE = LTYPE PNEW%NDIM = 0 @@ -136,15 +136,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%R1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:129 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:139 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%R1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:134 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:144 ' ELSE ALLOCATE(PNEW%R2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:137 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:147 ' END IF END IF @@ -152,15 +152,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%D1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:145 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:155 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%D1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:150 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:160 ' ELSE ALLOCATE(PNEW%D2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:153 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:163 ' END IF END IF @@ -169,15 +169,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%I1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:162 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:172 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%I1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:167 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:177 ' ELSE ALLOCATE(PNEW%I2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:170 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:180 ' END IF END IF @@ -186,15 +186,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%L1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:179 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:189 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%L1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:184 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:194 ' ELSE ALLOCATE(PNEW%L2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:187 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:197 ' END IF END IF @@ -203,15 +203,15 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM == 1)THEN IF(NSIZE > 1)THEN ALLOCATE(PNEW%S1(NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:196 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:206 ' END IF ELSE IF(NSIZE == 1)THEN ALLOCATE(PNEW%S1(NDIM), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:201 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:211 ' ELSE ALLOCATE(PNEW%S2(NDIM,NSIZE), STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:204 ' + IF(ISTAT /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mk ERR:214 ' END IF END IF diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index 01a6611..76b00b8 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -268,7 +268,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) N4 = 0 ! ALLOCATE(I3(NELEM,3),I4(NELEM,4), STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:260 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:271 ' DO I=1,NELEM @@ -314,7 +314,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) DEALLOCATE(I3,I4, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:306 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:317 ' END FUNCTION READ_NODE_UCD @@ -406,7 +406,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) N4 = 0 ! ALLOCATE(I3(NELEM,3),I4(NELEM,4), STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:397 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_read_ucd ERR:409 ' DO I=1,NELEM @@ -452,7 +452,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) DEALLOCATE(I3,I4, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:443 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_read_ucd ERR:455 ' END FUNCTION READ_NODE_UCD_L diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index 5ccbe54..a338f94 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -100,7 +100,7 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! NULLIFY NODE ! DEALLOCATE(PNODE, STAT=ISTAT) - IF(ISTAT /= 0)STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:93 ' + IF(ISTAT /= 0)STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:103 ' NULLIFY(PNODE) FPAR%SUCCESS = .TRUE. @@ -166,7 +166,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) END IF DEALLOCATE(PCURR, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:158 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:169 ' NULLIFY(PCURR) FPAR%SUCCESS = .TRUE. ELSE @@ -176,7 +176,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) PCURR%PCHILD%PLINK => NULL() PCURR%PCHILD => NULL() DEALLOCATE(PCURR, STAT=ISTAT) - IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:168 ' + IF(ISTAT /= 0)STOP'ERROR DEALLOCATING MEMORY ==> fll_rm ERR:179 ' NULLIFY(PCURR) FPAR%SUCCESS = .TRUE. END IF @@ -230,7 +230,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%R1))THEN DEALLOCATE(PNODE%R1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:221 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:233 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -240,7 +240,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%D1))THEN DEALLOCATE(PNODE%D1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:231 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:243 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -250,7 +250,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%I1))THEN DEALLOCATE(PNODE%I1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:241 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:253 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -260,7 +260,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%L1))THEN DEALLOCATE(PNODE%L1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:251 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:263 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -270,7 +270,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%S1))THEN DEALLOCATE(PNODE%S1, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:261 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:273 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -282,7 +282,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%R2))THEN DEALLOCATE(PNODE%R2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:273 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:285 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -292,7 +292,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%D2))THEN DEALLOCATE(PNODE%D2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:283 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:295 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -302,7 +302,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%I2))THEN DEALLOCATE(PNODE%I2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:293 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:305 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -312,7 +312,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%L2))THEN DEALLOCATE(PNODE%L2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:303 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:315 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. @@ -322,7 +322,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) IF(ASSOCIATED(PNODE%S2))THEN DEALLOCATE(PNODE%S2, STAT=ISTAT) IF(ISTAT /= 0)THEN - STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:313 ' + STOP' ERROR DEALLOCATING MEMORY ==> fll_rm ERR:325 ' FPAR%SUCCESS = .FALSE. END IF FPAR%SUCCESS = .TRUE. From fa3775d6b23da728e9ec3fff3a20aaeab7af5ea6 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 13 Nov 2017 13:00:33 -0700 Subject: [PATCH 301/325] add PLIST description --- data_util/fll_read_record.f90 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index 9efb8dc..cf450b4 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -89,6 +89,8 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! FILE In Name of file ! PNODE Out Node to a first node in list from a file ! IOUNIT In Number of unit +! PLIST In List of items in file, can be obtained by +! FLL_READ with SCAN = 'Y' optional parameter ! NAME In name of node ! NUMBER In position of node in list ! LTYPE In type of node - can be * From 256a946e73409f66d2dc93ec9ec2f4a812875de0 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 14 Nov 2017 07:21:19 -0700 Subject: [PATCH 302/325] rename LOC_ACT variable --- data_util/fll_cat.f90 | 8 +- data_util/fll_cp.f90 | 28 +++--- data_util/fll_deattach.f90 | 8 +- data_util/fll_duplicate.f90 | 80 ++++++++-------- data_util/fll_funct_prt.f90 | 10 +- data_util/fll_getnbytes.f90 | 10 +- data_util/fll_getndata.f90 | 176 +++++++++++++++++----------------- data_util/fll_locate.f90 | 12 +-- data_util/fll_mk.f90 | 14 +-- data_util/fll_mkdir.f90 | 8 +- data_util/fll_mv.f90 | 16 ++-- data_util/fll_nnodes.f90 | 10 +- data_util/fll_read.f90 | 60 ++++++------ data_util/fll_read_record.f90 | 26 ++--- data_util/fll_read_ucd.f90 | 106 ++++++++++---------- data_util/fll_rename.f90 | 8 +- data_util/fll_rm.f90 | 26 ++--- data_util/fll_scan_file.f90 | 10 +- data_util/fll_stich.f90 | 10 +- data_util/fll_sweep.f90 | 8 +- data_util/fll_write.f90 | 28 +++--- 21 files changed, 331 insertions(+), 331 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 6c4adb1..37a2302 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -69,14 +69,14 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC INTEGER :: DIR - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! body of subroutine @@ -98,7 +98,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' CAT - null node ' FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index 5350fb1..b89bf84 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -71,14 +71,14 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) TYPE(DNODE), POINTER :: PNEW CHARACTER(*), OPTIONAL :: ACTION - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! initialize PNEW pointer and check that PWHAT is not NULL @@ -88,7 +88,7 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -98,21 +98,21 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) ! IF NOT SPECIFIED WHERE TO COPY ! JUST DUPLICATE NODE ! - PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ACT) + PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ERRMSG) ELSE ! ! OTHERWISE DUPLICATE NODE AND MOVE IT ! TO PWHERE ! IF(.NOT.ASSOCIATED(PWHAT,PWHERE))& - PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR,LOC_ACT) + PNEW => FLL_CP_R(PWHAT,PWHERE,'C',FPAR,LOC_ERRMSG) END IF RETURN END FUNCTION FLL_CP - FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) + FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ERRMSG) RESULT(PSOURCETMP) ! ! Description: Module copies PWHAT pointer to PWHERE pointer ! If PWHERE pointer == NULL, PWHAT is a duplicate @@ -143,7 +143,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! LOCAL TYPES ! @@ -160,7 +160,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Cp - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhat null node' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -169,7 +169,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) ! IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Cp - Pwhere null node' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -179,7 +179,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) PTPAR => PWHERE%PPAR IF(MODE == 'C')THEN - PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ACT) + PNEW => FLL_DUPLICATE(PWHAT, FPAR,LOC_ERRMSG) PSOURCETMP => PNEW ! ! IN CASE NODE IS NOT COPIED ANYWAY, IT IS ONLY DUPLICATED, RETURN @@ -198,7 +198,7 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL FLL_STICH(PWHAT,FPAR,LOC_ACT) + IF(MODE == 'M') CALL FLL_STICH(PWHAT,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN ! @@ -233,11 +233,11 @@ FUNCTION FLL_CP_R(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) ! DATA TYPES OF NODES, THE PWEHRE NODE WILL BE OVERWRITTEN ! DELETE TARGET NODE ! - CALL FLL_RM(PWHERE, FPAR,LOC_ACT) + CALL FLL_RM(PWHERE, FPAR,LOC_ERRMSG) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - IF(MODE == 'M') CALL FLL_STICH(PSOURCETMP,FPAR,LOC_ACT) + IF(MODE == 'M') CALL FLL_STICH(PSOURCETMP,FPAR,LOC_ERRMSG) ! ! ADD A NEW NODE ! diff --git a/data_util/fll_deattach.f90 b/data_util/fll_deattach.f90 index 716beb9..25716aa 100644 --- a/data_util/fll_deattach.f90 +++ b/data_util/fll_deattach.f90 @@ -68,14 +68,14 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR,ACTION) RESULT(OK) TYPE(FUNC_DATA_SET) :: FPAR LOGICAL:: OK CHARACTER(*), OPTIONAL :: ACTION - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! check that PWAT is not null node @@ -83,7 +83,7 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR,ACTION) RESULT(OK) OK = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Deattach - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 5335c1b..9507dbc 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -71,14 +71,14 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF SUBROUTINE @@ -90,7 +90,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -100,7 +100,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! IF NODE HAS CHILDREN, DUPLICATE ALL OF THEM ! IF(ASSOCIATED(PCHILD))THEN - PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR,LOC_ACT) + PNEW => FLL_MK(PNODE%LNAME,'DIR',0_LINT,0_LINT,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' FPAR%SUCCESS = .FALSE. @@ -108,10 +108,10 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) RETURN END IF - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR,LOC_ACT) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW,FPAR,LOC_ERRMSG) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error duplicting children nodes ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN @@ -121,15 +121,15 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! ! NODE IS A FILE NODE ! - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR,ACTION=LOC_ACT) + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR,ACTION=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF - CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW,FPAR,LOC_ACT) + CALL FLL_COPY_NODE_ARRAYS(PNODE, PNEW,FPAR,LOC_ERRMSG) END IF @@ -140,7 +140,7 @@ END FUNCTION FLL_DUPLICATE ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ACT) + RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ERRMSG) ! ! Description: makes recursive duplicate of PNODE ! @@ -165,7 +165,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ACT) ! TYPE(DNODE), POINTER :: PNODE,PDUPL TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -181,29 +181,29 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ACT) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR,ACTION=LOC_ACT) + PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR,ACTION=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNEW => NULL() RETURN END IF IF(.NOT.ASSOCIATED(PCHILD))THEN - CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR,LOC_ACT) + CALL FLL_COPY_NODE_ARRAYS(PCURR, PNEW, FPAR,LOC_ERRMSG) ELSE ! ! NODE HAS CHILDREN ! - CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR,LOC_ACT) + CALL FLL_DUPLICATE_RECURSIVE_NODE(PCHILD,PNEW, FPAR,LOC_ERRMSG) IF(.NOT.FPAR%SUCCESS) STOP'DUPLICATE - Error duplicating nodes' END IF ! ! ADD TO PDUPL LIST ! - OK = FLL_MV(PNEW,PDUPL,FPAR,ACTION=LOC_ACT) + OK = FLL_MV(PNEW,PDUPL,FPAR,ACTION=LOC_ERRMSG) PCURR => PNEXT @@ -217,7 +217,7 @@ END SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE ! ! ! - SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) + SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ERRMSG) ! ! Description: duplicated data of the node ! @@ -246,7 +246,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -257,7 +257,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(TRIM(PNODE%LTYPE) /= TRIM(PNEW%LTYPE))THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF ! @@ -282,7 +282,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -290,7 +290,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -305,7 +305,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -313,7 +313,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -329,14 +329,14 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF PNEW%I1(1:NDIM) = PNODE%I1(1:NDIM) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -351,7 +351,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -359,7 +359,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -374,7 +374,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -382,7 +382,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S1 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF @@ -400,7 +400,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -408,7 +408,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - R2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF @@ -424,7 +424,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -432,7 +432,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - D2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF @@ -448,7 +448,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -456,7 +456,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - I2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF @@ -472,7 +472,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -480,7 +480,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - L2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF @@ -496,7 +496,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) IF(NDIM /= NNDIM .OR. NSIZE /= NNSIZE)THEN WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - nodes do not have same dimensions', TRIM(PNODE%LNAME),' ', TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -504,7 +504,7 @@ SUBROUTINE FLL_COPY_NODE_ARRAYS(PNODE,PNEW,FPAR,LOC_ACT) ELSE WRITE(FPAR%MESG,'(A,A,A,A)')' DUPLICATE - S2 array not allocated ',TRIM(PNEW%LNAME) FPAR%SUCCESS = .FALSE. - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF END IF diff --git a/data_util/fll_funct_prt.f90 b/data_util/fll_funct_prt.f90 index 68be43e..dae1bfa 100644 --- a/data_util/fll_funct_prt.f90 +++ b/data_util/fll_funct_prt.f90 @@ -93,24 +93,24 @@ FUNCTION TEST_IOSTAT(IOSTAT, FPAR,ACTION) RESULT(OK) LOGICAL :: OK CHARACTER(*), OPTIONAL :: ACTION - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! OK = .FALSE. IF (IOSTAT > 0) THEN WRITE(FPAR%MESG,'(A)')' Read - error readig node data' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. ELSE IF (IOSTAT < 0) THEN WRITE(FPAR%MESG,'(A)')' Read - EOF reached' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. ELSE FPAR%SUCCESS = .TRUE. diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 index 433f1e9..67474b9 100644 --- a/data_util/fll_getnbytes.f90 +++ b/data_util/fll_getnbytes.f90 @@ -67,14 +67,14 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD,PNEXT - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF SUBROUTINE @@ -85,7 +85,7 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -102,7 +102,7 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) IF(.NOT.FPAR%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' GETNBYTES - error duplicting children nodes ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index a1d5850..ecd4474 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -71,14 +71,14 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! check for null nodes @@ -86,17 +86,17 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R0 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'R',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -147,31 +147,31 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_R1 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'R',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME R1=>NULL() - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -221,14 +221,14 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -238,13 +238,13 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'R',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'R',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_R2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) R2=>NULL() RETURN END IF @@ -297,30 +297,30 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D0 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'D',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -372,30 +372,30 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D1 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'D',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) R1=>NULL() RETURN END IF @@ -447,30 +447,30 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_D2 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'D',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'D',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_D2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) R2=>NULL() RETURN END IF @@ -523,30 +523,30 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I0 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'I',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -597,30 +597,30 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I1 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'I',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) I1=>NULL() RETURN END IF @@ -670,30 +670,30 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_I2 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'I',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'I',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_I2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) I2=>NULL() RETURN END IF @@ -745,24 +745,24 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L0 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'L',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. @@ -808,30 +808,30 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L1 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'L',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) I1=>NULL() RETURN END IF @@ -881,30 +881,30 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_L2 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'L',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'L',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) I2=>NULL() RETURN END IF @@ -954,30 +954,30 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S0 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'S',0_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -1026,30 +1026,30 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S1 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'S',1_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S1 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) STRING=>NULL() RETURN END IF @@ -1099,30 +1099,30 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) ! local declarations ! TYPE(DNODE), POINTER :: PFIND - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! SET LOCAL ACTION ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PNODE))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')'FLL_GETNDATA_S2 - Null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF - PFIND => FLL_LOCATE(PNODE,NAME,'S',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ACT) + PFIND => FLL_LOCATE(PNODE,NAME,'S',2_LINT,NUMBER,.FALSE.,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_S2 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) STRING=>NULL() RETURN END IF diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index b47888c..1f4461d 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -76,22 +76,22 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD INTEGER(LINT) :: LOCNUM,NDIM, NSIZE - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! -! define LOC_ACT +! define LOC_ERRMSG ! NULLIFY(PFIND) IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF TLTYPE = ADJUSTL(TRIM(LTYPE(1:))) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -173,7 +173,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO PFIND => NULL() FPAR%SUCCESS = .FALSE. ! WRITE(FPAR%MESG,'(A,A)')' Locate - node not found: ',TRIM(NAME) -! CALL FLL_OUT(LOC_ACT,FPAR) +! CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END FUNCTION FLL_LOCATE diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index d2ae65e..072ac07 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -69,14 +69,14 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) ! Local declarations ! INTEGER :: ISTAT - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF PNEW => NULL() @@ -85,19 +85,19 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) ! IF(LEN_TRIM(LTYPE)<1.OR.LEN_TRIM(LTYPE)>TYPE_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF IF(LEN_TRIM(NAME)>NAME_LENGTH) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong name: ',TRIM(NAME) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF IF(.NOT.ANY(LTYPE(1:1)==(/'C','S','I','L','R','D','N'/))) THEN WRITE(FPAR%MESG,'(A,A)')' Wrong type: ',TRIM(LTYPE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -125,7 +125,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) IF(NDIM < 1 .OR. NSIZE < 1)THEN WRITE(FPAR%MESG,'(A,A,I5,I5)')' Wrong dimensions for node ',TRIM(NAME), NDIM, NSIZE - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF ! diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 index f7ba4ed..ecee0ae 100644 --- a/data_util/fll_mkdir.f90 +++ b/data_util/fll_mkdir.f90 @@ -58,20 +58,20 @@ FUNCTION FLL_MKDIR(NAME,FPAR,ACTION) RESULT(PNEW) ! ! Local declarations ! - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF PNEW => NULL() ! ! Body ! - PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR,ACTION=LOC_ACT) + PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR,ACTION=LOC_ERRMSG) RETURN END FUNCTION FLL_MKDIR diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 73257b1..9f8f67b 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -65,19 +65,19 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) ! Local declarations ! TYPE(DNODE), POINTER :: PSOURCETMP - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF IF(.NOT.ASSOCIATED(PWHAT,PWHERE))THEN - PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR,LOC_ACT) + PSOURCETMP => FLL_MVCP(PWHAT,PWHERE,'M',FPAR,LOC_ERRMSG) OK = FPAR%SUCCESS END IF @@ -85,7 +85,7 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) RETURN END FUNCTION FLL_MV - FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) + FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ERRMSG) RESULT(PSOURCETMP) ! ! Description: Module moves or copies PWHAT pointer to PWHERE pointer ! depending on MODE values (C or M) @@ -106,7 +106,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR CHARACTER :: MODE ! 'C' - COPY, 'M' - MOVE - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! Declarations ! @@ -131,14 +131,14 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ACT) RESULT(PSOURCETMP) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhat null node' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF IF(.NOT.ASSOCIATED(PWHERE))THEN WRITE(FPAR%MESG,'(A,A)')' Mv - Pwhere null node' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 4781ca6..1443bd9 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -72,14 +72,14 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESU CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE TYPE(DNODE), POINTER :: PCURR, PCHLD, PFIND INTEGER(LINT) :: I,NDIM,NSIZE - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF FUNCTION @@ -95,7 +95,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESU IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Locate - Null node: ',TRIM(NAME) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -113,7 +113,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESU ! IF(RECURSE .AND. ASSOCIATED(PCURR%PCHILD))THEN PCHLD => PCURR%PCHILD - NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,DATADIM,RECURSE,FPAR,LOC_ACT) + NUMBER = NUMBER + FLL_NNODES(PCHLD,NAME,LTYPE,DATADIM,RECURSE,FPAR,LOC_ERRMSG) IF(ASSOCIATED(PFIND))THEN FPAR%SUCCESS = .TRUE. RETURN diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 2cedc4f..950943f 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -104,20 +104,20 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) INTEGER :: ISTAT INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -134,7 +134,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -159,7 +159,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -173,7 +173,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -183,7 +183,7 @@ END FUNCTION FLL_READ ! ! READS NODE ! - RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ACT) RESULT(PNODE) + RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ERRMSG) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -231,30 +231,30 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ACT) RESULT(PNODE) INTEGER(LINT) :: NDIM, NSIZE,NNODES LOGICAL :: OK INTEGER(LINT):: POSOLD - CHARACTER(LEN=*), OPTIONAL :: LOC_ACT + CHARACTER(LEN=*), OPTIONAL :: LOC_ERRMSG ! ! READ HEADER ! POSOLD = POS - CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ACT) + CALL READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ERRMSG) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read - error reading header ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN END IF IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H,LOC_ACT) + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H,LOC_ERRMSG) ELSE - PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ACT) + PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H,LOC_ERRMSG) END IF IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Read - error allocating node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -273,7 +273,7 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ACT) RESULT(PNODE) ! ! ATTACH TO PNODE ! - OK = FLL_MV(PNEW,PNODE,FPAR,LOC_ACT) + OK = FLL_MV(PNEW,PNODE,FPAR,LOC_ERRMSG) IF(.NOT.OK) STOP' ERROR MV' END DO @@ -283,15 +283,15 @@ RECURSIVE FUNCTION READ_NODE(IOUNIT,FMT,POS,SCAN,FPAR,LOC_ACT) RESULT(PNODE) ! SELECT CASE(FMT) CASE('A') - CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ACT) + CALL READ_DATA_ASCII(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ERRMSG) CASE('B') IF(SCAN /= 'Y')THEN - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ACT) + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ERRMSG) ELSE IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN - CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ACT) + CALL READ_DATA_BIN(IOUNIT,PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ERRMSG) ELSE - POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ACT) + POS = POS + GET_NEW_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ERRMSG) END IF END IF END SELECT @@ -304,7 +304,7 @@ END FUNCTION READ_NODE ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) + SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR,LOC_ERRMSG) ! ! Description: Reads header of each node ! @@ -346,7 +346,7 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) CHARACTER(*) :: LTYPE CHARACTER(*) :: NAME INTEGER(LINT) :: NDIM, NSIZE - CHARACTER(LEN=*) :: LOC_ACT + CHARACTER(LEN=*) :: LOC_ERRMSG ! ! Local declarations ! @@ -443,12 +443,12 @@ SUBROUTINE READ_HEADER(IOUNIT,FMT,POS,NAME,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) END SELECT WRITE(FPAR%MESG,'(A)')' Read - reading header error ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN WRITE(FPAR%MESG,'(A)')' Read - reading header error, reached end of file ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN @@ -456,7 +456,7 @@ END SUBROUTINE READ_HEADER ! ! READ DATA ! - SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) + SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ERRMSG) ! ! Description: Reads data contatined in node Pnode - ASCII file ! @@ -493,7 +493,7 @@ SUBROUTINE READ_DATA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ACT) INTEGER(LINT) :: NDIM,NSIZE CHARACTER(LEN=TYPE_LENGTH) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(LEN=*), OPTIONAL :: LOC_ACT + CHARACTER(LEN=*), OPTIONAL :: LOC_ERRMSG ! ! Local declarations ! @@ -601,7 +601,7 @@ END SUBROUTINE READ_DATA_ASCII ! ! READ DATA ! - SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR,LOC_ACT) + SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR,LOC_ERRMSG) ! ! Description: Function reads data contained in Pnode, bindary file ! @@ -638,7 +638,7 @@ SUBROUTINE READ_DATA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR,LOC_ACT) INTEGER(LINT) :: NDIM,NSIZE,POS CHARACTER(*) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(LEN=*), OPTIONAL :: LOC_ACT + CHARACTER(LEN=*), OPTIONAL :: LOC_ERRMSG ! ! Local declarations ! @@ -780,7 +780,7 @@ END SUBROUTINE READ_DATA_BIN - FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR,LOC_ACT) RESULT (POS) + FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR,LOC_ERRMSG) RESULT (POS) ! ! Description: Function gets new position for reading bindary file without allocating arrays ! used for scanning files @@ -817,7 +817,7 @@ FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR,LOC_ACT) RESULT (POS) TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: NDIM, NSIZE, POS CHARACTER(LEN=*) :: LTYPE - CHARACTER(LEN=*), OPTIONAL :: LOC_ACT + CHARACTER(LEN=*), OPTIONAL :: LOC_ERRMSG ! ! Local declaration ! @@ -844,7 +844,7 @@ FUNCTION GET_NEW_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR,LOC_ACT) RESULT (POS) CASE DEFAULT WRITE(*,*)' WRONG TYPE' WRITE(FPAR%MESG,'(A,A)')' GET_NEW_POS - wrong type ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. END SELECT diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index cf450b4..cef4916 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -120,14 +120,14 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INTEGER :: ISTAT,PLISTOK INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF PLISTOK = 0 @@ -140,7 +140,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -148,15 +148,15 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! USE ONLY BINARY FORMAT ! - PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y',ACTION=LOC_ACT) - CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR,ACTION=LOC_ACT) + PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y',ACTION=LOC_ERRMSG) + CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR,ACTION=LOC_ERRMSG) ! END IF - PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR,ACTION=LOC_ACT) + PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR,ACTION=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PTMP))THEN - CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ACT) + CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ERRMSG) PNODE => NULL() RETURN END IF @@ -169,7 +169,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! LIST WAS CREATED IN THIS FUNCTION, REMOVE IT ! - CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ACT) + CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ERRMSG) END IF ! ! OPEN FILE @@ -177,7 +177,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -195,7 +195,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read_record - error opening file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -206,7 +206,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA PLIST => READ_NODE(IOUNIT,FMT_LOC,POS,SCAN_LOC,FPAR) IF(.NOT.ASSOCIATED(PLIST)) THEN WRITE(FPAR%MESG,'(A,A)')' Read_record - error reading specified data set ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -222,7 +222,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. END IF diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index 76b00b8..0d67d8d 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -101,20 +101,20 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) LOGICAL :: OK CHARACTER :: FMT_LOC INTEGER :: ISTAT - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -131,7 +131,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read - unknown format',TRIM(FMT) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -150,7 +150,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read - error opening file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -160,9 +160,9 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) ! SELECT CASE(ITYPE) CASE('I','i') - PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR,LOC_ACT) + PNODE => READ_NODE_UCD(IOUNIT,FMT_LOC,FPAR,LOC_ERRMSG) CASE('L','l') - PNODE => READ_NODE_UCD_L(IOUNIT,FMT_LOC,FPAR,LOC_ACT) + PNODE => READ_NODE_UCD_L(IOUNIT,FMT_LOC,FPAR,LOC_ERRMSG) CASE DEFAULT STOP'WRONG DATA FORMAT FOR UCD DATA SET' END SELECT @@ -170,7 +170,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -181,7 +181,7 @@ END FUNCTION FLL_READ_UCD - FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) + FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ERRMSG) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -217,7 +217,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -243,14 +243,14 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! allocate memory for coordinates ! - PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ACT) - PREG => FLL_MKDIR('region', FPAR,LOC_ACT) - OK = FLL_MV(PREG,PNODE,FPAR,LOC_ACT) - PBND => FLL_MKDIR('boundary', FPAR,LOC_ACT) - OK = FLL_MV(PBND,PREG,FPAR,LOC_ACT) + PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ERRMSG) + PREG => FLL_MKDIR('region', FPAR,LOC_ERRMSG) + OK = FLL_MV(PREG,PNODE,FPAR,LOC_ERRMSG) + PBND => FLL_MKDIR('boundary', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBND,PREG,FPAR,LOC_ERRMSG) - PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PREG,FPAR,LOC_ACT) + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PREG,FPAR,LOC_ERRMSG) COO => PTMP%D2 DO I=1,NPTS @@ -259,7 +259,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! add boundary name ! - PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) PTMP%S0 = 'wall' ! ! read elements @@ -289,26 +289,26 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! IF(N3> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) - OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ERRMSG) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) PTMP%S0 = 'tria3' - PTMP => FLL_MK('bound_elem_nodes','I',N3,3_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_nodes','I',N3,3_LINT,FPAR,LOC_ERRMSG) PTMP%I2 = I3(1:N3,:) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) END IF IF(N4> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) - OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ERRMSG) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) PTMP%S0 = 'quad4' - PTMP => FLL_MK('bound_elem_nodes','I',N4,4_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_nodes','I',N4,4_LINT,FPAR,LOC_ERRMSG) PTMP%I2 = I4(1:N4,:) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) END IF @@ -319,7 +319,7 @@ FUNCTION READ_NODE_UCD(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) END FUNCTION READ_NODE_UCD - FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) + FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ERRMSG) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -367,7 +367,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) INTEGER :: ISTAT LOGICAL :: OK CHARACTER(LEN = 200)TEXTLONG - CHARACTER(LEN=*) :: LOC_ACT + CHARACTER(LEN=*) :: LOC_ERRMSG ! ! disregard all lines starting with # - 3 lines ! @@ -381,14 +381,14 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! allocate memory for coordinates ! - PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ACT) - PREG => FLL_MKDIR('region', FPAR,LOC_ACT) - OK = FLL_MV(PREG,PNODE,FPAR,LOC_ACT) - PBND => FLL_MKDIR('boundary', FPAR,LOC_ACT) - OK = FLL_MV(PBND,PREG,FPAR,LOC_ACT) + PNODE => FLL_MKDIR('unstr_grid_data', FPAR,LOC_ERRMSG) + PREG => FLL_MKDIR('region', FPAR,LOC_ERRMSG) + OK = FLL_MV(PREG,PNODE,FPAR,LOC_ERRMSG) + PBND => FLL_MKDIR('boundary', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBND,PREG,FPAR,LOC_ERRMSG) - PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PREG,FPAR,LOC_ACT) + PTMP => FLL_MK('coordinates','D',NPTS,3_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PREG,FPAR,LOC_ERRMSG) COO => PTMP%D2 DO I=1,NPTS @@ -397,7 +397,7 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! ! add boundary name ! - PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('boundary_name','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) PTMP%S0 = 'wall' ! ! read elements @@ -427,26 +427,26 @@ FUNCTION READ_NODE_UCD_L(IOUNIT,FMT,FPAR,LOC_ACT) RESULT(PNODE) ! IF(N3> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) - OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ERRMSG) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) PTMP%S0 = 'tria3' - PTMP => FLL_MK('bound_elem_nodes','L',N3,3_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_nodes','L',N3,3_LINT,FPAR,LOC_ERRMSG) PTMP%L2 = I3(1:N3,:) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) END IF IF(N4> 0)THEN - PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ACT) - OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ACT) - PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ACT) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + PBELEM => FLL_MKDIR('belem_group', FPAR,LOC_ERRMSG) + OK = FLL_MV(PBELEM,PBND,FPAR,LOC_ERRMSG) + PTMP => FLL_MK('bound_elem_type','S',1_LINT,1_LINT,FPAR,LOC_ERRMSG) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) PTMP%S0 = 'quad4' - PTMP => FLL_MK('bound_elem_nodes','L',N4,4_LINT,FPAR,LOC_ACT) + PTMP => FLL_MK('bound_elem_nodes','L',N4,4_LINT,FPAR,LOC_ERRMSG) PTMP%L2 = I4(1:N4,:) - OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ACT) + OK = FLL_MV(PTMP,PBELEM,FPAR,LOC_ERRMSG) END IF diff --git a/data_util/fll_rename.f90 b/data_util/fll_rename.f90 index 8e4aa3b..de45fab 100644 --- a/data_util/fll_rename.f90 +++ b/data_util/fll_rename.f90 @@ -60,14 +60,14 @@ FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ACTION) RESULT(OK) CHARACTER(LEN=*) :: INAME LOGICAL :: OK CHARACTER(*), OPTIONAL :: ACTION - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! check that PWHAT is not NULL @@ -75,7 +75,7 @@ FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ACTION) RESULT(OK) IF(.NOT.ASSOCIATED(PWHAT))THEN WRITE(*,*)' Rename - SOURCE IS NULL NODE' WRITE(FPAR%MESG,'(A,A)')' Rename - Pwhat null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index a338f94..306cb60 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -65,14 +65,14 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! Local declarations ! INTEGER :: ISTAT - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF SUBROUTINE @@ -80,7 +80,7 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' RM - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -89,13 +89,13 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! ! STICH AND SUBSTRACT FROM PARENT ! - CALL FLL_STICH(PNODE,FPAR,LOC_ACT) + CALL FLL_STICH(PNODE,FPAR,LOC_ERRMSG) ! ! IF NODE HAS CHILDREN, REMOVE ALL OF THEM ! - IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR,LOC_ACT) + IF(ASSOCIATED(PCHILD))CALL FLL_RM_RECURSIVE_NODE(PCHILD,FPAR,LOC_ERRMSG) - CALL FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) + CALL FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ERRMSG) ! ! NULLIFY NODE ! @@ -110,7 +110,7 @@ END SUBROUTINE FLL_RM ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) + RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ERRMSG) ! ! Description: recursive function removes PNODE ! @@ -138,7 +138,7 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -154,12 +154,12 @@ RECURSIVE SUBROUTINE FLL_RM_RECURSIVE_NODE(PNODE,FPAR,LOC_ACT) DO WHILE(ASSOCIATED(PCURR)) PNEXT => PCURR%PNEXT IF(ASSOCIATED(PCURR%PCHILD))THEN - CALL FLL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR,LOC_ACT) + CALL FLL_RM_RECURSIVE_NODE(PCURR%PCHILD,FPAR,LOC_ERRMSG) END IF IF(TRIM(PCURR%LTYPE) /= 'LINK')THEN - CALL FLL_DEALLOC_DATA(PCURR,FPAR,LOC_ACT) + CALL FLL_DEALLOC_DATA(PCURR,FPAR,LOC_ERRMSG) IF(ASSOCIATED(PCURR%PLINK))THEN PNODE%PLINK%PCHILD => NULL(); @@ -192,7 +192,7 @@ END SUBROUTINE FLL_RM_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) + SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ERRMSG) ! ! Description: function deallocates data from associated with PNODE ! @@ -219,7 +219,7 @@ SUBROUTINE FLL_DEALLOC_DATA(PNODE,FPAR,LOC_ACT) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*) :: LOC_ACT + CHARACTER(*) :: LOC_ERRMSG ! ! local declarations ! diff --git a/data_util/fll_scan_file.f90 b/data_util/fll_scan_file.f90 index 5af2fc7..742ef47 100644 --- a/data_util/fll_scan_file.f90 +++ b/data_util/fll_scan_file.f90 @@ -68,20 +68,20 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) ! Local types ! LOGICAL :: OK - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF INQUIRE (FILE=TRIM(FILENAME), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read - file does not exist ',TRIM(FILENAME) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -89,7 +89,7 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) ! ! GET FILE STRUCTURE ! - PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y', ACTION=LOC_ACT) + PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y', ACTION=LOC_ERRMSG) RETURN diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index e08ea2d..42a8474 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -61,21 +61,21 @@ SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) ! Local declarations ! TYPE(DNODE), POINTER :: PNEXT=>NULL(), PPREV=>NULL(),PPAR=>NULL() - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF SUBROUTINE ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Stich - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -88,7 +88,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) IF(.NOT.ASSOCIATED(PNODE%PPAR))THEN WRITE(FPAR%MESG,'(A,A)')' Stich - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 77f9e6e..0e0d91f 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -78,14 +78,14 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) CHARACTER(LEN=TYPE_LENGTH) :: TLTYPE INTEGER(LINT) :: I TYPE(DNODE), POINTER :: PNEXT - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! BODY OF FUNCTION @@ -101,7 +101,7 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')'Sweep - Null node: ',TRIM(NAME) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index cd24541..7cf21d0 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -74,14 +74,14 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS - CHARACTER(LEN=10) :: LOC_ACT + CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! IF(.NOT.PRESENT(ACTION))THEN - LOC_ACT='ALL' + LOC_ERRMSG='ALL' ELSE - LOC_ACT = ACTION + LOC_ERRMSG = ACTION END IF ! ! DETERMINE RORMAT' @@ -95,7 +95,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Write unknown format',TRIM(FMT) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. @@ -115,7 +115,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -123,12 +123,12 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) ! ! WRITE LINKED LIST ! - CALL FLL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR,LOC_ACT) + CALL FLL_WRITE_LIST(PNODE,IOUNIT,FMT_LOC,FPAR,LOC_ERRMSG) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -141,7 +141,7 @@ END FUNCTION FLL_WRITE - SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ACT) + SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ERRMSG) ! ! Description: Function writes a list ! @@ -175,7 +175,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ACT) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT - CHARACTER(LEN=*) :: LOC_ACT + CHARACTER(LEN=*) :: LOC_ERRMSG ! ! Local declarations ! @@ -187,7 +187,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ACT) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Write - null node ' - CALL FLL_OUT(LOC_ACT,FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -202,7 +202,7 @@ SUBROUTINE FLL_WRITE_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ACT) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ACT) + IF(ASSOCIATED(PCHILD))CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ERRMSG) FPAR%SUCCESS = .TRUE. @@ -211,7 +211,7 @@ END SUBROUTINE FLL_WRITE_LIST ! ! DELETE CHID WITH ALL ITS CHILDREN ! - RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR,LOC_ACT) + RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR,LOC_ERRMSG) ! ! Description: Function writes a node ! @@ -244,7 +244,7 @@ RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR,LOC_ACT) TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS CHARACTER :: FMT - CHARACTER(LEN=*) :: LOC_ACT + CHARACTER(LEN=*) :: LOC_ERRMSG ! ! Local declarations ! @@ -267,7 +267,7 @@ RECURSIVE SUBROUTINE FLL_WRITE_RECURSIVE_NODE(PNODE,IOUNIT,POS,FMT,FPAR,LOC_ACT) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ACT) + CALL FLL_WRITE_RECURSIVE_NODE(PCHILD,IOUNIT,POS,FMT,FPAR,LOC_ERRMSG) END IF PCURR => PNEXT From 0a4c9b1425b377596fd2500202996b82f2e5c71c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 14 Nov 2017 07:30:36 -0700 Subject: [PATCH 303/325] change ACTION to ERRMSG --- data_util/fll_cat.f90 | 8 +- data_util/fll_cp.f90 | 8 +- data_util/fll_deattach.f90 | 8 +- data_util/fll_duplicate.f90 | 14 ++-- data_util/fll_funct_prt.f90 | 8 +- data_util/fll_getnbytes.f90 | 8 +- data_util/fll_getndata.f90 | 150 +++++++++++++++++----------------- data_util/fll_locate.f90 | 10 +-- data_util/fll_mk.f90 | 8 +- data_util/fll_mkdir.f90 | 10 +-- data_util/fll_mv.f90 | 8 +- data_util/fll_nnodes.f90 | 8 +- data_util/fll_out.f90 | 12 +-- data_util/fll_read.f90 | 8 +- data_util/fll_read_record.f90 | 18 ++-- data_util/fll_read_ucd.f90 | 8 +- data_util/fll_rename.f90 | 8 +- data_util/fll_rm.f90 | 8 +- data_util/fll_scan_file.f90 | 10 +-- data_util/fll_stich.f90 | 8 +- data_util/fll_sweep.f90 | 8 +- data_util/fll_write.f90 | 8 +- 22 files changed, 172 insertions(+), 172 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 37a2302..c4370a1 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -34,7 +34,7 @@ MODULE FLL_CAT_M ! CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -61,7 +61,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) INTEGER :: IOUNIT LOGICAL :: PARENT CHARACTER, OPTIONAL :: SCAN,SDIR - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local types ! @@ -73,10 +73,10 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ACTION) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! body of subroutine diff --git a/data_util/fll_cp.f90 b/data_util/fll_cp.f90 index b89bf84..e1e9c3a 100644 --- a/data_util/fll_cp.f90 +++ b/data_util/fll_cp.f90 @@ -34,7 +34,7 @@ MODULE FLL_CP_M ! CONTAINS - FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) + FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: Module copies PWHAT pointer to PWHERE pointer ! If PWHERE pointer == NULL, PWHAT is a duplicate @@ -69,16 +69,16 @@ FUNCTION FLL_CP(PWHAT,PWHERE,FPAR,ACTION) RESULT(PNEW) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! initialize PNEW pointer and check that PWHAT is not NULL diff --git a/data_util/fll_deattach.f90 b/data_util/fll_deattach.f90 index 25716aa..f5d24af 100644 --- a/data_util/fll_deattach.f90 +++ b/data_util/fll_deattach.f90 @@ -34,7 +34,7 @@ MODULE FLL_DEATTACH_M ! External Modules used CONTAINS - FUNCTION FLL_DEATTACH(PWHAT,FPAR,ACTION) RESULT(OK) + FUNCTION FLL_DEATTACH(PWHAT,FPAR,ERRMSG) RESULT(OK) ! ! Description: Deattach PWHAT node from the list ! upon return, PWHAT parent is set to NULL and @@ -67,15 +67,15 @@ FUNCTION FLL_DEATTACH(PWHAT,FPAR,ACTION) RESULT(OK) TYPE(DNODE), POINTER :: PWHAT TYPE(FUNC_DATA_SET) :: FPAR LOGICAL:: OK - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! check that PWAT is not null node diff --git a/data_util/fll_duplicate.f90 b/data_util/fll_duplicate.f90 index 9507dbc..9db0e52 100644 --- a/data_util/fll_duplicate.f90 +++ b/data_util/fll_duplicate.f90 @@ -33,7 +33,7 @@ MODULE FLL_DUPLICATE_M ! External Modules used ! CONTAINS - FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) + FUNCTION FLL_DUPLICATE(PNODE,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: Contains duplicates node to PNEW mode ! the parent, previous and next pointers of PNEW node are NULL @@ -66,7 +66,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -75,10 +75,10 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF SUBROUTINE @@ -121,7 +121,7 @@ FUNCTION FLL_DUPLICATE(PNODE,FPAR,ACTION) RESULT(PNEW) ! ! NODE IS A FILE NODE ! - PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR,ACTION=LOC_ERRMSG) + PNEW => FLL_MK(PNODE%LNAME,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR,ERRMSG=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' CALL FLL_OUT(LOC_ERRMSG,FPAR) @@ -181,7 +181,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ERRMSG) PNEXT => PCURR%PNEXT PCHILD=> PCURR%PCHILD - PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR,ACTION=LOC_ERRMSG) + PNEW => FLL_MK(PCURR%LNAME,PCURR%LTYPE,PCURR%NDIM,PCURR%NSIZE,FPAR,ERRMSG=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - error allocating PNEW ' CALL FLL_OUT(LOC_ERRMSG,FPAR) @@ -203,7 +203,7 @@ RECURSIVE SUBROUTINE FLL_DUPLICATE_RECURSIVE_NODE(PNODE,PDUPL,FPAR,LOC_ERRMSG) ! ! ADD TO PDUPL LIST ! - OK = FLL_MV(PNEW,PDUPL,FPAR,ACTION=LOC_ERRMSG) + OK = FLL_MV(PNEW,PDUPL,FPAR,ERRMSG=LOC_ERRMSG) PCURR => PNEXT diff --git a/data_util/fll_funct_prt.f90 b/data_util/fll_funct_prt.f90 index dae1bfa..07471d8 100644 --- a/data_util/fll_funct_prt.f90 +++ b/data_util/fll_funct_prt.f90 @@ -71,7 +71,7 @@ FUNCTION ERR_MSG(NAME,NTYPE) RESULT(MESG) RETURN END FUNCTION ERR_MSG - FUNCTION TEST_IOSTAT(IOSTAT, FPAR,ACTION) RESULT(OK) + FUNCTION TEST_IOSTAT(IOSTAT, FPAR,ERRMSG) RESULT(OK) ! ! Description: tests IOSTAT return parameter from R/W functions ! @@ -91,16 +91,16 @@ FUNCTION TEST_IOSTAT(IOSTAT, FPAR,ACTION) RESULT(OK) INTEGER :: IOSTAT TYPE(FUNC_DATA_SET) :: FPAR LOGICAL :: OK - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! OK = .FALSE. diff --git a/data_util/fll_getnbytes.f90 b/data_util/fll_getnbytes.f90 index 67474b9..1221baa 100644 --- a/data_util/fll_getnbytes.f90 +++ b/data_util/fll_getnbytes.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNBYTES_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) + RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ERRMSG) RESULT(BYTES) ! ! Description: Get size of linked list in bytes ! @@ -62,7 +62,7 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: BYTES - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -71,10 +71,10 @@ RECURSIVE FUNCTION FLL_GETNBYTES(PNODE,FPAR, ACTION) RESULT(BYTES) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF SUBROUTINE diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index ecd4474..484eccc 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -31,7 +31,7 @@ MODULE FLL_GETNDATA_M ! External Modules used ! CONTAINS - FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) + FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -66,19 +66,19 @@ FUNCTION FLL_GETNDATA_R0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE) :: R0 - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! check for null nodes @@ -107,7 +107,7 @@ END FUNCTION FLL_GETNDATA_R0 - FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) + FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -142,19 +142,19 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R1(:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -180,7 +180,7 @@ FUNCTION FLL_GETNDATA_R1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) END FUNCTION FLL_GETNDATA_R1 - FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) + FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -216,19 +216,19 @@ FUNCTION FLL_GETNDATA_R2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RSINGLE), POINTER :: R2(:,:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -256,7 +256,7 @@ END FUNCTION FLL_GETNDATA_R2 ! ! DOUBLE ! - FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) + FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R0) ! ! Description: returns single real data of the node ! @@ -292,19 +292,19 @@ FUNCTION FLL_GETNDATA_D0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE) :: R0 - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -331,7 +331,7 @@ END FUNCTION FLL_GETNDATA_D0 - FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) + FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R1) ! ! Description: returns single real data of the node ! @@ -367,19 +367,19 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R1(:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -406,7 +406,7 @@ FUNCTION FLL_GETNDATA_D1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R1) END FUNCTION FLL_GETNDATA_D1 - FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) + FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(R2) ! ! Description: returns single real data of the node ! @@ -442,19 +442,19 @@ FUNCTION FLL_GETNDATA_D2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(R2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER REAL(RDOUBLE), POINTER :: R2(:,:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -482,7 +482,7 @@ END FUNCTION FLL_GETNDATA_D2 ! ! INTEGER ! - FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) + FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -518,19 +518,19 @@ FUNCTION FLL_GETNDATA_I0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT) :: I0 - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -557,7 +557,7 @@ END FUNCTION FLL_GETNDATA_I0 - FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) + FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I1) ! ! Description: returns single real data of the node ! @@ -592,19 +592,19 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I1(:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -630,7 +630,7 @@ FUNCTION FLL_GETNDATA_I1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) END FUNCTION FLL_GETNDATA_I1 - FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) + FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -665,19 +665,19 @@ FUNCTION FLL_GETNDATA_I2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(SINT), POINTER :: I2(:,:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -705,7 +705,7 @@ END FUNCTION FLL_GETNDATA_I2 ! ! LONG INTEGER ! - FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) + FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I0) ! ! Description: returns single real data of the node ! @@ -740,19 +740,19 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I0) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT) :: I0 - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -779,7 +779,7 @@ END FUNCTION FLL_GETNDATA_L0 - FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) + FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I1) USE FLL_TYPE_M USE FLL_LOCATE_M @@ -803,19 +803,19 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I1(:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -841,7 +841,7 @@ FUNCTION FLL_GETNDATA_L1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I1) END FUNCTION FLL_GETNDATA_L1 - FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) + FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I2) ! ! Description: returns single real data of the node ! @@ -876,19 +876,19 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER INTEGER(LINT), POINTER :: I2(:,:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -914,7 +914,7 @@ FUNCTION FLL_GETNDATA_L2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(I2) END FUNCTION FLL_GETNDATA_L2 - FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) + FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -949,19 +949,19 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH) :: STRING - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -986,7 +986,7 @@ FUNCTION FLL_GETNDATA_S0(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) END FUNCTION FLL_GETNDATA_S0 -FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) +FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -1021,19 +1021,19 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN @@ -1059,7 +1059,7 @@ FUNCTION FLL_GETNDATA_S1(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) END FUNCTION FLL_GETNDATA_S1 - FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) + FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(STRING) ! ! Description: returns single real data of the node ! @@ -1094,19 +1094,19 @@ FUNCTION FLL_GETNDATA_S2(PNODE,NAME,NUMBER,FPAR,ACTION) RESULT(STRING) CHARACTER(*) :: NAME INTEGER(LINT) :: NUMBER CHARACTER(LEN=LSTRING_LENGTH), POINTER :: STRING(:,:) - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! TYPE(DNODE), POINTER :: PFIND CHARACTER(LEN=10) :: LOC_ERRMSG ! -! SET LOCAL ACTION +! SET LOCAL ERRMSG ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PNODE))THEN diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 1f4461d..3fd750b 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -32,7 +32,7 @@ MODULE FLL_LOCATE_M ! CONTAINS - RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTION) RESULT(PFIND) + RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ERRMSG) RESULT(PFIND) ! ! Description: function finds node identified by name, type, position in list, dimensions of data it contains ! search can be done recursively @@ -59,7 +59,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO ! RECURSE In search recursively ! PFIND Out return pointer to located node ! FPAR In/Out structure containing function specific data -! ACTION In/Out where to print err messages +! ERRMSG In/Out where to print err messages ! ! Arguments declaration ! @@ -69,7 +69,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -81,10 +81,10 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTIO ! define LOC_ERRMSG ! NULLIFY(PFIND) - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF TLTYPE = ADJUSTL(TRIM(LTYPE(1:))) diff --git a/data_util/fll_mk.f90 b/data_util/fll_mk.f90 index 072ac07..0fff416 100644 --- a/data_util/fll_mk.f90 +++ b/data_util/fll_mk.f90 @@ -36,7 +36,7 @@ MODULE FLL_MK_M ! External Modules used ! CONTAINS - FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) + FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: function creates node specified by name, type and dimensions ! @@ -64,7 +64,7 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) CHARACTER(*) :: NAME CHARACTER(*) :: LTYPE INTEGER(LINT) :: NDIM, NSIZE - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -73,10 +73,10 @@ FUNCTION FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR,ACTION) RESULT(PNEW) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF PNEW => NULL() diff --git a/data_util/fll_mkdir.f90 b/data_util/fll_mkdir.f90 index ecee0ae..b1cacb4 100644 --- a/data_util/fll_mkdir.f90 +++ b/data_util/fll_mkdir.f90 @@ -31,7 +31,7 @@ MODULE FLL_MKDIR_M ! External Modules used ! CONTAINS - FUNCTION FLL_MKDIR(NAME,FPAR,ACTION) RESULT(PNEW) + FUNCTION FLL_MKDIR(NAME,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: function creates node specified by name, type and dimensions ! @@ -54,7 +54,7 @@ FUNCTION FLL_MKDIR(NAME,FPAR,ACTION) RESULT(PNEW) TYPE(FUNC_DATA_SET) :: FPAR TYPE(DNODE), POINTER :: PNEW CHARACTER(LEN=*) :: NAME - CHARACTER(LEN=*), OPTIONAL :: ACTION + CHARACTER(LEN=*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -62,16 +62,16 @@ FUNCTION FLL_MKDIR(NAME,FPAR,ACTION) RESULT(PNEW) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF PNEW => NULL() ! ! Body ! - PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR,ACTION=LOC_ERRMSG) + PNEW => FLL_MK(NAME,'DIR',0_LINT, 0_LINT, FPAR,ERRMSG=LOC_ERRMSG) RETURN END FUNCTION FLL_MKDIR diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 9f8f67b..708057c 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -30,7 +30,7 @@ MODULE FLL_MV_M ! External Modules used ! CONTAINS - FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) + FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ERRMSG) RESULT(OK) ! ! Description: Module moves PWHAT pointer to PWHERE pointer ! @@ -60,7 +60,7 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) TYPE(DNODE), POINTER :: PWHAT,PWHERE TYPE(FUNC_DATA_SET) :: FPAR LOGICAL OK - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -69,10 +69,10 @@ FUNCTION FLL_MV(PWHAT,PWHERE,FPAR,ACTION) RESULT(OK) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF IF(.NOT.ASSOCIATED(PWHAT,PWHERE))THEN diff --git a/data_util/fll_nnodes.f90 b/data_util/fll_nnodes.f90 index 1443bd9..e561541 100644 --- a/data_util/fll_nnodes.f90 +++ b/data_util/fll_nnodes.f90 @@ -31,7 +31,7 @@ MODULE FLL_NNODES_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESULT(NUMBER) + RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ERRMSG) RESULT(NUMBER) ! ! Description: function returns number of nodes specified by ! name, type and dimensions of data @@ -65,7 +65,7 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESU CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! @@ -76,10 +76,10 @@ RECURSIVE FUNCTION FLL_NNODES(PNODE,NAME,LTYPE,DATADIM,RECURSE,FPAR,ACTION) RESU ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF FUNCTION diff --git a/data_util/fll_out.f90 b/data_util/fll_out.f90 index 1283e4c..a91130d 100644 --- a/data_util/fll_out.f90 +++ b/data_util/fll_out.f90 @@ -35,7 +35,7 @@ MODULE FLL_OUT_M ! CONTAINS - SUBROUTINE FLL_OUT(ACTION,FPAR) + SUBROUTINE FLL_OUT(ERRMSG,FPAR) ! ! Description: Contains subroutine pritning errmessage from FPAR structure ! @@ -55,7 +55,7 @@ SUBROUTINE FLL_OUT(ACTION,FPAR) ! ! Arguments description ! Name In/Out Function -! ACTION In determines what to do +! ERRMSG In determines what to do ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -64,7 +64,7 @@ SUBROUTINE FLL_OUT(ACTION,FPAR) ! ! ARGUMENTS: ! - CHARACTER(*) :: ACTION + CHARACTER(*) :: ERRMSG TYPE(FUNC_DATA_SET) :: FPAR CHARACTER(LEN=72) :: STRMES ='LOGFILE' ! @@ -73,7 +73,7 @@ SUBROUTINE FLL_OUT(ACTION,FPAR) ! ! Select here to print ! - SELECT CASE(ACTION) + SELECT CASE(ERRMSG) CASE('NONE') RETURN @@ -110,11 +110,11 @@ SUBROUTINE FLL_OUT(ACTION,FPAR) CASE DEFAULT WRITE(STDOUT,*)& - 'Error: wrong action in fll_out, action: "'//ACTION//'" not defined.' + 'Error: wrong action in fll_out, action: "'//ERRMSG//'" not defined.' WRITE(STDOUT,*)FPAR%MESG FLUSH(STDOUT) WRITE(IOLOGFILE,*)& - 'Error: wrong action in fll_out, action: "'//ACTION//'" not defined.' + 'Error: wrong action in fll_out, action: "'//ERRMSG//'" not defined.' WRITE(IOLOGFILE,*)FPAR%MESG FLUSH(IOLOGFILE) diff --git a/data_util/fll_read.f90 b/data_util/fll_read.f90 index 950943f..2acb1e3 100644 --- a/data_util/fll_read.f90 +++ b/data_util/fll_read.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_M ! CONTAINS - FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) + FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ERRMSG) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -95,7 +95,7 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER :: FMT CHARACTER, OPTIONAL :: SCAN - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -108,10 +108,10 @@ FUNCTION FLL_READ(FILE,IOUNIT,FMT,FPAR,SCAN, ACTION) RESULT(PNODE) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) diff --git a/data_util/fll_read_record.f90 b/data_util/fll_read_record.f90 index cef4916..0a89329 100644 --- a/data_util/fll_read_record.f90 +++ b/data_util/fll_read_record.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_RECORD_M ! CONTAINS - FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ACTION) RESULT(PNODE) + FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ERRMSG) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -110,7 +110,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA CHARACTER(*) :: LTYPE INTEGER(LINT) :: NUMBER,DATADIM LOGICAL :: RECURSE - CHARACTER(LEN=*), OPTIONAL :: ACTION + CHARACTER(LEN=*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -124,10 +124,10 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF PLISTOK = 0 @@ -148,15 +148,15 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! USE ONLY BINARY FORMAT ! - PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y',ACTION=LOC_ERRMSG) - CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR,ACTION=LOC_ERRMSG) + PLIST => FLL_READ(FILE,IOUNIT,'B',FPAR,SCAN = 'Y',ERRMSG=LOC_ERRMSG) + CALL FLL_CAT(PLIST, 6, .TRUE.,FPAR,ERRMSG=LOC_ERRMSG) ! END IF - PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR,ACTION=LOC_ERRMSG) + PTMP => FLL_LOCATE(PLIST,NAME,LTYPE,DATADIM,NUMBER,.TRUE.,FPAR,ERRMSG=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PTMP))THEN - CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ERRMSG) + CALL FLL_RM(PLIST, FPAR,ERRMSG=LOC_ERRMSG) PNODE => NULL() RETURN END IF @@ -169,7 +169,7 @@ FUNCTION FLL_READ_RECORD(FILE,IOUNIT,PLIST,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPA ! ! LIST WAS CREATED IN THIS FUNCTION, REMOVE IT ! - CALL FLL_RM(PLIST, FPAR,ACTION=LOC_ERRMSG) + CALL FLL_RM(PLIST, FPAR,ERRMSG=LOC_ERRMSG) END IF ! ! OPEN FILE diff --git a/data_util/fll_read_ucd.f90 b/data_util/fll_read_ucd.f90 index 0d67d8d..4a4968b 100644 --- a/data_util/fll_read_ucd.f90 +++ b/data_util/fll_read_ucd.f90 @@ -58,7 +58,7 @@ MODULE FLL_READ_UCD_M ! CONTAINS - FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) + FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ERRMSG) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -94,7 +94,7 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT,ITYPE - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -105,10 +105,10 @@ FUNCTION FLL_READ_UCD(FILE,IOUNIT,FMT,ITYPE,FPAR, ACTION) RESULT(PNODE) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) diff --git a/data_util/fll_rename.f90 b/data_util/fll_rename.f90 index de45fab..41a7e30 100644 --- a/data_util/fll_rename.f90 +++ b/data_util/fll_rename.f90 @@ -34,7 +34,7 @@ MODULE FLL_RENAME_M ! CONTAINS - FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ACTION) RESULT(OK) + FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ERRMSG) RESULT(OK) ! ! Description: Renames node ! @@ -59,15 +59,15 @@ FUNCTION FLL_RENAME(PWHAT,INAME,FPAR,ACTION) RESULT(OK) TYPE(FUNC_DATA_SET) :: FPAR CHARACTER(LEN=*) :: INAME LOGICAL :: OK - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG CHARACTER(LEN=10) :: LOC_ERRMSG ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! check that PWHAT is not NULL diff --git a/data_util/fll_rm.f90 b/data_util/fll_rm.f90 index 306cb60..6d4971f 100644 --- a/data_util/fll_rm.f90 +++ b/data_util/fll_rm.f90 @@ -30,7 +30,7 @@ MODULE FLL_RM_M ! External Modules used ! CONTAINS - SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) + SUBROUTINE FLL_RM(PNODE,FPAR,ERRMSG) ! ! Description: function removes PNODE ! @@ -60,7 +60,7 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! TYPE(DNODE), POINTER :: PNODE,PCHILD TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -69,10 +69,10 @@ SUBROUTINE FLL_RM(PNODE,FPAR,ACTION) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF SUBROUTINE diff --git a/data_util/fll_scan_file.f90 b/data_util/fll_scan_file.f90 index 742ef47..6ddd815 100644 --- a/data_util/fll_scan_file.f90 +++ b/data_util/fll_scan_file.f90 @@ -34,7 +34,7 @@ MODULE FLL_SCAN_FILE_M ! CONTAINS - FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) + FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ERRMSG) RESULT(PNODE) ! ! Description: Scan file, returns fll list with data names in file and their ! position in file in bytes @@ -63,7 +63,7 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER(LEN=FILE_NAME_LENGTH) :: FILENAME CHARACTER :: FMT - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local types ! @@ -72,10 +72,10 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF INQUIRE (FILE=TRIM(FILENAME), EXIST=OK) @@ -89,7 +89,7 @@ FUNCTION FLL_SCAN_FILE(FILENAME,IOUNIT,FMT,FPAR,ACTION) RESULT(PNODE) ! ! GET FILE STRUCTURE ! - PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y', ACTION=LOC_ERRMSG) + PNODE => FLL_READ(FILENAME,IOUNIT,FMT,FPAR,SCAN = 'Y', ERRMSG=LOC_ERRMSG) RETURN diff --git a/data_util/fll_stich.f90 b/data_util/fll_stich.f90 index 42a8474..9f32f80 100644 --- a/data_util/fll_stich.f90 +++ b/data_util/fll_stich.f90 @@ -30,7 +30,7 @@ MODULE FLL_STICH_M ! External Modules used ! CONTAINS - SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) + SUBROUTINE FLL_STICH(PNODE,FPAR, ERRMSG) ! ! Description: subroutine stiches list after PNODE ! is taken away @@ -56,7 +56,7 @@ SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) ! TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -65,10 +65,10 @@ SUBROUTINE FLL_STICH(PNODE,FPAR, ACTION) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF SUBROUTINE diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index 0e0d91f..a10d30a 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -30,7 +30,7 @@ MODULE FLL_SWEEP_M ! External Modules used ! CONTAINS - RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) + RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ERRMSG) RESULT(OK) ! ! Description: Function sweep through list return each node ------------- NOT FINISHED YET ! @@ -71,7 +71,7 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) CHARACTER(*) :: LTYPE INTEGER(LINT) :: DIM LOGICAL OK - CHARACTER(*), OPTIONAL :: ACTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! LOCAL TYPES ! @@ -82,10 +82,10 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ACTION) RESULT(OK) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! BODY OF FUNCTION diff --git a/data_util/fll_write.f90 b/data_util/fll_write.f90 index 7cf21d0..ad95590 100644 --- a/data_util/fll_write.f90 +++ b/data_util/fll_write.f90 @@ -31,7 +31,7 @@ MODULE FLL_WRITE_M ! External Modules used ! CONTAINS - FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) + FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ERRMSG) RESULT(OK) ! ! Description: main function opening, writing and closing file ! @@ -67,7 +67,7 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) INTEGER :: IOUNIT CHARACTER :: FMT LOGICAL OK - CHARACTER(LEN=*), OPTIONAL :: ACTION + CHARACTER(LEN=*), OPTIONAL :: ERRMSG ! ! local declarations ! @@ -78,10 +78,10 @@ FUNCTION FLL_WRITE(PNODE,FILE,IOUNIT,FMT,FPAR, ACTION) RESULT(OK) ! ! local action ! - IF(.NOT.PRESENT(ACTION))THEN + IF(.NOT.PRESENT(ERRMSG))THEN LOC_ERRMSG='ALL' ELSE - LOC_ERRMSG = ACTION + LOC_ERRMSG = ERRMSG END IF ! ! DETERMINE RORMAT' From 3f1628345014ef2976d44bdb7ba06d2269d7fb43 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 15 Nov 2017 10:57:15 -0700 Subject: [PATCH 304/325] ad optional parameters to calls --- data_util/fll_mv.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data_util/fll_mv.f90 b/data_util/fll_mv.f90 index 708057c..329351f 100644 --- a/data_util/fll_mv.f90 +++ b/data_util/fll_mv.f90 @@ -158,7 +158,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ERRMSG) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - CALL FLL_STICH(PWHAT,FPAR) + CALL FLL_STICH(PWHAT,FPAR,ERRMSG=LOC_ERRMSG) IF(.NOT.ASSOCIATED(PWHERE%PCHILD))THEN ! @@ -198,7 +198,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ERRMSG) RESULT(PSOURCETMP) PWHERPAR => PWHERE%PPAR PWHERENEXT => PWHERE%PNEXT - CALL FLL_RM(PWHERE, FPAR) + CALL FLL_RM(PWHERE, FPAR,ERRMSG=LOC_ERRMSG) ! ! IF LIST MOVED TO ITS DIRECT PREDECESSOR OR SUCCESSOR ! LEAVE @@ -208,7 +208,7 @@ FUNCTION FLL_MVCP(PWHAT,PWHERE,MODE,FPAR,LOC_ERRMSG) RESULT(PSOURCETMP) ! ! STICH THE LIST WHERE THE SOURCE WILL BE TAKEN FROM ! - CALL FLL_STICH(PSOURCETMP,FPAR) + CALL FLL_STICH(PSOURCETMP,FPAR,ERRMSG=LOC_ERRMSG) ! ! ADD A NEW NODE ! From ed1958c9fbcec8ec0eb02503e0ade67e5583df9c Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 15 Nov 2017 11:09:36 -0700 Subject: [PATCH 305/325] read - add optional parameter ERRMSG --- data_util/depend.mk | 28 +++++----- data_util/fll_read_ffa.f90 | 104 +++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index c89262d..3ed151e 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,7 +1,7 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! # # Created by: jiraseka -# Date: 2017-09-08 19:44:16 +# Date: 2017-11-15 18:08:21 # fll_deattach.o : \ @@ -58,13 +58,6 @@ fll_read.o : \ fll_out.o \ fll_type.o -fll_read_ucd.o : \ - fll_mkdir.o \ - fll_mv.o \ - fll_mk.o \ - fll_out.o \ - fll_type.o - fll_cp.o : \ fll_mv.o \ fll_cat.o \ @@ -102,10 +95,8 @@ fll_match_pattern.o : \ fll_out.o \ fll_type.o -fll_read_ffa.o : \ - fll_mv.o \ - fll_funct_prt.o \ - fll_mk.o \ +fll_rm.o : \ + fll_stich.o \ fll_out.o \ fll_type.o @@ -114,6 +105,13 @@ fll_locate.o : \ fll_out.o \ fll_type.o +fll_read_ffa.o : \ + fll_mv.o \ + fll_funct_prt.o \ + fll_mk.o \ + fll_out.o \ + fll_type.o + fll_duplicate.o : \ fll_mv.o \ fll_mk.o \ @@ -148,8 +146,10 @@ fll_mods.o : \ fll_cp.o \ fll_read.o -fll_rm.o : \ - fll_stich.o \ +fll_read_ucd.o : \ + fll_mkdir.o \ + fll_mv.o \ + fll_mk.o \ fll_out.o \ fll_type.o diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 8e5a004..94c91d4 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -30,7 +30,7 @@ MODULE FLL_READ_FFA_M ! External Modules used ! CONTAINS - FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) + FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN,ERRMSG) RESULT(PNODE) ! ! Description: main function opening, reading and closing file ! @@ -67,6 +67,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) INTEGER :: IOUNIT CHARACTER :: FMT CHARACTER, OPTIONAL :: SCAN + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -75,12 +76,21 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) INTEGER :: ISTAT,FMTS INTEGER(LINT) :: POS CHARACTER :: SCAN_LOC + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF INQUIRE (FILE=TRIM(FILE), EXIST=OK) IF(.NOT.OK) THEN WRITE(FPAR%MESG,'(A,A)')' Read-ffa - file does not exist ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -99,7 +109,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Read-ffa - unknown format',TRIM(FMT) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -124,7 +134,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN @@ -133,7 +143,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) ! READ INITIAL NODE ! FMTS = 0 - PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR) + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR,LOC_ERRMSG) IF(FMTS == 1)THEN WRITE(*,*)' Reopening as old format' @@ -141,7 +151,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) CLOSE(IOUNIT) OPEN(UNIT=IOUNIT,STATUS='UNKNOWN',FILE=TRIM(FILE),FORM='UNFORMATTED',& CONVERT='big_endian',IOSTAT=ISTAT) - PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR) + PNODE => READ_NODE_FFA(IOUNIT,FMT_LOC,POS,SCAN_LOC,FMTS,FPAR,LOC_ERRMSG) CLOSE(IOUNIT) ELSE CLOSE(IOUNIT) @@ -149,7 +159,7 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read-ffa - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. END IF @@ -158,8 +168,8 @@ FUNCTION FLL_READ_FFA(FILE,IOUNIT,FMT,FPAR,SCAN) RESULT(PNODE) END FUNCTION FLL_READ_FFA ! ! READS NODE -! - RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) +!, + RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR,LOC_ERRMSG) RESULT(PNODE) ! ! Description: Function reads a node ! @@ -198,6 +208,7 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,FMTS CHARACTER :: SCAN + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -212,25 +223,25 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) ! READ HEADER ! CALL READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NSUB,NDIMO,NSIZEO,& - EXTRALINE,FMTS,FPAR_H) + EXTRALINE,FMTS,FPAR_H,LOC_ERRMSG) IF(.NOT.FPAR_H%SUCCESS)THEN WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading header ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() RETURN END IF IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN - PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,0_LINT,0_LINT,FPAR_H,ERRMSG=LOC_ERRMSG) ELSE - PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H) + PNODE => FLL_MK(NAME,LTYPE,NDIM,NSIZE,FPAR_H,ERRMSG=LOC_ERRMSG) END IF IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Read-ffa - error allocating node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() STOP @@ -245,23 +256,23 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) PNODE%NLINK = NSUB SELECT CASE(FMT) CASE('A') - CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H,LOC_ERRMSG) CASE('B') IF(FMTS == 0)THEN - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,POS,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,POS,FPAR_H,LOC_ERRMSG) ELSE - CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H) + CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,NDIMO,NSIZEO,FPAR_H,LOC_ERRMSG) END IF END SELECT END IF DO NNODES = 1,NDIM - PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) + PNEW => READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR,LOC_ERRMSG) IF(.NOT.ASSOCIATED(PNEW))STOP ' ERROR READING NODE' ! ! ATTACH TO PNODE ! - OK = FLL_MV(PNEW,PNODE,FPAR) + OK = FLL_MV(PNEW,PNODE,FPAR,ERRMSG=LOC_ERRMSG) IF(.NOT.OK) STOP' ERROR MV' END DO @@ -271,20 +282,20 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR) RESULT(PNODE) ! SELECT CASE(FMT) CASE('A') - CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_ASCII(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ERRMSG) CASE('B') IF(SCAN /= 'Y')THEN IF(FMTS == 0)THEN - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ERRMSG) ELSE - CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + CALL READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ERRMSG) END IF ELSE IF(PNODE%NSIZE * PNODE%NDIM == 1)THEN IF(FMTS /= 0)STOP' Cannot use scan == y with old format' - CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H) + CALL READ_DATA_FFA_BIN(IOUNIT,PNODE,PNODE%FTYPE,PNODE%NDIM,PNODE%NSIZE,POS,FPAR_H,LOC_ERRMSG) ELSE - POS = POS + GET_NEW_FFA_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H) + POS = POS + GET_NEW_FFA_POS(PNODE,PNODE%LTYPE,PNODE%NDIM,PNODE%NSIZE,FPAR_H,LOC_ERRMSG) END IF END IF @@ -298,7 +309,8 @@ END FUNCTION READ_NODE_FFA ! ! READ HEADER OR EACH NODE ! - SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIMO,NSIZEO,EXTRALINE,FMTS,FPAR) + SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,& + NDIMO,NSIZEO,EXTRALINE,FMTS,FPAR,LOC_ERRMSG) ! ! Description: Reads header of each node ! @@ -344,7 +356,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM LOGICAL :: EXTRALINE INTEGER(LINT) :: NDIM, NSIZE,NLINK,NDIMO,NSIZEO,POS CHARACTER(*) :: LTYPE - CHARACTER(*) :: NAME + CHARACTER(*) :: NAME,LOC_ERRMSG ! ! Local declarations ! @@ -500,7 +512,7 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM READ(IOUNIT,IOSTAT=IOSTAT)NAME,LTYPE,NSIZE,NDIM,NLINK ELSE WRITE(FPAR%MESG,'(A)')' Read-ffa - error reading ffa header ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. FMTS = 1 RETURN @@ -540,12 +552,12 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,NDIM END SELECT WRITE(FPAR%MESG,'(A)')' Read-ffa - reading header error ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN WRITE(FPAR%MESG,'(A)')' Read-ffa - reading header error, reached end of file ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN @@ -553,7 +565,7 @@ END SUBROUTINE READ_HEADER_FFA ! ! READ DATA ! - SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ERRMSG) ! ! Description: Reads data contatined in node Pnode - ASCII file ! @@ -568,6 +580,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -590,6 +603,7 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) INTEGER(LINT) :: NDIM,NSIZE CHARACTER(LEN=TYPE_LENGTH) :: LTYPE TYPE(FUNC_DATA_SET) :: FPAR + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -699,6 +713,9 @@ SUBROUTINE READ_DATA_FFA_ASCII(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) CASE DEFAULT WRITE(*,*)' WRONG TYPE ', pnode%lname, pnode%ltype + WRITE(FPAR%MESG,'(A)')' Read-ffa - WRONG TYPE ', pnode%lname, pnode%ltype + CALL FLL_OUT(LOC_ERRMSG,FPAR) + FPAR%SUCCESS = .FALSE. END SELECT @@ -710,7 +727,7 @@ END SUBROUTINE READ_DATA_FFA_ASCII - SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) + SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR,LOC_ERRMSG) ! ! Description: Function reads data contained in Pnode, binary file ! @@ -725,6 +742,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -745,7 +763,7 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE,NINTEG,POS - CHARACTER(*) :: LTYPE + CHARACTER(*) :: LTYPE,LOC_ERRMSG TYPE(FUNC_DATA_SET) :: FPAR ! ! Local declarations @@ -937,7 +955,9 @@ SUBROUTINE READ_DATA_FFA_BIN(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,POS,FPAR) RETURN CASE DEFAULT - WRITE(*,*)' WRONG TYPE' + WRITE(FPAR%MESG,'(A)')' Read-ffa - WRONG TYPE ', pnode%lname, pnode%ltype + CALL FLL_OUT(LOC_ERRMSG,FPAR) + FPAR%SUCCESS = .FALSE. END SELECT @@ -949,7 +969,7 @@ END SUBROUTINE READ_DATA_FFA_BIN - SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) + SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR,LOC_ERRMSG) ! ! Description: Function reads data contained in Pnode, binary file ! @@ -964,6 +984,7 @@ SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -983,7 +1004,7 @@ SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) TYPE(DNODE), POINTER :: PNODE INTEGER :: IOUNIT INTEGER(LINT) :: NDIM,NSIZE - CHARACTER(*) :: LTYPE + CHARACTER(*) :: LTYPE,LOC_ERRMSG TYPE(FUNC_DATA_SET) :: FPAR ! ! Local declarations @@ -1141,7 +1162,9 @@ SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) RETURN CASE DEFAULT - WRITE(*,*)' WRONG TYPE' + WRITE(FPAR%MESG,'(A)')' Read-ffa - WRONG TYPE ', pnode%lname, pnode%ltype + CALL FLL_OUT(LOC_ERRMSG,FPAR) + FPAR%SUCCESS = .FALSE. END SELECT @@ -1152,7 +1175,7 @@ SUBROUTINE READ_DATA_FFA_BIN_OLD(IOUNIT,PNODE,LTYPE,NDIM,NSIZE,FPAR) END SUBROUTINE READ_DATA_FFA_BIN_OLD - FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) + FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR, LOC_ERRMSG) RESULT (POS) ! ! Description: Function gets new position for reading bindary file without allocating arrays ! used for scanning files @@ -1168,6 +1191,7 @@ FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) ! USE FLL_TYPE_M USE FLL_FUNC_PRT_M + USE FLL_OUT_M IMPLICIT NONE ! @@ -1187,7 +1211,7 @@ FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: NDIM, NSIZE, POS - CHARACTER(LEN=*) :: LTYPE + CHARACTER(LEN=*) :: LTYPE,LOC_ERRMSG ! ! Local declaration ! @@ -1213,7 +1237,9 @@ FUNCTION GET_NEW_FFA_POS(PNODE,LTYPE, NDIM, NSIZE, FPAR) RESULT (POS) RETURN CASE DEFAULT - WRITE(*,*)' WRONG TYPE' + WRITE(FPAR%MESG,'(A)')' Read-ffa - WRONG TYPE ', pnode%lname, pnode%ltype + CALL FLL_OUT(LOC_ERRMSG,FPAR) + FPAR%SUCCESS = .FALSE. END SELECT From 73ef3328760076edb0bade05abc2e761fcd51191 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 15 Nov 2017 11:13:04 -0700 Subject: [PATCH 306/325] add optional ERRMSG to write --- data_util/fll_write_ffa.f90 | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/data_util/fll_write_ffa.f90 b/data_util/fll_write_ffa.f90 index deece67..6834cda 100644 --- a/data_util/fll_write_ffa.f90 +++ b/data_util/fll_write_ffa.f90 @@ -30,7 +30,7 @@ MODULE FLL_WRITE_FFA_M ! External Modules used ! CONTAINS - FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) + FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR,ERRMSG) RESULT(OK) ! ! Description: main function opening, writing and closing file ! @@ -67,12 +67,22 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) CHARACTER :: FMT LOGICAL OK CHARACTER(32) :: FFVERSION='FFA-format-v2' + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! CHARACTER :: FMT_LOC INTEGER :: ISTAT INTEGER(LINT) :: POS + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! DETERMINE RORMAT' ! @@ -85,7 +95,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) FMT_LOC = 'U' CASE DEFAULT WRITE(FPAR%MESG,'(A,A)')' Write - unknown format',TRIM(FMT) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. PNODE => NULL() OK = .FALSE. @@ -106,8 +116,7 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write - error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -115,13 +124,12 @@ FUNCTION FLL_WRITE_FFA(PNODE,FILE,IOUNIT,FMT,FPAR) RESULT(OK) ! ! WRITE LINKED LIST ! - CALL FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT_LOC,FPAR) + CALL FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT_LOC,FPAR,LOC_ERRMSG) CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -134,7 +142,7 @@ END FUNCTION FLL_WRITE_FFA - SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) + SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR,LOC_ERRMSG) ! ! Description: Function writes a list ! @@ -167,6 +175,7 @@ SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT CHARACTER :: FMT + CHARACTER(*) :: LOC_ERRMSG ! ! Local declarations ! @@ -179,7 +188,7 @@ SUBROUTINE FLL_WRITE_FFA_LIST(PNODE,IOUNIT,FMT,FPAR) FPAR%SUCCESS = .FALSE. IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' Write - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF From dc4d5311fb27d73a5566544870615ebb4d1362ce Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 15 Nov 2017 11:39:24 -0700 Subject: [PATCH 307/325] add ERRMSG to mpi routines --- mpi_util/fll_mpi_cp.f90 | 14 +++++++-- mpi_util/fll_mpi_cp_all.f90 | 16 ++++++++-- mpi_util/fll_mpi_proc_struct.f90 | 53 ++++++++++++++++++++++++-------- mpi_util/fll_mpi_read.f90 | 23 ++++++++++---- mpi_util/fll_mpi_write.f90 | 22 +++++++++---- 5 files changed, 98 insertions(+), 30 deletions(-) diff --git a/mpi_util/fll_mpi_cp.f90 b/mpi_util/fll_mpi_cp.f90 index 7afad5e..3c43c85 100644 --- a/mpi_util/fll_mpi_cp.f90 +++ b/mpi_util/fll_mpi_cp.f90 @@ -33,7 +33,7 @@ MODULE FLL_MPI_CP_M ! External Modules used ! CONTAINS - FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) + FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: Sends FLL subset to a specified process in comunicator ! if process ID == sending proceess ID, do not create @@ -72,11 +72,21 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: COMMUNICATOR,SENDPART,RECPART + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD INTEGER :: RANK, IERR + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! if not in group, return ! @@ -121,7 +131,7 @@ FUNCTION FLL_MPI_CP(PNODE,COMMUNICATOR,SENDPART,RECPART,FPAR) RESULT(PNEW) ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF diff --git a/mpi_util/fll_mpi_cp_all.f90 b/mpi_util/fll_mpi_cp_all.f90 index 3e612f5..e08bafd 100644 --- a/mpi_util/fll_mpi_cp_all.f90 +++ b/mpi_util/fll_mpi_cp_all.f90 @@ -33,7 +33,7 @@ MODULE FLL_MPI_CP_ALL_M ! External Modules used ! CONTAINS - FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) + FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR,ERRMSG) RESULT(PNEW) ! ! Description: Broadcasts FLL subset to all processes in comunicator ! if process ID == sending proceess ID, do not create @@ -71,11 +71,21 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) TYPE(DNODE), POINTER :: PNODE,PNEW TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: COMMUNICATOR,SENDPART + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! TYPE(DNODE), POINTER :: PCHILD INTEGER :: RANK, IERR + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! if not in group, return ! @@ -120,7 +130,7 @@ FUNCTION FLL_MPI_CP_ALL(PNODE,COMMUNICATOR,SENDPART,FPAR) RESULT(PNEW) ! IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A)')' DUPLICATE - null node ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -320,7 +330,7 @@ SUBROUTINE BROADCAST_NODE_SEND(PNODE,COMMUNICATOR,SENDPART,FPAR) CALL MPI_BCAST(PNODE%LNAME, NAME_LENGTH, MPI_CHARACTER, SENDPART,COMMUNICATOR, IERR) ! IF(IERR /= 0)THEN ! WRITE(FPAR%MESG,'(A)')' GET_NCODE- null node ' -! CALL FLL_OUT('ALL',FPAR) +! CALL FLL_OUT(LOC_ERRMSG,FPAR) ! FPAR%SUCCESS = .FALSE. ! CODE = -1 ! RETURN diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 4dd0194..69265c4 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -57,7 +57,7 @@ MODULE FLL_MPI_PROC_STRUCT_M ! CONTAINS - FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) + FUNCTION FLL_MPI_PROC_STRUCT(FPAR,ERRMSG) RESULT(PNODE) ! ! Description: Creates structure with header for MPI process definition ! @@ -82,16 +82,23 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) ! Arguments declaration ! TYPE(DNODE), POINTER :: PNODE + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! TYPE(DNODE), POINTER :: PTMP,PSUBPROC TYPE(FUNC_DATA_SET) :: FPAR - INTEGER :: WORLD_GROUP_ID, IERR, NPROC - LOGICAL :: OK - + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! Main pointer ! @@ -120,7 +127,7 @@ FUNCTION FLL_MPI_PROC_STRUCT(FPAR) RESULT(PNODE) PSUBPROC => FLL_MKDIR('Subprocs',FPAR) IF(.NOT.FLL_MV(PSUBPROC, PNODE, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving Subprocs' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -131,7 +138,7 @@ END FUNCTION FLL_MPI_PROC_STRUCT - SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) + SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR,ERRMSG) ! ! Description: Contains function prepiring MPI I/O structure for NM model ! It splits all world_processes to NFILES groups @@ -174,6 +181,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) TYPE(FUNC_DATA_SET) :: FPAR CHARACTER(LEN=*) :: NAME_OF_FILE,EXTENSION INTEGER(LINT) :: NFILES + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -183,6 +191,15 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) CHARACTER(LEN=NAME_LENGTH) :: FILENAME CHARACTER(LEN=5) :: STR INTEGER, ALLOCATABLE :: EVEN_RANK(:) + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! get number of processors and world group ! @@ -192,7 +209,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) IF(MOD(NPROC,NFILES) /= 0)THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - NPROC is not multiplication of NFILES' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF ! @@ -205,7 +222,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) PIOSTR => FLL_MKDIR('IO-NM_struct',FPAR) IF(.NOT.FLL_MV(PIOSTR, PSUBPROC, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -222,7 +239,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR) IF(NFILES == NPROC)THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')' FLL_NMIO_STRUCT - error witing files, nfiles == npart ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF @@ -333,7 +350,7 @@ END SUBROUTINE FLL_NMIO_STRUCT - SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) + SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR,ERRMSG) ! ! Description: Contains function prepiring MPI I/O structure for NM model ! It splits all world_processes to NFILES groups @@ -389,6 +406,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) CHARACTER(LEN=*) :: NAME_OF_FILE,EXTENSION INTEGER(LINT) :: NFILES CHARACTER :: MODE + CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local declarations ! @@ -398,6 +416,15 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) CHARACTER(LEN=NAME_LENGTH) :: FILENAME CHARACTER(LEN=5) :: STR INTEGER, ALLOCATABLE :: EVEN_RANK(:) + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! get number of processors and world group ! @@ -407,7 +434,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) IF(MOD(NPROC,NFILES) /= 0)THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - NPROC is not multiplication of NFILES' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF ! @@ -417,7 +444,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) PIOSTR => FLL_MKDIR('IO-SNM_struct',FPAR) IF(.NOT.FLL_MV(PIOSTR, PSUBPROC, FPAR))THEN WRITE(FPAR%MESG,'(A)')' FLL_MPI_PROC_STRUCT: Error moving IO-NM_struct' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -434,7 +461,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR) IF(NFILES == NPROC)THEN FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A)')' FLL_SNMIO_STRUCT - error witing files, nfiles == npart ' - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF diff --git a/mpi_util/fll_mpi_read.f90 b/mpi_util/fll_mpi_read.f90 index 413533d..e3440ed 100644 --- a/mpi_util/fll_mpi_read.f90 +++ b/mpi_util/fll_mpi_read.f90 @@ -32,7 +32,7 @@ MODULE FLL_MPI_READ_M ! CONTAINS - FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) RESULT(PNODE) + FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR, ERRMSG) RESULT(PNODE) ! ! Description: contains subroutine readig file in paralell mode ! @@ -104,6 +104,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT,RANK, ROOT_RANK, COMMUNICATOR CHARACTER :: OPTION + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! @@ -111,6 +112,15 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R INTEGER :: ISTAT,IERR INTEGER(LINT), POINTER :: DISPL(:) INTEGER(LINT) :: POS + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! if not in group, return ! @@ -126,7 +136,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -137,7 +147,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R ! get positions for each subset, ie. each process solution ! IF(RANK == ROOT_RANK)THEN - PTMP => FLL_RPART_FILE_HEADER(IOUNIT, FPAR) + PTMP => FLL_RPART_FILE_HEADER(IOUNIT, FPAR, LOC_ERRMSG) END IF ! ! distribute that info to all processes @@ -163,7 +173,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. RETURN END IF @@ -179,7 +189,7 @@ FUNCTION FLL_MPI_READ(FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) R END FUNCTION FLL_MPI_READ - FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) + FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR, LOC_ERRMSG) RESULT(PNEW) ! ! Description: Reads header of partitioned file containing ! positions of each record in the file @@ -215,13 +225,14 @@ FUNCTION FLL_RPART_FILE_HEADER(IOUNIT, FPAR) RESULT(PNEW) CHARACTER(LEN=NAME_LENGTH) :: NAME CHARACTER(LEN=TYPE_LENGTH) :: TYPE INTEGER(LINT) :: NDIM,NSIZE,I + CHARACTER(*) :: LOC_ERRMSG ! ! read name, type, ndim, nsize ! create node, read valus of record positions and return ! READ(IOUNIT)NAME,TYPE,NDIM,NSIZE READ(IOUNIT)NAME,TYPE,NDIM,NSIZE - PNEW => FLL_MK(NAME,TYPE,NDIM,NSIZE,FPAR) + PNEW => FLL_MK(NAME,TYPE,NDIM,NSIZE,FPAR,ERRMSG=LOC_ERRMSG) READ(IOUNIT)(PNEW%L1(I), I=1,NDIM) RETURN diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index ee3fab6..e119023 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -32,7 +32,7 @@ MODULE FLL_MPI_WRITE_M ! CONTAINS - FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR) RESULT(OK) + FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, FPAR, ERRMSG) RESULT(OK) ! ! Description: contains subroutine writing file in paralell mode ! @@ -104,12 +104,22 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, INTEGER :: IOUNIT,RANK, ROOT_RANK, COMMUNICATOR CHARACTER :: OPTION LOGICAL OK + CHARACTER(*), OPTIONAL :: ERRMSG ! ! local declarations ! INTEGER :: ISTAT,IERR,NPROC INTEGER(LINT), ALLOCATABLE :: POS(:),DISPL(:) INTEGER(LINT) :: POS1,I,PART_NUM,LOC_DISPL + CHARACTER(LEN=10) :: LOC_ERRMSG +! +! local action +! + IF(.NOT.PRESENT(ERRMSG))THEN + LOC_ERRMSG='ALL' + ELSE + LOC_ERRMSG = ERRMSG + END IF ! ! if not in group, return ! @@ -129,7 +139,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, IF(ISTAT/=0) THEN WRITE(FPAR%MESG,'(A,A)')' Write error opening file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN @@ -150,7 +160,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! get length of each data subset of actual data ! POS = 0 - POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR) + POS(RANK+2) = FLL_GETNBYTES(PNODE,FPAR,ERRMSG=LOC_ERRMSG) ! ! the first subset is a header ! header = 16 + 4 + 8 + 8 (name, type, ndim, nsize) @@ -167,7 +177,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! ! Calculate displacement, ie where each subset starts ! - PART_NUM = FLL_GETNDATA_L0(PNODE, 'process_number',1_LINT, FPAR) + PART_NUM = FLL_GETNDATA_L0(PNODE, 'process_number',1_LINT, FPAR,ERRMSG=LOC_ERRMSG) ! ! the first subset will start always at position 1 ! ie. beginning of the file @@ -200,14 +210,14 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! ! Write data set ! - CALL FLL_WRITE_LIST(PNODE,IOUNIT,'B',FPAR) + CALL FLL_WRITE_LIST(PNODE,IOUNIT,'B',FPAR,LOC_ERRMSG) ! ! close file and sync with barrier ! CLOSE(IOUNIT) IF(.NOT.ASSOCIATED(PNODE))THEN WRITE(FPAR%MESG,'(A,A)')' Read - error reading file ',TRIM(FILE) - CALL FLL_OUT('ALL',FPAR) + CALL FLL_OUT(LOC_ERRMSG,FPAR) FPAR%SUCCESS = .FALSE. OK = .FALSE. RETURN From 392d87860de70f584ae7d99e561ca904170710b1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 16 Nov 2017 07:10:52 -0700 Subject: [PATCH 308/325] add STOP to FLL_OUT --- data_util/fll_out.f90 | 51 +++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/data_util/fll_out.f90 b/data_util/fll_out.f90 index a91130d..5fca95b 100644 --- a/data_util/fll_out.f90 +++ b/data_util/fll_out.f90 @@ -35,7 +35,7 @@ MODULE FLL_OUT_M ! CONTAINS - SUBROUTINE FLL_OUT(ERRMSG,FPAR) + SUBROUTINE FLL_OUT(ACT_ERRMSG,FPAR) ! ! Description: Contains subroutine pritning errmessage from FPAR structure ! @@ -55,7 +55,7 @@ SUBROUTINE FLL_OUT(ERRMSG,FPAR) ! ! Arguments description ! Name In/Out Function -! ERRMSG In determines what to do +! ACT_ERRMSG In determines what to do ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -64,57 +64,76 @@ SUBROUTINE FLL_OUT(ERRMSG,FPAR) ! ! ARGUMENTS: ! - CHARACTER(*) :: ERRMSG + CHARACTER(*) :: ACT_ERRMSG TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(LEN=72) :: STRMES ='LOGFILE' + CHARACTER(LEN=72) :: STRMES ='LOGFILE' + CHARACTER(LEN=72) :: STRSTAT ='STATFILE' ! ! Local declarations ! ! ! Select here to print ! - SELECT CASE(ERRMSG) + SELECT CASE(ACT_ERRMSG) CASE('NONE') RETURN - CASE('OPEN') + CASE('OPEN_LOG') OPEN(UNIT=IOLOGFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') + WRITE(IOLOGFILE,'(A)')'Begining of LOG file ...' CASE('OPEN_STAT') - OPEN(UNIT=IOSTATFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') - WRITE(IOSTATFILE,'(A)')'Process running ...' + OPEN(UNIT=IOSTATFILE,STATUS='UNKNOWN',FILE=STRSTAT,FORM='FORMATTED') + WRITE(IOLOGFILE,'(A)')'Begining of STAT file ...' CLOSE(IOSTATFILE) - CASE('CLOSE') + CASE('CLOSE_LOG') + WRITE(IOLOGFILE,'(A)')'Process finished ...' CLOSE(IOLOGFILE) CASE('CLOSE_STAT') - OPEN(UNIT=IOSTATFILE,STATUS='UNKNOWN',FILE=STRMES,FORM='FORMATTED') - WRITE(IOSTATFILE,'(A)')'Finished' + WRITE(IOSTATFILE,'(A)')'Process finished ...' CLOSE(IOSTATFILE) - +! +! print to log file +! CASE('LOG') WRITE(IOLOGFILE,'(A)')FPAR%MESG FLUSH(IOLOGFILE) - +! +! print on stdoutput +! CASE('OUT') WRITE(STDOUT,'(A)')FPAR%MESG FLUSH(STDOUT) - +! +! print on stodoutput and to log file +! CASE('ALL') WRITE(IOLOGFILE,'(A)')FPAR%MESG FLUSH(IOLOGFILE) WRITE(STDOUT,'(A)')FPAR%MESG FLUSH(STDOUT) +! +! print on stodoutput and to log file and terminate +! + CASE('STOP') + WRITE(IOLOGFILE,'(A)')FPAR%MESG + FLUSH(IOLOGFILE) + WRITE(STDOUT,'(A)')FPAR%MESG + FLUSH(STDOUT) + WRITE(IOLOGFILE,'(A)')'Process finished ...' + CLOSE(IOLOGFILE) + STOP 'Terminating ...' CASE DEFAULT WRITE(STDOUT,*)& - 'Error: wrong action in fll_out, action: "'//ERRMSG//'" not defined.' + 'Error: wrong action in fll_out, action: "'//ACT_ERRMSG//'" not defined.' WRITE(STDOUT,*)FPAR%MESG FLUSH(STDOUT) WRITE(IOLOGFILE,*)& - 'Error: wrong action in fll_out, action: "'//ERRMSG//'" not defined.' + 'Error: wrong action in fll_out, action: "'//ACT_ERRMSG//'" not defined.' WRITE(IOLOGFILE,*)FPAR%MESG FLUSH(IOLOGFILE) From 7d5416fd37d53c8326990492ff5051d341763e15 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 16 Nov 2017 07:25:44 -0700 Subject: [PATCH 309/325] cosmetic changes --- data_util/fll_out.f90 | 7 +++---- data_util/fll_type.f90 | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/data_util/fll_out.f90 b/data_util/fll_out.f90 index 5fca95b..f2022d7 100644 --- a/data_util/fll_out.f90 +++ b/data_util/fll_out.f90 @@ -48,14 +48,13 @@ SUBROUTINE FLL_OUT(ACT_ERRMSG,FPAR) ! ! External Modules used ! - USE FLL_TYPE_M ! ! Declarations ! ! Arguments description ! Name In/Out Function -! ACT_ERRMSG In determines what to do +! ACT_ERRMSG In determines what to do ! FPAR In/Out structure containing function specific data ! ! Arguments declaration @@ -66,11 +65,11 @@ SUBROUTINE FLL_OUT(ACT_ERRMSG,FPAR) ! CHARACTER(*) :: ACT_ERRMSG TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER(LEN=72) :: STRMES ='LOGFILE' - CHARACTER(LEN=72) :: STRSTAT ='STATFILE' ! ! Local declarations ! + CHARACTER(LEN=72) :: STRMES ='LOGFILE' + CHARACTER(LEN=72) :: STRSTAT ='STATFILE' ! ! Select here to print ! diff --git a/data_util/fll_type.f90 b/data_util/fll_type.f90 index b202330..834b3ff 100644 --- a/data_util/fll_type.f90 +++ b/data_util/fll_type.f90 @@ -116,8 +116,8 @@ MODULE FLL_TYPE_M REAL(RDOUBLE) , POINTER, CONTIGUOUS :: D1(:) =>NULL(), D2(:,:) => NULL() ! double arrays INTEGER(SINT) , POINTER, CONTIGUOUS :: I1(:) =>NULL(), I2(:,:) => NULL() ! integer arrays INTEGER(LINT) , POINTER, CONTIGUOUS :: L1(:) =>NULL(), L2(:,:) => NULL() ! long integer arrays - CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S1(:) => NULL() ! 1D array of strings - CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S2(:,:)=> NULL() ! 2D array of strings + CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S1(:) => NULL() ! 1D array of strings + CHARACTER(LEN=LSTRING_LENGTH), POINTER, CONTIGUOUS :: S2(:,:)=> NULL() ! 2D array of strings #else REAL(RSINGLE) , POINTER :: R1(:) =>NULL(), R2(:,:) => NULL() REAL(RDOUBLE) , POINTER :: D1(:) =>NULL(), D2(:,:) => NULL() From 320a08e9ab542368aa69e12b397eeaf6a73b68e9 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 16 Nov 2017 07:26:28 -0700 Subject: [PATCH 310/325] add missing depend.mk in ReadRecord --- examples/Read_Record/depend.mk | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 examples/Read_Record/depend.mk diff --git a/examples/Read_Record/depend.mk b/examples/Read_Record/depend.mk new file mode 100644 index 0000000..264b0ec --- /dev/null +++ b/examples/Read_Record/depend.mk @@ -0,0 +1,8 @@ +# This file is generated automatically by fort_depend.py. DO NOT EDIT! +# +# Created by: jiraseka +# Date: 2017-09-08 19:44:16 +# + +fll_read_record.o : \ + ../../data_util/fll_mods.o From b2cc572165a81c519980220574dffb3957d23793 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 16 Nov 2017 10:45:10 -0700 Subject: [PATCH 311/325] add optional parameter for color --- data_util/fll_cat.f90 | 81 ++++++++++++++++++++++++++------------ data_util/fll_read_ffa.f90 | 7 +++- 2 files changed, 62 insertions(+), 26 deletions(-) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index c4370a1..97b4ce5 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -34,7 +34,7 @@ MODULE FLL_CAT_M ! CONTAINS - SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) + SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG,COLOR) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -60,14 +60,14 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT LOGICAL :: PARENT - CHARACTER, OPTIONAL :: SCAN,SDIR + CHARACTER, OPTIONAL :: SCAN,SDIR,COLOR CHARACTER(*), OPTIONAL :: ERRMSG ! ! Local types ! TYPE(DNODE), POINTER :: PCHILD INTEGER(LINT) :: POS - CHARACTER :: SCAN_LOC + CHARACTER :: SCAN_LOC,COL_LOC INTEGER :: DIR CHARACTER(LEN=10) :: LOC_ERRMSG ! @@ -78,6 +78,12 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) ELSE LOC_ERRMSG = ERRMSG END IF + + IF(.NOT.PRESENT(COLOR))THEN + COL_LOC='Y' + ELSE + COL_LOC = COLOR + END IF ! ! body of subroutine ! @@ -111,11 +117,11 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) ! ! print main node ! - CALL FLL_PRINT(PNODE, IOUNIT, 0_LINT, SCAN, DIR, FPAR) + CALL FLL_PRINT(PNODE, IOUNIT, 0_LINT, SCAN, DIR, FPAR, COL_LOC) ! ! IF NODE HAS CHILDREN PRINT THEM TOO ! - IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,DIR,FPAR) + IF(ASSOCIATED(PCHILD))CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN_LOC,DIR,FPAR, COL_LOC) FPAR%SUCCESS = .TRUE. @@ -123,7 +129,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG) END SUBROUTINE FLL_CAT ! ! - RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) + RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR, COL_LOC) ! ! Description: Module prints the short content of PNODE to IOUNIT ! @@ -148,7 +154,7 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER(LINT) :: POS INTEGER :: IOUNIT,DIR - CHARACTER :: SCAN + CHARACTER :: SCAN,COL_LOC ! ! Local variables ! @@ -163,12 +169,12 @@ RECURSIVE SUBROUTINE FLL_CAT_RECURSIVE_NODE(PNODE,IOUNIT,POS,SCAN,DIR,FPAR) ! DO WHILE(ASSOCIATED(PCURR)) - CALL FLL_PRINT(PCURR, IOUNIT, POS, SCAN, DIR, FPAR) + CALL FLL_PRINT(PCURR, IOUNIT, POS, SCAN, DIR, FPAR,COL_LOC) PNEXT => PCURR%PNEXT PCHILD => PCURR%PCHILD IF(ASSOCIATED(PCHILD))THEN - CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN,DIR,FPAR) + CALL FLL_CAT_RECURSIVE_NODE(PCHILD,IOUNIT,POS,SCAN,DIR,FPAR,COL_LOC) END IF PCURR => PNEXT @@ -183,7 +189,7 @@ END SUBROUTINE FLL_CAT_RECURSIVE_NODE ! ! FREE MEMORY FOR NODE ! - SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) + SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR,COL_LOC) ! ! Description: print content of PNODE ! @@ -209,7 +215,7 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) TYPE(FUNC_DATA_SET) :: FPAR INTEGER :: IOUNIT INTEGER(LINT) :: POS - CHARACTER :: SCAN + CHARACTER :: SCAN,COL_LOC ! ! Local variables ! @@ -233,27 +239,52 @@ SUBROUTINE FLL_PRINT(PNODE, IOUNIT, POS, SCAN, DIR, FPAR) WRITE(NDSTR,'(I8)')PNODE%NDIM WRITE(NSSTR,'(I8)')PNODE%NSIZE - IF(TRIM(PNODE%LTYPE) == 'DIR')THEN - WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& + IF(COL_LOC == 'Y' .OR. COL_LOC == 'y')THEN + IF(TRIM(PNODE%LTYPE) == 'DIR')THEN + WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& achar(27),"[32m",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' - WRITE(IOUNIT, *)TRIM(TEXT1) - RETURN - ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN -! WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& -! "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',SPACE,ADJUSTL(PNODE%LNAME) - WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN + WRITE(TEXT1,'(A,A,A3,A,A,A,A,A,A,A,A,A16,A,A)')& achar(27),"[31m-",TRIM(PNODE%LTYPE),"- ",achar(27),'[30m' ,(TRIM(NDSTR)),'/ ',& achar(27),"[32m",SPACE,ADJUSTL(PNODE%LNAME),achar(27),'[30m' - WRITE(IOUNIT, *)TRIM(TEXT1) - RETURN - ELSE IF(DIR == 0) THEN - WRITE(TEXT1,'(A,A3,A,A,A,A,A,A16)')& + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + ELSE IF(DIR == 0) THEN + WRITE(TEXT1,'(A,A3,A,A,A,A,A,A16)')& + "-",TRIM(PNODE%LTYPE),"- ",TRIM(NDSTR),'x',ADJUSTL(TRIM(NSSTR)),SPACE,NAME + IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + END IF + END IF + + ELSE + + IF(TRIM(PNODE%LTYPE) == 'DIR')THEN + WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',& + SPACE,ADJUSTL(PNODE%LNAME) + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + ELSE IF(TRIM(PNODE%LTYPE) == 'N')THEN + WRITE(TEXT1,'(A,A3,A,A,A,A,A16)')& + "-",TRIM(PNODE%LTYPE),"- ",(TRIM(NDSTR)),'/ ',& + SPACE,ADJUSTL(PNODE%LNAME) + WRITE(IOUNIT, *)TRIM(TEXT1) + RETURN + ELSE IF(DIR == 0) THEN + WRITE(TEXT1,'(A,A3,A,A,A,A,A,A16)')& "-",TRIM(PNODE%LTYPE),"- ",TRIM(NDSTR),'x',ADJUSTL(TRIM(NSSTR)),SPACE,NAME - IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN + IF(SCAN == 'Y' .AND. (NDIM*NSIZE /= 1) )THEN WRITE(IOUNIT, *)TRIM(TEXT1) RETURN - END IF + END IF + END IF + + END IF IF(DIR == 1)RETURN diff --git a/data_util/fll_read_ffa.f90 b/data_util/fll_read_ffa.f90 index 94c91d4..cf1e30b 100644 --- a/data_util/fll_read_ffa.f90 +++ b/data_util/fll_read_ffa.f90 @@ -247,7 +247,9 @@ RECURSIVE FUNCTION READ_NODE_FFA(IOUNIT,FMT,POS,SCAN,FMTS,FPAR,LOC_ERRMSG) RESUL STOP RETURN END IF - +! +! save original ffa type node if FTYPE variable +! PNODE%FTYPE = FTYPE IF(TRIM(LTYPE) == 'DIR' .OR. TRIM(LTYPE) == 'N')THEN @@ -523,6 +525,9 @@ SUBROUTINE READ_HEADER_FFA(IOUNIT,FMT,POS,NAME,LTYPE,FTYPE,NDIM,NSIZE,NLINK,& INQUIRE(UNIT = IOUNIT, POS=POS) LTYPE(2:) = ' ' +! +! save original ffa file type +! FTYPE = LTYPE NSIZEO = NSIZE NDIMO = NDIM From 8e53cd774e9b64d56f0926e7c02967a736cf00d1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Thu, 16 Nov 2017 11:03:43 -0700 Subject: [PATCH 312/325] add color to fll_cat accessory --- accessories/fll_cat/fll_cat.f90 | 7 ++-- accessories/fll_cat/fll_cat.py | 66 ++++++++++++++++++++++++--------- data_util/fll_cat.f90 | 2 +- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/accessories/fll_cat/fll_cat.f90 b/accessories/fll_cat/fll_cat.f90 index fd5e33c..5d7160c 100644 --- a/accessories/fll_cat/fll_cat.f90 +++ b/accessories/fll_cat/fll_cat.f90 @@ -62,7 +62,7 @@ PROGRAM FLL_CATU CHARACTER(LEN=FILE_NAME_LENGTH) FILE TYPE(DNODE), POINTER :: PNODE TYPE(FUNC_DATA_SET) :: FPAR - CHARACTER :: FMT, SCAN, DIR + CHARACTER :: FMT, SCAN, DIR, COLOR CHARACTER(LEN=3) :: EFMT ! ! read a file and print on screen @@ -72,6 +72,7 @@ PROGRAM FLL_CATU READ(*,'(A3)')EFMT READ(*,*)SCAN READ(*,*)DIR + READ(*,*)COLOR SELECT CASE(EFMT) CASE('fll') @@ -83,9 +84,9 @@ PROGRAM FLL_CATU ! print node on the screen ! IF(DIR == 'Y')THEN - CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN, SDIR = DIR) + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN, SDIR = DIR, COLOR=COLOR) ELSE - CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN) + CALL FLL_CAT(PNODE, 6, .TRUE.,FPAR,SCAN = SCAN,COLOR=COLOR) END IF WRITE(*,*) CALL FLL_RM(PNODE,FPAR) diff --git a/accessories/fll_cat/fll_cat.py b/accessories/fll_cat/fll_cat.py index 3f2be7f..5041700 100755 --- a/accessories/fll_cat/fll_cat.py +++ b/accessories/fll_cat/fll_cat.py @@ -11,7 +11,7 @@ #Definitions -def run(file,fmt,efmt,scan,dir): +def run(file,fmt,efmt,scan,dir,colour): # # execute # @@ -27,16 +27,27 @@ def run(file,fmt,efmt,scan,dir): if not os.path.isfile(file): print(" ") - print("\033[031mERROR:\033[039m specified file \033[032m"+file+"\033[039m does not exist, terminating .... ") + if colour == 'y': + print("\033[031mERROR:\033[039m specified file \033[032m"+file+"\033[039m does not exist, terminating .... ") + else: + print("ERROR: specified file "+file+" does not exist, terminating .... ") sys.exit() print(" ") - print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + if colour == 'y': + print("\033[039m Specified file is: \033[032m"+file+"\033[039m") + else: + print(" Specified file is: "+file) if fmt == 'b' or fmt == 'B': - print("\033[039m Specified file format is: \033[032mbinary\033[039m") + if colour == 'y': + print("\033[039m Specified file format is: \033[032mbinary\033[039m") + else: + print(" Specified file format is: binary") else: - print("\033[039m Specified file format is: \033[032mASCII \033[039m") - + if colour == 'y': + print("\033[039m Specified file format is: \033[032mASCII \033[039m") + else: + print(" Specified file format is: ASCII ") if dir == 'Y': print(" ") print("\033[035m ... printing DIR structure only ... \033[039m") @@ -44,25 +55,37 @@ def run(file,fmt,efmt,scan,dir): if scan == 'Y': print(" ") - print("\033[035m ... running in scan only mode ... \033[039m") + if colour == 'y': + print("\033[035m ... running in scan only mode ... \033[039m") + else: + print(" ... running in scan only mode ... ") print(" ") if sys.version_info < (3,0): p = Popen([executable], stdin=PIPE) #NOTE: no shell=True here - p.communicate(os.linesep.join([file, fmt, efmt, scan, dir])) + p.communicate(os.linesep.join([file, fmt, efmt, scan, dir, colour])) else: p = Popen([executable], stdin=PIPE,universal_newlines=True) #NOTE: no shell=True here - p.communicate(os.linesep.join( [file, fmt, efmt, scan, dir])) + p.communicate(os.linesep.join( [file, fmt, efmt, scan, dir, colour])) def print_header(): - print(" ") - print ("\033[031m************************************************************************************ \033[039m") - print ("\033[031m \033[039m") - print ("\033[031m \033[039m fll_cat - v1.1 \033[031m \033[039m") - print ("\033[031m \033[039m") - print ("\033[031m \033[039m prints content of file on screen \033[031m \033[039m") - print ("\033[031m \033[039m") - print ("\033[031m************************************************************************************ \033[039m") + if colour == 'y': + print(" ") + print ("\033[031m************************************************************************************ \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m fll_cat - v1.1 \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m \033[039m prints content of file on screen \033[031m \033[039m") + print ("\033[031m \033[039m") + print ("\033[031m************************************************************************************ \033[039m") + else: + print ("************************************************************************************ ") + print (" ") + print (" fll_cat - v1.1 ") + print (" ") + print (" prints content of file on screen ") + print (" ") + print ("************************************************************************************ ") def check_path(path): @@ -84,6 +107,7 @@ def check_path(path): parser.add_argument('-s','--scan',action='store_true',help='Scan file only',required=False) parser.add_argument('-D','--dir',action='store_true',help='Print DIR only',required=False) parser.add_argument('-e','--external_format',nargs=1,help='External format of the file') + parser.add_argument('-c','--colour',action='store_true',help='Coloured output',required=False) # Parse the command line arguments args = parser.parse_args() @@ -93,6 +117,7 @@ def check_path(path): eformat = args.external_format[0] if args.external_format else None scan = args.scan dir = args.dir + colour = args.colour if not scan: scan = 'n' @@ -104,6 +129,11 @@ def check_path(path): else: dir = 'Y' + if not colour: + colour = 'n' + else: + colour = 'y' + if not len(sys.argv) > 1: print("\nfll_cat - prints content of file on standard output\n") print("usage: fll_cat.py [-h] [-i FILE] [-f FORMAT] [-s] [-D] [-e EXTERNAL_FORMAT]\n") @@ -128,4 +158,4 @@ def check_path(path): print ("\033[031m \033[039m \033[032m ffa - ffa format\033[039m") sys.exit() - run(file=file,fmt=format, efmt = eformat, scan=scan, dir=dir) + run(file=file,fmt=format, efmt = eformat, scan=scan, dir=dir, colour=colour) diff --git a/data_util/fll_cat.f90 b/data_util/fll_cat.f90 index 97b4ce5..421808e 100644 --- a/data_util/fll_cat.f90 +++ b/data_util/fll_cat.f90 @@ -80,7 +80,7 @@ SUBROUTINE FLL_CAT(PNODE,IOUNIT,PARENT,FPAR, SCAN, SDIR,ERRMSG,COLOR) END IF IF(.NOT.PRESENT(COLOR))THEN - COL_LOC='Y' + COL_LOC='N' ELSE COL_LOC = COLOR END IF From 217abf9bcc38e5d64667ed07f429c46629f281d1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Fri, 17 Nov 2017 12:29:43 -0700 Subject: [PATCH 313/325] add missing fll_out --- data_util/fll_getndata.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/data_util/fll_getndata.f90 b/data_util/fll_getndata.f90 index 484eccc..442a04f 100644 --- a/data_util/fll_getndata.f90 +++ b/data_util/fll_getndata.f90 @@ -768,6 +768,7 @@ FUNCTION FLL_GETNDATA_L0(PNODE,NAME,NUMBER,FPAR,ERRMSG) RESULT(I0) FPAR%SUCCESS = .FALSE. WRITE(FPAR%MESG,'(A,A,A,A)')'FLL_GETNDATA_L0 - Node ',& TRIM(PNODE%LNAME),' does not contain specified data ',NAME + CALL FLL_OUT(LOC_ERRMSG,FPAR) RETURN END IF From 53c95e3f675fde1cefdfe44af669346723ce88d3 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 22 Nov 2017 07:53:48 -0700 Subject: [PATCH 314/325] fix bug in locate --- data_util/fll_locate.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_util/fll_locate.f90 b/data_util/fll_locate.f90 index 3fd750b..55c3e82 100644 --- a/data_util/fll_locate.f90 +++ b/data_util/fll_locate.f90 @@ -122,7 +122,7 @@ RECURSIVE FUNCTION FLL_LOCATE(PNODE,NAME,LTYPE,DATADIM,NUMBER,RECURSE,FPAR,ERRMS ! ! LOOK FOR NODE ! - IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(PCURR%LNAME) == '*') .AND. & + IF( (TRIM(PCURR%LNAME) == TRIM(NAME) .OR.TRIM(NAME) == '*') .AND. & (TRIM(TLTYPE) == TRIM(PCURR%LTYPE) .OR. TLTYPE(1:1) == '*' ) )THEN NDIM = PCURR%NDIM From 15da3c178829d4b9f619e928ec0626acc0ef6bc1 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 22 Nov 2017 08:02:58 -0700 Subject: [PATCH 315/325] finish fll_sweep --- data_util/depend.mk | 3 ++- data_util/fll_sweep.f90 | 43 +++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/data_util/depend.mk b/data_util/depend.mk index 3ed151e..f45eb2f 100644 --- a/data_util/depend.mk +++ b/data_util/depend.mk @@ -1,7 +1,7 @@ # This file is generated automatically by fort_depend.py. DO NOT EDIT! # # Created by: jiraseka -# Date: 2017-11-15 18:08:21 +# Date: 2017-11-22 14:54:08 # fll_deattach.o : \ @@ -37,6 +37,7 @@ fll_funct_prt.o : \ fll_type.o fll_sweep.o : \ + fll_locate.o \ fll_match_pattern.o \ fll_out.o \ fll_type.o diff --git a/data_util/fll_sweep.f90 b/data_util/fll_sweep.f90 index a10d30a..ef03446 100644 --- a/data_util/fll_sweep.f90 +++ b/data_util/fll_sweep.f90 @@ -45,6 +45,7 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ERRMSG) RESULT(OK) ! USE FLL_TYPE_M USE FLL_OUT_M + USE FLL_LOCATE_M USE FLL_MATCH_PATTERN_M IMPLICIT NONE @@ -107,28 +108,36 @@ RECURSIVE FUNCTION FLL_SWEEP(PNODE,PFIND,NAME,LTYPE,DIM,FPAR,ERRMSG) RESULT(OK) END IF ! ! start loop +! +! if PFIND == NULL get the first child ! IF(.NOT.ASSOCIATED(PFIND))THEN - IF(ASSOCIATED(PNODE%PCHILD))THEN - PFIND => PNODE%PCHILD - ELSE - PFIND => PNODE - END IF - ELSE - PFIND => PFIND%PNEXT - END IF + PFIND => FLL_LOCATE(PNODE,NAME,TLTYPE,DIM,1_LINT,.FALSE. ,FPAR) + IF(ASSOCIATED(PFIND))THEN + OK = .TRUE. + ELSE + END IF + RETURN + ELSE - DO WHILE(ASSOCIATED(PFIND)) + DO WHILE(ASSOCIATED(PFIND)) + + PFIND => PFIND%PNEXT + IF(ASSOCIATED(PFIND))THEN - IF(FLL_MATCH_PATTERN(PFIND,NAME,LTYPE,DIM,FPAR))THEN - OK =.TRUE. - RETURN - END IF - - PFIND => PFIND%PNEXT + IF(FLL_MATCH_PATTERN(PFIND,NAME,LTYPE,DIM,FPAR))THEN + OK =.TRUE. + RETURN + END IF + ELSE + OK =.FALSE. + RETURN + END IF - END DO - + END DO + END IF + + OK =.FALSE. RETURN END FUNCTION FLL_SWEEP From 97eff3845b337a506876da39279ede391f3a61e0 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 27 Nov 2017 09:29:59 -0700 Subject: [PATCH 316/325] sync ERR line numbers --- mpi_util/fll_mpi_proc_struct.f90 | 8 ++++---- mpi_util/fll_mpi_write.f90 | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mpi_util/fll_mpi_proc_struct.f90 b/mpi_util/fll_mpi_proc_struct.f90 index 69265c4..0f5f975 100644 --- a/mpi_util/fll_mpi_proc_struct.f90 +++ b/mpi_util/fll_mpi_proc_struct.f90 @@ -244,7 +244,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR,ERRMSG) END IF ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:230 ' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:247 ' ! ! loop over number of separate files, define which process is going to be ! saving in what file (defined by EVEN_RANK array @@ -340,7 +340,7 @@ SUBROUTINE FLL_NMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,FPAR,ERRMSG) ! free memory ! DEALLOCATE(EVEN_RANK, STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:326 ' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:343 ' RETURN @@ -466,7 +466,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR,ERRMS END IF ALLOCATE(EVEN_RANK(NSTEP), STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:442 ' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:469 ' ! ! loop over number of separate files, define which process is going to be ! saving in what file (defined by EVEN_RANK array @@ -562,7 +562,7 @@ SUBROUTINE FLL_SNMIO_STRUCT(PNODE,NAME_OF_FILE,EXTENSION,NFILES,MODE,FPAR,ERRMS ! free memory ! DEALLOCATE(EVEN_RANK, STAT = IERR) - IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:538 ' + IF(IERR /= 0)STOP' ERROR ALLOCATING MEMORY ==> fll_mpi_proc_struct ERR:565 ' RETURN diff --git a/mpi_util/fll_mpi_write.f90 b/mpi_util/fll_mpi_write.f90 index e119023..9874e89 100644 --- a/mpi_util/fll_mpi_write.f90 +++ b/mpi_util/fll_mpi_write.f90 @@ -155,7 +155,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! subsets #2: are actual data from each process ! ALLOCATE(POS(NPROC+1), DISPL(NPROC+1), STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:148 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:158 ' ! ! get length of each data subset of actual data ! @@ -228,7 +228,7 @@ FUNCTION FLL_MPI_WRITE(PNODE,FILE,IOUNIT,ROOT_RANK, RANK, COMMUNICATOR, OPTION, ! free memory ! DEALLOCATE(POS, DISPL, STAT = ISTAT) - IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:221 ' + IF(ISTAT /= 0)STOP'ERROR ALLOCATING MEMORY ==> fll_mpi_write ERR:231 ' OK = .TRUE. RETURN From f98ab6bd115bb30f2b39db43be8a6ef809a1c051 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 27 Nov 2017 10:45:27 -0700 Subject: [PATCH 317/325] update Makefile for mpif90 command check --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3500734..669fb0b 100644 --- a/Makefile +++ b/Makefile @@ -34,14 +34,14 @@ SUBDIRS= \ data_util\ accessories\ -mpi_util\ -examples\ -miscellaneous\ ifneq ($(strip $(MPI_FC)),) SUBDIRS+= mpi_util endif +SUBDIRS+= examples\ +miscellaneous\ + SUBCLEAN=$(SUBDIRS) ########################################################################### From ef3e654d6fe261093b2dff26ed84b0d3257ba836 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 27 Nov 2017 11:14:04 -0700 Subject: [PATCH 318/325] improve MPIF90 check in Makefiles --- Makefile | 6 +++++- examples/Makefile | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 669fb0b..165e340 100644 --- a/Makefile +++ b/Makefile @@ -31,13 +31,17 @@ -include src_dir_path.mk -include config.mk +MPIF = $(shell command -v mpif90) + SUBDIRS= \ data_util\ accessories\ -ifneq ($(strip $(MPI_FC)),) +ifneq ($(MPI_FC),) +ifneq ($(MPIF),) SUBDIRS+= mpi_util endif +endif SUBDIRS+= examples\ miscellaneous\ diff --git a/examples/Makefile b/examples/Makefile index f9bc514..8c001d3 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -36,16 +36,19 @@ include ../config.mk DEP_FILE=depend.mk +MPIF = $(shell command -v mpif90) + #SUBDIRS= $(dir $(wildcard $(srcdir)/*)) SUBDIRS= \ Simple_data_operation \ Read_Record\ -#ifneq ($(strip $(MPI_FC)),) +#ifneq ($(and $(MPI_FC), $(command -v mpif90)),) ifneq ($(MPI_FC),) - SUBDIRS+= Example_MPI-IO +ifneq ($(MPIF),) + SUBDIRS+= Example_MPI-IO +endif endif - From a03043b536bb0e32faaf1d06fd0bf2f8c2e8f288 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 29 Nov 2017 13:09:48 -0700 Subject: [PATCH 319/325] add comments to file header --- fort_depend.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index f4f41ec..19ca70e 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -22,14 +22,32 @@ #SOFTWARE. # # -# this is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py +# This is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py # done by Adam Jirasek -# the modified version can be found @https://github.com/libm3l/fort_depend.py -# -# this is a script which maked fortran project dependecies -# it is executed in each directory separately and creates a project.dep file with fortran dependencies -# if fortran source uses module from other directory the script will add the module too -# the project root directory is specified as an input parameter with an option -r +# The modified version can be found @https://github.com/libm3l/fort_depend.py +# +# This is a script which makes fortran project dependecies +# Fortran project can have source files located in diffrent subdirectories +# where the common directory (project root directory)is specified as an input parameter with an option -r +# The script is executed in each directory separately and creates a project.dep file with fortran dependencies +# however, while searching modules it will loop over all subdirectories in project root directory +# +# If user wants to specify the search for modules to selected set of subdirectories, +# he/she can use --dep_dir followed by list of selected directories +# +# If -r not specified, the script will use the current working directory and it will search +# for modules in this directory only. +# +# List of all options is: +# -f --files Files to process +# -o --output Output file +# -v -vv -vvv Different level of verbosity contained in standard output +# -w --overwrite Overwrite output file without warning +# -r --root_dir Project root directory +# -d --dep_dir List of selected dependecy directories +# +# For example of how the fortran dependency scritp can be used for larger project see +# FLL linked list utility at https://github.com/libm3l/fll # # import os From 817c4abf0bfcd4d57ff002c596c8ab1c32239873 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 29 Nov 2017 13:22:42 -0700 Subject: [PATCH 320/325] add comments --- fort_depend.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index e9896e7..c88896e 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -22,15 +22,32 @@ #SOFTWARE. # # -# this is a modification of the original script of D Dickinson and Peter Hill -# @https://github.com/ZedThree/fort_depend.py -# -# The modification was done by Adam Jirasek -# the modified version can be found @https://github.com/libm3l/fort_depend.py -# -# the major update is that the dependency script can make dependenies -# from files located in different directories, so it is more suitable -# for bigger project +# This is a modification of the original script of D Dickinson @https://github.com/ZedThree/fort_depend.py +# done by Adam Jirasek +# The modified version can be found @https://github.com/libm3l/fort_depend.py +# +# This is a script which makes fortran project dependecies +# Fortran project can have source files located in diffrent subdirectories +# where the common directory (project root directory)is specified as an input parameter with an option -r +# The script is executed in each directory separately and creates a project.dep file with fortran dependencies +# however, while searching modules it will loop over all subdirectories in project root directory +# +# If user wants to specify the search for modules to selected set of subdirectories, +# he/she can use --dep_dir followed by list of selected directories +# +# If -r not specified, the script will use the current working directory and it will search +# for modules in this directory only. +# +# List of all options is: +# -f --files Files to process +# -o --output Output file +# -v -vv -vvv Different level of verbosity contained in standard output +# -w --overwrite Overwrite output file without warning +# -r --root_dir Project root directory +# -d --dep_dir List of selected dependecy directories +# +# For example of how the fortran dependency scritp can be used for larger project see +# FLL linked list utility at https://github.com/libm3l/fll # # History: # Version Date Author Patch number CLA Comment From 7dd6bb6d80ef475740f27340abfbb8015a079e0f Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Mon, 11 Dec 2017 09:39:18 -0700 Subject: [PATCH 321/325] add latest changes --- fort_depend.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index c88896e..419eff2 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -63,7 +63,8 @@ import fnmatch import os import sys - +from time import gmtime, strftime +import getpass #Definitions @@ -143,6 +144,14 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, print(" ") f=open(outfile,'w') f.write('# This file is generated automatically by fort_depend.py. DO NOT EDIT!\n') +# +# header +# + username = getpass.getuser() + f.write("#\n") + f.write("# Created by: "+username+"\n") + f.write("# Date: "+strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n") + f.write("#\n") for i in dep.keys(): tmp,fil=os.path.split(i) From 9192494fcdb40dfed9dfd658d888a50352acd249 Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 12 Dec 2017 10:50:09 -0700 Subject: [PATCH 322/325] add additional comment lines --- fort_depend.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 419eff2..1d9c444 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -315,6 +315,11 @@ def check_if_there(use,file): if "module" in line.lower(): extrline = line.lower() extrline = extrline.replace("module", "",1) +# +# check that module name on line line (extrline) +# is the same as module name which we are looking fore (defined in USE) +# if yes, we found module, return +# if use.lower().strip() == extrline.strip(): f.close() return 1 @@ -325,6 +330,11 @@ def check_if_there(use,file): if "module" in line.lower(): extrline = line.lower() extrline = extrline.replace("module", "",1) +# +# check that module name on line line (extrline) +# is the same as module name which we are looking fore (defined in USE) +# if yes, we found module, return +# if use.lower().strip() == extrline.strip(): f.close() return 1 @@ -470,7 +480,7 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): istat = 1 except KeyError: # -# module is not, loop through all other files specified in ffiles +# module is not located in the same directory, loop through all other files specified in ffiles # these are files found in function get_all_files # for k in ffiles: From 6b96c38801226c380b32237530a5ce89350c4e7a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 13 Dec 2017 07:56:51 -0700 Subject: [PATCH 323/325] add keywords on module line which should be igored - add keywords on module line which should be igored - change gmtime to local time --- fort_depend.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fort_depend.py b/fort_depend.py index 1d9c444..9c4ef5a 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -65,6 +65,7 @@ import sys from time import gmtime, strftime import getpass +from datetime import datetime #Definitions @@ -150,7 +151,8 @@ def write_depend(verbose,path,cwd,outfile="makefile.dep",dep=[],overwrite=False, username = getpass.getuser() f.write("#\n") f.write("# Created by: "+username+"\n") - f.write("# Date: "+strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n") +# f.write("# Date: "+strftime("%Y-%m-%d %H:%M:%S", gmtime()) + "\n") + f.write("# Date: "+ datetime.now().strftime('%Y-%m-%d %H:%M:%S') + "\n") f.write("#\n") for i in dep.keys(): @@ -309,11 +311,20 @@ def check_if_there(use,file): # "return if you see module name" # make routine to consider version of python installation # + list = ['use', 'program', 'end'] + if sys.version_info < (3,0): with open(file) as f: for line in f: if "module" in line.lower(): extrline = line.lower() +# +# if line with module contains any of the list word +# do not cinsider this line +# + if any(word in extrline for word in list): + continue + extrline = extrline.replace("module", "",1) # # check that module name on line line (extrline) @@ -329,6 +340,13 @@ def check_if_there(use,file): for line in f: if "module" in line.lower(): extrline = line.lower() +# +# if line with module contains any of the list word +# do not cinsider this line +# + if any(word in extrline for word in list): + continue + extrline = extrline.replace("module", "",1) # # check that module name on line line (extrline) From ce53bd94224a1ca44f896a5754fe7f8d2ae48cfb Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Wed, 13 Dec 2017 09:31:46 -0700 Subject: [PATCH 324/325] add status line --- fort_depend.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 9c4ef5a..9b7f829 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -66,6 +66,7 @@ from time import gmtime, strftime import getpass from datetime import datetime +import time, sys #Definitions @@ -85,6 +86,8 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= print(" ") print("\033[031m Making dependencies in \033[032m"+cwd+"\033[039m directory") print(" ") + else: + print(" ") # # get files where to look for modules # if list of preferred directories is specified in dep @@ -94,7 +97,7 @@ def run(path,dep=None,ignore=None,files=None,verbose=None,overwrite=None,output= # files paths is relative to projet root directory path so that if the compillation is done in different directory then # where the source files are located, there are no any prolems with it # - ff=get_all_files(path=path, dep=dep) + ff=get_all_files(path=path, dep=dep) if int(verbose) > 2: print(" ") @@ -240,8 +243,12 @@ def get_all_files(path,dep): # # list only files located in those # + files = 0 + + if not(dep == None): dep.append(currdirr) + for i in dep: # # use basolute path to preferred directories ie.: os.path.abspath(i) @@ -252,6 +259,9 @@ def get_all_files(path,dep): # for filename in filenames: if filename.endswith(('.f', '.f90', '.F', '.F90')): +# files = files + 1 +# status(files) + ## matches.append(os.path.join(root, filename)) ## ## add specified dependency directory location (i) rather then aboslute path @@ -286,6 +296,10 @@ def get_all_files(path,dep): for filename in filenames: if filename.endswith(('.f', '.f90', '.F', '.F90')): + +# files = files + 1 +# status(files) + # matches.append(os.path.join(root, filename)) if(root == currdirr): @@ -374,7 +388,7 @@ def create_file_objs(verbose, files=None, macros={}): print("\033[031m Searching modules for files:\033[039m") print(" ") - + for i in files: source_file = file_obj() @@ -482,10 +496,15 @@ def file_objs_to_mod_dict(file_objs=[]): def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): deps={} istat = 0 + files = 0 for i in fob: if int(verbose) > 1 : print("\033[031m Checking dependency for file: \033[032m"+i.file_name+"\033[039m") + + else: + files = files + 1 + status(files) tmp=[] for j in i.uses: @@ -566,6 +585,14 @@ def get_relative_path_name(file,path,cwd): return fil +def status(i): + width = i + sys.stdout.write(u"\u001b[1000D") # Move left + if(status > 1): + sys.stdout.write(u"\u001b[" + str(0) + "A") # Move up + + print "[" + "#" * width + " " * (25 - width) + "]" + class file_obj: def __init__(self): From b153dfb0824aaf6236b6e4d91ebf75b56c31157a Mon Sep 17 00:00:00 2001 From: Adam Jirasek Date: Tue, 28 May 2019 08:59:39 -0600 Subject: [PATCH 325/325] change output for modules located in different directories --- fort_depend.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fort_depend.py b/fort_depend.py index 9b7f829..79c316c 100755 --- a/fort_depend.py +++ b/fort_depend.py @@ -536,9 +536,8 @@ def get_depends(ignore,verbose,cwd,fob=[],m2f=[], ffiles=[]): tmp.append(name.lower()) if int(verbose) > 2 : - print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m not defined in any file in this directory") - print ("\033[031m \033[039m module found in \033[032m"+name+"\033[039m file") - print ("\033[031m \033[039m adding the module to dependency file, not checking its dependency further \033[032m\033[039m") + print ("\033[031m Note: \033[039m module \033[032m"+j+"\033[039m found in \033[032m"+name+"\033[039m file") + print ("\033[031m \033[039m adding this module to the dependency tree \033[032m\033[039m") break #break loop, dependency declared if istat== 0 and (j != ""): @@ -591,7 +590,7 @@ def status(i): if(status > 1): sys.stdout.write(u"\u001b[" + str(0) + "A") # Move up - print "[" + "#" * width + " " * (25 - width) + "]" +# print "[" + "#" * width + " " * (25 - width) + "]" class file_obj: