diff --git a/.gitignore b/.gitignore index 39daf3416..946f1b4f2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,26 @@ * # Now, whitelist anything that's a directory !*/ +!*/python # whitelist only the files that ever need to be tracked !*.f90 +!*.sh !CHANGELOG !README.md !README.swifter -!Makefile.Defines_example +!*.in +!example/cleanup +!example/swifter_symba_omp +!Makefile +src/*/Makefile +!Makefile.Defines +src/*/Makefile.Defines +!.gitignore +!*.py +!*.ipynb +*ipynb_checkpoints + +#fxdr library !fxdr*/*.c !fxdr*/*.F !fxdr*/*.3f @@ -15,15 +29,50 @@ !fxdr*/*.inc !fxdr*/cxdrreal64 !fxdr*/test.orig.xdr +!fxdr*/test_read_only.xdr !fxdr*/configure/ !fxdr*/README* !fxdr*/Makefile.bak !fxdr*/Makefile.fxdr !fxdr*/Makefile.tmpl !fxdr*/Defines.* -!example/*.in -!example/cleanup -!example/swifter_symba_omp -!Makefile -*/Makefile -!.gitignore + +#collresolve +!collresolve/*.c +!collresolve/*.h +!collresolve/*.py +!collresolve/Makefile.am +!collresolve/configure.ac +!collresolve/cambioni2019/*.h +!collresolve/cambioni2019/*.c +collresolve/config.h + + + +#Documentation +#Disable for now +docs/ +#!docs/* +#!docs/*/* +#!docs/*/*/* + + +python/swiftest/tests/convert_code_type/swift2swifter/pl.swift2swifter.in + +python/swiftest/tests/convert_code_type/swift2swifter/tp.swift2swifter.in + +python/swiftest/tests/convert_code_type/swift2swiftest/cb.swift2swiftest.in + +python/swiftest/tests/convert_code_type/swift2swiftest/pl.swift2swiftest.in + +python/swiftest/tests/convert_code_type/swift2swiftest/tp.swift2swiftest.in + +python/swiftest/tests/convert_code_type/swifter2swiftest/cb.swifter2swiftest.in + +python/swiftest/tests/convert_code_type/cb.swifter2swiftest.in + +python/swiftest/tests/convert_code_type/swifter2swiftest/pl.swifter2swiftest.in + +python/swiftest/tests/convert_code_type/swifter2swiftest/tp.swifter2swiftest.in + +!python/swiftest/requirements.txt diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/Makefile b/Makefile index 690fca337..94dfbceeb 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # # Unit Name : Makefile # Unit Type : makefile -# Project : SWIFTER +# Project : SWIFTEST # Package : N/A # Language : GNU makefile syntax # @@ -18,15 +18,14 @@ # (3) lib : builds entire Swifter library # (4) libdir : compiles local directory source and adds the # resulting objects to the Swifter library -# (5) fxdr : builds FXDR library by invoking its makefile -# (6) drivers : builds Swifter drivers -# (7) tools : builds Swifter tools -# (8) bin : compiles local directory source and installs -# resulting executables to $(SWIFTER_HOME)/bin -# (9) clean : removes all soft links to Makefile and +# (5) drivers : builds Swifter drivers +# (6) tools : builds Swifter tools +# (7) bin : compiles local directory source and installs +# resulting executables to $(SWIFTEST_HOME)/bin +# (8) clean : removes all soft links to Makefile and # Makefile.Defines from subdirectories of -# $(SWIFTER_HOME), removes the entire contents -# of $(SWIFTER_HOME)/lib and $(SWIFTER_HOME)/bin, +# $(SWIFTEST_HOME), removes the entire contents +# of $(SWIFTEST_HOME)/lib and $(SWIFTEST_HOME)/bin, # and removes the include file installed by the # FXDR makefile # Terminal : none @@ -37,7 +36,7 @@ # Terminal : status messages # File : none # -# Invocation : make [all|mod|lib|libdir|fxdr|drivers|tools|bin|clean] +# Invocation : make [all|mod|lib|libdir|drivers|tools|bin|clean] # # Notes : The use of the above arguments as phony targets inside the # makefile precludes their use as base names of Swifter drivers @@ -45,167 +44,178 @@ # #****************************************************************************** -SWIFTER_MODULES = module_parameters.f90 module_swifter.f90 module_bs.f90 \ - module_helio.f90 module_ra15.f90 module_tu4.f90 \ - module_whm.f90 module_rmvs.f90 module_symba.f90 \ - module_fxdr.f90 module_nrutil.f90 module_interfaces.f90 \ - module_random_access.f90 +SWIFTEST_MODULES = swiftest_globals.f90 \ + lambda_function.f90\ + swiftest_classes.f90 \ + swiftest_operators.f90 \ + whm_classes.f90 \ + rmvs_classes.f90 \ + helio_classes.f90 \ + symba_classes.f90 \ + swiftest.f90 + include Makefile.Defines -MODULES = $(SWIFTER_MODULES) $(USER_MODULES) +MODULES = $(SWIFTEST_MODULES) $(USER_MODULES) -.PHONY : all mod lib libdir fxdr drivers tools bin clean force +.PHONY : all mod lib libdir drivers bin clean force % : %.f90 force - $(FORTRAN) $(FFLAGS) -I$(SWIFTER_HOME)/include $< -o $@ \ - -L$(SWIFTER_HOME)/lib -lswifter -lfxdr - $(INSTALL_PROGRAM) $@ $(SWIFTER_HOME)/bin + $(FORTRAN) $(FFLAGS) -I$(SWIFTEST_HOME)/include $< -o $@ \ + -L$(SWIFTEST_HOME)/lib -lswiftest + $(INSTALL_PROGRAM) $@ $(SWIFTEST_HOME)/bin rm -f $@ all: - cd $(SWIFTER_HOME); \ + cd $(SWIFTEST_HOME); \ make mod; \ make lib; \ - make fxdr; \ make drivers; \ - make tools mod: - cd $(SWIFTER_HOME)/module; \ - rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ - $(FORTRAN) $(FFLAGS) -I$(SWIFTER_HOME)/include -c $(MODULES); \ - $(AR) rv $(SWIFTER_HOME)/lib/libswifter.a *.o; \ - $(INSTALL_DATA) *.mod $(SWIFTER_HOME)/include; \ - rm -f *.o *.mod + cd $(SWIFTEST_HOME)/src/modules/; \ + $(FORTRAN) $(FFLAGS) -I$(SWIFTEST_HOME)/include -c $(MODULES); \ + $(AR) rv $(SWIFTEST_HOME)/lib/libswiftest.a *.o; \ + $(INSTALL_DATA) *.mod *.smod $(SWIFTEST_HOME)/include; \ + rm -f *.o *.mod *.smod lib: - cd $(SWIFTER_HOME)/bs; \ + cd $(SWIFTEST_HOME)/src/discard; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/coord; \ + cd $(SWIFTEST_HOME)/src/drift; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/discard; \ + cd $(SWIFTEST_HOME)/src/eucl; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/drift; \ + cd $(SWIFTEST_HOME)/src/fragmentation; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/helio; \ + cd $(SWIFTEST_HOME)/src/gr; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/io; \ + cd $(SWIFTEST_HOME)/src/io; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/obl; \ + cd $(SWIFTEST_HOME)/src/kick; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/orbel; \ + cd $(SWIFTEST_HOME)/src/obl; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/ra15; \ + cd $(SWIFTEST_HOME)/src/operators; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/rmvs; \ + cd $(SWIFTEST_HOME)/src/orbel; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/symba; \ + cd $(SWIFTEST_HOME)/src/setup; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/tu4; \ + cd $(SWIFTEST_HOME)/src/tides; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/util; \ + cd $(SWIFTEST_HOME)/src/util; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTER_HOME)/whm; \ + cd $(SWIFTEST_HOME)/src/whm; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ + make libdir + cd $(SWIFTEST_HOME)/src/rmvs; \ + rm -f Makefile.Defines Makefile; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ + make libdir + cd $(SWIFTEST_HOME)/src/helio; \ + rm -f Makefile.Defines Makefile; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ + make libdir + cd $(SWIFTEST_HOME)/src/symba; \ + rm -f Makefile.Defines Makefile; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ + make libdir + cd $(SWIFTEST_HOME)/src/user; \ + rm -f Makefile.Defines Makefile; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir libdir: - $(FORTRAN) $(FFLAGS) -I$(SWIFTER_HOME)/include -c *.f90 - $(AR) rv $(SWIFTER_HOME)/lib/libswifter.a *.o - rm -f *.o - -fxdr: - cd $(SWIFTER_HOME)/fxdr; \ - rm -f Makefile.Defines; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - make -f Makefile.fxdr; \ - make -f Makefile.fxdr test; \ - make -f Makefile.fxdr install; \ - make -f Makefile.fxdr clean + $(FORTRAN) $(FFLAGS) -I$(SWIFTEST_HOME)/include -c *.f90; \ + $(AR) rv $(SWIFTEST_HOME)/lib/libswiftest.a *.o *.smod; \ + $(INSTALL_DATA) *.smod $(SWIFTEST_HOME)/include; \ + rm -f *.o *.smod -drivers: - cd $(SWIFTER_HOME)/main; \ - rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ - make bin -tools: - cd $(SWIFTER_HOME)/tool; \ +drivers: + cd $(SWIFTEST_HOME)/src/main; \ rm -f Makefile.Defines Makefile; \ - ln -s $(SWIFTER_HOME)/Makefile.Defines .; \ - ln -s $(SWIFTER_HOME)/Makefile .; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ make bin bin: *.f90 make $(basename $^) clean: - cd $(SWIFTER_HOME)/module; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/coord; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/discard; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/drift; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/helio; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/io; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/obl; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/orbel; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/ra15; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/rmvs; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/symba; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/tu4; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/util; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/whm; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/fxdr; rm -f Makefile.Defines *.gc* - cd $(SWIFTER_HOME)/main; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/tool; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTER_HOME)/bin; rm -f swifter_* - cd $(SWIFTER_HOME)/bin; rm -f tool_* - cd $(SWIFTER_HOME)/lib; rm -f lib*.a - cd $(SWIFTER_HOME)/include; rm -f *.mod fxdr.inc + cd $(SWIFTEST_HOME)/src/modules; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/discard; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/drift; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/eucl; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/fragmentation; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/gr; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/helio; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/io; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/kick; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/main; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/obl; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/operators; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/orbel; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/rmvs; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/setup; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/symba; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/tides; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/user; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/util; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/whm; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/bin; rm -f swiftest_* + cd $(SWIFTEST_HOME)/bin; rm -f tool_* + cd $(SWIFTEST_HOME)/lib; rm -f lib* + cd $(SWIFTEST_HOME)/include; rm -f *.mod *.smod + cd $(COLLRESOLVE_HOME); rm -rf autom4te.cache aux Makefile stamp-h1 configure config.status config.h config.log aclocal.m4 lib* *.in *.o *.lo cambioni2019/*.o cambioni2019/*.lo + force: @@ -231,3 +241,5 @@ force: # # #****************************************************************************** + + diff --git a/Makefile.Defines b/Makefile.Defines index 9525dbf9f..291f2c604 100644 --- a/Makefile.Defines +++ b/Makefile.Defines @@ -2,7 +2,7 @@ # # Unit Name : Makefile.Defines # Unit Type : makefile -# Project : SWIFTER +# Project : SWIFTEST # Package : N/A # Language : GNU makefile syntax # @@ -34,56 +34,52 @@ RANLIB = ranlib INSTALL = install INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_DATA = $(INSTALL) -m 644 - +ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) # Swifter definitions -SWIFTER_HOME = /home/daminton/git/swifter-omp +SWIFTEST_HOME = $(ROOT_DIR) USER_MODULES = +COLLRESOLVE_HOME = $(ROOT_DIR)/collresolve/ # Compiler definitions # DO NOT include in FFLAGS the "-c" option to compile object only # this is done explicitly as needed in the Makefile +ADVIXE_DIR = /apps/cent7/intel/advisor_2019 +ADVIXE_FLAGS = -g -O2 -qopt-report=5 -vec -vecabi=cmdtarget -simd -shared-intel -debug inline-debug-info -DTBB_DEBUG -DTBB_USE_THREADING_TOOLS -fp-model no-except -mp1 -xhost -traceback + +VTUNE_FLAGS = -g -O2 -vec -simd -shared-intel -qopenmp -debug inline-debug-info -parallel-source-info=2 -parallel -DTBB_DEBUG -DTBB_USE_THREADING_TOOLS -qopenmp -fp-model no-except -mp1 -xhost -traceback +#Be sure to set the environment variable KMP_FORKJOIN_FRAMES=1 for OpenMP debuging in vtune + +IDEBUG = -O0 -nogen-interfaces -no-pie -no-ftz -fpe-all=0 -g -traceback -mp1 -fp-model strict -fpe0 -debug all -align all -pad -ip -prec-div -prec-sqrt -assume protect-parens -CB -no-wrap-margin -init=snan,arrays +STRICTREAL = -fp-model strict -fp-model no-except -prec-div -prec-sqrt -assume protect-parens +SIMDVEC = -simd -xhost -align all -assume contiguous_assumed_shape -vecabi=cmdtarget -prec-div -prec-sqrt -assume protect-parens +PAR = -parallel -qopenmp +HEAPARR = -heap-arrays 1048576 +OPTIMIZE = -qopt-report=5 + +#gfortran flags +GDEBUG = -g -O0 -fbacktrace -fbounds-check +GPRODUCTION = -O3 +GPAR = -fopenmp -ftree-parallelize-loops=4 +GMEM = -fsanitize=undefined -fsanitize=address -fsanitize=leak +GWARNINGS = -Wall -Warray-bounds -Wimplicit-interface -Wextra -Warray-temporaries -FORTRAN = ifort -FFLAGS = -O3 -qopenmp -132 -align all -pad -ip -fp-model strict -prec-div -prec-sqrt -ftz -assume protect-parens -#FORTRAN = gfortran -#FFLAGS = -O3 -fopenmp +FFLAGS = $(IDEBUG) $(HEAPARR) +#FFLAGS = -init=snan,arrays -no-wrap-margin -O3 $(STRICTREAL) $(SIMDVEC) $(PAR) +FORTRAN = ifort +#AR = xiar + +#FORTRAN = gfortran +#FFLAGS = -ffree-line-length-none $(GDEBUG) $(GMEM) +AR = ar # DO NOT include in CFLAGS the "-c" option to compile object only # this is done explicitly as needed in the Makefile -CC = cc -CFLAGS = -O3 -w -m64 +CC = icc +#CC = cc +CFLAGS = -O3 -w -m64 -std=c99 64_BIT_REALS = -r8 -# FXDR Makefile compatibility - DO NOT ALTER - -F77CMD = $(FORTRAN) -F77OPTS = $(FFLAGS) -CCCMD = $(CC) -CCOPTS = $(CFLAGS) - -#****************************************************************************** -# -# Author(s) : David E. Kaufmann -# -# Revision Control System (RCS) Information -# -# Source File : $RCSfile: Makefile.Defines,v $ -# Full Path : $Source: /d1/kaufmann/development/RCS/Makefile.Defines,v $ -# Revision : $Revision: 0.1 $ -# Date : $Date: 2003/04/15 22:56:57 $ -# Programmer : $Author: kaufmann $ -# Locked By : $Locker: $ -# State : $State: Exp $ -# -# Modification History: -# -# $Log: Makefile.Defines,v $ -# Revision 0.1 2003/04/15 22:56:57 kaufmann -# Initial implementation -# -# -#****************************************************************************** diff --git a/bs/Makefile b/bs/Makefile deleted file mode 120000 index cd21b7edd..000000000 --- a/bs/Makefile +++ /dev/null @@ -1 +0,0 @@ -/Users/daminton/work/Git/swifter-omp/Makefile \ No newline at end of file diff --git a/bs/Makefile.Defines b/bs/Makefile.Defines deleted file mode 120000 index e24f9172a..000000000 --- a/bs/Makefile.Defines +++ /dev/null @@ -1 +0,0 @@ -/Users/daminton/work/Git/swifter-omp/Makefile.Defines \ No newline at end of file diff --git a/bs/bs_bsstep.f90 b/bs/bs_bsstep.f90 deleted file mode 100644 index 9899b7d78..000000000 --- a/bs/bs_bsstep.f90 +++ /dev/null @@ -1,220 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_bsstep -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Take a Bulirsch-Stoer step with monitoring of local truncation error to ensure accuracy and adjust step size -! -! Input -! Arguments : npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! x : independent variable (time) -! htry : step size to be attempted -! eps : local truncation error tolerance -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! derivs : name of subroutine used to compute planet and test particle velocities and accelerations -! Terminal : none -! File : none -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! x : independent variable (time) -! hdid : step size actually accomplished -! hnext : estimated next step size -! Terminal : error message -! File : none -! -! Invocation : CALL bs_bsstep(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, x, htry, eps, hdid, hnext, j2rp2, j4rp4, lextra_force, -! derivs) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1303-5 -! -!********************************************************************************************************************************** -SUBROUTINE bs_bsstep(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, x, htry, eps, hdid, hnext, j2rp2, j4rp4, lextra_force, derivs) - -! Modules - USE module_parameters - USE module_bs - USE module_nrutil - USE module_interfaces, EXCEPT_THIS_ONE => bs_bsstep - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: htry, eps, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: hdid, hnext - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - INTERFACE - SUBROUTINE derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE derivs - END INTERFACE - -! Internals - LOGICAL(LGT) :: reduct - LOGICAL(LGT), SAVE :: first = .TRUE. - INTEGER(I4B), PARAMETER :: IMAX = 9, KMAXX = IMAX - 1 - INTEGER(I4B) :: i, k, km, ndum - INTEGER(I4B), SAVE :: kopt, kmax - INTEGER(I4B), DIMENSION(IMAX) :: nseq = (/ 2, 4, 6, 8, 10, 12, 14, 16, 18 /) - REAL(DP), PARAMETER :: SAFE1 = 0.25_DP, SAFE2 = 0.7_DP - REAL(DP), PARAMETER :: REDMAX = 1.0E-5_DP, REDMIN = 0.7_DP, SCALMX = 0.1_DP - REAL(DP) :: eps1, errmax, fact, h, red, scale, wrkmin, xest - REAL(DP), SAVE :: epsold = -1.0_DP, xnew - REAL(DP), DIMENSION(KMAXX) :: err - REAL(DP), DIMENSION(IMAX), SAVE :: a - REAL(DP), DIMENSION(KMAXX, KMAXX), SAVE :: alf - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - IF (eps /= epsold) THEN - hnext = -1.0E29_DP - xnew = -1.0E29_DP - eps1 = SAFE1*eps - a(:) = cumsum(nseq, 1) - WHERE (upper_triangle(KMAXX, KMAXX)) & - alf = eps1**(outerdiff(a(2:), a(2:))/outerprod(arth(3.0_DP, 2.0_DP, KMAXX), (a(2:) - a(1) + 1.0_DP))) - epsold = eps - DO kopt = 2, KMAXX - 1 - IF (a(kopt+1) > a(kopt)*alf(kopt-1, kopt)) EXIT - END DO - kmax = kopt - END IF - h = htry - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%ysav(:) = bs_plP%y(:) - bs_plP%dydxsav(:) = bs_plP%dydx(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%ysav(:) = bs_tpP%y(:) - bs_tpP%dydxsav(:) = bs_tpP%dydx(:) - bs_tpP => bs_tpP%nextP - END DO - IF (h /= hnext .OR. x /= xnew) THEN - first = .TRUE. - kopt = kmax - END IF - reduct = .FALSE. - MAIN_LOOP: DO - DO k = 1, kmax - xnew = x + h - IF (xnew == x) THEN - WRITE(*, *) "Step size underflow in bs_bsstep" - CALL util_exit(FAILURE) - END IF - CALL bs_mmid(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, x, h, nseq(k), j2rp2, j4rp4, lextra_force, derivs) - xest = (h/nseq(k))**2 - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%yseq(:) = bs_plP%y(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%yseq(:) = bs_tpP%y(:) - bs_tpP => bs_tpP%nextP - END DO - CALL bs_pzextr(k, xest, npl, ntp, bs_pl1P, bs_tp1P) - IF (k /= 1) THEN - errmax = 0.0_DP - bs_plP => bs_pl1P - DO i = 1, npl - errmax = MAX(errmax, MAXVAL(ABS(bs_plP%yerr(:)/bs_plP%yscal(:)))) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - errmax = MAX(errmax, MAXVAL(ABS(bs_tpP%yerr(:)/bs_tpP%yscal(:)))) - bs_tpP => bs_tpP%nextP - END DO - errmax = MAX(TINYBS, errmax)/eps - km = k - 1 - err(km) = (errmax/SAFE1)**(1.0_DP/(2*km + 1)) - END IF - IF (k /= 1 .AND. (k >= kopt - 1 .OR. first)) THEN - IF (errmax < 1.0_DP) EXIT MAIN_LOOP - IF (k == kmax .OR. k == kopt + 1) THEN - red = SAFE2/err(km) - EXIT - ELSE IF (k == kopt) THEN - IF (alf(kopt-1, kopt) < err(km)) THEN - red = 1.0_DP/err(km) - EXIT - END IF - ELSE IF (kopt == kmax) THEN - IF (alf(km, kmax-1) < err(km)) THEN - red = alf(km, kmax-1)*SAFE2/err(km) - EXIT - END IF - ELSE IF (alf(km, kopt) < err(km)) THEN - red = alf(km, kopt-1)/err(km) - EXIT - END IF - END IF - END DO - red = MAX(MIN(red, REDMIN), REDMAX) - h = h*red - reduct = .TRUE. - END DO MAIN_LOOP - x = xnew - hdid = h - first = .FALSE. - kopt = 1 + iminloc(a(2:km+1)*MAX(err(1:km), SCALMX)) - scale = MAX(err(kopt-1), SCALMX) - wrkmin = scale*a(kopt) - hnext = h/scale - IF (kopt >= k .AND. kopt /= kmax .AND. .NOT. reduct) THEN - fact = MAX(scale/alf(kopt-1, kopt), SCALMX) - IF (a(kopt+1)*fact <= wrkmin) THEN - hnext = h/fact - kopt = kopt + 1 - END IF - END IF - - RETURN - -END SUBROUTINE bs_bsstep -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_derivs.f90 b/bs/bs_derivs.f90 deleted file mode 100644 index 65b0cd988..000000000 --- a/bs/bs_derivs.f90 +++ /dev/null @@ -1,92 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_derivs -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Compute time derivatives of positions and velocities of planets and test particles for Bulirsch-Stoer method -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_derivs - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - CALL bs_getaccb(lextra_force, t, npl, nplmax, bs_pl1P, j2rp2, j4rp4) - IF (ntp > 0) CALL bs_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%dydx(1:NDIM) = bs_plP%y(NDIM+1:NDIM2) - bs_plP%dydx(NDIM+1:NDIM2) = bs_plP%ab(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%dydx(1:NDIM) = bs_tpP%y(NDIM+1:NDIM2) - bs_tpP%dydx(NDIM+1:NDIM2) = bs_tpP%ab(:) - bs_tpP => bs_tpP%nextP - END DO - - RETURN - -END SUBROUTINE bs_derivs -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_discard.f90 b/bs/bs_discard.f90 deleted file mode 100644 index f3d5fde26..000000000 --- a/bs/bs_discard.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_discard -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! bs_tpd1P : pointer to head of discard BS test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! bs_tpd1P : pointer to head of discard BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_discard(t, npl, ntp, nsp, bs_pl1P, bs_tp1P, bs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, -! qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_discard(t, npl, ntp, nsp, bs_pl1P, bs_tp1P, bs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P, bs_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(bs_tp), POINTER :: bs_tpP, bs_tpspP - -! Executable code - swifter_pl1P => bs_pl1P%swifter - swifter_tp1P => bs_tp1P%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpspP => bs_tpP - bs_tpP => bs_tpP%nextP - swifter_tpspP => bs_tpspP%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL bs_discard_spill(ntp, nsp, bs_tp1P, bs_tpd1P, bs_tpspP) - END DO - - RETURN - -END SUBROUTINE bs_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_discard_spill.f90 b/bs/bs_discard_spill.f90 deleted file mode 100644 index efb861196..000000000 --- a/bs/bs_discard_spill.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) BS test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! bs_tpd1P : pointer to head of discard BS test particle structure linked-list -! bs_tpspP : pointer to BS test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! bs_tpd1P : pointer to head of discard BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_discard_spill(ntp, nsp, bs_tp1P, bs_tpd1P, bs_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_discard_spill(ntp, nsp, bs_tp1P, bs_tpd1P, bs_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(bs_tp), POINTER :: bs_tp1P, bs_tpd1P, bs_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - swifter_tpspP => bs_tpspP%swifter - IF (nsp == 0) THEN - bs_tpd1P => bs_tpspP - ELSE - bs_tpP => bs_tpd1P - DO i = 1, nsp - 1 - bs_tpP => bs_tpP%nextP - END DO - bs_tpP%nextP => bs_tpspP - bs_tpP%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(bs_tpspP%prevP)) THEN - bs_tpspP%prevP%nextP => bs_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - bs_tp1P => bs_tpspP%nextP - END IF - IF (ASSOCIATED(bs_tpspP%nextP)) THEN - bs_tpspP%nextP%prevP => bs_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(bs_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - bs_tpspP%prevP => bs_tpP - swifter_tpspP%prevP => bs_tpP%swifter - END IF - NULLIFY(bs_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE bs_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_getaccb.f90 b/bs/bs_getaccb.f90 deleted file mode 100644 index 163004388..000000000 --- a/bs/bs_getaccb.f90 +++ /dev/null @@ -1,124 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of planets -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! bs_pl1P : pointer to head of BS planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_getaccb(lextra_force, t, npl, nplmax, bs_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb.f -! -!********************************************************************************************************************************** -SUBROUTINE bs_getaccb(lextra_force, t, npl, nplmax, bs_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_getaccb - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: mu, r2, ir3 - REAL(DP), DIMENSION(NDIM) :: dx, acc - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_pliP, swifter_pljP - TYPE(bs_pl), POINTER :: bs_pliP, bs_pljP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - bs_pl1P%ab(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - mu = bs_pl1P%swifter%mass - bs_pliP => bs_pl1P - DO i = 2, npl - bs_pliP => bs_pliP%nextP - swifter_pliP => bs_pliP%swifter - dx(:) = bs_pl1P%y(1:NDIM) - bs_pliP%y(1:NDIM) - xh(:, i) = -dx(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - irh(i) = 1.0_DP/SQRT(r2) - ir3 = irh(i)/r2 - acc(:) = ir3*dx(:) - bs_pl1P%ab(:) = bs_pl1P%ab(:) - swifter_pliP%mass*acc(:) - bs_pliP%ab(:) = mu*acc(:) - END DO - bs_pliP => bs_pl1P - DO i = 2, npl - 1 - bs_pliP => bs_pliP%nextP - swifter_pliP => bs_pliP%swifter - bs_pljP => bs_pliP - DO j = i + 1, npl - bs_pljP => bs_pljP%nextP - swifter_pljP => bs_pljP%swifter - dx(:) = bs_pliP%y(1:NDIM) - bs_pljP%y(1:NDIM) - r2 = DOT_PRODUCT(dx(:), dx(:)) - ir3 = 1.0_DP/(r2*SQRT(r2)) - acc(:) = ir3*dx(:) - bs_pliP%ab(:) = bs_pliP%ab(:) - swifter_pljP%mass*acc(:) - bs_pljP%ab(:) = bs_pljP%ab(:) + swifter_pliP%mass*acc(:) - END DO - END DO - IF (j2rp2 /= 0.0_DP) THEN - swifter_pl1P => bs_pl1P%swifter - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - bs_pliP => bs_pl1P - DO i = 1, npl - bs_pliP%ab(:) = bs_pliP%ab(:) + aobl(:, i) - bs_pliP => bs_pliP%nextP - END DO - END IF - IF (lextra_force) CALL bs_user_getaccb(t, npl, bs_pl1P) - - RETURN - -END SUBROUTINE bs_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_getaccb_tp.f90 b/bs/bs_getaccb_tp.f90 deleted file mode 100644 index 287cf972d..000000000 --- a/bs/bs_getaccb_tp.f90 +++ /dev/null @@ -1,119 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of test particles -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE bs_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_getaccb_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(NDIM) :: dx, xsun - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%ab(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - bs_plP => bs_pl1P - DO j = 1, npl - dx(:) = bs_tpP%y(1:NDIM) - bs_plP%y(1:NDIM) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = bs_plP%swifter%mass/(r2*SQRT(r2)) - bs_tpP%ab(:) = bs_tpP%ab(:) - fac*dx(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tpP%nextP - END DO - IF (j2rp2 /= 0.0_DP) THEN - IF (lmalloc) THEN - ALLOCATE(xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - xsun(:) = bs_pl1P%y(1:NDIM) - mu = bs_pl1P%swifter%mass - bs_tpP => bs_tp1P - DO i = 1, ntp - xht(:, i) = bs_tpP%y(1:NDIM) - xsun(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - bs_tpP => bs_tpP%nextP - END DO - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%ab(:) = bs_tpP%ab(:) + aoblt(:, i) - bs_tpP => bs_tpP%nextP - END DO - END IF - IF (lextra_force) CALL bs_user_getaccb_tp(t, ntp, bs_tp1P) - - RETURN - -END SUBROUTINE bs_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_mmid.f90 b/bs/bs_mmid.f90 deleted file mode 100644 index f731a301d..000000000 --- a/bs/bs_mmid.f90 +++ /dev/null @@ -1,143 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_mmid -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Perform a modified midpoint step to advance planet and test particle positions and velocities one time step -! -! Input -! Arguments : npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! xs : independent variable (time) -! htot : total time step to take -! nstep : number of substeps to use -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! derivs : name of subroutine used to compute planet and test particle velocities and accelerations -! Terminal : none -! File : none -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_mmid(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, xs, htot, nstep, j2rp2, j4rp4, lextra_force, derivs) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1302-3 -! -!********************************************************************************************************************************** -SUBROUTINE bs_mmid(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, xs, htot, nstep, j2rp2, j4rp4, lextra_force, derivs) - -! Modules - USE module_parameters - USE module_bs - USE module_nrutil - USE module_interfaces, EXCEPT_THIS_ONE => bs_mmid - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax, nstep - REAL(DP), INTENT(IN) :: xs, htot, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - INTERFACE - SUBROUTINE derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE derivs - END INTERFACE - -! Internals - INTEGER(I4B) :: i, n, ndum - REAL(DP) :: h, h2, x - REAL(DP), DIMENSION(NDIM2) :: dum - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - h = htot/nstep - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%ym(:) = bs_plP%ysav(:) - bs_plP%y(:) = bs_plP%ym(:) + h*bs_plP%dydxsav(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%ym(:) = bs_tpP%ysav(:) - bs_tpP%y(:) = bs_tpP%ym(:) + h*bs_tpP%dydxsav(:) - bs_tpP => bs_tpP%nextP - END DO - x = xs + h - CALL derivs(lextra_force, x, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - h2 = 2.0_DP*h - DO n = 2, nstep - bs_plP => bs_pl1P - DO i = 1, npl - dum(:) = bs_plP%ym(:) - bs_plP%ym(:) = bs_plP%y(:) - bs_plP%y(:) = dum(:) - bs_plP%y(:) = bs_plP%y(:) + h2*bs_plP%dydx(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - dum(:) = bs_tpP%ym(:) - bs_tpP%ym(:) = bs_tpP%y(:) - bs_tpP%y(:) = dum(:) - bs_tpP%y(:) = bs_tpP%y(:) + h2*bs_tpP%dydx(:) - bs_tpP => bs_tpP%nextP - END DO - x = x + h - CALL derivs(lextra_force, x, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - END DO - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%y(:) = 0.5_DP*(bs_plP%ym(:) + bs_plP%y(:) + h*bs_plP%dydx(:)) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%y(:) = 0.5_DP*(bs_tpP%ym(:) + bs_tpP%y(:) + h*bs_tpP%dydx(:)) - bs_tpP => bs_tpP%nextP - END DO - - RETURN - -END SUBROUTINE bs_mmid -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_pzextr.f90 b/bs/bs_pzextr.f90 deleted file mode 100644 index 40f4283f0..000000000 --- a/bs/bs_pzextr.f90 +++ /dev/null @@ -1,144 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_pzextr -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Use polynomial extrapolation to evaluate the positions and velocities of planets and test particles across a -! full time step using an effectively infinitesimal substep by fitting a polynomial to a sequence of estimates -! with progressively smaller substep values -! -! Input -! Arguments : iest : number of the current estimate in the sequence -! xest : substep size for the current estimate -! npl : number of planets -! ntp : number of active test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL bs_pzextr(iest, xest, npl, ntp, bs_pl1P, bs_tp1P) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1305-6 -! -!********************************************************************************************************************************** -SUBROUTINE bs_pzextr(iest, xest, npl, ntp, bs_pl1P, bs_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_pzextr - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: iest, npl, ntp - REAL(DP), INTENT(IN) :: xest - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: delta, f1, f2 - REAL(DP), DIMENSION(NDIM2) :: d, tmp, q - REAL(DP), DIMENSION(IEST_MAX), SAVE :: x - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - IF (iest > IEST_MAX) THEN - WRITE(*, *) "bs_pzextr: probable misuse, too much extrapolation" - CALL util_exit(FAILURE) - END IF - x(iest) = xest - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%yerr(:) = bs_plP%yseq(:) - bs_plP%y(:) = bs_plP%yseq(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%yerr(:) = bs_tpP%yseq(:) - bs_tpP%y(:) = bs_tpP%yseq(:) - bs_tpP => bs_tpP%nextP - END DO - IF (iest == 1) THEN - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%qcol(:, 1) = bs_plP%yseq(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%qcol(:, 1) = bs_tpP%yseq(:) - bs_tpP => bs_tpP%nextP - END DO - ELSE - bs_plP => bs_pl1P - DO i = 1, npl - d(:) = bs_plP%yseq(:) - DO j = 1, iest - 1 - delta = 1.0_DP/(x(iest-j) - xest) - f1 = xest*delta - f2 = x(iest-j)*delta - q(:) = bs_plP%qcol(:, j) - bs_plP%qcol(:, j) = bs_plP%yerr(:) - tmp(:) = d(:) - q(:) - bs_plP%yerr(:) = f1*tmp(:) - d(:) = f2*tmp(:) - bs_plP%y(:) = bs_plP%y(:) + bs_plP%yerr(:) - END DO - bs_plP%qcol(:, iest) = bs_plP%yerr(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - d(:) = bs_tpP%yseq(:) - DO j = 1, iest - 1 - delta = 1.0_DP/(x(iest-j) - xest) - f1 = xest*delta - f2 = x(iest-j)*delta - q(:) = bs_tpP%qcol(:, j) - bs_tpP%qcol(:, j) = bs_tpP%yerr(:) - tmp(:) = d(:) - q(:) - bs_tpP%yerr(:) = f1*tmp(:) - d(:) = f2*tmp(:) - bs_tpP%y(:) = bs_tpP%y(:) + bs_tpP%yerr(:) - END DO - bs_tpP%qcol(:, iest) = bs_tpP%yerr(:) - bs_tpP => bs_tpP%nextP - END DO - END IF - - RETURN - -END SUBROUTINE bs_pzextr -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_setup.f90 b/bs/bs_setup.f90 deleted file mode 100644 index 4db70829f..000000000 --- a/bs/bs_setup.f90 +++ /dev/null @@ -1,133 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_setup -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Set up pointers within BS and Swifter planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! bs_plA : BS planet structure array -! bs_tpA : BS test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : bs_plA : BS planet structure array -! bs_tpA : BS test particle structure array -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_setup(npl, ntp, bs_plA, bs_tpA, bs_pl1P, bs_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_setup(npl, ntp, bs_plA, bs_tpA, bs_pl1P, bs_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(bs_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: bs_plA - TYPE(bs_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: bs_tpA - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - bs_pl1P => bs_plA(1) - swifter_pl1P => bs_plA(1)%swifter - NULLIFY(bs_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(bs_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - bs_pl1P%nextP => bs_plA(2) - swifter_pl1P%nextP => bs_plA(2)%swifter - DO i = 2, npl - 1 - bs_plA(i)%prevP => bs_plA(i-1) - bs_plA(i)%nextP => bs_plA(i+1) - swifter_plP => bs_plA(i)%swifter - swifter_plP%prevP => bs_plA(i-1)%swifter - swifter_plP%nextP => bs_plA(i+1)%swifter - END DO - bs_plA(npl)%prevP => bs_plA(npl-1) - bs_plP => bs_plA(npl) - NULLIFY(bs_plP%nextP) - swifter_plP => bs_plA(npl)%swifter - swifter_plP%prevP => bs_plA(npl-1)%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(bs_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - bs_tp1P => bs_tpA(1) - swifter_tp1P => bs_tpA(1)%swifter - NULLIFY(bs_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(bs_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - bs_tp1P%nextP => bs_tpA(2) - swifter_tp1P%nextP => bs_tpA(2)%swifter - DO i = 2, ntp - 1 - bs_tpA(i)%prevP => bs_tpA(i-1) - bs_tpA(i)%nextP => bs_tpA(i+1) - swifter_tpP => bs_tpA(i)%swifter - swifter_tpP%prevP => bs_tpA(i-1)%swifter - swifter_tpP%nextP => bs_tpA(i+1)%swifter - END DO - bs_tpA(ntp)%prevP => bs_tpA(ntp-1) - bs_tpP => bs_tpA(ntp) - NULLIFY(bs_tpP%nextP) - swifter_tpP => bs_tpA(ntp)%swifter - swifter_tpP%prevP => bs_tpA(ntp-1)%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE bs_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_step.f90 b/bs/bs_step.f90 deleted file mode 100644 index c4bc4c3bc..000000000 --- a/bs/bs_step.f90 +++ /dev/null @@ -1,146 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_step -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : eps : local truncation error control parameter -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! bs_pl1P : pointer to head of BS planet structure linked-list -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL bs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine bs_step.f -! -!********************************************************************************************************************************** -SUBROUTINE bs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: x, h, hdid, hnext, msys - REAL(DP), SAVE :: eps - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpP - TYPE(bs_pl), POINTER :: bs_plP - TYPE(bs_tp), POINTER :: bs_tpP - -! Executable code - swifter_pl1P => bs_pl1P%swifter - swifter_tp1P => bs_tp1P%swifter - IF (lfirst) THEN - WRITE(*, 100, ADVANCE = "NO") "Enter the value of eps: " - 100 FORMAT(A) - READ(*, *) eps - WRITE(*, *) " eps = ", eps - CALL coord_h2b(npl, swifter_pl1P, msys) - CALL coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - bs_plP => bs_pl1P - DO i = 1, npl - swifter_plP => bs_plP%swifter - bs_plP%y(1:NDIM) = swifter_plP%xb(:) - bs_plP%y(NDIM+1:NDIM2) = swifter_plP%vb(:) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - swifter_tpP => bs_tpP%swifter - bs_tpP%y(1:NDIM) = swifter_tpP%xb(:) - bs_tpP%y(NDIM+1:NDIM2) = swifter_tpP%vb(:) - bs_tpP => bs_tpP%nextP - END DO - lfirst = .FALSE. - END IF - x = t - h = dt - DO WHILE ((ABS(x - t - dt)/dt) > DELTABS) - CALL bs_derivs(lextra_force, x, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - bs_plP => bs_pl1P - DO i = 1, npl - bs_plP%yscal(:) = ABS(bs_plP%y(:)) + ABS(h*bs_plP%dydx(:)) + TINYBS - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - bs_tpP%yscal(:) = ABS(bs_tpP%y(:)) + ABS(h*bs_tpP%dydx(:)) + TINYBS - bs_tpP => bs_tpP%nextP - END DO - IF ((x + h - t - dt)*(x + h - t) > 0.0_DP) h = t + dt - x - CALL bs_bsstep(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, x, h, eps, hdid, hnext, j2rp2, j4rp4, lextra_force, bs_derivs) - h = hnext - END DO - bs_plP => bs_pl1P - DO i = 1, npl - swifter_plP => bs_plP%swifter - swifter_plP%xb(:) = bs_plP%y(1:NDIM) - swifter_plP%vb(:) = bs_plP%y(NDIM+1:NDIM2) - bs_plP => bs_plP%nextP - END DO - bs_tpP => bs_tp1P - DO i = 1, ntp - swifter_tpP => bs_tpP%swifter - swifter_tpP%xb(:) = bs_tpP%y(1:NDIM) - swifter_tpP%vb(:) = bs_tpP%y(NDIM+1:NDIM2) - bs_tpP => bs_tpP%nextP - END DO - CALL coord_b2h(npl, swifter_pl1P) - CALL coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) - - RETURN - -END SUBROUTINE bs_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_user_getaccb.f90 b/bs/bs_user_getaccb.f90 deleted file mode 100644 index bc9d71dc3..000000000 --- a/bs/bs_user_getaccb.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_user_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! bs_pl1P : pointer to head of BS planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : bs_pl1P : pointer to head of BS planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL bs_user_getaccb(t, npl, bs_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_user_getaccb(t, npl, bs_pl1P) - -! Modules - USE module_parameters - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_user_getaccb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(bs_pl), POINTER :: bs_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE bs_user_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/bs/bs_user_getaccb_tp.f90 b/bs/bs_user_getaccb_tp.f90 deleted file mode 100644 index 5b92c9180..000000000 --- a/bs/bs_user_getaccb_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : bs_user_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : bs -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : bs_tp1P : pointer to head of active BS test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL bs_user_getaccb_tp(t, ntp, bs_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE bs_user_getaccb_tp(t, ntp, bs_tp1P) - -! Modules - USE module_parameters - USE module_bs - USE module_interfaces, EXCEPT_THIS_ONE => bs_user_getaccb_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(bs_tp), POINTER :: bs_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE bs_user_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/collresolve/.gitignore b/collresolve/.gitignore new file mode 100644 index 000000000..0a49fe99d --- /dev/null +++ b/collresolve/.gitignore @@ -0,0 +1,20 @@ +.deps +.libs +aclocal.m4 +autom4te.cache +aux +build +cambioni2019/.dirstamp +config.h +config.h.in +config.h.in~ +config.log +config.status +configure +libtool +Makefile +Makefile.in +stamp-h1 +*.la +*.lo +*.o diff --git a/collresolve/Makefile.am b/collresolve/Makefile.am new file mode 100644 index 000000000..881253d86 --- /dev/null +++ b/collresolve/Makefile.am @@ -0,0 +1,5 @@ +lib_LTLIBRARIES = libcollresolve.la + +include_HEADERS = collresolve.h + +libcollresolve_la_SOURCES = collresolve.c collresolve_for.c cambioni2019/accretion_efficiency.c cambioni2019/collision_classifier.c cambioni2019/orbital_hnr.c diff --git a/collresolve/README.md b/collresolve/README.md new file mode 100644 index 000000000..521355c98 --- /dev/null +++ b/collresolve/README.md @@ -0,0 +1,137 @@ +**collresolve** is a library designed to provide collision analysis and handling for N-body codes. + +The library has interfaces for the following languages: +* C/C++ +* Fortran +* Python + +## Installation + +### C/C++/Fortran + +The installation of the C/C++/Fortran library using the standard `./configure`, `make` and `make install` commands. + +The repository does not provide the `configure` script. If installing directly from the repository, the file must be created first. The easiest way to do this is executing `autoreconf --install` command which will create the `configure` script and its dependencies. This command requires the [GNU autoconf](http://www.gnu.org/software/autoconf) tool. In this situation, the commands to execute are: +``` +autoreconf --install +./configure +make +make install +``` + +As for other packages, you may want to execute `./configure --help` to see which options are available and tune that command to your needs, e.g. by changing the location where the library will be installed using the `--prefix=PATH` option. + +### Linking + +If the library has been installed in a non-standard part, then the paths to the header files and library object files must be provided to the compiler and linker calls. Hereafter, we assume that the base location of the library is `PREFIX`, which is the value of the `--prefix` argument to `./configure` call. + +The public interface of the library for the C/C++ languages is provided in the `collresolve.h` file. In case the path must be provided, then the argument `-IPREFIX/include` must be added to the compiler commands of files that make use of `collresolve.h`. + +To use the library, the argument `-lcollresolve` is to be provided to the linking command. In case the library is in a non-standard directory, the path can be provided using `-LPREFIX/lib` argument. + +The Fortran interface is tailored to use with the `mercury` package. + +### Python + +From a checkout of the repository, the Python module can be easily built and installed by the executing the following commands: +``` +python setup.py build +python setup.py install +``` + +In case the library is to be installed for the current user only, then the `--user` argument can be provided to the `install` command. + +This will put the Python module in a location where is it readily available. No further action is needed. + +## Usage + +To use most of the library, a configuration object must be created and set first. The configuration object contains essential parameters for the calls, such as the collision model to determine the outcome of collisions and the unit system in use. The object must not be accessed directly, but the functions `collresolve_conf_*` should be used instead to alter its state. + +### Python + +An example of usage of the library is provided in the `example.py` file. + +### Mercury + +To use the library with the `mercury`, the following modifications to the code of the latter are needed. When compiling the code, the additional flags described above to link the executable to the library are required. + +In the `mce_coll` subroutine, near the end, in lieu of the part +``` +c +c Do the collision (inelastic merger) + call mce_merg (jcen,i,j,nbod,nbig,m,xh,vh,s,stat,elost, + % nsetup) +``` +the code should be changed to something like +``` + if (opt(2).eq.2 .and. i.gt.1 .and. j.gt.1) then + model = 4 + nres = 2 + + regime = collresolve_resolve(model, m(i) / K2, m(j) / K2, + % rphys(i), rphys(j), xh(:,i), xh(:,j), vh(:,i), vh(:,j), nres, + % mres, rres, pres, vres) + + if (regime .lt. 0) then + ! An error occurred + ! Do not do anything. + else if (mres(1) .lt. 1.d-3 / (1047.d0 * 317.8d0)) then + stat(i) = -2 + stat(j) = -2 + xh(:,j) = -xh(:,j) + vh(:,j) = -vh(:,j) + else if (mres(2) .lt. 1.d-3 / (1047.d0 * 317.8d0)) then + m(i) = mres(1) * K2 + rphys(i) = rres(1) + xh(:,i) = pres(:,1) + vh(:,i) = vres(:,1) + stat(j) = -2 + xh(:,j) = -xh(:,j) + vh(:,j) = -vh(:,j) + else + m(i) = mres(1) * K2 + m(j) = mres(2) * K2 + rphys(i) = rres(1) + rphys(j) = rres(2) + xh(:,i) = pres(:,1) + xh(:,j) = pres(:,2) + vh(:,i) = vres(:,1) + vh(:,j) = vres(:,2) + end if + else +c +c Do the collision (inelastic merger) + call mce_merg (jcen,i,j,nbod,nbig,m,xh,vh,s,stat,elost, + % nsetup) + end if +``` +with the following new variables at the beginning of the subroutine +``` + real*8 mres(3),rres(3),pres(3,3),vres(3,3) + integer nres,model,regime,collresolve_resolve +``` +There are a few items to be noted with the above code: +* The library is only called when the flag about using the "fragmentation" mode in the parameters file is enabled. This allows to easily perform comparison run with mercury's standard merging algorithm with having to re-compile the code. +* The value of the `model` variable should be adjusted to which model the library is to use to resolve the collisions. The possible values are given in the `collresolve_model` enummeration in `collresolve.h`. The value provided in this code snippet, `4`, tells the library to use Cambioni et al. (2019) model. +* It implements a minimum mass cutoff for the remnants, with a value to 1/1000 of an Earth mass (the factor 1047 * 317.8 being the conversion to solar mass that Mercury uses as the mass unit). + +While the above codes sets the correct radii on return, these will be ignored in a standard version of the `mercury` package. In effect, this will assume a constant density for each body. In case the model 4 (Cambioni et al. 2019) is used, a further modification is needed so that the bodies have a consistent radius with the bodies that were used to generate the model. To achieve this, the code setting the physical radius in `mce_init` should be changed from `rphys(j)=hill(j)/a(j)*(temp/rho(j))**THIRD` to `rphys(j) = collresolve_radius(4, m(j) / K2)` while adding `real*8 collresolve_radius` in the definitions of that subroutine. This will make mercury use the library's mass-radius relation for all bodies (both at the beginning of the simulation and after a collision), except for the central body. In effect, this makes the `d` parameter in the input file useless. + +## License + +The library is licensed under version 2.0 of the Apache License, see the `LICENSE` file for the full terms and conditions. + +## Citations + +If you use this library in a scientific work that lead to publication, we would like you to acknowledge the following article: +* Emsenhuber, A., Cambioni S., Asphaug, E., Gabriel, T. S. J., Schwartz, S. R., and Furfaro, R. (subm.). Realistic On-the-fly Outcomes of Planetary Collisions II: Bringing Machine Learning to N-body Simulations. **The Astrophysical Journal**. + +If you use the `LS2012` model, you should also cite: + * Leinhardt, Z. M. and Stewart, S. T. (2012). Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling Laws. **The Astrophysical Journal**, 745(1), 79. [doi:10.1088/0004-637X/745/1/79](https://doi.org/10.1088/0004-637X/745/1/79) [bib:2012ApJ...745...79L](https://ui.adsabs.harvard.edu/abs/2012ApJ...745...79L) + +If you use the `SL2012` model, you should also cite the same publication as for `LS2012`, and: + * Stewart, S. T. and Leinhardt, Z. M. (2012). Collisions between Gravity-dominated Bodies. II. The Diversity of Impact Outcomes during the End Stage of Planet Formation. **The Astrophysical Journal**, 751(1), 32. [doi:10.1088/0004-637X/751/1/32](https://doi.org/10.1088/0004-637X/751/1/32) [bib:2012ApJ...751...32S](https://ui.adsabs.harvard.edu/abs/2012ApJ...751...32S) + * Genda, H., Kokubo, E., and Ida, S. (2012). Merging Criteria for Giant Impacts of Protoplanets. **The Astrophysical Journal**, 744(2), 137. [doi:10.1088/0004-637X/744/2/137](https://doi.org/10.1088/0004-637X/744/2/137) [bib:2012ApJ...744..137G](https://ui.adsabs.harvard.edu/abs/2012ApJ...744..137G) + +If you use the `C2019` model, you should also cite: + * Cambioni, S., Asphaug, E., Emsenhuber, A., Gabriel, T. S. J., Furfaro, R., and Schwartz, S. R. (2019). Realistic On-the-fly Outcomes of Planetary Collisions: Machine Learning Applied to Simulations of Giant Impacts. **The Astrophysical Journal**, 875(1), 40. doi:[10.3847/1538-4357/ab0e8a](https://doi.org/10.3847/1538-4357/ab0e8a) [bib:2019ApJ...875...40C](https://ui.adsabs.harvard.edu/abs/2019ApJ...875...40C) diff --git a/collresolve/cambioni2019/accretion_efficiency.c b/collresolve/cambioni2019/accretion_efficiency.c new file mode 100644 index 000000000..7b4f407d4 --- /dev/null +++ b/collresolve/cambioni2019/accretion_efficiency.c @@ -0,0 +1,125 @@ +/** + * Implementation of the orbital elements Neural Network + * for the Cambioni et al. (2019) model. + * + * Copyright (c) 2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file + * @author Alexandre Emsenhuber + * @author Saverio Cambioni + */ + +#include + +#include "accretion_efficiency.h" + +/** + * Neural network predicting the mass of the two largest remnants in a giant impact. + * + * @param X predictors. Array of 4 values: + * - log10( mass of the target / Earth mass ) + * - ratio mass projectile / mass target + * - impact angle [degree] + * - ration impact velocity / escape velocity + * + * @param Y output. Array of 2 values: + * - accretion efficiency of the largest remnant + * - accretion efficiency of the second remnant + */ +void accretion_efficiency( const double X[4], double Y[2] ) { + static const double bi[ 4 ] = { -2.0, 0.1, 0.1, 1.0 }; + static const double ai[ 4 ] = { 1.0, 3.33333333333333, 0.0223713646532438, 0.666666666666667 }; + + double v1[ 4 ]; + + static const double a1[ 4 ][ 10 ] = { + { -0.99259839053989929, 0.449187477909109, 0.075714686288260766, -0.020452590896203708, -0.58210516295726789, -0.013375250174277573, -0.48230946052460555, 0.16155327325554553, 0.10059744565500377, 0.13487202760093472 }, + { -0.54850611624671042, -1.734400064893842, 0.12915537201987323, 0.51316347585462074, -1.8203395764481449, -1.3335444899051745, -1.3867410094961816, -0.052339441637571961, 0.036215339838831268, 1.207085191429994 }, + { -0.74716820627104474, 1.2785409210221961, 1.2652684857190708, 2.3907390150920693, -0.027941098981490296, 1.1616118117854528, 1.1396670154660771, 1.4257102657167255, 0.87383172088677019, 1.3677821392485054 }, + { -1.4700873121241802, -0.31715783969951872, 2.3291763959280321, -0.69301858150785567, 0.927299850211842, 1.6777369443192311, 1.0506189979021969, 3.18380459684492, -2.329702148199758, -0.75080966510173219 } + }; + static const double b1[ 10 ] = { 2.6073917552308483, -1.0543123438098263, 0.96084184343995738, 0.69887250663650113, -0.98100464756141359, -0.906472183922059, -1.1101160800828256, 2.8254372986637817, -2.9400814516311091, 1.9583962053001855 }; + + double v2[ 10 ]; + + static const double a2[ 10 ][ 7 ] = { + { -0.87990456358613534, 0.335543031246743, 0.3581652750145079, 0.58460887529764316, -0.45423132008533629, 0.64895072596147585, -0.021596476946219717 }, + { 0.22475402459940549, -0.17485625690465434, -0.67256888021927785, -0.11002848850414457, 0.14385499031001098, 0.013825160492508339, 0.39563080034309944 }, + { 2.1447041514117435, 1.0671671005511982, -0.68997027346305106, -0.27342197218341729, 1.1158837017809888, 1.4084051655938017, -0.61034530498228023 }, + { 0.56030858631123337, 2.0206686741989626, 1.0360206955111424, -1.3364754692561343, 0.91162901010430253, 0.7376073950802593, 0.67893901758448283 }, + { 0.74389027973146282, 0.048848059692643719, -0.626257013955689, 0.84295465866421748, -0.11000121156688385, 0.61945691827036709, 0.562156280988821 }, + { 1.3382486343175444, -0.20922932495558832, 0.38144254432319952, -0.52674278682366749, 0.2243971147692253, 0.016630541015777888, -0.24014117875728225 }, + { -1.0718243092718496, 0.24617839735881439, 0.24867754258386898, -0.81352902234736746, 0.17254616035570938, -0.020410456814524996, 0.068276600591814229 }, + { -0.72208026395591307, 2.4518440419430951, -0.65330625662048869, -0.58097734345701046, 0.78955639574419723, -0.824353140870295, -0.33162033495057408 }, + { -2.8858350457936264, -1.7494915582502779, -0.79025917768403275, -0.18106778121125583, -1.7844260497243247, -0.47059907849077875, 0.1609032536893332 }, + { 0.46928043044999546, -0.60635394949707533, -0.20210050646504393, -0.7942878116668044, -0.48335886235441328, 0.087153327942112557, 0.74539974921278862 } + }; + static const double b2[ 7 ] = { 1.9419204301505677, -2.3602001842178129, 0.063446988508151655, 1.0048637842885846, -0.55849965456441653, 1.5882132856273441, 2.4891174723212859 }; + + double v3[ 7 ]; + + static const double a3[ 7 ][ 2 ] = { + { -0.34035179476411376, 2.0954445444771603 }, + { -0.29216640695761847, 1.3584206111291943 }, + { 0.030079636529542306, 0.36228562742969384 }, + { -1.731732654101318E-5, -0.60968713698202848 }, + { 0.12300830290120388, -0.97034128143693188 }, + { 0.31073727469560125, -0.90262887636934974 }, + { 1.2083519248324135, 0.55989998922383477 } + }; + + static const double b4[ 2 ] = { 0.5941676668573361, -0.9515431408306219 }; + + static const double ao[ 2 ] = { 0.404858299595142, 2.0 }; + static const double bo[ 2 ] = { -3.94, -1.0 }; + + /* Input layer */ + for ( int k = 0; k < 4; k++ ) { + v1[ k ] = ( ( X[ k ] - bi[ k ] ) * ai[ k ] ) - 1.; + } + + /* Layer 1 */ + /* Sigmoid Symmetric Transfer Function */ + for ( int k = 0; k < 10; k++ ) { + double d = 0.0; + for ( int l = 0; l < 4; l++ ) { + d += a1[ l ][ k ] * v1[ l ]; + } + + v2[ k ] = 2. / ( 1. + exp( -2. * ( b1[ k ] + d ) ) ) - 1.; + } + + /* Layer 2 */ + /* Sigmoid Symmetric Transfer Function */ + for ( int k = 0; k < 7; k++ ) { + double d = 0.0; + for ( int l = 0; l < 10; l++ ) { + d += a2[ l ][ k ] * v2[ l ]; + } + + v3[ k ] = 2. / ( 1. + exp( -2. * ( b2[ k ] + d ) ) ) - 1.; + } + + /* Output layer */ + /* Map Minimum and Maximum Output Reverse-Processing Function */ + for ( int k = 0; k < 2; k++ ) { + double d = 0.0; + for ( int l = 0; l < 7; l++ ) { + d += a3[ l ][ k ] * v3[ l ]; + } + + Y[ k ] = ( ( d + b4[ k ] ) / ao[ k ] ) + bo[ k ]; + } +} diff --git a/collresolve/cambioni2019/accretion_efficiency.h b/collresolve/cambioni2019/accretion_efficiency.h new file mode 100644 index 000000000..5509085cf --- /dev/null +++ b/collresolve/cambioni2019/accretion_efficiency.h @@ -0,0 +1,6 @@ +#ifndef ACCRETION_EFFICIENCY_H +#define ACCRETION_EFFICIENCY_H + +void accretion_efficiency( const double X[ 4 ], double Y[ 2 ] ); + +#endif diff --git a/collresolve/cambioni2019/collision_classifier.c b/collresolve/cambioni2019/collision_classifier.c new file mode 100644 index 000000000..27a2ac72b --- /dev/null +++ b/collresolve/cambioni2019/collision_classifier.c @@ -0,0 +1,259 @@ +/** + * Implementation of the classifier + * for the Cambioni et al. (2019) model. + * + * Copyright (c) 2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file + * @author Alexandre Emsenhuber + * @author Saverio Cambioni + */ + +/* Include Files */ + +#include + +#include "collision_classifier.h" + +/** + * Classifier of collision outcome for a giant impact. + * + * @param X predictors. Array of 4 values: + * - log10( mass of the target / Earth mass ) + * - ratio mass projectile / mass target + * - impact angle [degree] + * - ration impact velocity / escape velocity + * @param label Collision label: + * - 1 => Hit-and-run + * - 0 => Accretion + * - -1 => Disruption + * @param score SVM scores for each class + */ +void collision_classifier( const double X[4], int* label, double score[3] ) { + static const double c0[ 20 ] = { + -0.99999999999999911, -0.3748588133292457, -0.99999999999999911, -0.99999999999999911, -0.23515929829608595, -0.21885102306190557, -0.61832588942015076, -0.99999999999999911, -0.59944312696661817, -0.99999999999999911, + -0.99999999999999911, 0.88651421931625418, 0.44946956985132969, 0.99999999999999911, 0.99999999999999911, 0.99999999999999911, 0.99999999999999911, 0.99999999999999911, 0.71065436190642228, 0.99999999999999911 + }; + + static const double d0[ 80 ] = { + -0.96812029973325509, -0.41005860951897372, -0.94467388146643227, 0.53583033933168323, -0.96812029973325509, 0.989415275665051, -0.94467388146643227, 0.19701007863568945, -0.0029336978779782525, -0.68995338655577865, + -0.94467388146643227, 0.53583033933168323, -0.0029336978779782525, -0.68995338655577865, -0.34149690721110715, 0.53583033933168323, -0.0029336978779782525, -0.68995338655577865, 0.062416245192012422, 0.19701007863568945, + -0.0029336978779782525, -0.68995338655577865, 1.4491847351093896, -0.48063044275629813, -0.0029336978779782525, 0.989415275665051, -0.94467388146643227, 0.19701007863568945, -0.0029336978779782525, 0.989415275665051, + -0.34149690721110715, 1.2134708607236708, 0.96225290397729857, -0.41005860951897372, -0.94467388146643227, 0.19701007863568945, 0.96225290397729857, -0.41005860951897372, -0.54345348341266686, 0.19701007863568945, + 0.96225290397729857, 0.989415275665051, -0.94467388146643227, 0.19701007863568945, -0.96812029973325509, -0.41005860951897372, -0.94467388146643227, 0.87465060002767692, -0.96812029973325509, 0.989415275665051, + -0.94467388146643227, 0.87465060002767692, -0.0029336978779782525, -0.68995338655577865, -0.13954033100954735, 0.53583033933168323, -0.0029336978779782525, -0.68995338655577865, 0.062416245192012422, 0.53583033933168323, + -0.0029336978779782525, 0.0097835560362337145, -0.94467388146643227, 0.53583033933168323, -0.0029336978779782525, 0.989415275665051, -0.94467388146643227, 0.53583033933168323, 0.96225290397729857, -0.41005860951897372, + -0.94467388146643227, 0.53583033933168323, 0.96225290397729857, -0.41005860951897372, -0.13954033100954735, 0.53583033933168323, 0.96225290397729857, 0.989415275665051, -0.94467388146643227, 0.53583033933168323 + }; + + static const double c1[ 46 ] = { + -1.000000000000002, -0.76670342934144986, -1.000000000000002, -1.000000000000002, -0.70344151259629351, -0.018471782343521263, -0.080110544146148446, -1.000000000000002, -0.078907221146861134, -0.60814908181881111, + -1.000000000000002, -1.000000000000002, -1.000000000000002, -1.000000000000002, -1.000000000000002, -0.23916359608618118, -1.000000000000002, -1.000000000000002, -0.11648904039659738, -1.000000000000002, + -1.000000000000002, -1.000000000000002, -0.276775816564861, -1.000000000000002, -0.011912253422085212, 0.46772353672116118, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, + 0.99999999999999956, 0.99999999999999956, 0.85223145726220983, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, 0.99999999999999956, + 0.28919147275244123, 0.99999999999999956, 0.99999999999999956, 0.0055619032835237184, 0.28541590784350507, 0.99999999999999956 + }; + + static const double d1[ 184 ] = { + -2.13440421594161, -1.1856779806440236, -2.2745417110389918, 1.0363299530020105, -2.13440421594161, -1.1856779806440236, -1.7997405823943717, 1.0363299530020105, -2.13440421594161, -1.1856779806440236, + -0.37533719646051239, 2.5066981135857094, -2.13440421594161, 1.9010899712947762, -3.21781328661297, 1.77151403329386, -2.13440421594161, 1.9010899712947762, -1.7997405823943717, 2.5066981135857094, + -2.13440421594161, 1.9010899712947762, 1.5238673181179667, -1.7573695521070178, 2.8435976452744592E-15, -1.8030315710317839, -0.85013832510513221, -1.0221854718151682, 2.8435976452744592E-15, -1.8030315710317839, + -0.37533719646051239, 0.30114587271016091, 2.8435976452744592E-15, -1.8030315710317839, 0.57426506082872719, -1.7573695521070178, 2.8435976452744592E-15, -1.8030315710317839, 0.57426506082872719, 2.5066981135857094, + 2.8435976452744592E-15, -1.1856779806440236, -2.2745417110389918, 1.0363299530020105, 2.8435976452744592E-15, -1.1856779806440236, -1.7997405823943717, 0.30114587271016091, 2.8435976452744592E-15, -1.1856779806440236, + -1.7997405823943717, 1.0363299530020105, 2.8435976452744592E-15, -1.1856779806440236, -1.3249394537497519, 1.0363299530020105, 2.8435976452744592E-15, -1.1856779806440236, -0.37533719646051239, 2.5066981135857094, + 2.8435976452744592E-15, -0.25964759506238377, -2.2745417110389918, 1.0363299530020105, 2.8435976452744592E-15, -0.25964759506238377, -1.7997405823943717, 1.77151403329386, 2.8435976452744592E-15, 1.9010899712947762, + -3.21781328661297, 1.77151403329386, 2.8435976452744592E-15, 1.9010899712947762, -2.2745417110389918, 1.0363299530020105, 2.8435976452744592E-15, 1.9010899712947762, -2.2745417110389918, 1.77151403329386, + 2.1344042159416157, -1.1856779806440236, -1.7997405823943717, 0.30114587271016091, 2.1344042159416157, -1.1856779806440236, -0.85013832510513221, 1.77151403329386, 2.1344042159416157, -1.1856779806440236, + -0.37533719646051239, 2.5066981135857094, 2.1344042159416157, 1.9010899712947762, -2.2745417110389918, 1.0363299530020105, 2.1344042159416157, 1.9010899712947762, -0.37533719646051239, -1.6103327360486479, + -2.13440421594161, -1.1856779806440236, -1.7997405823943717, 1.77151403329386, -2.13440421594161, -1.1856779806440236, -1.3249394537497519, 1.77151403329386, -2.13440421594161, -1.1856779806440236, + -0.85013832510513221, 2.5066981135857094, -2.13440421594161, 1.9010899712947762, -3.21781328661297, 1.0363299530020105, -2.13440421594161, 1.9010899712947762, -2.2745417110389918, 2.5066981135857094, + 2.8435976452744592E-15, -1.8030315710317839, -1.3249394537497519, 0.30114587271016091, 2.8435976452744592E-15, -1.8030315710317839, -0.85013832510513221, 0.30114587271016091, 2.8435976452744592E-15, -1.8030315710317839, + -0.85013832510513221, 1.0363299530020105, 2.8435976452744592E-15, -1.8030315710317839, -0.37533719646051239, 1.0363299530020105, 2.8435976452744592E-15, -1.1856779806440236, -1.3249394537497519, 1.77151403329386, + 2.8435976452744592E-15, -1.1856779806440236, -0.85013832510513221, 1.77151403329386, 2.8435976452744592E-15, -0.25964759506238377, -3.21781328661297, 0.30114587271016091, 2.8435976452744592E-15, -0.25964759506238377, + -2.2745417110389918, 1.77151403329386, 2.8435976452744592E-15, -0.25964759506238377, -1.3249394537497519, 2.5066981135857094, 2.8435976452744592E-15, 1.9010899712947762, -3.21781328661297, 0.30114587271016091, + 2.8435976452744592E-15, 1.9010899712947762, -3.21781328661297, 1.0363299530020105, 2.1344042159416157, -1.1856779806440236, -1.3249394537497519, 0.30114587271016091, 2.1344042159416157, -1.1856779806440236, + -1.3249394537497519, 1.0363299530020105, 2.1344042159416157, 1.9010899712947762, -3.21781328661297, 0.30114587271016091, 2.1344042159416157, 1.9010899712947762, -2.2745417110389918, 2.5066981135857094, + 2.1344042159416157, 1.9010899712947762, -1.7997405823943717, 2.5066981135857094 + }; + + static const double c2[ 136 ] = { + -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, + -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -0.619643797572181, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, + -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, + -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, + -0.48152498010844691, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -0.2854038914275413, -0.8306810612092973, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, + -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -0.072582757747631843, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -0.81360251156629881, -1.0000000000000018, -1.0000000000000018, + -1.0000000000000018, -0.21445097628068693, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, -1.0000000000000018, 0.74719315629539418, 0.99999999999999944, + 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.66951450230080178, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.19604255721711347, + 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, + 0.99999999999999944, 0.59789874476577376, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, + 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, + 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.32332351039587859, 0.99999999999999944, + 0.99999999999999944, 0.99999999999999944, 0.98752629370117551, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, 0.99999999999999944, + 0.52707858329864354, 0.99999999999999944, 0.99999999999999944, 0.26931262793741517, 0.99999999999999944, 0.99999999999999944 + }; + + static const double d2[ 544 ] = { + -4.7673073854411134, -2.7399058149021052, -1.7265799742132044, -1.0064218285397697, -4.7673073854411134, -2.7399058149021052, -0.64803792665534987, -1.793050384180074, -4.7673073854411134, -2.7399058149021052, + 0.430504120902505, -2.1863646620002264, -4.7673073854411134, -2.7399058149021052, 1.5090461684603598, -2.7763360787304547, -4.7673073854411134, -2.7399058149021052, 1.5090461684603598, -2.3830218009103032, + -4.7673073854411134, -2.7399058149021052, 4.7446723111339244, -2.5796789398203783, -4.7673073854411134, -2.7399058149021052, 5.7513115555212551, -2.5796789398203783, -4.7673073854411134, 4.2810349087266912, + -7.1049096513683736, 6.8598637278632753, -4.7673073854411134, 4.2810349087266912, -2.8051220217710595, -1.0064218285397697, -4.7673073854411134, 4.2810349087266912, -1.7265799742132044, -1.3997361063599223, + -4.7673073854411134, 4.2810349087266912, -0.64803792665534987, -1.793050384180074, -4.7673073854411134, 4.2810349087266912, 0.430504120902505, -2.1863646620002264, -4.7673073854411134, 4.2810349087266912, + 3.6661302635760693, -2.5796789398203783, -4.7673073854411134, 4.2810349087266912, 5.7513115555212551, -2.3830218009103032, 0.067355991317064087, -4.144093959627865, -0.64803792665534987, -1.793050384180074, + 0.067355991317064087, -4.144093959627865, 0.430504120902505, -2.3830218009103032, 0.067355991317064087, -4.144093959627865, 0.430504120902505, -2.1863646620002264, 0.067355991317064087, -4.144093959627865, + 1.5090461684603598, -2.5796789398203783, 0.067355991317064087, -4.144093959627865, 1.5090461684603598, -2.3830218009103032, 0.067355991317064087, -4.144093959627865, 3.6661302635760693, -2.7763360787304547, + 0.067355991317064087, -4.144093959627865, 4.7446723111339244, -2.7763360787304547, 0.067355991317064087, -4.144093959627865, 5.7513115555212551, -2.7763360787304547, 0.067355991317064087, -4.144093959627865, + 5.7513115555212551, -2.5796789398203783, 0.067355991317064087, -2.7399058149021052, -4.9622061168867688, 4.8932923387625147, 0.067355991317064087, -2.7399058149021052, -1.7265799742132044, -1.3997361063599223, + 0.067355991317064087, -2.7399058149021052, -0.64803792665534987, -1.793050384180074, 0.067355991317064087, -2.7399058149021052, 0.430504120902505, -2.3830218009103032, 0.067355991317064087, -2.7399058149021052, + 0.430504120902505, -2.1863646620002264, 0.067355991317064087, -2.7399058149021052, 1.5090461684603598, -2.5796789398203783, 0.067355991317064087, -2.7399058149021052, 1.5090461684603598, -2.3830218009103032, + 0.067355991317064087, -2.7399058149021052, 5.7513115555212551, -2.5796789398203783, 0.067355991317064087, -0.63362359781346644, -2.8051220217710595, -0.6131075507196172, 0.067355991317064087, -0.63362359781346644, + -1.7265799742132044, -1.3997361063599223, 0.067355991317064087, -0.63362359781346644, -0.64803792665534987, -1.793050384180074, 0.067355991317064087, -0.63362359781346644, 0.430504120902505, -2.3830218009103032, + 0.067355991317064087, -0.63362359781346644, 0.430504120902505, -2.1863646620002264, 0.067355991317064087, -0.63362359781346644, 1.5090461684603598, -2.3830218009103032, 0.067355991317064087, -0.63362359781346644, + 3.6661302635760693, -2.5796789398203783, 0.067355991317064087, -0.63362359781346644, 4.7446723111339244, -2.5796789398203783, 0.067355991317064087, -0.63362359781346644, 5.7513115555212551, -2.5796789398203783, + 0.067355991317064087, -0.63362359781346644, 5.7513115555212551, -2.3830218009103032, 0.067355991317064087, 4.2810349087266912, -7.1049096513683736, 6.8598637278632753, 0.067355991317064087, 4.2810349087266912, + -3.8836640693289142, -0.21979327289946551, 0.067355991317064087, 4.2810349087266912, -2.8051220217710595, -1.0064218285397697, 0.067355991317064087, 4.2810349087266912, -1.7265799742132044, -1.793050384180074, + 0.067355991317064087, 4.2810349087266912, 0.430504120902505, -2.1863646620002264, 0.067355991317064087, 4.2810349087266912, 1.5090461684603598, -2.3830218009103032, 0.067355991317064087, 4.2810349087266912, + 3.6661302635760693, -2.5796789398203783, 0.067355991317064087, 4.2810349087266912, 4.7446723111339244, -2.5796789398203783, 0.067355991317064087, 4.2810349087266912, 5.7513115555212551, -2.5796789398203783, + 4.9020193680752406, -2.7399058149021052, -1.7265799742132044, -1.3997361063599223, 4.9020193680752406, -2.7399058149021052, -0.64803792665534987, -2.1863646620002264, 4.9020193680752406, -2.7399058149021052, + -0.64803792665534987, -1.793050384180074, 4.9020193680752406, -2.7399058149021052, -0.64803792665534987, 8.8264351169640367, 4.9020193680752406, -2.7399058149021052, 0.430504120902505, -2.3830218009103032, + 4.9020193680752406, -2.7399058149021052, 0.430504120902505, -2.1863646620002264, 4.9020193680752406, -2.7399058149021052, 1.5090461684603598, -2.5796789398203783, 4.9020193680752406, -2.7399058149021052, + 3.6661302635760693, -2.5796789398203783, 4.9020193680752406, -2.7399058149021052, 4.7446723111339244, -2.5796789398203783, 4.9020193680752406, -2.7399058149021052, 5.7513115555212551, -2.5796789398203783, + 4.9020193680752406, -2.7399058149021052, 5.7513115555212551, -2.3830218009103032, 4.9020193680752406, 4.2810349087266912, -2.8051220217710595, -1.0064218285397697, 4.9020193680752406, 4.2810349087266912, + -1.7265799742132044, -1.793050384180074, 4.9020193680752406, 4.2810349087266912, -0.64803792665534987, -2.1863646620002264, 4.9020193680752406, 4.2810349087266912, 0.430504120902505, -2.3830218009103032, + 4.9020193680752406, 4.2810349087266912, 3.6661302635760693, -2.5796789398203783, 4.9020193680752406, 4.2810349087266912, 4.7446723111339244, -2.5796789398203783, 4.9020193680752406, 4.2810349087266912, + 5.7513115555212551, -2.3830218009103032, -4.7673073854411134, -2.7399058149021052, -3.8836640693289142, 0.17352100492068709, -4.7673073854411134, -2.7399058149021052, -1.7265799742132044, -1.3997361063599223, + -4.7673073854411134, -2.7399058149021052, 0.430504120902505, -2.3830218009103032, -4.7673073854411134, -2.7399058149021052, 1.5090461684603598, -2.1863646620002264, -4.7673073854411134, -2.7399058149021052, + 3.6661302635760693, -2.7763360787304547, -4.7673073854411134, -2.7399058149021052, 4.7446723111339244, -2.9729932176405311, -4.7673073854411134, -2.7399058149021052, 4.7446723111339244, -2.7763360787304547, + -4.7673073854411134, -2.7399058149021052, 5.7513115555212551, -2.7763360787304547, -4.7673073854411134, 4.2810349087266912, -4.9622061168867688, 0.96014956056099143, -4.7673073854411134, 4.2810349087266912, + -3.8836640693289142, -0.6131075507196172, -4.7673073854411134, 4.2810349087266912, -3.8836640693289142, -0.21979327289946551, -4.7673073854411134, 4.2810349087266912, -1.7265799742132044, -1.793050384180074, + -4.7673073854411134, 4.2810349087266912, 0.430504120902505, -2.3830218009103032, -4.7673073854411134, 4.2810349087266912, 1.5090461684603598, -2.5796789398203783, -4.7673073854411134, 4.2810349087266912, + 4.7446723111339244, -2.7763360787304547, 0.067355991317064087, -4.144093959627865, -3.8836640693289142, 2.9267209496617528, 0.067355991317064087, -4.144093959627865, -2.8051220217710595, -0.6131075507196172, + 0.067355991317064087, -4.144093959627865, -1.7265799742132044, -1.3997361063599223, 0.067355991317064087, -4.144093959627865, -1.7265799742132044, 0.96014956056099143, 0.067355991317064087, -4.144093959627865, + 0.430504120902505, -2.5796789398203783, 0.067355991317064087, -4.144093959627865, 1.5090461684603598, -2.7763360787304547, 0.067355991317064087, -4.144093959627865, 3.6661302635760693, -2.9729932176405311, + 0.067355991317064087, -4.144093959627865, 4.7446723111339244, -2.9729932176405311, 0.067355991317064087, -4.144093959627865, 5.6794087523507324, -2.9729932176405311, 0.067355991317064087, -2.7399058149021052, + -2.8051220217710595, -0.6131075507196172, 0.067355991317064087, -2.7399058149021052, -0.64803792665534987, -2.1863646620002264, 0.067355991317064087, -2.7399058149021052, 1.5090461684603598, -2.7763360787304547, + 0.067355991317064087, -2.7399058149021052, 3.6661302635760693, -2.9729932176405311, 0.067355991317064087, -2.7399058149021052, 3.6661302635760693, -2.7763360787304547, 0.067355991317064087, -2.7399058149021052, + 4.7446723111339244, -2.9729932176405311, 0.067355991317064087, -2.7399058149021052, 4.7446723111339244, -2.7763360787304547, 0.067355991317064087, -2.7399058149021052, 5.7513115555212551, -2.7763360787304547, + 0.067355991317064087, -0.63362359781346644, -3.8836640693289142, 0.17352100492068709, 0.067355991317064087, -0.63362359781346644, -2.8051220217710595, -1.0064218285397697, 0.067355991317064087, -0.63362359781346644, + -0.64803792665534987, -2.1863646620002264, 0.067355991317064087, -0.63362359781346644, 1.5090461684603598, -2.7763360787304547, 0.067355991317064087, -0.63362359781346644, 1.5090461684603598, -2.5796789398203783, + 0.067355991317064087, -0.63362359781346644, 3.6661302635760693, -2.9729932176405311, 0.067355991317064087, -0.63362359781346644, 3.6661302635760693, -2.7763360787304547, 0.067355991317064087, -0.63362359781346644, + 4.7446723111339244, -2.7763360787304547, 0.067355991317064087, -0.63362359781346644, 5.7513115555212551, -2.7763360787304547, 0.067355991317064087, 4.2810349087266912, -4.9622061168867688, 0.96014956056099143, + 0.067355991317064087, 4.2810349087266912, -3.8836640693289142, -0.6131075507196172, 0.067355991317064087, 4.2810349087266912, -3.8836640693289142, 6.8598637278632753, 0.067355991317064087, 4.2810349087266912, + -1.7265799742132044, 4.8932923387625147, 0.067355991317064087, 4.2810349087266912, 1.5090461684603598, -2.7763360787304547, 0.067355991317064087, 4.2810349087266912, 1.5090461684603598, -2.5796789398203783, + 0.067355991317064087, 4.2810349087266912, 1.5090461684603598, -0.21979327289946551, 0.067355991317064087, 4.2810349087266912, 3.6661302635760693, -2.7763360787304547, 0.067355991317064087, 4.2810349087266912, + 4.7446723111339244, -2.7763360787304547, 4.9020193680752406, -2.7399058149021052, -2.8051220217710595, -1.0064218285397697, 4.9020193680752406, -2.7399058149021052, -2.8051220217710595, -0.6131075507196172, + 4.9020193680752406, -2.7399058149021052, -1.7265799742132044, -1.793050384180074, 4.9020193680752406, -2.7399058149021052, 0.430504120902505, -2.5796789398203783, 4.9020193680752406, -2.7399058149021052, + 1.5090461684603598, -2.9729932176405311, 4.9020193680752406, -2.7399058149021052, 1.5090461684603598, -2.7763360787304547, 4.9020193680752406, -2.7399058149021052, 3.6661302635760693, -2.9729932176405311, + 4.9020193680752406, -2.7399058149021052, 3.6661302635760693, -2.7763360787304547, 4.9020193680752406, -2.7399058149021052, 4.7446723111339244, -2.9729932176405311, 4.9020193680752406, -2.7399058149021052, + 4.7446723111339244, -2.7763360787304547, 4.9020193680752406, -2.7399058149021052, 5.7513115555212551, -2.7763360787304547, 4.9020193680752406, 4.2810349087266912, -0.64803792665534987, -2.3830218009103032, + 4.9020193680752406, 4.2810349087266912, 0.430504120902505, -2.7763360787304547, 4.9020193680752406, 4.2810349087266912, 0.430504120902505, -2.5796789398203783, 4.9020193680752406, 4.2810349087266912, + 1.5090461684603598, -2.7763360787304547, 4.9020193680752406, 4.2810349087266912, 3.6661302635760693, -2.9729932176405311, 4.9020193680752406, 4.2810349087266912, 3.6661302635760693, -2.7763360787304547, + 4.9020193680752406, 4.2810349087266912, 4.7446723111339244, -2.7763360787304547 + }; + + const double* ci[ 3 ] = { c0, c1, c2 }; + const double* di[ 3 ] = { d0, d1, d2 }; + + const double oi[ 3 ][ 4 ] = { + { -0.99696048632218981, 0.34650455927051926, 35.182066869301195, 1.7092705167173332 }, + { -1.0000000000000013, 0.39205816554809358, 50.928859060402196, 2.2951901565995461 }, + { -1.0139318885448916, 0.39512383900928133, 49.506346749225287, 1.7558823529411685 } + }; + + const double mi[ 3 ][ 4 ] = { + { 0.68297448548548256, 0.23551630001045257, 24.480429228819204, 0.97278394958655334 }, + { 0.71184721492684289, 0.2461101255913701, 24.000096118927456, 1.0333260317898867 }, + { 0.7097052701984341, 0.24435372788243789, 23.859890900103604, 0.87237770699226624 } + }; + + const int li[ 3 ] = { + 20, + 46, + 136 + }; + + const double ai[ 3 ] = { + 1.5169953015819087, + 0.65816766137128868, + 0.29144440937686777 + }; + + const double bi[ 3 ] = { + -1.6512373495903629, + -6.3007673496917675, + -7.548107436699695 + }; + + static const signed char iv[ 9 ] = { 1, -1, 0, 1, 0, -1, 0, 1, -1 }; + static const double def[ 3 ] = { 0.091420534458509145, 0.37130801687763715, 0.53727144866385368 }; + + double pscore[ 3 ]; + + for ( int n = 0; n < 3; n++ ) { + double mu[ 4 ]; + + for ( int i = 0; i < 4; i++ ) { + mu[ i ] = ( X[ i ] - oi[ n ][ i ] ) / ( mi[ n ][ i ] * ai[ n ] ); + } + + pscore[ n ] = 0.; + + for ( int i = 0; i < li[ n ]; i++ ) { + double f = 0.; + for ( int j = 0; j < 4; j++ ) { + f += mu[ j ] * di[ n ][ j + 4 * i ]; + } + + pscore[ n ] += ( f + 1. ) * ( f + 1. ) * ci[ n ][ i ]; + } + + pscore[ n ] += bi[ n ]; + } + + /* Compute the score for each class */ + + int good = 0; /* Flag indicating if at least one value is not NaN */ + for ( int i = 0; i < 3; i++ ) { + double tot = 0.; + for ( int n = 0; n < 3; n++ ) { + if ( iv[ i + 3 * n ] != 0 ) { + double val = 1. - (double)( iv[ i + 3 * n ] ) * pscore[ n ]; + if ( val > 0. ) tot += val; + } + } + + score[ i ] = -tot / 6.; + + if ( score[ i ] == score[ i ] ) { + good = 1; + } + } + + /* Find the index of the largest value in "search" */ + + const double* search = good ? score : def; + + double val = strtod( "-inf", NULL ); + *label = 0; /* Default index if all values are NaN, which should not happen anyway */ + + for ( int i = 0; i < 3; i++ ) { + if ( search[ i ] > val ) { + val = search[ i ]; + *label = i + 1; + } + } + + *label = *label - 2; +} diff --git a/collresolve/cambioni2019/collision_classifier.h b/collresolve/cambioni2019/collision_classifier.h new file mode 100644 index 000000000..12fcb495a --- /dev/null +++ b/collresolve/cambioni2019/collision_classifier.h @@ -0,0 +1,6 @@ +#ifndef COLLISION_CLASSIFIER_H +#define COLLISION_CLASSIFIER_H + +void collision_classifier( const double X[ 4 ], int* label, double score[ 3 ] ); + +#endif diff --git a/collresolve/cambioni2019/orbital_hnr.c b/collresolve/cambioni2019/orbital_hnr.c new file mode 100644 index 000000000..edebd4271 --- /dev/null +++ b/collresolve/cambioni2019/orbital_hnr.c @@ -0,0 +1,236 @@ +/** + * Implementation of the orbital elements Neural Network + * for the Cambioni et al. (2019) model. + * + * Copyright (c) 2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file + * @author Alexandre Emsenhuber + * @author Saverio Cambioni + */ + +#include + +#include "orbital_hnr.h" + +/** + * Neural network predicting the relative orbit of the two largest remnants for Hit-and-run collisions. + * + * @param X predictors. Array of 4 values: + * - log10( mass of the target / Earth mass ) + * - ratio mass projectile / mass target + * - impact angle [degree] + * - ration impact velocity / escape velocity + * + * @param Y output. Array of 3 values: + * - E: specific orbital energy of the second remnant; scaled to the kinetic energy at the mutual escape velocity + * - b: impact parameter + * - delta omega: shift of the pericentre [rad] in the direction of motion + */ +void orbital_hnr( const double X[4], double Y[3] ) { + static const double bi[ 4 ] = { -0.993071593533487, 0.421131639722861, 56.4461893764434, 2.05981524249423 }; + static const double ai[ 4 ] = { 1.38570465236717, 4.05371898028927, 0.0480247338292496, 1.05551091905284 }; + + double v1[ 4 ]; + + static const double a1[ 4 ][ 50 ] = { + { -0.0027061582690720942, 0.031137184615957002, 0.0020390703987558712, 0.015175695397017502, 0.081042219519364384, -0.10714015360163014, -0.063767149660569816, -0.019025099833497164, -0.040243580810943841, -0.038781412917220745, 0.018621508824334932, -0.13556078343919417, -0.0066157604471441837, 0.01739778118387552, -0.0040616543341302344, -0.020707009840123591, 0.0018715168796718949, -0.014862494827099792, 0.055357446871101806, -0.0083224152154333843, -0.012238357896120374, 0.013908621391893788, 0.012822597411728663, -0.015069257003365229, -0.048470234449970222, 0.2353248090711802, -0.045149403703562158, -0.024490892142435852, -0.057910668077622622, 0.011985850068546449, -0.027414891341553886, -0.013766287780923397, -0.010837904468099057, 0.1083246281531747, 0.06576627101548585, -0.036028428823958895, 0.048535133993103025, -0.12958792076934536, 0.039716822911441345, -0.058452400447076377, 0.007369920397830197, -0.080303379636972538, 0.015296772594337184, -0.019513981359445574, 0.072996897875807112, -0.079256432726445711, 0.071646722961807546, 0.035099854144594524, 0.02038464795002368, 0.013579829285189287 }, + { 0.0039651739968073179, 0.021195937341609298, 0.004174727916935881, -0.075256491614245011, 0.072224322292913284, 0.041014671371140232, 0.078017429169209535, -0.10065037186307743, -0.040323572100502136, 0.10134146692766249, 0.01647774455478054, -0.017978393491584775, 0.036576727354274856, -0.073002458169402012, -0.014656624271151043, -0.028838996379079409, 0.029316971361692229, -0.10804091241575288, 0.027685757744644265, -0.019490155025792578, 0.012178046425368766, 0.0099856632368875257, 0.051745867574737495, -0.062642791273315457, -0.092412651794261558, -0.094670511829825041, -0.06745798907173764, -0.023542594353021716, -0.037988167147562778, 0.01186726127580537, -0.0892600464459177, 0.013410433510013505, 0.12543246454444348, 0.11597728450816741, -0.034523893473478916, 0.022390732357038545, 0.0323347158840256, 0.0854727499590982, 0.026150549782661941, -0.0147949336679527, 0.12069783238143302, -0.020613276003575355, 0.025564883158426321, -0.00247529445623122, 0.11761352638988355, 0.019034019287013624, 0.01460606829085326, -0.076576495433923225, 0.020935651781985982, 0.0177335833490868 }, + { 0.10597595358526569, -0.038465629043312154, 0.062328391064758487, -0.076443514668778717, -0.016605005898046653, -0.52332157086705866, 0.089174125782190042, -0.060238658036555918, 0.23613935871375563, 0.13158974073005222, 0.12935941322695671, -0.20535158804662362, -0.18751045651319379, -0.40786719292612056, 0.085551368672105527, 0.048052807881673751, -0.14108504920045942, -0.25480239107202995, 0.10367522688453835, -0.10602416934680783, 0.17968838857836794, 0.39030923228263203, 0.14159333735922075, -0.020772631782322883, 0.025997099088773078, 0.3348867692385345, -0.050831475139305748, 0.10249467078161323, -0.17017561703616516, 0.13530177088865272, -0.1904192849832658, -0.10090401647283793, -0.0064473382486891989, 0.23769749172470409, -0.16415376337659301, -0.095175933349746625, -0.14575760124799661, 0.18900364110673737, -0.24934579868623241, 0.23576469526367055, 0.095718669437051929, 0.19726239680646454, -0.050608813274325495, -0.038479728762542444, 0.092656999871271156, 0.20399912117723321, -0.10471651962129433, -0.13198119990236898, 0.10265839443289716, -0.047353705329025539 }, + { -0.164486211142471, -0.097944132938435166, 0.012628230836967276, 0.15592331374700766, -0.074610591165832726, -0.17339092468164727, 0.16911868054100426, -0.17898561683484637, -0.26291144681441564, -0.080947630748273089, 0.12845386878343668, -0.063564704679154621, 0.26517641317652513, -0.11322555182497031, -0.15901708304316026, 0.082499618880079617, 0.087419439948208874, 0.016178468184188284, 0.085295558275087446, 0.17905477850986795, -0.24333793763751146, 0.1746853735343683, -0.183763966370477, -0.039678716032535574, 0.077892798714868747, 0.19659795919590856, 0.13785592224411466, 0.09040758698133998, 0.22574247501588535, -0.12917520202750993, 0.15020701314396093, -0.019451868904418235, 0.13681220437592953, -0.026225409985623373, 0.033982087627934879, 0.077684712829060892, -0.080667091811249467, 0.15454909753619031, -0.095358429797797781, 0.077457744823488175, 0.015268386923507378, 0.056921655415501426, -0.22317227819308108, 0.11247324895860765, -0.03345228784295879, -0.046765061223084665, -0.04325230821845432, 0.021249950627368633, 0.14507495890643016, 0.1595397173943264 } + }; + static const double b1[ 50 ] = { 0.26981523315636835, 0.21153443436905514, -0.15187139856956314, 0.16826813749517772, -0.1019796369440379, -0.42636455668608531, -0.20107493486527758, 0.26941551971453359, -0.24162781341062725, 0.23981785320643467, -0.15215289419030226, 0.011120295483527184, 0.079873007119526981, -0.36433107526355979, 0.035411787394939047, 0.069163278464226513, -0.16921542973594964, -0.29601747520071148, 0.00081580306942439845, 0.024851920483998331, 0.076211098309921857, 0.33350159990662143, 0.05848681875390066, -0.01124625366625983, -0.11949708889554184, -0.093346229924875346, -0.15752601847543721, -0.012986566995229053, -0.20611222419007907, 0.0912503158792304, -0.24388753291692064, 0.021263913622168149, 0.086924557391025059, 0.21504048993667954, -0.053589685456102175, -0.015834236684686274, -0.061710561428211214, -0.12611650272142233, -0.18795071508200051, 0.16374704063757076, 0.15863123179351624, 0.19703699056047452, 0.34045480782446214, 0.084430302926531753, 0.056832587162494286, 0.29560124131307175, 0.13905412929621824, -0.20546320205359042, -0.17996650672943534, -0.33687940511762088 }; + + double v2[ 50 ]; + + static const double a2[ 50 ][ 45 ] = { + { 0.012116665484604066, -0.029478348714572229, 0.035628124562786093, -0.029868291200756774, 4.4809399577067788E-5, -0.014327215834108236, 0.015892027250513044, -0.12492697152817094, -0.031223557883815943, -0.044063035122475537, 0.0040904986950476147, -0.078768320653327076, 0.026207296529852223, 0.00366582999723986, -0.0082058743197017427, 0.016789252799277083, -0.06111911409104865, -0.03407336536399113, -0.047899778024147972, -0.02625048290345891, -0.05214933448668678, 0.024057707280476178, 0.10538096854898142, 0.05972500507208095, 0.021421753488960495, -0.15075231562514496, 0.19874779910802681, 0.0060855374446356419, -0.088548351918847759, -0.029912122562984689, -0.029216221202457742, -0.038429937706843914, 0.04857927188575218, -0.02182539650339535, 0.035986961332470285, -0.034105649576769904, 0.092218598018006359, -0.069765211904929875, -0.035135417500049587, 0.057552754797801947, -0.044084250198787533, 0.023349737170912922, -0.011538900945338226, 0.013072868811447567, 0.01022296601748727 }, + { 0.019583510997436413, -0.052040845675677738, 0.058212546670183586, -0.03966299961297385, -0.0019068156845082663, -7.8951081023338439E-5, -0.016646548643760195, -0.067812216632219507, -0.047539914117476108, -3.686981999482069E-5, -0.019860240666615989, -0.056868075345691826, 0.047272991836137285, 0.0035076836028534674, 0.0033928899075047554, 0.040523231771691204, -0.048971683386223958, -0.033214335414855654, -0.015720110748009487, -0.029877699136155185, -0.0020473536823993571, -0.010054189702701192, 0.036973146348836645, 0.018158371776993427, 0.0090751402564573438, -0.035244376332934146, 0.15939738793545252, 0.030651182003260315, -0.086398803701622187, -0.025876149058382394, -0.0011398447001491402, -0.028535103871286705, 0.05171280094337842, -0.0016736363624494485, 0.0076263395783786906, -0.0041745837602637607, 0.069909509565552475, -0.032675843828095213, -0.052888330355021, 0.01102399789018565, -0.018378445468885229, 0.034820362950457012, -0.036575164821951556, -0.0353843079604502, 0.01059986843311064 }, + { -0.016350924839581556, 0.047346056936069046, -0.052694086837772561, 0.038812289500533906, 0.00351979249578264, 0.0092884291588685979, 0.027247382850581914, 0.027264346879162616, 0.044126727120739825, 0.0055252525710258928, 0.02508643670669862, 0.034760885147787517, -0.0319140813608338, -0.010532840619760897, 0.011540732107110636, -0.025783175261279934, 0.020622360900288645, 0.014535696941216389, 0.0088525985395082156, 0.034582887008390364, 0.0016919619079097366, 0.019774235377541766, -0.016869203438250883, -0.011872140137964747, -0.011164594869350794, -0.021000743778555511, -0.075596615946532775, -0.029307852555546691, 0.0560965603829606, 0.011865216597816751, 0.013716847073227253, 0.017681845111678741, -0.030011290668360887, -0.024096670880512223, 0.017361538013868895, -0.015315712831449523, -0.037663115802690023, 0.010828028272477993, 0.055219054210005024, 0.014233975103047043, 0.018958351493891162, -0.035361770172067923, 0.045214502507017848, 0.039276123305636984, -0.019421649888589455 }, + { 0.0111961541867694, -0.049687112062638115, 0.049111229735122566, -0.033259398376130511, 0.040168985908367032, -0.026150128839174273, -0.049834555092049052, -0.036509773610597547, -0.045784769024935765, -0.061108856577668194, 0.018010895223392887, -0.035782447687591853, 0.023701653299391893, 0.026746376525092277, -0.042779488943260016, 0.042189834431469259, 0.0069239397830904012, -0.00048306111865138848, -0.0621807409499853, -0.044985668186230683, 0.061161527764517332, -0.016918762959256903, 0.026654019580815619, 0.04667190264801039, 0.02812688967460782, 0.024212050553181784, 0.063261490135527884, -0.013938862076136694, -0.056822008332799823, -0.015568779701215132, -0.072771118663517861, -0.056598412220907092, 0.023784152598744095, 0.042040199398781196, -0.045759661284042887, 0.031322707329768, 0.037716917183019769, 0.0015191291590071758, -0.054689683797980407, -0.011340950152842802, -0.043031735141754165, 0.028371419552020438, -0.036376631503376361, -0.067849891449043992, 0.029316164530329022 }, + { -0.0072194354843015248, 0.0097151649286814148, -0.0035198142958316457, 0.00854265591107658, -0.016904560997260506, 0.03807417440681219, 0.015436635901894848, 0.043619036879172027, 0.030900946693503416, 0.046292757306167907, -0.01120498566257064, 0.0526308150571768, -0.018981614705672063, -0.011193874286038149, 0.050162955251031, -0.0056700713977439823, -0.006224616150083552, -0.004795281290464885, 0.068159281016225218, 0.017888567094635849, -0.016932885478654722, 0.0017929556438430422, -0.065660184616976369, -0.070402811151894035, -0.032651749294774678, 0.026883457959492311, 0.029087900967310343, 0.029503137420629797, 0.020505051100844354, 0.0086874538968249541, 0.062861833010687568, 0.051355547933250978, -0.020280161730417037, -0.026955412863010592, 0.030048085896699748, -0.025049722195289958, -0.027235426916937259, -0.0033123874948346311, 0.017639230723461446, -0.016528782766913473, 0.046307883287993741, -0.0023059934150928951, 0.013555099960338331, 0.0035686794202685417, -0.0108654610397062 }, + { 0.017592466562078676, 0.0011772341555204614, 0.016652753362745982, -0.01253059896334156, -0.0662880346818602, 0.11042574318283561, 0.014569864894487784, -0.017894131431060816, 0.015276463828121036, 0.24995857194494062, -0.12770511761322476, -0.016122479168898016, 0.08103516478626438, -0.013954239057255183, 0.11047283102587901, -0.0073759983865260923, -0.0608185848035377, 0.019769386730546561, 0.18836687658346379, -0.0031033627203924247, 0.0073380475447327263, -0.0055351054913884944, -0.13213360241421118, -0.16105113673105678, -0.084575219950138808, 0.085022012526318386, -0.43456113382160638, 0.12633493991569825, -0.071495042488102165, -0.009747798359963018, 0.15989226845812773, 0.13709859967663152, 0.0300542538829723, 0.035821608729726478, -0.0091758060545105938, -0.020916401178127896, 0.072697037869541445, -0.02886434735001801, -0.018940439953096775, 0.028613835604936761, 0.10517521763956873, 0.019546755840374595, 0.0066619917513619795, -0.018023359080430776, -0.062260578566931679 }, + { -0.014096102017626346, 0.018405716231614595, -0.025898050659250594, 0.012114186193982452, 0.017593879934387057, -0.018911751460167634, -0.00083757190268338047, 0.13319853593610509, 0.028634619915030066, -0.012223118717429909, 0.033589594303503847, 0.0829190416301782, -0.039296594078593386, 0.0076175379331610386, -0.021465567117134588, -0.039914669851625423, 0.05185932612142613, 0.035737211571763905, -0.0054649473835426824, 0.023134743661404722, 0.030879802951873432, -0.013084506790422239, -0.035014060545668475, 0.0057908977349299959, 0.014401469027562929, 0.11752624643320138, -0.092631934754737313, -0.021474374808158676, 0.097362716357971266, 0.03321482765138415, -0.030333551593353613, 0.00307266860822294, -0.0409461161066852, 0.054853553147530668, -0.040683407815559812, 0.0453082125542139, -0.070842898811338623, 0.070925632233961422, 0.026388872367130906, -0.070826190028426939, -0.0093901857731057432, -0.024688081712946792, 0.0017508182609894854, 0.00097862795767700078, 0.025752555097096157 }, + { 0.01611263865411067, -0.054114561548725272, 0.062177217107285028, -0.040450114134850029, 0.029326003239113121, 0.033131283513085148, -0.0050473352606580412, -0.17345793265026763, -0.038341109742476474, 0.0051209443492084335, -0.012446745631160832, -0.0833715822072994, 0.073821859058689418, 0.00975303822766076, 0.021068933489884031, 0.02799657925783167, -0.045348901720352844, -0.021524435317260868, 0.00299000952223329, -0.058950878393944375, 0.024876688487795784, 0.032363397602842091, 0.064224770659278882, 0.0047196997817094549, -0.0045412670322612144, -0.15686785354320931, 0.0615996209460283, 0.018567234110687291, -0.12950005607980261, -0.054600202882748784, 0.020661329234960026, 0.014681458634642949, 0.065165681223915237, -0.027118411937165951, 0.019486907781780326, -0.035841780846055764, 0.10650334406167768, -0.088262943294276128, -0.067355210291333623, 0.067300603589803581, 0.0019015323151379939, 0.028459442959511166, 0.0060708068577174827, -0.05327718665969388, -0.004927333757976389 }, + { 0.015206929002393087, 0.03994745134670933, -0.03694953996282295, 0.017682811427457444, -0.10396486027491775, 0.053926916815782044, 0.087780632610016812, 0.010620889971941761, 0.036708781824056617, 0.081499399265411235, -0.13408197272656319, -0.028867141161421729, 0.05642267875028583, -0.055307038009150655, 0.086488082785687731, -0.040978826273816653, -0.10795591757951729, -0.032358398471213731, 0.069229932773231848, 0.040399563152524895, -0.12154780709323333, 0.010399770698421219, -0.061172032192716712, -0.06548163396457192, -0.039418541062662439, -0.014066291818366074, -0.091694795471118334, 0.0768427763810422, -0.066889577155094318, 0.016656027542989529, 0.09321904309294593, 0.033174064434536236, 0.0028011558276675595, -0.10254303105798236, 0.07382538144529309, -0.074659656901529745, 0.071577838797554569, -0.042624027056252442, 0.036336145265189905, 0.060104959825509306, 0.053478572235998764, 0.0095208661465751923, 0.020411803690721597, 0.083577168631596824, -0.050925794920036009 }, + { 0.0015451020842035966, -0.01640158408958255, 0.019753791941615868, -0.011578574827826323, -0.0031173534453323346, -0.041084809771259063, 0.014895709273768671, -0.058681911948362177, -0.031261521415394219, -0.0425717414626797, 0.0098169583941675447, -0.032685875569989239, 0.022069215561183391, -0.0061087224530298485, -0.024317881493230296, 0.007382328795965315, -0.043839694466509579, -0.033877227472002475, -0.012415755985025988, 0.0032785677956114613, -0.043353465671326988, -0.014174988351389148, 0.080314786271230842, 0.053117860349264294, 0.016125801373710443, -0.082156928679830238, 0.25154481325669692, -0.00071323711197408791, -0.062067318260940953, -0.0080041053042556477, -0.04848336550898881, -0.0459078680139511, 0.031598275156900162, -0.027177415091471934, 0.028942675224910935, -0.015656646100579687, 0.0029325991617346276, -0.015984070299161716, -0.011616553524541913, 0.0027898732745131635, -0.017541560861510611, 0.017653530386185851, -0.01396495989675069, 0.023468263268870984, 0.02384914070219956 }, + { -0.021952294839939303, 0.026133312443096007, -0.044912469367294289, 0.031099845651275698, 0.013472721173390448, -0.039612800792428265, 0.011694472225242447, 0.097428578670261071, 0.039343194789374786, -0.047969398946712115, 0.034285442599816335, 0.070833130651620946, -0.04010467209400824, 0.0026373626645610146, 0.00014531455190979305, -0.03043230094854012, 0.03413630603617291, 0.012152401083277331, -0.026191312404810443, 0.024817718694931653, 0.032657586665165238, 0.017890053062892462, -0.04110239725518567, 0.0090676980922490824, 0.0095915342016312331, 0.055539169927663973, -0.0197310885471282, -0.037301415230747662, 0.094035070766557372, 0.024821455322416437, -0.025037954151702173, -0.0040428026362790059, -0.071610996717894976, -0.0058006946765678013, 0.0061577153215705447, 0.014841074028182522, -0.074767159120411, 0.027101266412364298, 0.034334084111207544, -0.027848705268835369, 0.00030882701246514363, -0.033346854729465143, 0.023017876090550591, 0.018727085521776911, 0.012696813866186145 }, + { 0.013599247867062294, -0.021422984724060287, 0.033270871559522811, -0.026987471040330425, -0.0030465575517464203, 0.030368864601861976, -0.015665770053539869, -0.050995215635108858, -0.03313770106655467, 0.039112479167075505, -0.046358801287009754, -0.0627690060035871, 0.053593763591312647, 0.0066391846384476309, 0.0079546776066958813, 0.015180397542829838, 0.0024872081449940722, 0.015191739098060583, 0.022096037492937377, -0.0435408814241963, 0.029561263990259507, -0.014039727169709438, 0.011456956050730811, -0.02726537184190414, -0.0043380537511108928, 0.01006376052307666, -0.11525708755350925, 0.038920378231952726, -0.024105607517235252, -0.018527573477142019, 0.023158880083303551, 0.0038197330290645052, 0.036417646918707344, 0.050155183176323392, -0.024891340626615945, 0.01760886488799366, 0.054568382045042552, -0.010976247176479907, -0.035681022749563279, 0.016000357852274397, 0.0074974518871458963, 0.035538443077394871, -0.020441234051642474, -0.026981894988284658, -0.018989945587383785 }, + { -0.0036581047185973645, -0.033852121844987856, 0.052821648556767582, -0.025238936839484628, 0.068657321155613155, -0.036506769258744125, -0.072808363877508123, 0.0099560761090666562, -0.030506183762027968, -0.046183368747974893, 0.074597470726029014, 0.030767962844913562, -0.031294795920913505, 0.036092793224332564, -0.048396002354231984, 0.033616176754628552, 0.065206342747098772, 0.030303969102331442, -0.037868427332145592, -0.047917114070328629, 0.096920748765536885, -0.015613665932859072, 0.0049807716507618907, 0.029266404406173587, 0.01980276821253955, 0.0656010225224392, 0.020578651621808913, -0.038349540806097142, 0.041096795477180918, -0.0016877842879831507, -0.040703267014543534, -0.02410321346455999, 0.010450118062681764, 0.09427331458662512, -0.0711739803909954, 0.057570722577683267, -0.045692003721637821, 0.043959940092004421, -0.0278562738589239, -0.051920153639438874, -0.035006987863827908, 0.0078893804065162977, -0.0220649102098678, -0.078283530710370919, 0.031347295718867262 }, + { -0.0022948302964040448, 0.016215020679020479, -0.0054751985135995654, 0.0082354959308635328, -0.030136506288083263, 0.091487467044003526, -0.0029613703048231381, 0.032514042561485872, 0.027402005971713553, 0.14833974929766003, -0.086442827528043428, 0.010934079627280968, 0.058676364616639866, -0.011072764945528593, 0.073626914441638228, 0.00061816172025821688, -0.035151993445250246, 0.023840498612962894, 0.12884757386390103, 0.016909646991861413, 0.0077515247267315388, -0.0015167784002954874, -0.10931533130655718, -0.12997717876605328, -0.064663692453107227, 0.082714582055847558, -0.34444524752380135, 0.076419367018316128, -0.013659858447943551, -0.014488348480746304, 0.10798383664891319, 0.10297040571366181, 0.0010570307837073772, 0.034424166629499695, -0.015185019598267615, -0.01238869329097469, 0.024995222693361647, -0.0035404122064489033, 0.011744295126441782, -0.0091684968234033472, 0.091490636195439762, -0.0012395032520854294, 0.017822765093571797, -0.027105814771307041, -0.042079104358868226 }, + { -0.0038983757995343002, 0.022543225541287088, -0.023091523657429648, 0.013531185108232081, -0.025977995791705438, -0.007139508698765543, 0.048176009310616594, -0.031757826753435622, 0.018443406833120367, -0.0020907770918910762, -0.020025472914050428, -0.0019942454962546133, -0.0080416359402157821, -0.015170473334654258, 0.016510834500612612, -0.02639192165031716, -0.0467204411846325, -0.01666625494401848, 0.022951254124042968, 0.020002404881574135, -0.077529542058455053, 0.0041133733100241991, 0.022594661271242177, -0.010755841552602754, -0.0090819789681948013, -0.062135944725289126, 0.053027025463473126, 0.0045023632336849417, -0.022666290027372034, -0.00076693101191370027, 0.0086072713036864715, -0.012457804914215663, -0.010639881478574427, -0.055000445305743335, 0.051350958976628933, -0.035829249353516321, 0.0007049142416966531, -0.033240617633112195, 0.016408292031752442, 0.023549782127601216, 0.01513053880597059, 0.0058423574911591978, 0.011198609800258039, 0.040411567710617942, -0.010482273181798306 }, + { 0.0064574119606904115, -0.01066028670298869, 0.0042848884809306214, -0.0051737654951079393, 0.013005159132439043, -0.018798994786623429, -0.0084564978303475844, 0.001921993260391115, -0.019536326760290962, -0.040074074227444655, 0.0059587354647184518, -0.013346668273460479, 0.01105606606833209, 0.0088038727005862061, -0.048559620358306313, -0.00084401462252321313, 0.00702076705507295, 0.00596348500794673, -0.046728902506310482, -0.016755734487926537, 0.0055977353775407005, -0.0023896972703730422, 0.0345594163354665, 0.06546202246414333, 0.030006920654099108, 0.022362217232422769, 0.0028531941807580044, -0.025538957083683568, -0.010159001945828586, -0.00062768920199134624, -0.058670629396929151, -0.03500087092502803, -0.00013024531332481669, 0.025549944769301235, -0.030940189052351776, 0.016000769999899887, 0.00052373836827146383, 0.026120544735020006, -0.0075394179621649142, -0.016432794603691864, -0.033008719292176046, -7.93780073778767E-5, -0.020769772999647364, 0.004349480163008991, 0.019840304700738626 }, + { -0.009467121545316504, 0.0009475521429393619, 0.0024597459351871648, 0.0028624338943644763, -0.020059453698502219, 0.018160027181136375, -0.028906114174897024, 0.058203643837818723, 0.00829576001123087, 0.075853022921073959, -0.0094916359670942, 0.049977850381234368, -0.014099560271192984, 0.0033442642452104375, 0.046220952696690673, 0.0038661951256613175, 0.015767618423563619, 0.021059733112524, 0.068967401325729538, 0.0022332448739867256, 0.01801065987603085, -0.018469475243910648, -0.088358519277413519, -0.06707575176334464, -0.032201611250039924, 0.099539532546646547, -0.15336828035827979, 0.026109652499682275, 0.013533299892563917, 0.027704874475964703, 0.0397126772474414, 0.052052449796316888, -0.047511675361325043, 0.050825056505047338, -0.020262630751963655, 0.0088936224648703231, -0.039244928439913035, 0.034683933257649513, 0.0089521921842153646, -0.030565985688466888, 0.034407872999690413, -0.00063827659431864325, 0.0047553261635088348, 0.0010183244572180743, -0.016834003918093129 }, + { -0.0053113225172162857, 0.016575431308292535, -0.0052837692001091651, 0.0039557658865457188, -0.0047438603296029325, 0.05884486986217502, -0.0058116485239636129, 0.057233600082805182, 0.02377060273761436, 0.096375171140475835, -0.04524135498833174, 0.026781307973916129, -0.02205088931324516, 0.0044819590698692707, 0.031159924502151385, -0.00059515665307148275, 0.025344164177799753, 0.053710610601899751, 0.0760667079511176, -0.010099476820951156, 0.040229870765824738, 0.010675505033598098, -0.081552994114159047, -0.0803102559412016, -0.031319617242046814, 0.094287466094178846, -0.31353097865322932, 0.033896480892220644, 0.043089809107775275, 0.00562387782353672, 0.067816681637169043, 0.064732939858516469, -0.022078202380349576, 0.056559589811322628, -0.035952545833993495, 0.013080086062799649, -0.01388813153038714, 0.013286377640558018, 0.012688684596323468, -0.013466644994216601, 0.040064093018387877, -0.011587385172930873, 0.017928357296526545, -0.041701249773180828, -0.033756153488777245 }, + { -0.00662908469333348, 0.023614246194462445, -0.032683619407645415, 0.010764585842846576, 0.0076517662512290245, -0.013212912052656057, 0.0082030888185516647, 0.042701270126421206, 0.020661808823957191, -0.022104122791159888, 0.012313498654190385, -0.00017849820523219026, -0.050198110097494239, -0.0026581664410131704, -0.013880781199166848, -0.023337666289309326, 0.015910272212193266, 0.015122093935477815, -0.043028996859516895, -0.0015850564559257772, 0.011200552456688622, 0.0051325732621934628, -0.0060261214918634221, 0.033031721578561261, 0.024291365538298904, 0.020427840245640122, 0.040796632679345565, -0.025487797460428605, 0.06606898366284783, 0.0066362231445479735, -0.023632487533147287, -0.047199096278131264, -0.014856974273196974, -0.03047706527299554, 0.0048452818360349165, 0.007392966378786758, -0.030514349668264249, 0.018130356358278529, 0.019974839640326994, 0.004377730675412945, -0.031594932270495556, -0.015556861795042001, 0.011899944728454093, 0.0036436023041284929, -0.0078187389122542552 }, + { 0.003371393801270725, -0.026689039957477081, 0.025839748572056852, -0.015596433839626545, 0.02605498639472326, -0.026456099176530551, -0.050707859575951225, 0.02701431199706367, -0.019375768582601028, -0.060448650251327986, 0.025446393085879645, 0.0024671611987849926, -1.197832891253821E-5, 0.020876854315809209, -0.032248111741137953, 0.0232489436227079, 0.030628516408990652, 0.011256607837812956, -0.03923940855531946, -0.020088812183157761, 0.048973850624059671, -0.01892111881048536, -0.0086167696120936169, 0.019530707478437534, 0.011183630047898119, 0.074266412102066942, 0.011601798885858041, -0.023441614517220342, -0.0090671972446991975, 0.0062586675843155854, -0.056804172494110065, -0.028524779516615747, 0.00096635101169014641, 0.064837950150724508, -0.042677493020334113, 0.036160989422994227, -0.0016541849123939147, 0.03687577379841, -0.017345376977714409, -0.030877909395840151, -0.021840205144169067, 0.012225816993171696, -0.028765326144336759, -0.049564135444870393, 0.022594819484729987 }, + { 0.0079468379837879955, 0.022236779031610265, -0.027549164075492624, 0.017019007086739125, -0.033814375278816408, 0.015602742206285432, 0.071992348416933444, -0.057203405996179207, 0.019561875907100557, 0.033443282098431594, -0.021006589968672596, -0.032454522666993613, 0.040492927343220367, -0.027349754702173545, 0.035685971026731433, -0.0019534293325799757, -0.078993873998844985, -0.038913618721514089, 0.0038398242907516072, 0.034557485684188413, -0.063935101421299184, 0.022275848770108408, 0.03901605967258992, 0.0009644283289335304, -0.0040308538873852582, -0.1138915259198086, 0.092573644662677326, 0.0055590967157521957, -0.0465346462719161, -0.019189151095432382, 0.024866700432070284, -0.0036863850436127249, 0.0070267655304966752, -0.094755007370192879, 0.084929167596119848, -0.0439659628717664, 0.043012490097564457, -0.054270147595109966, 0.013200285248218067, 0.056707579441156307, 0.012723258212046009, -0.000724256960114964, 0.024398059544756094, 0.06865662366753511, -0.02392705691612633 }, + { -0.013838371318788588, -0.00094849988242938087, -0.024190963553565967, 0.034045607689828325, 0.053053572470833192, -0.10006543588992932, 0.019248776948433771, -0.00089654703199779106, -0.0057179150706795885, -0.22631669196067583, 0.10832609693756216, 0.022638445313254645, -0.013451294229861339, 0.0042914914951710835, -0.10438002786782184, -0.021123583956939303, 0.018578537226808113, -0.045623051538497821, -0.16250862506825786, 0.016625674651626794, -0.026933275515112019, 0.024901331853440897, 0.11860849383566145, 0.1439687006825745, 0.070233078627646869, -0.060657157983564594, 0.32739384297454965, -0.11747556265622443, 0.040618524547071579, -0.0058113962952909739, -0.16299566214302755, -0.12667281855774104, 0.0085981389998899729, -0.056422704341695058, 0.025732764144426087, 0.0024045390517240302, -0.022098950413241791, 0.022630617364396852, 0.013681286397342863, -0.02418368484240738, -0.061348983785604487, -0.019079917911723129, -0.010645113268034337, 0.049130435533180215, 0.071181686659883989 }, + { 0.0075828993836393032, 0.023925807104284505, -0.026108073014152904, 0.01842918315540408, -0.028754768456046166, 0.00581931390465661, 0.058895169120000021, -0.041464849090560557, 0.0058502405550315576, 0.026658756249544675, -0.018264451694197048, -0.027020092606120712, 0.012237059180152637, -0.025112405494398582, 0.023305536366722109, -0.010251358152168264, -0.037962745800208954, -0.023501913686094156, 4.4602776218901957E-5, 0.026042445374558309, -0.054741127220765622, 0.013197041398966613, 0.025665899800050351, 0.011534976342820448, 0.0011333813976515447, -0.081312961160402569, 0.0720055309700474, -0.0021290186681735962, -0.01785793897466274, -0.0070457580961969871, 0.027374632660443727, -0.0097673072503397067, 0.0075216576887030843, -0.078501137529829082, 0.052812388093155166, -0.027792763491404908, 0.031202223366157498, -0.03744010103909326, 0.016629066735700433, 0.049856896789533457, -0.00029847891339187236, -0.005656385373215736, 0.021137103854406713, 0.06598684803950397, -0.015876876400310335 }, + { 0.0096226041574014667, 0.0019724365117503354, -0.006484309196308896, -0.0041410814539313773, 0.002661449915332573, 0.024246860436239154, 0.012942646117429417, -0.04391201624943266, -0.00495056990263818, 0.017020763560103808, -0.015581109954664794, -0.033435000925609276, 0.013644040445868089, -0.00020666517418486589, -0.006619946648024861, -0.026374999462821187, 0.014365918909364469, 0.013666319607874981, 0.0089558843206731086, -0.0129785083673866, 0.0020403125677995967, 0.011345549721234275, 0.027078691985563962, 0.0049610668125386363, 0.0030847149327884347, -0.036622791155004865, -0.090244774420384186, 0.022176064749754223, 0.0026174204775466941, -0.017339770466103487, 0.012568209365380879, 0.0082412679564308738, 0.014232969603577275, -0.0022572212865074582, -0.013133339093856819, -0.0094733331300462346, 0.021983264517554574, -0.02543927297915417, -0.0050504971714673014, 0.02571361821663139, 0.0034509434164459044, 0.0082191917736792932, 0.0053390950162210109, 0.0013499976698355942, -0.0052885193110689174 }, + { -0.0024886878051289096, 0.01983928207010132, -0.035130599420518722, 0.018462907706685086, 0.020779920322104149, 0.00090595053276630751, 0.015585217729714511, 0.026402430098462933, 0.010646880965494581, -0.017441234715889709, 0.035890890914142964, 0.0039107485476792391, -0.039669093064619763, 0.0066804675163823473, -0.019899766140511119, -0.02045944275412306, 0.036568396069688335, 0.018317003427627352, -0.036372308586951792, -0.0013097065567408601, 0.025193032084567957, 0.029654494391220903, 0.014396124835104043, 0.034420962944468454, 0.017357132549966195, 0.021871934608174815, -0.1652206338807175, -0.031969406684176346, 0.0406887884637402, -0.0064947480433200019, -0.022203571887391568, -0.0065300051820109846, -0.022777641823796213, 0.011556832040006133, -0.010734036967095602, 0.015033453461939581, 0.011328498603540902, -7.9048176857032619E-5, 0.012218225325309475, 0.013475726200744794, -0.021466301415691207, -0.02301217368274551, 0.016743436981282205, -0.0082225896683881822, 0.0034713944650305059 }, + { -0.030904783169958264, 0.051030611231282864, -0.0655282364257609, 0.053149066468538654, 0.035378562847474329, -0.073739079575463912, 0.0074405416705596791, 0.13842559367519283, 0.047785924674076025, -0.14643527884739801, 0.0659903575113572, 0.094937058736581884, -0.076559160375427843, 0.0057843163415531992, -0.073235936549223182, -0.034567906197752622, 0.04135575974714939, 0.010303401730861136, -0.10307292026306192, 0.034553818979717286, 0.026253763540957084, 0.015419821317662055, -0.0144855281727873, 0.060416340602540156, 0.041680960029164715, 0.059896086007545257, 0.13921411004506826, -0.095435093641702343, 0.13458527173539214, 0.019155464321790962, -0.090225760670160679, -0.063867745775313775, -0.074403118053232159, -0.021310886736912373, 0.0016291919073639523, 0.012769395988718377, -0.10969404688847882, 0.059217168524859934, 0.076531403369630518, -0.05236800227262927, -0.022655193941755691, -0.044067166782751743, 0.023356048322244326, 0.016783553087398092, 0.027359084592506921 }, + { -0.016952343485660947, 0.00090405494987016012, -0.010893783847263727, 0.0045667954603411153, 0.023921374994024597, -0.01293127335352294, -0.035577773952125753, 0.076269767956747891, 0.021719081855706774, -0.023760557177788865, 0.032213298558290658, 0.037606605893948847, -0.018189503308052354, 0.012157028543209155, -0.02107570979133017, -0.0095094209906850437, 0.045578483458965029, 0.026576076611078837, -0.010292329539172479, 0.0012535995415175851, 0.043278873981087304, -0.0054588455899370848, -0.039189681008548506, -0.00564343694794941, -0.002587265771698015, 0.10196970052649997, -0.15018282804760261, -0.01888974296666807, 0.047288952329568694, 0.020102431500686, -0.040374767007798164, 0.0035085671650717343, -0.027012959028789505, 0.059928550226320827, -0.040977871291391091, 0.026797364756300339, -0.032508686354949294, 0.053342990862578543, 0.0018966706591745754, -0.044823874329430372, 0.0028630419869965589, -0.019242156043595152, -0.0027978428482922637, -0.033910522803923794, 0.013224164334673544 }, + { -0.00076577888518661872, 0.00934294749825185, -0.02001508640747866, 0.0047660817707612735, 0.0089072465885750574, -0.015048616936950152, -0.00011189394946510235, 0.017482044829160853, 0.01130094217012715, -0.031228048170958759, 0.023190109379447349, 0.016138300534364242, -0.037292125904129975, 0.0083907895207860315, -0.027111231627377514, -0.029896815523453944, 0.0042092008333700515, 0.014210302188190463, -0.036541835524251706, -0.00062923748848657589, -0.0024976353952820976, 0.0087007137881773035, 0.032646580047455638, 0.043957405030546425, 0.020400548327015471, 0.00020548655351792334, -0.01629993016738631, -0.026472132120820242, 0.03188121501802077, -0.00048245895532709576, -0.044678659160096328, -0.026306998360833563, -0.027494133921146403, 0.00047315151376179114, -0.0060381635577074939, -0.0038814802000111978, -0.022696154459732245, 0.007179381639565505, 0.014354503130540212, 0.00037370759016663722, -0.030179410391753741, -0.01580425165965876, 0.00359850913418934, 0.012283756308848716, 0.007730919717843298 }, + { -0.006455085494147088, -0.015318045248716498, 0.011609406357204376, 0.0068135726973256967, 0.042703345332549617, -0.025511262532885357, -0.05167876293657795, 0.09981985653720063, 0.0014010599352842241, -0.029070801889801445, 0.048724092973324314, 0.0652721268834396, -0.049208073255145, 0.033621639016726795, -0.033501247712300682, -0.034158905469394832, 0.090628717638228287, 0.034204381107162486, -0.014056037540615036, -0.02350206203383914, 0.077043749712723653, -0.01078996155532216, -0.046036566596932275, 0.0084728785469151448, 0.004986163673641862, 0.1384195248769963, -0.19610994665033987, -0.027819044600872565, 0.08551694772569679, 0.019475789254809476, -0.029725319270794751, 0.0169152518175215, -0.036783000029266072, 0.092085214919535613, -0.078213182030857684, 0.060606840171304313, -0.06816417738495463, 0.06513924670469, -0.012501207109290258, -0.066681876126716735, -0.0089117828151842691, -0.026331527879635774, -0.012597810904445419, -0.054588058435471987, 0.028996561208054404 }, + { 0.0146019255227254, 0.0049074823663486627, 0.00071457654015971879, -0.0015572489125734268, -0.0082199340589209739, 0.0009089302829140075, 0.049257781815791525, -0.062035204600482355, -0.011930552673519203, -0.012092772288163431, 0.0023689187777925038, -0.031795069915023039, 0.017202977923364782, -0.011333734039817201, -0.011129056697195263, -0.03714287526820978, -0.025951306852613862, -0.007306889446330401, -0.01100219897163548, 0.013739780074060058, -0.0553613493868831, 0.0091776480184934811, 0.068421665598625864, 0.034331893087923004, 0.014203564147035701, -0.075346262391432536, 0.0698730999728095, 0.023160045892712439, -0.022348578427246833, -0.017318900202601774, -0.0086399871318725927, -0.025889422302278014, 0.023219505982880403, -0.0318447703406178, 0.0051058234047473769, -0.021572191647006314, 0.03423342813639043, -0.032312901054501547, 0.0036545093044862116, 0.020475992564996916, -0.0065412733943150028, 0.00716579417915524, -0.00376676249194666, 0.042329683338109325, -0.00099076513581961142 }, + { -0.0049350787935228532, 0.007592857485048809, -0.00568340740437318, 0.0013367282690910415, 0.013837438420729466, 0.018214134096592855, -0.046947967147981454, 0.081267482491087409, -2.1919658373973603E-5, 0.021887295895175497, 0.014019806508510219, 0.020712432480311634, -0.0123408586780852, 0.016529310330436319, 0.0044319583828625348, 0.021264802007337526, 0.052255708878532876, 0.03320526937998889, -0.00324123421763435, -0.02187969998640836, 0.063165878781079765, -0.0037103468761717356, -0.062253740895304117, -0.031324790292282925, 0.0039660620677502761, 0.12453294518778157, -0.233289026212659, -0.0035701652614532017, 0.052049739062571029, -0.0022025839654297979, 0.019337039004472787, 0.023763719299378903, -0.039122066974295308, 0.065927814543022323, -0.050982584494589166, 0.042175089205659252, -0.031023255273927096, 0.039278063035308251, 0.0043649791171062576, -0.03349421123777948, 0.0087383882600338969, -0.010104305789132156, 0.0014849038857481216, -0.051906507509859458, -0.013041179558252423 }, + { 0.014324371888828744, -0.019586834254695661, 0.026975573184754995, -0.026276795293154503, 0.011077125215192251, 0.040544719500118544, -0.00607959850930152, -0.023200203039352729, -0.0077586143598793013, 0.051304201666980541, -0.0011461429966051738, -0.018640530978784955, 0.017459491623801629, 0.013494919328141885, 0.01976006784670448, 0.017475626533282045, 0.00847894182918308, 0.0095499631022127763, 0.014945406091888958, -0.031197951841128564, 0.041291480855340415, 0.016932870187787448, -0.01006874687408716, -0.011384828176369783, -0.0025290337260111505, 0.022206837804150104, -0.056908232797042636, 0.018145186451075095, -0.013353662545218997, -0.026135174580346046, 0.019499367900045694, 0.021756518059643397, 0.0202274147064534, 0.00482389492710543, -0.0062074088756235565, 0.010707388325262978, 0.039703574493399917, -0.020017891943168008, -0.029058339691405709, 0.013107593867916772, 0.0073108407583243771, 0.012626805423551353, -0.005514847524640442, -0.039578091392068311, -0.0029796480676497605 }, + { 0.012937532741583203, -0.044855978890636021, 0.0487739154957045, -0.027125964746606977, 0.022011235655675334, -0.0035404112251696232, -0.034925896336186445, 0.0048948561662047552, -0.02297066316095463, -0.01846614287418636, 0.01592691133165109, 0.039174564828802216, -0.00019935049761963985, 0.01837591169669215, -0.012957062184053625, 0.0273840032255313, 0.00045507875429515507, -0.00012684501801512164, -0.0071577268314995243, -0.027356210057314204, 0.028032506976708973, -0.00879643451894031, -0.0051870940422062556, 0.021298265973038629, 0.0095310896845904533, 0.063186164870069172, 0.14211136913069675, -0.004739367552292241, -0.008722514178396713, -0.0038630902699356745, -0.01793821295949494, -0.00589030122913879, -0.0090633792458135916, 0.028997988324780635, -0.017475854030503491, 0.015736879830125311, -0.013329995599588031, 0.027222547091968811, -0.013263020768663876, -0.040475668095190084, -0.004373477741282, 0.016783697463214474, -0.029287640924260869, -0.035865564731339609, 0.019507318269737318 }, + { 0.0025998840454290635, 0.0010192718568242259, -0.0125592026101984, -0.00853457982343789, -0.008561251046449914, -0.021051988621111455, -0.0016673775157599706, -0.019223305510603562, -0.00673897411969733, -0.074697070450421815, 0.015649847203728841, -0.020705272446302072, 0.010394905580393547, -0.0048675096497300171, -0.012297747531930333, 0.035171303837329082, -0.014562835198255011, -0.042477315622599245, -0.055890609244587622, 0.0020407489891356217, -0.031753841956613828, -0.0036186367192755416, 0.037692038295584512, 0.044205920007966866, 0.02161337680853152, -0.0836880768135908, 0.28979168791868937, -0.037796894018840212, -0.02002471146493617, -0.0013727528838005326, -0.036670883234469161, -0.045631770037196741, -0.010924634523409598, -0.087844529635681859, 0.046999764276766554, -0.0099925531335409989, -0.021561435152010987, -0.025238003885497334, 0.00073135081812197508, 0.024175354412982554, -0.039187289063047873, 0.010520902892462013, -0.003836980630082113, 0.023591214323991846, 0.0039236897078553778 }, + { 0.0063622063720624447, -0.015326402063507522, 0.011355934828435294, -0.021244083468335062, 0.0095179859513562746, 0.034370652451935511, -0.044617165169311329, 0.014903600338412881, -0.021537991967229282, 0.036367359527854123, -0.006024086861376966, -0.026648526662021575, 0.0074966049760157132, 0.011980990174974787, 0.0301034579996756, 0.037527339679437825, 0.019956838305636909, 0.0043549686832638655, 0.0083465723002677118, -0.032239291631435192, 0.047339431279130963, 0.0018210193079202092, -0.041168211448341333, -0.033774065139277838, -0.0024065758788150505, 0.042712981423957359, -0.10596947321274197, 0.016372397099931036, -0.018711092027626178, -0.021059142254417955, 0.036308194555744577, 0.02945402498949037, -0.0062234250985235924, 0.015438929734312067, -0.017151519998470654, 0.016903005704854975, 0.031225248811962366, -0.012202757728691725, -0.012927024555503949, 0.0060755184011485192, 0.0044009750171928727, 0.0025533358487155856, 0.0002804226292502126, -0.056269660350358595, -0.016758842197470088 }, + { -0.0013975367999518899, -0.019301504016964906, 0.03879298684060755, -0.017864103136083664, -0.001402968507965198, -0.0021756188172317326, -0.018996298290211197, 0.024852475849269792, -0.007603686245512345, 0.0064078787162765863, -0.010428765580213405, 0.017464994053960105, -0.011180098176890871, 0.0098253178059066245, -0.0025524057362164435, 0.027515267673861466, 0.010612031487954221, 0.0062797681571657793, 0.017877853981689489, -0.031131969516881356, 0.0044930186687095535, -0.012143379301065547, -0.020762713703481549, -0.014999380911161465, -0.0053302432220645483, 0.061340541448118707, -0.0056290385567889538, 0.017759169367451155, -0.0074451882963578846, 0.014570012444207393, -0.0027530238692699514, 0.0082361907684476449, -0.0013671088776549471, 0.059648639406605593, -0.026007012414754314, 0.016617085994757086, -0.0099590897854567977, 0.021703159549891431, -0.018197203787453594, -0.034588877206244255, 0.0029022564980717641, 0.0068306708369708195, -0.022665845448112815, -0.012944593924868733, 0.0071523055141300565 }, + { 0.010594929819698772, -0.0083608867064387249, 0.019831731894469004, -0.013675658259447394, -0.012109411166183389, 0.039404799099462616, 0.022581855875787749, -0.020460401153098561, 0.017590797455989741, 0.0735864892999763, -0.051256797751482584, -0.0076284572046223858, 0.043933588334074354, -0.01175168431173489, 0.024585233843545492, -0.0085589066034059223, -0.020690200805260427, 0.017736101721934648, 0.076478090270487409, -0.0023843487168333324, -0.014172985964341264, -0.012734812479188527, -0.026990113299068041, -0.054313825173471934, -0.034499702452697727, 0.01470528678217016, -0.052332886873976948, 0.059495513481978922, -0.002369375510965813, -0.0020362063283970609, 0.043765684228796113, 0.035277255017874425, 0.016785111862626937, 0.018181058342602884, -0.012985344860497332, -0.0069599667756847523, -0.0015710647623865051, 0.0090532604486087079, -0.0035275537138149612, -0.0076557418182654716, 0.043618841329046955, 0.009810505113350073, -0.0079272578127695652, 0.00325409836196594, -0.014756536971884733 }, + { -0.018850686296456996, 0.030879262869018563, -0.030111341640732096, 0.029530178451782713, 0.0082467701506722686, -0.05894813592904144, 0.00976217557622252, 0.086587974456127828, 0.029292285156524975, -0.067828514371150339, 0.075441184548983922, 0.089864928887257542, -0.052052915874262522, 0.0028428060659523896, -0.051469101612238805, -0.0491723564905139, 0.059441667879901766, 0.008564607666360833, -0.049039086439253934, 0.044049221223450077, -0.0066090916155993979, -0.020094633606515078, 0.0055148968782840853, 0.044440608898975588, 0.023093509590419736, 0.079696706045275442, 0.03070859409115936, -0.044195502600299114, 0.099917998375871869, 0.052579717618944033, -0.0692375642604211, -0.034620912413394246, -0.047813103662014016, 0.014925953202686065, -0.022731455486207509, 0.032230735409392759, -0.086295076112384766, 0.0801933808915886, 0.035955762227499612, -0.069221974852195334, -0.018461701371033694, -0.032980601554552791, -0.0053969071491592876, 0.048557308247364588, 0.029051622051686887 }, + { 0.0083799455626497425, -0.0026324042917505422, 0.016900098408791715, -0.017582025643689953, -0.026025839715563444, 0.07149572995757654, 0.0063988217663369373, -0.0054620083132850194, 0.016580477139384313, 0.1205958549877095, -0.07758442994454505, -0.012104810499101934, 0.047315570874653622, -0.016760147334830888, 0.066744478776525326, -0.0035841776186703572, -0.032268808813235329, 0.016455094251352633, 0.11141892814237221, -0.012652940244543057, -0.00826368139475407, -0.013441303581081733, -0.08138254914812118, -0.098843619790259074, -0.0536379152753723, 0.04271614950539198, -0.16987193953577878, 0.086740606595348518, -0.029758612025832736, 0.00064288072373581571, 0.093830120338378689, 0.076325858699346744, 0.017529433890519482, 0.022489041830039261, -0.013939410801686919, -0.0092502767143998049, 0.014481820204064307, 0.0053620410130690282, -0.0025754065204569841, -0.0040856604156263672, 0.055570892271664285, -0.00013703235021860974, 0.0022689048957721383, -0.00045264020912906154, -0.040439213971100223 }, + { -0.0066241925557364509, -0.013406788159050049, 7.0633777717504667E-5, 0.0030800191132565788, 0.022319263853548786, -0.060166338665135349, -0.0081841171763191584, -0.010338263145888959, -0.016867113974066043, -0.12377606798847293, 0.072887364372813457, 0.020699019531503486, -0.017081729080282174, 0.018693130973416603, -0.058293013307163986, 0.0029138722009035309, 0.016031258375730006, -0.019183043498365686, -0.10084678922724921, 0.0007248543820100598, -0.005350302239638228, 0.0046675862354763021, 0.077286636281412982, 0.096920876664833649, 0.043144251255647276, -0.011988676852215071, 0.14041755406108547, -0.0648057729105915, -0.0009160553221567463, 0.011694473472271956, -0.10061388495562704, -0.065761710060288928, -0.01680382451845985, -0.014588313281630924, -0.00030314218030982963, 0.0054875311698603917, 0.0016748715484476726, 0.008684740729718355, -0.013208974283393895, -0.0052233063528791413, -0.049009885293127144, -0.010694634780721114, -0.014123811895396731, 0.0057942221288337682, 0.0342234864559633 }, + { 0.0054249168939745612, -0.032405576820450976, 0.041478906708231893, -0.017856815408649973, -0.00868867249709228, -0.030180785022221851, -0.010449676777578952, -0.011199942420801183, -0.030904640207016259, -0.029986393675853953, -0.0092912984424767323, 0.015921072423122042, 0.00649003581367912, -0.00051392332812175492, 0.0022788413450640678, 0.019123947217204004, -0.037611862415477489, -0.033693497630272282, -0.0084778473231368646, -0.012467096168547003, -0.008307467941988507, -0.00071171774270470552, 0.010289872945279636, 0.014853982544882568, 0.0092227951293315773, 0.0025265362180136811, 0.23401153465963476, -0.0013540696775894499, -0.034043358694618137, 0.0030252498449784659, -0.012443938889922016, -0.0098124710206281482, 0.014260800686582446, -0.0089193359508384622, 0.013387314345069548, -0.003076756247560067, 0.0098347292224687625, -0.00055736779408026846, -0.02282456524451278, -0.022277488600336477, -0.0079736200854791765, 0.01386196504324517, -0.022084332283946361, 0.0063830103093049312, 0.015352048553334932 }, + { -0.0023832586709735008, -0.012226554112534845, 0.004821305851756409, -0.0068050397116606823, 0.027193021471317334, -0.059039196945299986, -0.0010222411416195829, -0.033945310593863694, -0.017455842808451156, -0.11254341972761624, 0.067978927862598071, -0.01329088258079845, 0.01115656695347788, 0.0171809173261427, -0.065629016749313124, 0.014693225251182487, 0.018065898045625452, -0.013935856426088291, -0.10187438006003162, -0.013050667542723278, 0.0010377323176026213, -0.00071139445533106329, 0.094313770480582856, 0.10262427012405875, 0.047090251669945384, -0.032775637162958352, 0.12116671226205046, -0.061292138260921343, -0.012320663134131589, -4.1922794384115193E-5, -0.10211566309750994, -0.079699671829431024, -0.0055052679371290578, -0.011879251146098946, -0.003496937677493784, 0.013544481604177547, -0.00034408776659159129, 0.0067807382943481757, -0.020062878331397919, 0.0080623845657187432, -0.056487499671550194, 0.0027231139501449164, -0.017233574709808019, 0.0050875056989624495, 0.03219005489714484 }, + { 0.020222450921674302, -0.04681441041381066, 0.063263907062346122, -0.044414791621853363, -0.016904513608353166, 0.013614500110034643, -0.0046623977557640559, -0.16562629945168211, -0.054656256757818121, 0.01884732468668824, -0.048861354892669087, -0.087811262441571947, 0.0726588090041508, -0.0029542241632297484, 0.025989114924835913, 0.073381966538516419, -0.0783568786902674, -0.046864353578996557, 0.0036344892537820864, -0.050442184463842368, -0.036561775350177621, 0.013354098025959904, 0.058541653471435605, 0.022803843222867534, 0.00067172952129989716, -0.1230920617916083, 0.2280455785519824, 0.038707927268375159, -0.15005922929975213, -0.030978082516814498, 0.022878752032168739, -0.016781190555505178, 0.067407050196286261, -0.0440757677615599, 0.04239555526561032, -0.048066747888122631, 0.10859684972082025, -0.078615218693027941, -0.0575246536653738, 0.05862500621829398, -0.019752785010077826, 0.04856869190275042, -0.02071333551370054, 0.012789613012847091, -0.004064354478594814 }, + { 0.007910106991343686, -0.022320209331144113, 0.020798594926616763, -0.01532484828064278, 0.0173177228551684, -0.0099144626743916282, -0.036614787190385981, -0.0081037020507592865, -0.031908967651920778, -0.028061411583664507, 0.024521847615517938, -0.026998580716073625, 0.020246299210910403, 0.019310659555500535, -0.038828351682203111, 0.03583070177263796, 0.021423576811936476, -0.005076382638127091, -0.036348553679742532, -0.020029665393860505, 0.0525300188818924, -0.012366086600746434, 0.020942568493070163, 0.035488136884209633, 0.025721860226869335, 0.029523548216817803, 0.0412208404343419, -0.022181065411136524, -0.011767135122255924, -0.020312001557455935, -0.042154827632328237, -0.026898388139369487, 0.013063625153110988, 0.027698585558799, -0.021991471720735966, 0.032636536111271354, 0.018847734038958914, 0.0078360882476580917, -0.030791568564993054, -0.0087489447379758851, -0.02597905072785384, 0.019254532464741344, -0.0236530384177425, -0.036951000570156718, 0.021216724207712451 }, + { 0.0054581520789202679, -0.03284137790796831, 0.041388046417431, -0.018340534464538132, -0.0075268998614110693, 0.019247840323984296, 0.0034812154230638524, 0.007840307895492768, -0.0011006374184323029, -0.011043067587558342, -0.0042683607765405859, 0.054421906485060852, 0.0068147764875412927, -0.0027491960682659833, 0.025487786819587743, 0.0080111211682273691, -0.024402205150529575, -0.018529919556104498, 0.028986873503595634, -0.015973550366128617, -0.025812746988018866, -0.00038927725710760359, -0.028034128535057528, -0.025214449383461058, -0.011948521865254861, 0.02248361807053682, 0.17980334158134526, 0.030729800080040486, -0.0239051223170358, 0.012961859534489296, 0.01280826913244322, 0.026107388988532206, -0.0051879680322508637, -0.013575007328112426, 0.0064929873533031719, -0.019546632136500527, 0.0029940335748287164, 0.011168011653069781, -0.021383799128294977, -0.037106711879300543, 0.013253103630468839, 0.0038839944366597123, -0.017672111206647672, 0.00476379121643974, 0.0167956880233296 }, + { 0.006397357406211503, -0.016310434863123689, 0.013374818212289342, -0.019488836534602857, 0.029378965449089519, -0.052525147201077357, 0.0064423558261258789, -0.0756301042089379, -0.026185744742124453, -0.10023134631589807, 0.046752501332082863, -0.056077612664331811, -0.022024249812463481, 0.0066851044317652571, -0.044688193619762111, 0.0076770180238799474, -0.011701928141132101, -0.0246196983332236, -0.092966384300587568, -0.01439433064185639, -0.033381945941824809, 0.013572499169898942, 0.13282794666887296, 0.088618288460822842, 0.044575436028416869, -0.13313438011694165, 0.21641712376745376, -0.034445735447428807, -0.035196880482010626, -0.018728693264238296, -0.0700870530462459, -0.078005569118293511, 0.022923999623639009, -0.016443102363824961, 0.024450327412744579, -0.017035080936561572, 0.024604831295032006, -0.047402209814646226, -0.0086979639516643874, 0.031730223027503134, -0.06604562348762906, 0.013311289805781341, -0.00968053371043241, 0.0097690607899530678, 0.019237208274597836 }, + { 0.015248475226363471, -0.041249870352248329, 0.041471172065756928, -0.036845305458223225, 0.008657032458253805, 0.018271658651038504, -0.036255609024149905, -0.044104541684544286, -0.041110936660172188, 0.022673971023082967, -0.035497260993697662, -0.060871276780403889, 0.045805612156590909, 0.00895979137221722, 0.010020207450981731, 0.047866590391448374, -0.012813046623035214, -0.012804627857568725, -0.0070803009273484093, -0.03306230793006016, 0.035036820693575443, -0.0028427670077540604, 0.011397345682333465, -0.01059789916095707, 0.0076076591127585353, -0.016388515823765853, 0.060572777538944175, 0.01439112640343366, -0.059792344040753613, -0.039295521352038718, 0.013243137782313782, 0.0061900275107398539, 0.04577358675677607, 0.0055714532900707986, 0.0015549758082173224, 0.00035380097842665885, 0.075442105182662436, -0.039251989549129222, -0.032867136646097438, 0.026196912526663889, -0.010758418391781887, 0.032617647725744985, -0.016122657196493573, -0.055984590112400118, -0.002235071964940185 }, + { -0.0087438844518952352, 0.037640934999272659, -0.042244837024120477, 0.023537801817223702, 0.0036130534800784195, 0.022903603488715184, -0.0022338840077500747, 0.037746344681804142, 0.038031725017466836, 0.059453827513590227, -0.009874427006008454, 0.019779205916014956, -0.01330365480152324, -0.0059632032518472768, 0.019828061109287875, -0.027575714452483274, 0.038031288965642562, 0.033210615382113146, 0.053257240069752319, 0.012788279264560295, 0.0063754746570427318, 0.0021345773712347269, -0.062717672120950974, -0.062902126535971672, -0.033395171036853757, 0.030601980052006796, -0.21800593609109536, 0.006571050335960173, 0.047909563427075613, 0.0023492055842246323, 0.037168150514015806, 0.046993404624111133, -0.03176605829551004, 0.0071852640902117324, -0.016045291523774131, -0.00050741664390369209, -0.039907637346325721, 0.018870614791270543, 0.040142190617078889, -0.0038685541239528768, 0.043261919784866994, -0.021329738064219662, 0.031208645763253384, -0.0015900524321167677, -0.020896442517160007 }, + { -0.016332848964072676, 0.038762062108793849, -0.0443921520299234, 0.033129581133033506, 0.016339114465390641, -0.013519479289437017, 0.0087574603650272427, 0.103599408143829, 0.0428978562638904, -0.023774565125539413, 0.036384741635808557, 0.084857203250948116, -0.030965931322816716, -0.00035664836982199561, -0.023604341945668381, -0.045327822997445873, 0.0591407639222815, 0.037000340262124114, -0.016451821450837765, 0.053118797286467172, 0.030735600750739837, -0.0087834517269001038, -0.037758601482860039, -0.0044659863056230719, 0.0030944116999756777, 0.0861060757286423, -0.11350205646297995, -0.036310729253533243, 0.10087931899044805, 0.025845629333383809, -0.023472790243179435, 0.0076640289923353014, -0.047970124835328309, 0.031565355735810326, -0.030863776697651103, 0.02813740111463767, -0.063643953593416014, 0.055480336377528895, 0.052328728902742053, -0.040392362676430323, 0.0034888083074103736, -0.035496156732426488, 0.01914396641849726, 0.0039787664871059605, 0.0090368234691439037 }, + { -0.0066165578004783272, 0.01438512849158698, -0.019757370062275504, 0.026642897926599324, 0.00854952390966707, 0.032497100480128042, 0.0019754619540935706, 0.14191128595608829, 0.04805562016954508, 0.04202079655106021, 0.01378916765765611, 0.094965726513981316, -0.019446304810994918, -0.006899879861034134, 0.00149436173661281, -0.041079383516760534, 0.0726125053824072, 0.044288551448974332, 0.036197949772484618, 0.02902857923973105, 0.050181466008535285, -0.024984616037098853, -0.10155427995526825, -0.055459135716772648, -0.015424327210622724, 0.1992657455553993, -0.19896064257177939, 0.016595343739536254, 0.10677163025737624, 0.040541778961638734, 0.012207224146837429, 0.040812982683876148, -0.047986046862271189, 0.060563710521414259, -0.0571702572390341, 0.046762169480924348, -0.053222887200199895, 0.095017738190339887, 0.021208651819864394, -0.085884047263144914, 0.036375992425913536, -0.034139467845795225, -0.0021551328591638982, -0.016099264296997189, 0.010657609201036363 } + }; + + static const double b2[ 45 ] = { 0.051933756862425566, -0.13352402917228884, 0.14389670707993116, -0.11217264638925904, -0.0024519581384152261, -0.0304506850944222, -0.067806193014844335, -0.17593835115568018, -0.13422584517586841, -0.063065215642878328, -0.044855821396546446, -0.14313182273622133, 0.098924034202180433, 0.031319585012413532, -0.015343331627225648, 0.10011076213382004, -0.080321569609751564, -0.054523443619834196, -0.084516300457012944, -0.10986751840964636, 0.026521518481122667, -0.016188149524004616, 0.11885034137184577, 0.091214836712203234, 0.055635359393274436, -0.0992988550416824, 0.41545934884336011, 0.020727908082042276, -0.18862464329229117, -0.048089615230161968, -0.026933717091237753, -0.089549469732947737, 0.11573387577895169, 0.039298045540403795, -0.0037627461696782796, 0.0092124864322265868, 0.15036677551357491, -0.081042673623696576, -0.12927845515793218, 0.051413357737975243, -0.086105615885071179, 0.10409730074802558, -0.10151236211947827, -0.062102377729233355, 0.027368189285879242 }; + + double v3[ 45 ]; + + static const double a3[ 45 ][ 15 ] = { + { 0.030429911710792273, -0.011471135454710082, -0.0041012922514453085, 0.060713435248879406, 0.0042893956888992, 0.023435233516808464, 0.0067517724677054695, 0.027186495359614003, 0.015083935116398354, -0.024601660844353317, -0.0019376448815856269, -0.050726973396056314, 0.05596515507170903, 0.020614116644298984, -0.061362346707494735 }, + { -0.051913410370812429, -0.0846454874406107, 0.027548723588435936, -0.076918651105045463, -0.044150782760130645, -0.065605327213256279, 0.048258060752739723, 0.04989908381330229, 0.11548460882106283, 0.091428164041598342, 0.023668589932228059, 0.084056465010753048, -0.0021655777483999888, -0.095142322899718218, 0.12743983237982914 }, + { 0.062736261769938517, 0.10285806405833192, -0.014436085031533666, 0.073359947949067111, 0.093739879003863907, 0.078100916716378352, -0.042402247179985988, -0.032087187263508107, -0.13446144833266344, -0.13449122661678309, -0.021507810192825216, -0.095620005281284864, -0.012307600952700417, 0.1013316855040016, -0.14501473472793067 }, + { -0.055933646735485433, -0.069351575380872485, 0.02356199846199674, -0.064312364355896087, -0.043241936796195264, -0.0535435723550283, 0.02345289461798555, 0.0044862073503098262, 0.0896511894770307, 0.08076061383794747, 0.005010654147537188, 0.066066688065052781, -0.00796877960921767, -0.081415202207654913, 0.1178068259596682 }, + { 0.0421713410552741, 0.022846249045793441, -0.070203810951339, -0.058113116211339605, 0.037577628411446413, -0.000617719493330107, -0.028130632748420821, -0.13649787053773582, -0.0095521101626357616, -0.028000721785167007, -0.0086116508010165779, 0.021929645958017639, -0.020121267493434212, 0.024959721072243739, 0.0337575060528831 }, + { 0.060548518479893412, -0.047694381576188591, 0.089227254979461226, 0.037369559884887861, 0.021481432682225715, 0.01229610528645317, 0.15392572877044597, 0.21755560865719314, 0.081679045279520371, 0.047045981681828004, -0.00050021176345416032, 0.055484570637561147, 0.01592009665131771, -0.045300985218761254, -0.030801066708636728 }, + { -0.11961038603564135, -0.094110897255196918, 0.051128383439387755, 0.061452191948732686, -0.084013871462305614, -0.065347048373818384, 0.012018277173287874, 0.0954042077274219, 0.11454243649346799, 0.10680510177526467, 0.054932962387892026, -0.030584461468478864, 0.072787250497511016, -0.083880514004292653, 0.065866051581520535 }, + { 0.07530827953916408, -0.0036406854599983314, 0.10628548585194755, -0.098532450728155238, 0.047523858970537312, 0.015640911046345848, 0.12774370643464483, 0.056794058471655293, 0.00023143253303290547, 0.025997236132136489, -0.018863686154381682, 0.19084282899988891, 0.0064966719920620886, 0.029819179058784576, 0.44257607241604707 }, + { -0.05499061310488905, -0.085149591573317529, 0.038104105193558828, -0.079058820522947909, -0.018662407322421165, -0.05948876698050018, 0.039690527262874052, 0.061030562681481555, 0.12486257607498134, 0.083184824122443685, 0.01010874243596689, 0.084657718951017868, -0.0067967422428056711, -0.098947651585489238, 0.15987087461455926 }, + { 0.065559330783364678, -0.0049025883810794044, 0.22067806439506696, 0.1144917956762372, 0.0047551320265096786, -0.0042533831351278736, 0.14149727226202924, 0.35505898209156955, 0.0061289606468675518, 0.0016740748202837578, -0.015060042670749197, -0.075344200900218025, 0.0020480039127023435, -0.0029382006162338545, -0.1421138095255641 }, + { -0.048947582773189266, 0.023917483491164473, -0.10827685198602598, -0.10111255316638476, 0.0020282783387239925, 0.0014226148423994564, -0.11241746070560635, -0.29848243671758684, -0.041616278768950618, -0.010159644726691565, -0.023901215172210041, 0.047067958210588907, -0.0094318411871759048, 0.022622744160240949, 0.12137032231742648 }, + { -0.028486417913353539, -0.035954413812772881, 0.014057321250040259, -0.17164086391860026, 0.03601112332376815, -0.016982922453067689, 0.0331954647847284, -0.00093435460966549027, 0.055907517268346085, 0.025746356764197273, -0.008086612530806005, 0.23060718588575527, -0.05302461552295408, -0.06949512577863419, 0.34775182105097319 }, + { 0.015258456307422851, 0.014256116138848283, 0.079039030930735055, 0.090153142523193161, -0.035921665443793528, 0.025768214477583332, 0.034606943252055808, 0.13755471034840527, -0.011108914135090185, -0.0320150141904274, 0.0079968233190727579, -0.10631918788074685, -0.035237464013310266, -0.00422525813100657, -0.23538980567464141 }, + { 0.082500798357196453, 0.03976786406837373, -0.04912037664746155, -0.0086811509241653713, 0.029014481044039614, 0.016520932935122568, 0.00092358143242100951, -0.06239748256012894, -0.05698163826824109, -0.039491975972077813, 0.0013310781859463389, 0.036425369137304271, -0.021698817132354432, 0.0174063683112195, -0.005094268081278326 }, + { -0.057019759203445548, -0.017912568196362222, 0.14144834313096494, 0.030541017937002507, -0.0241523768541347, -7.3856323349179266E-5, 0.070593872654212048, 0.22169775288592511, 0.0210941643033798, 0.0076297656021086973, 0.00024269414048257832, -0.041202151783949266, 0.00096964239105648152, -0.013666797331092054, -0.03425855965631134 }, + { 0.034481689622051073, 0.063364052724519823, 0.017185699215834987, 0.0029118305771845413, 0.0288111188177203, 0.046919368167217, -0.013082535935437773, -0.0090351088001599522, -0.075846553431634156, -0.081766122184560822, -0.043865841765178187, -0.034942909502333336, -0.036131830768170718, 0.053740401985593, -0.23338826175231298 }, + { 0.10420088840260999, 0.025197072500151761, -0.050595499300874577, -0.10685162324834716, 0.027274219616837528, 0.0077981514566190209, 0.044865341787861113, -0.12826238304881921, -0.010586488397607095, -0.030483251356596408, -0.0465271674623787, 0.095965547476508165, -0.081109332620384209, 0.012090686983744397, 0.15598185661443184 }, + { 0.0854567446764708, -0.040164213514901341, 0.05021667445805901, -0.038740998147728023, 0.021019684595962162, 0.00098740529939323287, 0.080174434167158123, 0.023810990903546395, 0.044926597686074723, 0.010004559095727507, -0.049531790597423013, 0.10252771392663909, -0.015755297321779556, -0.04342246228670938, 0.098019907461799047 }, + { 0.0064067337286297489, -0.02281917774681335, 0.20562684401349235, 0.076166738544654125, 0.013156651917070767, -0.019642093756164641, 0.10201670627294276, 0.27223340408619834, 0.033169466619679677, 0.036190140650589758, 0.00063030001667352463, -0.038571302779441867, 0.0021567877170354556, -0.021728727292568365, -0.0446787531985041 }, + { -0.10105821022000235, -0.0744146671193959, 0.046696068909185734, -0.05210440292067197, -0.019444157392881273, -0.0417596180404804, 0.021311213852070684, 0.027391468627373013, 0.092590051287716274, 0.08333844298094753, 0.031400373700296517, 0.079958200317442565, -0.014710973152306229, -0.075619503613849989, 0.14508999989742807 }, + { 0.1345145624488171, 0.066399225675715393, -0.020873520669454085, -0.092373441375967327, 0.10215833323994743, 0.067048069209119238, -0.00826583749212706, -0.13062285650215127, -0.063222060771570512, -0.06469559680241288, -0.039200999368335931, 0.035767572132862496, -0.098421003177130664, 0.039164170501568854, 0.071509117136192152 }, + { 0.017644291231186458, -0.037946338305616542, -0.027850462430960114, 0.023800568841611757, -0.024123495732664469, -0.01324841843712183, 0.026859649461505326, -5.5277709885126112E-5, 0.043510939998041349, 0.034705667712323189, 0.027847573481882267, 0.02038441110041065, 0.073148537597028593, -0.026164547256083769, -0.0086630441603520736 }, + { -0.016018599458302318, 0.032163952731496116, -0.23462415089884034, -0.0080295082175469868, -0.028141486618301553, -0.0022721501220701826, -0.17949886310503477, -0.23837177951832045, -0.017828724154644135, -0.029678053516879088, 0.011860798920263114, -0.013596713993374435, -0.042055962748004674, 0.024951496298478076, -0.11053824991838804 }, + { -0.021125066960171916, 0.022634692635585669, -0.22238563933047661, -0.040467095352758629, -0.020910075283433187, 0.023301298249947703, -0.18986278627605568, -0.29583582418208554, -0.015784354058010819, -0.018138031303046014, 0.021577558831286404, 0.054910393378086626, -0.011236683021233852, 0.00877845442564174, 0.011293218422952528 }, + { 0.033318252005182514, 0.020719465834775984, -0.12792906108730964, 0.021057142081778328, -0.017611716499011634, 0.027722293849198255, -0.087127861492544353, -0.16347350406315936, -0.0016538498368028217, -0.04163273298455443, -4.4122236048622172E-5, 0.022542722295022317, 0.029773156950222365, 0.028255409200216557, -0.0064297109959932913 }, + { 0.13032132776269278, 0.029486997734477036, 0.16332994419296604, -0.067402719802974756, 0.12731345004674788, 0.043564859696755991, 0.19050134675436309, 0.10376226039806809, -0.040174601962661795, -0.037054538682762178, -0.039553639889794968, 0.089007903281781542, -0.0030199586993138717, 0.02835152072725404, 0.37515543273094387 }, + { -0.094392741678245531, 0.017797341184873312, -0.27857642682726336, -0.53886436862893849, 0.058667067729699096, 0.001662607309318723, -0.35887108206518881, -0.35355420397347687, -0.032647150100124436, -0.076565004134741252, -0.001217780790233033, 0.48654988696783519, -0.15372530842579893, -0.02444735226150993, 0.25016273096570418 }, + { 0.0026457381701077347, 0.011503924597638342, 0.1175603091616461, 0.034449601606574821, 0.028064359945938141, 0.0029181064860448404, 0.072943735239683546, 0.20770252698394578, -0.0047107207351138655, 0.0010824087352990079, -0.00018978879988645404, -0.078693103140536791, -0.017609345479548164, 0.013428369299658831, -0.076776690858054719 }, + { 0.072706670894673128, -0.04900765407884642, 0.0024113786661052851, -0.15749961683901406, 0.010935389462336421, -0.011489211811422114, 0.094299245160691283, -0.05887373214146744, 0.074204763983954578, 0.043154904894156139, -0.027889784187642739, 0.19909407864010623, -0.023996367549743363, -0.04964260941219524, 0.39792944573521749 }, + { -0.095686216938245222, -0.000991452114913601, -0.0034268163483982786, -0.058425655805285082, 0.0076160801517539938, 0.012708897583423711, -0.00914058662922086, -0.0061216291575799178, -0.021971429955153523, 0.022548676750343111, -0.014756013724273043, 0.0047929212862059681, -0.03592983409862624, -0.004683126370967146, 0.12556906623480349 }, + { 0.03315691059765058, -0.0023519550433419223, 0.19541166949962244, 0.06592382717211312, -0.013395786776405757, -0.0066995916131926585, 0.093901030427433183, 0.31604501979219052, 0.013862810910415304, -0.016190608459731855, 0.0009666629000670984, -0.024806461952027355, -0.018708758063849102, 0.040748601788698477, -0.062586727780247153 }, + { 0.078588164567668026, -0.018642592509085343, 0.15894262110100582, 0.064318454076294773, 0.017944246208215019, -0.0246121317980917, 0.13801427050162152, 0.17258484955250644, 0.022313814925521976, 0.033838101686673561, 0.011276175817526109, 0.0092439218821910463, -0.0090510622660181419, -0.00058079351841038582, 0.035939242192066123 }, + { 0.032370438851218319, 0.061822785949998939, 2.2515656240178291E-5, 0.099550022468243349, -0.0030864300219358397, 0.018953146883096055, -0.048377341088583513, 0.015933803919361514, -0.0897687238797186, -0.058522417849391731, 0.025731037885089292, -0.11241165053444906, 0.0059934965747593374, 0.077519430096226208, -0.2125710085180659 }, + { 0.10061253641216726, 0.044380993192921707, -0.042016458099369734, 0.03488672119631131, 0.057978048567032335, -0.010894289148146817, -0.0052159918954473887, -0.15945661827242988, -0.049022217287297172, -0.010722578352527381, -0.06788693665175656, 0.070318917238598649, -0.183942245083176, 0.0023318797185769638, 0.15653164813420128 }, + { -0.15720922393602241, -0.037645451743024479, 0.00092029746123738546, 0.067773784369160581, -0.10079357069313977, -0.014132630808582061, -0.052332495987918094, 0.06360946049359549, 0.040215434604489862, 0.030086985906411665, 0.028544095328113462, -0.096901421865764434, 0.066034772969815053, -0.026245836866611687, -0.078371481092602127 }, + { 0.074062718004924782, 0.049244353051645089, -0.023056656806572436, -0.044252882308371995, 0.062231272277009156, 0.022650263842589755, -0.0013871006359365832, -0.10585632816962336, -0.034387979334577691, -0.048673570479462552, -0.039770196070150719, 0.02821044999189519, -0.044689385888829314, 0.046135317580077134, 0.066628352381758668 }, + { -0.059659805195959238, 0.0060193436990479852, 0.0060430643440244894, 0.093467970558001129, -0.084121872167893283, 0.021474104640702263, -0.028906670239839186, 0.10986507248713982, -0.016416946140447582, -0.0031706388100968641, -0.024142520265522237, -0.16347010386539823, -0.0068807006172086956, -0.009484951819502159, -0.32097682564372548 }, + { 0.025027597690085727, 0.023116577698323981, 0.025647750389152277, -0.12432191956313283, 0.089919395416061254, -0.0010032178808474397, 0.034154216316645537, -0.073258150208852735, -0.0082717048276847, -0.0085013713591728639, -0.040036418368419674, 0.10654199196017296, -0.0718813141234634, 0.031808510122176871, 0.23115055590279554 }, + { -0.075488177284467092, -0.071776660282181742, 0.046468262983681195, -0.092264487663929889, -0.027683218739383321, -0.072597712633641717, 0.067382637821066, 0.02321485385353372, 0.0947743774627414, 0.098261285016872743, 0.029554223554100867, 0.12241571210613868, -0.024534925571359945, -0.0703515457144001, 0.17761444776547267 }, + { -0.049027426344744357, -0.016233511692686296, 0.0025759638168079985, 0.10159921434214048, -0.11211756309722204, -0.012775672474882057, -0.020566830347744265, 0.077375715953660065, -0.00901379843145126, 0.018255542784233136, 0.018419875764159, -0.098256794011679527, 0.026959425877853813, -0.019700315948286546, -0.21723340664627469 }, + { -0.020940553543628962, -0.04054794998219742, 0.14727098125947621, -0.012125578793213689, 0.017852107734153692, -0.039878508384314948, 0.096235470430363346, 0.17788554639715984, 0.049756934384053396, 0.057923047790416141, -0.00038416347031019148, 0.0033584995501507457, -0.00959222750780903, -0.036174102197861, 0.030642141424393261 }, + { 0.034699909577602606, 0.051338155809273957, -0.00072752642213258934, 0.064923450941197211, -0.0016719255983632354, 0.052965507802081313, -0.037177940935703119, 0.013456246605129727, -0.055606306967696015, -0.05425776251520692, -0.017599910825923836, -0.074992072717836242, 0.0093885723375285012, 0.048547335615615493, -0.13482402222190409 }, + { -0.043079593064996757, -0.052204622617255239, 0.018383175102716375, -0.043010836505462433, -0.026918120343519612, -0.056104371864350709, 0.029348832949610125, 0.043945454130226734, 0.062402159322316457, 0.062207673704178408, 0.029038007062175294, 0.0489008760884029, 0.010826822062293517, -0.048948940132146929, 0.046782516272861584 }, + {-0.15387908842516629, -0.073666239607598, 0.010689026646281461, 0.061503377425313747, -0.11226161852298806, -0.017443019416759083, 0.00891507284904646, 0.055735512430850107, 0.084809779500954877, 0.10033908241902251, 0.05068512638056779, -0.02935751603086947, 0.0774266173283182, -0.064498073470460063, 0.06618956627205716 }, + { 0.01400914038724874, 0.022935140332806577, -0.066490517571514182, -0.00061334513341812318, 0.023068981418270219, 0.04112798978856741, -0.076056709248761692, -0.12567592114978585, -0.022355279112106059, -0.031655532130436738, -0.00592269608855733, 0.0055763285280232226, 0.023941474706561956, 0.026576132940705939, 0.042327903821042796 } + }; + static const double b3[ 15 ] = { 0.1509159451715264, 0.17903151894955524, -0.054927917643813065, 0.17645237894737631, 0.085211944671718623, 0.15677750602438928, -0.042998239500351622, -0.097006998042479781, -0.21956481772061825, -0.18646731717119161, -0.068028663170147621, -0.1808114370372878, 0.0043667745382358356, 0.17910630761441323, -0.25518080682851763 }; + + double v4[ 15 ]; + + static const double a4[ 15 ][ 3 ] = { + { 0.34160071894678073, -0.37217567814406566, -0.073438174683426644 }, + { 0.2360609485928192, -0.081649836378150389, -0.30137781342003234 }, + { -0.16528594248952178, -0.2014456466455789, -0.614197570055916 }, + { -0.66044563888392227, -0.2741627898810618, -0.22696915173429449 }, + { 0.29294219502893032, -0.28563231191573507, 0.03767334742521089 }, + { 0.201416479572921, -0.06654539462054769, -0.28039792906531968 }, + { -0.37742707540375364, -0.16743165065926807, -0.36936426969147412 }, + { 0.12804178546710865, -0.30228226041438511, -0.87011334739184454 }, + { -0.27609956512411193, 0.0735728127187767, 0.36535986126768921 }, + { -0.36049372632169013, 0.14942055814470945, 0.26730928760533818 }, + { -0.23004922243116888, 0.098427096299886385, 0.16286408757819881 }, + { 0.76831346894351393, 0.15776570668042308, 0.14926347945128754 }, + { -0.3120979030694791, 0.1159212556012188, -0.15780333650988518 }, + { 0.16572871133416767, -0.12086663847069315, -0.22639716104184104 }, + { 1.0773969011791018, 0.074120128836744542, 0.028591035907610123 } + }; + static const double b4[ 3 ] = { 0.35004631807090653, -0.11700815424551032, -0.54618213782366509 }; + + static const double ao[ 3 ] = { 0.236034641103551, 5.09429075779317, 1.80332235534696 }; + static const double bo[ 3 ] = { 3.1380831408776, 0.887875288683602, -0.348013856812933 }; + + /* Input */ + for ( int k = 0; k < 4; k++ ) { + v1[ k ] = ( X[ k ] - bi[ k ] ) * ai[ k ]; + } + + /* Layer 1 */ + /* Sigmoid Symmetric Transfer Function */ + for ( int k = 0; k < 50; k++ ) { + double d = 0.; + for ( int l = 0; l < 4; l++ ) { + d += a1[ l ][ k ] * v1[ l ]; + } + + v2[ k ] = 2. / ( 1. + exp( -2. * ( d + b1[ k ] ) ) ) - 1.; + } + + /* Layer 2 */ + /* Sigmoid Symmetric Transfer Function */ + for ( int k = 0; k < 45; k++ ) { + double d = 0.; + for ( int l = 0; l < 50; l++ ) { + d += a2[ l ][ k ] * v2[ l ]; + } + + v3[ k ] = 2. / ( 1. + exp( -2. * ( d + b2[ k ] ) ) ) - 1.; + } + + /* Layer 3 */ + /* Sigmoid Symmetric Transfer Function */ + for ( int k = 0; k < 15; k++ ) { + double d = 0.; + for ( int l = 0; l < 45; l++ ) { + d += a3[ l ][ k ] * v3[ l ]; + } + + v4[ k ] = 2. / ( 1. + exp( -2. * ( d + b3[ k ] ) ) ) - 1.; + } + + /* Output 1 */ + /* Map Standard Deviation and Mean Output Reverse-Processing Function */ + for ( int k = 0; k < 3; k++ ) { + double d = 0.; + for ( int l = 0; l < 15; l++ ) { + d += a4[ l ][ k ] * v4[ l ]; + } + + Y[ k ] = ( ( d + b4[ k ] ) / ao[ k ] ) + bo[ k ]; + } +} diff --git a/collresolve/cambioni2019/orbital_hnr.h b/collresolve/cambioni2019/orbital_hnr.h new file mode 100644 index 000000000..5af23c096 --- /dev/null +++ b/collresolve/cambioni2019/orbital_hnr.h @@ -0,0 +1,6 @@ +#ifndef ORBITAL_HNR_H +#define ORBITAL_HNR_H + +void orbital_hnr( const double X[ 4 ], double Y[ 3 ] ); + +#endif diff --git a/collresolve/collresolve.c b/collresolve/collresolve.c new file mode 100644 index 000000000..7c3b40f44 --- /dev/null +++ b/collresolve/collresolve.c @@ -0,0 +1,1364 @@ +/** + * Main implementation of the collresolve library. + * + * Copyright (c) 2016-2017 University of Bern, Switzerland + * Copyright (c) 2018-2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * If you use this library in a scientific work that lead to publication, + * we would like you to acknowledge the following article: + * Emsenhuber, A., Cambioni S., Asphaug, E., Gabriel, T. S. J., Schwartz, S. R., and Furfaro, R. (in prep.). Realistic On-the-fly Outcomes of Planetary Collisions II: Bringing Machine Learning to N-body Simulations. + * + * If you use the LS2012 model, you should also cite: + * Leinhardt, Z. M. and Stewart, S. T. (2012). Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling Laws. The Astrophysical Journal, 745(1), 79. doi:10.1088/0004-637X/745/1/79 bib:2012ApJ...745...79L + * + * If you use the SL2012 model, you should also cite the same publication as for LS2012, and: + * Stewart, S. T. and Leinhardt, Z. M. (2012). Collisions between Gravity-dominated Bodies. II. The Diversity of Impact Outcomes during the End Stage of Planet Formation. The Astrophysical Journal, 751(1), 32. doi:10.1088/0004-637X/751/1/32 bib:2012ApJ...751...32S + * Genda, H., Kokubo, E., and Ida, S. (2012). Merging Criteria for Giant Impacts of Protoplanets. The Astrophysical Journal, 744(2), 137. doi:10.1088/0004-637X/744/2/137 bib:2012ApJ...744..137G + * + * If you use the C2019 model, you should also cite: + * Cambioni, S., Asphaug, E., Emsenhuber, A., Gabriel, T. S. J., Furfaro, R., and Schwartz, S. R. (2019). Realistic On-the-fly Outcomes of Planetary Collisions: Machine Learning Applied to Simulations of Giant Impacts. The Astrophysical Journal, 875(1), 40. doi:10.3847/1538-4357/ab0e8a bib:2019ApJ...875...40C + * + * @file + * @author Alexandre Emsenhuber + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "collresolve.h" + +/** + * Cambioni et al. (2019) surrogate model. + */ +#include "cambioni2019/accretion_efficiency.h" +#include "cambioni2019/collision_classifier.h" +#include "cambioni2019/orbital_hnr.h" + +/** + * The gravity constant in SI units. + * Value is from CODATA 2014: G = 6.67408(31) * 10^-11 kg^-1 m^3 s^-2 + */ +#define GRAV_SI 6.67408e-11 + +/** + * An astronomical unit expressed in SI unit; definition of 2012 + */ +#define AU_SI 149597870700. + +/** + * A day in SI units + */ +#define DAY_SI 86400. + +/** + * Following values are from IAU 2015 Resolution B3. + * They are conversion factors only; not true values. + */ +#define R_E_E 6.3781e6 +#define R_E_P 6.3568e6 +#define R_J_E 7.1492e7 +#define R_J_P 6.6854e7 +#define R_S 6.957e8 +#define GM_E 3.986004e14 +#define GM_J 1.2668653e17 +#define GM_S 1.3271244e20 + +/** + * The configuration object. + * + * It is not part of the public interface. + */ + +struct collresolve_conf { + size_t model; + double G; + double mEarth; + double refDens; + double drel; +}; + +/** + * Common quantities for a collision + */ +struct collresolve_quant { + double total_mass; + double reduced_mass; + double total_radius; + + double dpos_sq; + double dvel_sq; + + double specific_energy; + double impact_velocity_sq; + double escape_velocity_sq; + double impact_parameter; +}; + +/** + * Function to get an user-friendly error message + */ +char* collresolve_model_desc( int model ) { + if ( model == COLLRESOLVE_MODEL_PERFECT_MERGE ) { + return "Perfect mergering"; + } else if ( model == COLLRESOLVE_MODEL_LS2012 ) { + return "Leinhardt & Stewart (2012)"; + } else if ( model == COLLRESOLVE_MODEL_SL2012 ) { + return "Stewart & Leinhardt (2012)"; + } else if ( model == COLLRESOLVE_MODEL_C2019 ) { + return "Cambioni et al. (2019)"; + } else { + return NULL; + } +} + +/** + * Function to get an user-friendly error message + */ +char* collresolve_regime_desc( int regime ) { + if ( regime == COLLRESOLVE_REGIME_MERGE ) { + return "Merger"; + } else if ( regime == COLLRESOLVE_REGIME_DISRUPTION ) { + return "Disruption"; + } else if ( regime == COLLRESOLVE_REGIME_SUPERCATASTROPHIC ) { + return "Super catastrophic"; + } else if ( regime == COLLRESOLVE_REGIME_GRAZE_AND_MERGE ) { + return "Graze and merge"; + } else if ( regime == COLLRESOLVE_REGIME_HIT_AND_RUN ) { + return "Hit and run"; + } else { + return NULL; + } +} + +/** + * Function to get an user-friendly error message + */ +char* collresolve_error_message( int error ) { + if ( error == COLLRESOLVE_ERROR_GENERAL ) { + return "General error"; + } else if ( error == COLLRESOLVE_ERROR_NO_CONF ) { + return "No configuration set"; + } else if ( error == COLLRESOLVE_ERROR_INCORRECT_PARAMETER ) { + return "Incorrect parameter provided"; + } else if ( error == COLLRESOLVE_ERROR_INCORRECT_MODEL ) { + return "Incorrect model"; + } else if ( error == COLLRESOLVE_ERROR_INCORRECT_UNIT ) { + return "Incorrect unit system configured"; + } else if ( error == COLLRESOLVE_ERROR_NON_CROSSING ) { + return "Non-crossing orbit"; + } else { + return "Unknown error code"; + } +} + +/** + * Functions to set the configuration + */ + +struct collresolve_conf* collresolve_conf_new() { + struct collresolve_conf* ret = calloc( 1, sizeof( struct collresolve_conf ) ); + ret->model = COLLRESOLVE_MODEL_NONE; + return ret; +} + +void collresolve_conf_free( struct collresolve_conf* conf ) { + free( conf ); +} + +int collresolve_conf_unit_si( struct collresolve_conf* conf ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + conf->G = GRAV_SI; + conf->mEarth = GM_E / GRAV_SI; + conf->refDens = 1000.; + + return 1; +} + +int collresolve_conf_unit_msun_au_day( struct collresolve_conf* conf ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + const double mass = GM_S / GRAV_SI; /* Mass of the sun; the IAU way */ + const double dist = AU_SI; + const double time = DAY_SI; + const double vol = dist * dist * dist; + + conf->G = GM_S * time * time / vol; + conf->mEarth = GM_E / GM_S; + conf->refDens = 1000. * vol / mass; + + return 1; +} + +int collresolve_conf_unit_m_earth( struct collresolve_conf* conf ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + const double mass = GM_E / GRAV_SI; /* Mass of the earth; the IAU way */ + + conf->G = GM_E; + conf->mEarth = mass; + conf->refDens = 1000. / mass; + + return 1; +} + +int collresolve_conf_unit_merc( struct collresolve_conf* conf ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + const double mass = 1.9891e30; + const double dist = 1.4959787e11; + const double vol = dist * dist * dist; + + conf->G = 2.959122082855911e-4; + conf->mEarth = GM_E / GM_S; + conf->refDens = 1000. * vol / mass; + + return 1; +} + +int collresolve_conf_model( struct collresolve_conf* conf, int model ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + if ( model == COLLRESOLVE_MODEL_NONE || model == COLLRESOLVE_MODEL_PERFECT_MERGE || model == COLLRESOLVE_MODEL_LS2012 || model == COLLRESOLVE_MODEL_SL2012 || model == COLLRESOLVE_MODEL_C2019 ) { + conf->model = model; + return 1; + } else { + return COLLRESOLVE_ERROR_INCORRECT_MODEL; + } +} + +int collresolve_conf_sep_after( struct collresolve_conf* conf, double drel ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + if ( drel >= 1. ) { + conf->drel = drel; + return 1; + } else { + return COLLRESOLVE_ERROR_INCORRECT_PARAMETER; + } +} + +/** + * Body setup functions + * @{ + */ + +/** + * Retrieve the bulk density for a given model and mass + * + * For now this always provide the bulk density associated with the mass of the Cambioni et al. (2019) model (i.e. MODEL_C2019). + */ +double collresolve_bulk_density( struct collresolve_conf* conf, double mass ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return (double)COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + double mscale = mass / conf->mEarth; + + /* Masses in Earth mass */ + double ms[] = { + 1.0e-3, + 2.0e-3, + 3.5e-3, + 5.0e-3, + 7.0e-3, + 9.0e-3, + 1.0e-2, + 2.0e-2, + 3.5e-2, + 5.0e-2, + 7.0e-2, + 9.0e-2, + 1.0e-1, + 2.0e-1, + 3.5e-1, + 5.0e-1, + 7.0e-1, + 9.0e-1, + 1.0e0 + }; + + /* Corresponding density (in terms of the reference density) */ + double ds[] = { + 3.1017, + 3.1168, + 3.1348, + 3.1499, + 3.1688, + 3.1850, + 3.1928, + 3.2582, + 3.3344, + 3.3986, + 3.4688, + 3.5303, + 3.5605, + 3.8758, + 4.2942, + 4.5702, + 4.8341, + 5.0417, + 5.1251 + }; + + if ( mscale <= ms[ 0 ] ) { + return ds[ 0 ] * conf->refDens; + } + + int i; + for ( i = 0; i < 19; i++ ) { + if ( mscale >= ms[ i ] && mscale < ms[ i + 1 ] ) { + double lm = log( mscale ); + double ll = log( ms[ i ] ); + double lh = log( ms[ i + 1 ] ); + double f = ( lm - ll ) / ( lh - ll ); + return ( ds[ i + 1 ] * f + ds[ i ] * ( 1. - f ) ) * conf->refDens; + } + } + + /* Extrapolation using the low last data points. */ + double lm = log( mscale ); + double ll = log( ms[ 17 ] ); + double lh = log( ms[ 18 ] ); + double f = ( lm - ll ) / ( lh - ll ); + return ( ds[ 18 ] * f + ds[ 17 ] * ( 1. - f ) ) * conf->refDens; +} + +/** + * Set a consistent body radius depending on the model and other body properties. + * + * For now this always provide the radius associated with the mass of the Cambioni et al. (2019) model (i.e. MODEL_C2019). + */ +int collresolve_body_radius( struct collresolve_conf* conf, struct collresolve_body* body ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + if ( body == NULL ) { + return COLLRESOLVE_ERROR_INCORRECT_PARAMETER; + } + + double dens = collresolve_bulk_density( conf, body->mass ); + + if ( dens < 0 ) { + return (int)( dens - 0.5 ); + } + + body->radius = cbrt( 3. / 4. / M_PI * body->mass / dens ); + + return 1; +} + +/** @} */ + +/** + * Collision setup functions + * @{ + */ + +void collresolve_setup( struct collresolve_conf* conf, struct collresolve_body* big, struct collresolve_body* small, double velocity, double angle ) { + const double total_radius = big->radius + small->radius; + + collresolve_setup_dist( conf, big, small, total_radius, velocity, angle ); +} + +void collresolve_setup_dist( struct collresolve_conf* conf, struct collresolve_body* big, struct collresolve_body* small, double distance, double velocity, double angle ) { + const double total_mass = big->mass + small->mass; + + const double big_factor = -small->mass / total_mass; + const double small_factor = big->mass / total_mass; + + const double dpos_x = distance; + const double dpos_y = 0.; + const double dpos_z = 0.; + + const double dvel_x = -cos( angle ) * velocity; + const double dvel_y = sin( angle ) * velocity; + const double dvel_z = 0.; + + big->pos[0] = dpos_x * big_factor; + big->pos[1] = dpos_y * big_factor; + big->pos[2] = dpos_z * big_factor; + big->vel[0] = dvel_x * big_factor; + big->vel[1] = dvel_y * big_factor; + big->vel[2] = dvel_z * big_factor; + + small->pos[0] = dpos_x * small_factor; + small->pos[1] = dpos_y * small_factor; + small->pos[2] = dpos_z * small_factor; + small->vel[0] = dvel_x * small_factor; + small->vel[1] = dvel_y * small_factor; + small->vel[2] = dvel_z * small_factor; +} + +/** + * @} + */ + +/** + * Functions for quantities + * @{ + */ + +void collresolve_quant_init( struct collresolve_quant* pquant ) { + const double nan = strtod( "NAN", NULL ); + + pquant->total_mass = nan; + pquant->reduced_mass = nan; + pquant->total_radius = nan; + + pquant->dpos_sq = nan; + pquant->dvel_sq = nan; + + pquant->specific_energy = nan; + pquant->impact_velocity_sq = nan; + pquant->escape_velocity_sq = nan; + pquant->impact_parameter = nan; +} + +#define INIT_QUANT struct collresolve_quant quant; \ + struct collresolve_quant* pquant = &quant; \ + collresolve_quant_init( pquant ); \ + struct collresolve_body* pbig = &big; \ + struct collresolve_body* psmall = &small; + +double collresolve_quant_total_mass( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->total_mass != pquant->total_mass ) { + pquant->total_mass = pbig->mass + psmall->mass; + } + + return pquant->total_mass; +} + +#define TOTAL_MASS collresolve_quant_total_mass( conf, pbig, psmall, pquant ) + +double collresolve_quant_reduced_mass( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->reduced_mass != pquant->reduced_mass ) { + pquant->reduced_mass = ( pbig->mass * psmall->mass ) / TOTAL_MASS; + } + + return pquant->reduced_mass; +} + +#define REDUCED_MASS collresolve_quant_reduced_mass( conf, pbig, psmall, pquant ) + +double collresolve_quant_total_radius( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->total_radius != pquant->total_radius ) { + pquant->total_radius = pbig->radius + psmall->radius; + } + + return pquant->total_radius; +} + +#define TOTAL_RADIUS collresolve_quant_total_radius( conf, pbig, psmall, pquant ) + +double collresolve_quant_dpos_sq( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->dpos_sq != pquant->dpos_sq ) { + pquant->dpos_sq = ( pbig->pos[0] - psmall->pos[0] ) * ( pbig->pos[0] - psmall->pos[0] ) + ( pbig->pos[1] - psmall->pos[1] ) * ( pbig->pos[1] - psmall->pos[1] ) + ( pbig->pos[2] - psmall->pos[2] ) * ( pbig->pos[2] - psmall->pos[2] ); + } + + return pquant->dpos_sq; +} + +#define DPOS_SQ collresolve_quant_dpos_sq( conf, pbig, psmall, pquant ) + +double collresolve_quant_dvel_sq( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->dvel_sq != pquant->dvel_sq ) { + pquant->dvel_sq = ( pbig->vel[0] - psmall->vel[0] ) * ( pbig->vel[0] - psmall->vel[0] ) + ( pbig->vel[1] - psmall->vel[1] ) * ( pbig->vel[1] - psmall->vel[1] ) + ( pbig->vel[2] - psmall->vel[2] ) * ( pbig->vel[2] - psmall->vel[2] ); + } + + return pquant->dvel_sq; +} + +#define DVEL_SQ collresolve_quant_dvel_sq( conf, pbig, psmall, pquant ) + +double collresolve_quant_specific_energy( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->specific_energy != pquant->specific_energy ) { + pquant->specific_energy = REDUCED_MASS * ( DVEL_SQ / TOTAL_MASS / 2. + conf->G * ( 1. / TOTAL_RADIUS - 1. / sqrt( DPOS_SQ ) ) ); + } + + return pquant->specific_energy; +} + +#define SPECIFIC_ENERGY collresolve_quant_specific_energy( conf, pbig, psmall, pquant ) + +double collresolve_quant_impact_velocity_sq( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->impact_velocity_sq != pquant->impact_velocity_sq ) { + pquant->impact_velocity_sq = 2. * SPECIFIC_ENERGY * TOTAL_MASS / REDUCED_MASS; + } + + return pquant->impact_velocity_sq; +} + +#define IMPACT_VELOCITY_SQ collresolve_quant_impact_velocity_sq( conf, pbig, psmall, pquant ) + +double collresolve_quant_escape_velocity_sq( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->escape_velocity_sq != pquant->escape_velocity_sq ) { + pquant->escape_velocity_sq = 2. * conf->G * TOTAL_MASS / TOTAL_RADIUS; + } + + return pquant->escape_velocity_sq; +} + +#define ESCAPE_VELOCITY_SQ collresolve_quant_escape_velocity_sq( conf, pbig, psmall, pquant ) + +double collresolve_quant_impact_parameter( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_quant* pquant ) { + if ( pquant->impact_parameter != pquant->impact_parameter ) { + const double dpos_x = psmall->pos[0] - pbig->pos[0]; + const double dpos_y = psmall->pos[1] - pbig->pos[1]; + const double dpos_z = psmall->pos[2] - pbig->pos[2]; + + const double dvel_x = psmall->vel[0] - pbig->vel[0]; + const double dvel_y = psmall->vel[1] - pbig->vel[1]; + const double dvel_z = psmall->vel[2] - pbig->vel[2]; + + const double h_x = dpos_y * dvel_z - dpos_z * dvel_y; + const double h_y = dpos_z * dvel_x - dpos_x * dvel_z; + const double h_z = dpos_x * dvel_y - dpos_y * dvel_x; + + const double h_sq = h_x * h_x + h_y * h_y + h_z * h_z; + + pquant->impact_parameter = sqrt( h_sq / ( TOTAL_RADIUS * TOTAL_RADIUS * IMPACT_VELOCITY_SQ ) ); + } + + return pquant->impact_parameter; +} + +#define IMPACR_PARAMETER collresolve_quant_impact_parameter( conf, pbig, psmall, pquant ) + +/** + * @} + */ + +/** + * Collision functions + * @{ + */ + +double collresolve_specific_energy( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return (double)COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + INIT_QUANT; + + return SPECIFIC_ENERGY; +} + +double collresolve_impact_distance( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + INIT_QUANT; + + return TOTAL_RADIUS; +} + +double collresolve_impact_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return (double)COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + INIT_QUANT; + + return sqrt( IMPACT_VELOCITY_SQ ); +} + +double collresolve_escape_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return (double)COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + INIT_QUANT; + + return sqrt( ESCAPE_VELOCITY_SQ ); +} + +double collresolve_infinity_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return (double)COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + INIT_QUANT; + + const double dvel_inf_sq = DVEL_SQ - 2. * conf->G * TOTAL_MASS / sqrt( DPOS_SQ ); + return dvel_inf_sq >= 0. ? sqrt( dvel_inf_sq ) : -sqrt( -dvel_inf_sq ); +} + +double collresolve_impact_parameter( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + INIT_QUANT; + + return IMPACR_PARAMETER; +} + +double collresolve_impact_angle( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ) { + if ( conf == NULL ) { + return (double)COLLRESOLVE_ERROR_NO_CONF; + } + + INIT_QUANT; + + const double impact_para = IMPACR_PARAMETER; + + if ( impact_para > 1. ) { + return (double)COLLRESOLVE_ERROR_NON_CROSSING; + } + + return asin( impact_para ); +} + +/** + * @} + */ + +/** + * The perfect merging case. + * + * Returns a single object, containing all the mass and follows the trajectory of the center of mass. + */ +int collresolve_resolve_merge( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small, int n, struct collresolve_body ret[], int regime ) { + if ( n < 0 ) { + return COLLRESOLVE_ERROR_INCORRECT_PARAMETER; + } + + const double total_mass = big.mass + small.mass; + const double big_factor = big.mass / total_mass; + const double small_factor = small.mass / total_mass; + + /* Perfect merging */ + /* Radius of the resulting body is determined assuming it has the same density as the most massive body. */ + ret[0].mass = total_mass; + ret[0].radius = big.radius * cbrt( total_mass / big.mass ); + ret[0].pos[0] = big.pos[0] * big_factor + small.pos[0] * small_factor; + ret[0].pos[1] = big.pos[1] * big_factor + small.pos[1] * small_factor; + ret[0].pos[2] = big.pos[2] * big_factor + small.pos[2] * small_factor; + ret[0].vel[0] = big.vel[0] * big_factor + small.vel[0] * small_factor; + ret[0].vel[1] = big.vel[1] * big_factor + small.vel[1] * small_factor; + ret[0].vel[2] = big.vel[2] * big_factor + small.vel[2] * small_factor; + + /* Nothing else remaining */ + int i; + for ( i = 1; i <= n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + + return regime; +} + +/** + * Compute the position and velocity of the second largest remnant in the general case. + * + * A two-bodies problem is assumed. + */ +void collresolve_resolve_posvel_slr( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_body* plr, struct collresolve_body* pslr ) { + const double drel = conf->drel == 0. ? 1.01 : conf->drel; + + const double mu = conf->G * ( pbig->mass + psmall->mass ); + + const double dpos_x = psmall->pos[0] - pbig->pos[0]; + const double dpos_y = psmall->pos[1] - pbig->pos[1]; + const double dpos_z = psmall->pos[2] - pbig->pos[2]; + + const double dvel_x = psmall->vel[0] - pbig->vel[0]; + const double dvel_y = psmall->vel[1] - pbig->vel[1]; + const double dvel_z = psmall->vel[2] - pbig->vel[2]; + + const double h_x = dpos_y * dvel_z - dpos_z * dvel_y; + const double h_y = dpos_z * dvel_x - dpos_x * dvel_z; + const double h_z = dpos_x * dvel_y - dpos_y * dvel_x; + + const double dpos_sq = dpos_x * dpos_x + dpos_y * dpos_y + dpos_z * dpos_z; + /* const double dvel_sq = dvel_x * dvel_x + dvel_y * dvel_y + dvel_z * dvel_z; */ + const double h_sq = h_x * h_x + h_y * h_y + h_z * h_z; + + const double dpos = sqrt( dpos_sq ); + const double p = h_sq / mu; + + /* Eccentricity vector, point along the semi-major axis */ + const double e_x = ( dvel_y * h_z - dvel_z * h_y ) / mu - dpos_x / dpos; + const double e_y = ( dvel_z * h_x - dvel_x * h_z ) / mu - dpos_y / dpos; + const double e_z = ( dvel_x * h_y - dvel_y * h_x ) / mu - dpos_z / dpos; + const double e = sqrt( e_x * e_x + e_y * e_y + e_z * e_z ); + const double a = p / ( 1. - e * e ); + + const double r = drel * ( plr->radius + pslr->radius ); + const double cf = ( ( a / r ) * ( 1 - e * e ) - 1. ) / e; /* cos(true anomaly) */ + const double sf = sqrt( 1. - cf * cf ); /* sin(true anomaly) */ + + const double v = sqrt( mu / p ); + const double cv = -sf; + const double sv = e + cf; + + /* Direction of the minor axis */ + const double q_x = h_y * e_z - h_z * e_y; + const double q_y = h_z * e_x - h_x * e_z; + const double q_z = h_x * e_y - h_y * e_x; + const double q = sqrt( q_x * q_x + q_y * q_y + q_z * q_z ); + + pslr->pos[0] = plr->pos[0] + r * ( e_x / e * cf + q_x / q * sf ); + pslr->pos[1] = plr->pos[1] + r * ( e_y / e * cf + q_y / q * sf ); + pslr->pos[2] = plr->pos[2] + r * ( e_z / e * cf + q_z / q * sf ); + + pslr->vel[0] = plr->vel[0] + v * ( e_x / e * cv + q_x / q * sv ); + pslr->vel[1] = plr->vel[1] + v * ( e_y / e * cv + q_y / q * sv ); + pslr->vel[2] = plr->vel[2] + v * ( e_z / e * cv + q_z / q * sv ); +} + +/** + * Compute the position and velocity of the second largest remnant in case there is no mass loss. + * + * We use momentum and angular momentum conservation to determine its orbit. + */ +void collresolve_resolve_posvel_slr_tot( struct collresolve_conf* conf, struct collresolve_body* pbig, struct collresolve_body* psmall, struct collresolve_body* plr, struct collresolve_body* pslr ) { + const double drel = conf->drel == 0. ? 1.01 : conf->drel; + + const double dpos_x = psmall->pos[0] - pbig->pos[0]; + const double dpos_y = psmall->pos[1] - pbig->pos[1]; + const double dpos_z = psmall->pos[2] - pbig->pos[2]; + + const double dvel_x = psmall->vel[0] - pbig->vel[0]; + const double dvel_y = psmall->vel[1] - pbig->vel[1]; + const double dvel_z = psmall->vel[2] - pbig->vel[2]; + + const double h_x = dpos_y * dvel_z - dpos_z * dvel_y; + const double h_y = dpos_z * dvel_x - dpos_x * dvel_z; + const double h_z = dpos_x * dvel_y - dpos_y * dvel_x; + + /* Momentum conservation */ + pslr->vel[0] = (pbig->vel[0] * pbig->mass + psmall->vel[0] * psmall->mass - plr->vel[0] * plr->mass) / pslr->mass; + pslr->vel[1] = (pbig->vel[1] * pbig->mass + psmall->vel[1] * psmall->mass - plr->vel[1] * plr->mass) / pslr->mass; + pslr->vel[2] = (pbig->vel[2] * pbig->mass + psmall->vel[2] * psmall->mass - plr->vel[2] * plr->mass) / pslr->mass; + + /* The new velocity difference */ + const double avel_x = pslr->vel[0] - plr->vel[0]; + const double avel_y = pslr->vel[1] - plr->vel[1]; + const double avel_z = pslr->vel[2] - plr->vel[2]; + + /* Direction where to put the new object, perpendicular to both h and v (i.e. the component that gives angular momentum) */ + const double apos_x = avel_y * h_z - avel_z * h_y; + const double apos_y = avel_z * h_x - avel_x * h_z; + const double apos_z = avel_x * h_y - avel_y * h_x; + + const double h_sq = h_x * h_x + h_y * h_y + h_z * h_z; + const double avel_sq = avel_x * avel_x + avel_y * avel_y + avel_z * avel_z; + const double apos_sq = apos_x * apos_x + apos_y * apos_y + apos_z * apos_z; + + /* The distance (squared) along apos and avel where to place the object */ + const double rpos_sq = h_sq / avel_sq; + const double rvel_sq = drel * drel * (plr->radius + pslr->radius) * (plr->radius + pslr->radius) - rpos_sq; + + const double rpos = sqrt( rpos_sq / apos_sq ); + const double rvel = rvel_sq > 0. ? sqrt( rvel_sq / avel_sq ) : 0.; // Just to be sure + + /* Angular momentum conservation */ + pslr->pos[0] = plr->pos[0] + apos_x * rpos + avel_x * rvel; + pslr->pos[1] = plr->pos[1] + apos_y * rpos + avel_y * rvel; + pslr->pos[2] = plr->pos[2] + apos_z * rpos + avel_z * rvel; +} + +/** + * The Leinhardt & Stewart (2012) and Stewart & Leinhardt (2012) model. + * + * References to equations are to the ones in the former of the above mentionned articles. + * References to the procedure are to the appendix of the same article. + */ +int collresolve_resolve_ls2012( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small, int n, struct collresolve_body ret[], int flags ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + if ( n < 0 ) { + return COLLRESOLVE_ERROR_INCORRECT_PARAMETER; + } else if ( n == 0 ) { + return collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_MERGE ); + } + + INIT_QUANT; + + /* Common stuff */ + const double m_tot = TOTAL_MASS; + const double gamma = small.mass / big.mass; + const double mu = REDUCED_MASS; + const double r_tot = TOTAL_RADIUS; + const double Q_R = SPECIFIC_ENERGY; + + /* Impact quantities */ + const double b = IMPACR_PARAMETER; + const double vel_sq = IMPACT_VELOCITY_SQ; + + if ( b > 1. ) { + return COLLRESOLVE_ERROR_NON_CROSSING; + } + + /* Pt 1 */ + const double l = r_tot * ( 1. - b ); + const double alpha = l > 2. * small.radius ? 1 : 0.25 * l * l * ( 3 * small.radius - l ) / ( small.radius * small.radius * small.radius ); + const double m_interact = alpha * small.mass; + const double m_coll = big.mass + m_interact; /* M' in LS2012 */ + const double big_rho = big.mass / ( 4. / 3. * M_PI * big.radius * big.radius * big.radius ); + const double r_coll = cbrt( 0.75 / M_PI * m_coll / big_rho ); /* R' in LS2012 */ + const double r_coll_tot = cbrt( 0.75 / M_PI * m_tot / big_rho ); /* same as R' but for the total mass */ + + /* Pt 2 */ + const double v_p_sq = 2. * m_tot * ( DVEL_SQ / m_tot / 2. + conf->G * ( 1. / r_coll_tot - 1. / sqrt( DPOS_SQ ) ) ); /* TODO: CHECK THIS */ + const double v_esc_p_sq = 2. * conf->G * m_coll / r_coll; /* Eq. (55) but squared */ + + if ( v_p_sq < v_esc_p_sq ) { + /* Perfect merging */ + return collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_MERGE ); + } + + /* Pt 3 */ + const double b_crit = big.radius / r_tot; /* Eq. (6) */ + const int grazing = ( b > b_crit ) ? 1 : 0; + + /* Pt 4 */ + /* a */ + const double rc1 = cbrt( 0.75 / M_PI * m_tot / conf->refDens ); + + /* b */ + const double c_star = 1.9; // Fixme, set text bottom right page 9 + const double Q_star_RD_1 = c_star * 0.8 * M_PI * conf->refDens * conf->G * rc1 * rc1; /* Eq. (28) */ + /* const double V_star_1 = sqrt( 6.4 * M_PI * c_star * conf->refDens * conf->G ) * rc1; */ /* Eq. (30) */ + + /* c */ + const double mu_alpha = ( alpha * big.mass * small.mass ) / ( big.mass + alpha * small.mass ); // Eq. (12) + + /* d */ + const double mu_bar = 0.36; // Same as for c_star + const double gamma_term = ( ( gamma + 1. ) * ( gamma + 1. ) / ( 4. * gamma ) ); + const double Q_star_RD = Q_star_RD_1 * pow( gamma_term, 2. / ( 3. * mu_bar ) - 1. ); /* Eq. (23) */ + /* const double V_star = V_star_1 * pow( gamma_term, 1. / ( 3. * mu_bar ) ); */ /* Eq. (22) */ + + /* e */ + const double Q_prime_star_RD = Q_star_RD * pow( mu / mu_alpha, 2. - 3. * mu_bar / 2. ); /* Eq. (15) */ + /* const double V_prime_star = V_star * sqrt( 2. * Q_prime_star_RD * m_tot / mu ); */ /* Eq. (16) */ + + /* Pt 5 */ + const double Q_R_erosion = Q_prime_star_RD * 2. * gamma / ( gamma + 1. ); // From eq. (5) and a sheet of paper + /* const double V_erosion_sq = sqrt( 2. * Q_R_erosion * m_tot / mu ); */ /* From eq. (1) and a sheet of paper, but squared */ + + /* Pt 7 */ + const double Q_R_supercat = 1.8 * Q_prime_star_RD; /* From eq. (5) and a sheet of paper */ + //const double V_supercat_sq = 2. * Q_R_supercat * m_tot / mu; */ /* From eq. (1) and a sheet of paper, but squared */ + + const double p_big = b > 0.7 ? 1. : 1. - ( b / 0.7 ) * ( small.mass / m_tot ); + const double p_small = b > 0.7 ? 0. : ( b / 0.7 ) * ( small.mass / m_tot ); + + /* Graze-and-Merge regime from Kokubo & Ida (2012); only used in the Stewart & Leinhardt (2012) model */ + const double xi = ( big.mass - small.mass ) / m_tot; + const double b_para_gnm = pow( 1. - b, 2.5 ); + const double vel_hr = 2.43 * xi * xi * b_para_gnm - 0.0408 * xi * xi + 1.86 * b_para_gnm + 1.08; + + if ( Q_R > Q_R_supercat ) { + /* Supercatastrophic; pt 9 */ + ret[0].mass = 0.1 * m_tot * pow( Q_R / Q_prime_star_RD / 1.8, -1.5 ); + ret[0].radius = cbrt( 0.75 / M_PI * ret[0].mass / big_rho ); + ret[0].pos[0] = big.pos[0] * p_big + small.pos[0] * p_small; + ret[0].pos[1] = big.pos[1] * p_big + small.pos[1] * p_small; + ret[0].pos[2] = big.pos[2] * p_big + small.pos[2] * p_small; + ret[0].vel[0] = big.vel[0] * p_big + small.vel[0] * p_small; + ret[0].vel[1] = big.vel[1] * p_big + small.vel[1] * p_small; + ret[0].vel[2] = big.vel[2] * p_big + small.vel[2] * p_small; + int i; + for ( i = 1; i < n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + ret[n].mass = m_tot - ret[0].mass; + ret[n].radius = 0.; + ret[n].pos[0] = 0.; + ret[n].pos[1] = 0.; + ret[n].pos[2] = 0.; + ret[n].vel[0] = 0.; + ret[n].vel[1] = 0.; + ret[n].vel[2] = 0.; + + return COLLRESOLVE_REGIME_SUPERCATASTROPHIC; + } else if ( Q_R > Q_R_erosion || !grazing ) { + /* Disruption; pt 8 */ + const double m_lr = m_tot * ( 1. - Q_R / ( 2. * Q_prime_star_RD ) ); + if ( m_lr >= m_tot ) { + return collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_MERGE ); + } else { + ret[0].mass = m_lr; + ret[0].radius = cbrt( 0.75 / M_PI * m_lr / big_rho ); + ret[0].pos[0] = big.pos[0] * p_big + small.pos[0] * p_small; + ret[0].pos[1] = big.pos[1] * p_big + small.pos[1] * p_small; + ret[0].pos[2] = big.pos[2] * p_big + small.pos[2] * p_small; + ret[0].vel[0] = big.vel[0] * p_big + small.vel[0] * p_small; + ret[0].vel[1] = big.vel[1] * p_big + small.vel[1] * p_small; + ret[0].vel[2] = big.vel[2] * p_big + small.vel[2] * p_small; + double m_r = m_lr; + if ( n > 1 ) { + double m_slr = ( 0.15 * ( m_lr / m_tot ) / ( 2.85 * 2 ) ) * m_tot; /* Eq. (37) */ + int all_mass = 0; + if ( m_lr + m_slr > m_tot ) { + m_slr = m_tot - m_lr; + all_mass = 1; + } + m_r += m_slr; + ret[1].mass = m_slr; + ret[1].radius = small.radius * cbrt( m_slr / small.mass ); /* Keeps density of the impactor */ + if ( all_mass ) { + collresolve_resolve_posvel_slr_tot( conf, pbig, psmall, ret, ret + 1 ); + } else { + collresolve_resolve_posvel_slr( conf, pbig, psmall, ret, ret + 1 ); + } + /* Todo: Implement eq. (31) */ + int i; + for ( i = 2; i < n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + } + ret[n].mass = m_tot - m_r; + ret[n].radius = 0.; + ret[n].pos[0] = 0.; + ret[n].pos[1] = 0.; + ret[n].pos[2] = 0.; + ret[n].vel[0] = 0.; + ret[n].vel[1] = 0.; + ret[n].vel[2] = 0.; + } + + return COLLRESOLVE_REGIME_DISRUPTION; + } else if ( sqrt( vel_sq / ESCAPE_VELOCITY_SQ ) < vel_hr && ( flags & 1 ) ) { + /* Graze and Merge; same outcome as perfect merging */ + return collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_GRAZE_AND_MERGE ); + } else { + /* Hit-and-run; pt 6 */ + ret[0].mass = big.mass; + ret[0].radius = big.radius; + ret[0].pos[0] = big.pos[0]; + ret[0].pos[1] = big.pos[1]; + ret[0].pos[2] = big.pos[2]; + ret[0].vel[0] = big.vel[0]; + ret[0].vel[1] = big.vel[1]; + ret[0].vel[2] = big.vel[2]; + double m_slr = 0.; + if ( n > 1 ) { + const double phi_rev = 2. * acos( ( l - small.radius ) / small.radius ); + const double A_interact = small.radius * small.radius * ( M_PI - ( phi_rev - sin( phi_rev ) ) / 2. ); /* Eq. (46) */ + const double L_interact = 2. * sqrt( big.radius * big.radius - ( big.radius - l / 2. ) * ( big.radius - l / 2. ) ); /* Eq. (47) */ + const double M_interact = A_interact * L_interact; /* Eq. (48) */ + + const double mass1_rev = small.mass; + const double mass2_rev = M_interact; + const double rho1_rev = small.mass / ( 4. / 3. * M_PI * small.radius * small.radius * small.radius ); + + const double m_tot_rev = mass1_rev + mass2_rev; + const double mu_rev = mass1_rev * mass2_rev / m_tot_rev; /* Eq. (49) */ + const double gamma_rev = mass2_rev / mass1_rev; /* Eq. (50) */ + const double Q_R_rev = mu_rev * vel_sq / ( 2. * m_tot_rev ); + + /* a */ + const double rc1_rev = cbrt( 0.75 / M_PI * m_tot_rev / conf->refDens ); + + /* b */ + const double Q_star_RD_1_rev = c_star * 0.8 * M_PI * rho1_rev * conf->G * rc1_rev * rc1_rev; /* Eq. (28) */ + /* const double V_star_1_rev = sqrt( 6.4 * M_PI * c_star * rho1_rev * conf->G ) * rc1_rev; */ /* Eq. (30) */ + + /* c */ + const double mu_alpha_rev = ( alpha * big.mass * small.mass ) / ( big.mass + alpha * small.mass ); /* Eq. (12) */ + + /* d */ + const double gamma_term_rev = ( ( gamma_rev + 1. ) * ( gamma_rev + 1. ) / ( 4. * gamma_rev ) ); + const double Q_star_RD_rev = Q_star_RD_1_rev * pow( gamma_term_rev, 2. / ( 3. * mu_bar ) - 1. ); /* Eq. (23) */ + /* const double V_star_rev = V_star_1_rev * pow( gamma_term_rev, 1. / ( 3. * mu_bar ) ); */ /* Eq. (22) */ + + /* e */ + const double Q_prime_star_RD_rev = Q_star_RD_rev * pow( mu_rev / mu_alpha_rev, 2. - 3. * mu_bar / 2. ); /* Eq. (15) */ + /* const double V_prime_star_rev = V_star_rev * sqrt( 2. * Q_prime_star_RD_rev * m_tot_rev / mu_rev ); */ /* Eq. (16) */ + + const double Q_R_supercat_rev = Q_prime_star_RD_rev * 2. * ( 0.1 * gamma_rev - 0.9 ) / ( gamma_rev + 1. ); /* From eq. (5) and a sheet of paper */ + /* const double V_supercat_rev_sq = 2. * Q_R_supercat_rev * m_tot_rev / mu_rev; */ /* From eq. (1) and a sheet of paper, but squared */ + + if ( Q_R_rev > Q_R_supercat_rev ) { + m_slr = 0.1 * m_tot_rev * pow( Q_R_rev / Q_prime_star_RD_rev / 1.8, -1.5 ); + } else { + m_slr = m_tot_rev * ( 1. - Q_R_rev / ( 2. * Q_prime_star_RD_rev ) ); + } + + /* Mass conservation */ + if ( m_slr > small.mass ) { + m_slr = small.mass; + } + + ret[1].mass = m_slr; + ret[1].radius = small.radius * cbrt( m_slr / small.mass ); /* Keeps density of the impactor */ + collresolve_resolve_posvel_slr( conf, pbig, psmall, ret, ret + 1 ); + + int i; + for ( i = 2; i < n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + } + ret[n].mass = small.mass - m_slr; + ret[n].radius = 0.; + ret[n].pos[0] = 0.; + ret[n].pos[1] = 0.; + ret[n].pos[2] = 0.; + ret[n].vel[0] = 0.; + ret[n].vel[1] = 0.; + ret[n].vel[2] = 0.; + + return COLLRESOLVE_REGIME_HIT_AND_RUN; + } +} + +int collresolve_resolve_c2019( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small, int n, struct collresolve_body ret[] ) { + /* Inputs are: Target mass [Earth mass]; Projectile-to-target mass ratio; Impact angle [degree]; Impact-to-escape velocity ratio. */ + /* Regimes are: -1: Erosion, 0: Accretion, 1: Hit-and-run. */ + + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } + + if ( conf->G == 0. ) { + return COLLRESOLVE_ERROR_INCORRECT_UNIT; + } + + /* Check for specific values of n */ + if ( n < 0 ) { + return COLLRESOLVE_ERROR_INCORRECT_PARAMETER; + } else if ( n == 0 ) { + collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_MERGE ); + collresolve_body_radius( conf, &( ret[0] ) ); + return COLLRESOLVE_REGIME_MERGE; + } + + INIT_QUANT; + + double impact_para = IMPACR_PARAMETER; + if ( impact_para > 1. ) { + return COLLRESOLVE_ERROR_NON_CROSSING; + } + + double params[4]; + + params[0] = log10( big.mass / conf->mEarth ); + params[1] = small.mass / big.mass; + params[2] = asin( impact_para ) * 180. / M_PI; + params[3] = sqrt( IMPACT_VELOCITY_SQ / ESCAPE_VELOCITY_SQ ); + + int regime; + double score[3]; + collision_classifier( params, ®ime, score ); + + double accs[2]; + accretion_efficiency( params, accs ); + + double orb[3]; + orbital_hnr( params, orb ); + + int grazing = 0; + if ( regime == 1 ) { + /* For now, only hit and run is grazing, i.e. has a second remnant. */ + if ( orb[0] > 0. ) { + grazing = 1; + } else { + /* This is a consistency check to be sure that the orbit is unbound. */ + grazing = 0; + } + } else { + grazing = 0; + } + + const double total_mass = big.mass + small.mass; + const double big_factor = big.mass / total_mass; + const double small_factor = small.mass / total_mass; + + if ( grazing && n > 1 ) { + /* Two remnants */ + + /* First let's compute the resulting mass and radius */ + double acclr = accs[0]; + double accsr = accs[1]; + double acctr = 0. - acclr - accsr; + + /* Mass conservation */ + if ( acclr > 1. ) { + acclr = 1.; + accsr = -1.; + acctr = 0.; + } else if ( acclr + accsr > 0. ) { + accsr = -acclr; + acctr = 0.; + } + + ret[0].mass = big.mass + small.mass * acclr; + collresolve_body_radius( conf, &( ret[0] ) ); + + ret[1].mass = small.mass * ( 1. + accsr ); + collresolve_body_radius( conf, &( ret[1] ) ); + + /* Now, we do quite a bit of orbital mechanics. */ + const double drel = conf->drel == 0. ? 1.01 : conf->drel; + + const double mu = conf->G * total_mass; + + const double dpos_x = small.pos[0] - big.pos[0]; + const double dpos_y = small.pos[1] - big.pos[1]; + const double dpos_z = small.pos[2] - big.pos[2]; + + const double dvel_x = small.vel[0] - big.vel[0]; + const double dvel_y = small.vel[1] - big.vel[1]; + const double dvel_z = small.vel[2] - big.vel[2]; + + const double h_x = dpos_y * dvel_z - dpos_z * dvel_y; + const double h_y = dpos_z * dvel_x - dpos_x * dvel_z; + const double h_z = dpos_x * dvel_y - dpos_y * dvel_x; + + const double dpos_sq = dpos_x * dpos_x + dpos_y * dpos_y + dpos_z * dpos_z; + const double dpos = sqrt( dpos_sq ); + /* const double dvel_sq = dvel_x * dvel_x + dvel_y * dvel_y + dvel_z * dvel_z; */ + const double h_sq = h_x * h_x + h_y * h_y + h_z * h_z; + const double h = sqrt( h_sq ); + + /* Eccentricity vector, point along the semi-major axis */ + const double e_x = ( dvel_y * h_z - dvel_z * h_y ) / mu - dpos_x / dpos; + const double e_y = ( dvel_z * h_x - dvel_x * h_z ) / mu - dpos_y / dpos; + const double e_z = ( dvel_x * h_y - dvel_y * h_x ) / mu - dpos_z / dpos; + const double e = sqrt( e_x * e_x + e_y * e_y + e_z * e_z ); + + /* Rotate the eccentricity vector, by the shift of the argument of pericenter, about the direction given by h. */ + const double peri_rot = orb[2]; + const double srot = sin( peri_rot ); + const double crot = cos( peri_rot ); + const double omcrot = 1. - crot; + + const double axis_x = h_x / h; + const double axis_y = h_y / h; + const double axis_z = h_z / h; + + const double maj_x = ( e_x / e ) * ( crot + axis_x * axis_x * omcrot ) + ( e_y / e ) * ( axis_x * axis_y * omcrot - axis_z * srot ) + ( e_z / e ) * ( axis_x * axis_z * omcrot + axis_y * srot ); + const double maj_y = ( e_x / e ) * ( axis_y * axis_x * omcrot + axis_z * srot ) + ( e_y / e ) * ( crot + axis_y * axis_y * omcrot ) + ( e_z / e ) * ( axis_y * axis_z * omcrot - axis_x * srot ); + const double maj_z = ( e_x / e ) * ( axis_z * axis_x * omcrot - axis_y * srot ) + ( e_y / e ) * ( axis_z * axis_y * omcrot + axis_x * srot ) + ( e_z / e ) * ( crot + axis_z * axis_z * omcrot ); + const double m = sqrt( maj_x * maj_x + maj_y * maj_y + maj_z * maj_z ); + + /* Direction of the minor axis */ + const double q_x = axis_y * maj_z - axis_z * maj_y; + const double q_y = axis_z * maj_x - axis_x * maj_z; + const double q_z = axis_x * maj_y - axis_y * maj_x; + const double q = sqrt( q_x * q_x + q_y * q_y + q_z * q_z ); + + /* Orbital characteristics of the remnants */ + const double eorb = orb[0]; + const double b = orb[1]; + + const double p = 2. * b * b * ( 1. + eorb ); + const double e_sq = 1. + 4. * b * b * eorb * ( 1. + eorb ); + const double e_af = e_sq < 0. ? 0. : sqrt( e_sq ); + + const double cf = ( p / drel - 1. ) / e_af; /* cos(true anomaly) */ + const double sf = sqrt( 1. - cf * cf ); /* sin(true anomaly) */ + + const double cv = -sf; + const double sv = e_af + cf; + + /* Characteristics of the bodies */ + const double mu_af = conf->G * ( ret[0].mass + ret[1].mass ); + const double r_ref = ret[0].radius + ret[1].radius; + + /* Relative position */ + const double r = drel * r_ref; + const double rpos_x = r * ( maj_x / m * cf + q_x / q * sf ); + const double rpos_y = r * ( maj_y / m * cf + q_y / q * sf ); + const double rpos_z = r * ( maj_z / m * cf + q_z / q * sf ); + + /* Relative velocity */ + const double v = sqrt( mu_af / ( r_ref * p ) ); + const double rvel_x = v * ( maj_x / m * cv + q_x / q * sv ); + const double rvel_y = v * ( maj_y / m * cv + q_y / q * sv ); + const double rvel_z = v * ( maj_z / m * cv + q_z / q * sv ); + + /* Set the positions and velocities */ + const double lr_factor = -ret[1].mass / ( ret[0].mass + ret[1].mass ); + const double sr_factor = ret[0].mass / ( ret[0].mass + ret[1].mass ); + + ret[0].pos[0] = big.pos[0] * big_factor + small.pos[0] * small_factor + lr_factor * rpos_x; + ret[0].pos[1] = big.pos[1] * big_factor + small.pos[1] * small_factor + lr_factor * rpos_y; + ret[0].pos[2] = big.pos[2] * big_factor + small.pos[2] * small_factor + lr_factor * rpos_z; + ret[0].vel[0] = big.vel[0] * big_factor + small.vel[0] * small_factor + lr_factor * rvel_x; + ret[0].vel[1] = big.vel[1] * big_factor + small.vel[1] * small_factor + lr_factor * rvel_y; + ret[0].vel[2] = big.vel[2] * big_factor + small.vel[2] * small_factor + lr_factor * rvel_z; + + ret[1].pos[0] = big.pos[0] * big_factor + small.pos[0] * small_factor + sr_factor * rpos_x; + ret[1].pos[1] = big.pos[1] * big_factor + small.pos[1] * small_factor + sr_factor * rpos_y; + ret[1].pos[2] = big.pos[2] * big_factor + small.pos[2] * small_factor + sr_factor * rpos_z; + ret[1].vel[0] = big.vel[0] * big_factor + small.vel[0] * small_factor + sr_factor * rvel_x; + ret[1].vel[1] = big.vel[1] * big_factor + small.vel[1] * small_factor + sr_factor * rvel_y; + ret[1].vel[2] = big.vel[2] * big_factor + small.vel[2] * small_factor + sr_factor * rvel_z; + + int i; + for ( i = 2; i < n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + + ret[n].mass = small.mass * acctr; + ret[n].radius = 0.; + ret[n].pos[0] = 0.; + ret[n].pos[1] = 0.; + ret[n].pos[2] = 0.; + ret[n].vel[0] = 0.; + ret[n].vel[1] = 0.; + ret[n].vel[2] = 0.; + } else { + /* Non-grazing collision; only a single remnant */ + double acc = accs[0]; + + double rem_mass = big.mass + small.mass * acc; + if ( rem_mass > total_mass ) { + rem_mass = total_mass; + } + + ret[0].mass = rem_mass; + collresolve_body_radius( conf, &( ret[0] ) ); + ret[0].pos[0] = big.pos[0] * big_factor + small.pos[0] * small_factor; + ret[0].pos[1] = big.pos[1] * big_factor + small.pos[1] * small_factor; + ret[0].pos[2] = big.pos[2] * big_factor + small.pos[2] * small_factor; + ret[0].vel[0] = big.vel[0] * big_factor + small.vel[0] * small_factor; + ret[0].vel[1] = big.vel[1] * big_factor + small.vel[1] * small_factor; + ret[0].vel[2] = big.vel[2] * big_factor + small.vel[2] * small_factor; + + int i; + for ( i = 1; i < n; i++ ) { + ret[i].mass = 0.; + ret[i].radius = 0.; + ret[i].pos[0] = 0.; + ret[i].pos[1] = 0.; + ret[i].pos[2] = 0.; + ret[i].vel[0] = 0.; + ret[i].vel[1] = 0.; + ret[i].vel[2] = 0.; + } + + ret[n].mass = total_mass - rem_mass; + ret[n].radius = 0.; + ret[n].pos[0] = 0.; + ret[n].pos[1] = 0.; + ret[n].pos[2] = 0.; + ret[n].vel[0] = 0.; + ret[n].vel[1] = 0.; + ret[n].vel[2] = 0.; + } + + /* Type of collision */ + if ( regime == 1 ) { + if ( orb[0] > 0. ) { + return COLLRESOLVE_REGIME_HIT_AND_RUN; + } else { + /* This is a special value to indicate the "inconsistent" outcome. */ + return COLLRESOLVE_REGIME_GRAZE_AND_MERGE; + } + } else if ( regime == 0 ) { + return COLLRESOLVE_REGIME_MERGE; + } else if ( regime == -1 ) { + return COLLRESOLVE_REGIME_DISRUPTION; + } else { + return 0; + } +} + +int collresolve_resolve( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small, int n, struct collresolve_body ret[] ) { + if ( conf == NULL ) { + return COLLRESOLVE_ERROR_NO_CONF; + } else if ( conf->model == COLLRESOLVE_MODEL_PERFECT_MERGE ) { + return collresolve_resolve_merge( conf, big, small, n, ret, COLLRESOLVE_REGIME_MERGE ); + } else if ( conf->model == COLLRESOLVE_MODEL_LS2012 ) { + return collresolve_resolve_ls2012( conf, big, small, n, ret, 0 ); + } else if ( conf->model == COLLRESOLVE_MODEL_SL2012 ) { + return collresolve_resolve_ls2012( conf, big, small, n, ret, 1 ); + } else if ( conf->model == COLLRESOLVE_MODEL_C2019 ) { + return collresolve_resolve_c2019( conf, big, small, n, ret ); + } else { + return COLLRESOLVE_ERROR_INCORRECT_MODEL; + } +} diff --git a/collresolve/collresolve.h b/collresolve/collresolve.h new file mode 100644 index 000000000..cda723d03 --- /dev/null +++ b/collresolve/collresolve.h @@ -0,0 +1,247 @@ +/** + * The library's public interface in C. + * + * Copyright (c) 2016-2017 University of Bern, Switzerland + * Copyright (c) 2018-2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * If you use this library in a scientific work that lead to publication, + * we would like you to acknowledge the following article: + * Emsenhuber, A., Cambioni S., Asphaug, E., Gabriel, T. S. J., Schwartz, S. R., and Furfaro, R. (in prep.). Realistic On-the-fly Outcomes of Planetary Collisions II: Bringing Machine Learning to N-body Simulations. + * + * If you use the LS2012 model, you should also cite: + * Leinhardt, Z. M. and Stewart, S. T. (2012). Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling Laws. The Astrophysical Journal, 745(1), 79. doi:10.1088/0004-637X/745/1/79 bib:2012ApJ...745...79L + * + * If you use the SL2012 model, you should also cite the same publication as for LS2012, and: + * Stewart, S. T. and Leinhardt, Z. M. (2012). Collisions between Gravity-dominated Bodies. II. The Diversity of Impact Outcomes during the End Stage of Planet Formation. The Astrophysical Journal, 751(1), 32. doi:10.1088/0004-637X/751/1/32 bib:2012ApJ...751...32S + * Genda, H., Kokubo, E., and Ida, S. (2012). Merging Criteria for Giant Impacts of Protoplanets. The Astrophysical Journal, 744(2), 137. doi:10.1088/0004-637X/744/2/137 bib:2012ApJ...744..137G + * + * If you use the C2019 model, you should also cite: + * Cambioni, S., Asphaug, E., Emsenhuber, A., Gabriel, T. S. J., Furfaro, R., and Schwartz, S. R. (2019). Realistic On-the-fly Outcomes of Planetary Collisions: Machine Learning Applied to Simulations of Giant Impacts. The Astrophysical Journal, 875(1), 40. doi:10.3847/1538-4357/ab0e8a bib:2019ApJ...875...40C + * + * @file + * @author Alexandre Emsenhuber + */ + +#ifndef COLLRESOLVE_H +#define COLLRESOLVE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Model to use for collisions + */ +enum collresolve_model { + COLLRESOLVE_MODEL_NONE = 0, + COLLRESOLVE_MODEL_PERFECT_MERGE, /* Always perfect merging */ + COLLRESOLVE_MODEL_LS2012, /* According to Leinhardt & Stewart (2012) */ + COLLRESOLVE_MODEL_SL2012, /* According to Stewart & Leinhardt (2012): as previously, but with the addition of the Graze-and-Merge regime from Kokubo & Ida (2012) */ + COLLRESOLVE_MODEL_C2019 /* According to Cambioni et al. (2019) */ +}; + +/** + * Type of collision. + * + * These are the possible values of the status returned by collresolve_resolve(). + * @{ + */ +#define COLLRESOLVE_REGIME_MERGE 1 +#define COLLRESOLVE_REGIME_DISRUPTION 2 +#define COLLRESOLVE_REGIME_SUPERCATASTROPHIC 3 +#define COLLRESOLVE_REGIME_GRAZE_AND_MERGE 4 +#define COLLRESOLVE_REGIME_HIT_AND_RUN 5 +/** @} */ + +/** + * Error codes. + * + * @{ + */ +#define COLLRESOLVE_ERROR_GENERAL -1 +#define COLLRESOLVE_ERROR_NO_CONF -2 +#define COLLRESOLVE_ERROR_INCORRECT_PARAMETER -3 +#define COLLRESOLVE_ERROR_INCORRECT_MODEL -4 +#define COLLRESOLVE_ERROR_INCORRECT_UNIT -5 +#define COLLRESOLVE_ERROR_NON_CROSSING -6 +/** @} */ + +/** + * General configuration for the library. + * + * It should be treated as an opaque type; the internal state can (and should!) + * be modified using the different collresolve_conf_* functions. + */ +struct collresolve_conf; + +/** + * Representation of a body involved in a collision. + * + * The different fields should be self-explanatory. + */ +struct collresolve_body { + double mass; + double radius; + double pos[3]; + double vel[3]; +}; + +/** + * Get an human-readable description of the given model code + */ +char* collresolve_model_desc( int ); + +/** + * Get an human-readable description of the given regime code + */ +char* collresolve_regime_desc( int ); + +/** + * Get an error message for the given error code + */ +char* collresolve_error_message( int ); + +/** + * Create a new configuration object. + * + * The object is set to an invalid state; it cannot be used directly. + */ +struct collresolve_conf* collresolve_conf_new( void ); + +/** + * Frees a configuration object + */ +void collresolve_conf_free( struct collresolve_conf* conf ); + +/** + * Set the unit system to SI. + */ +int collresolve_conf_unit_si( struct collresolve_conf* conf ); + +/** + * Set the unit system to M_sol, AU, day using the standard IAU values. + */ +int collresolve_conf_unit_msun_au_day( struct collresolve_conf* conf ); + +/** + * Set the unit system to M_earth, metre, second. + */ +int collresolve_conf_unit_m_earth( struct collresolve_conf* conf ); + +/** + * Set the unit system to M_sol, AU, day using Mercury's values. + */ +int collresolve_conf_unit_merc( struct collresolve_conf* conf ); + +/** + * Set the collision model to use. + * + * model can take one of the values from the collresolve_model enum. + */ +int collresolve_conf_model( struct collresolve_conf* conf, int model ); + +/** + * Set the distance separating the objects after a collision. + * + * This is given in terms of the sum of the body radii. + * + * This is needed by some algorithms to prevent the re-discovery of the same collision over and over. + */ +int collresolve_conf_sep_after( struct collresolve_conf* conf, double drel ); + +/** + * Retrieve the bulk density for a given model and mass + * + * For now this always provide the bulk density associated with the mass of the Cambioni et al. (2019) model (i.e. COLLRESOLVE_MODEL_C2019). + */ +double collresolve_bulk_density( struct collresolve_conf* conf, double mass ); + +/** + * Set a consistent body radius depending on the model and other body properties. + * + * For now this always provide the radius associated with the mass of the Cambioni et al. (2019) model (i.e. COLLRESOLVE_MODEL_C2019). + */ +int collresolve_body_radius( struct collresolve_conf* conf, struct collresolve_body* body ); + +/** + * Collision setup function. + * + * This can be used when when the directions do not matter. The bodies will + * be positioned at initial contact (distance is the sum of the radii), and + * their relative velocity is set according to the two last parameters. + */ +void collresolve_setup( struct collresolve_conf* conf, struct collresolve_body* big, struct collresolve_body* small, double velocity, double angle ); + +/** + * Similar, but the relative distance at moment of setup is provided. + * + * Useful when collisions aren't detected exactly at initial contact. + */ +void collresolve_setup_dist( struct collresolve_conf* conf, struct collresolve_body* big, struct collresolve_body* small, double distance, double velocity, double angle ); + +/** + * Get the specific kinetic energy at initial contact. + */ +double collresolve_specific_energy( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the relative distance at initial contact. + */ +double collresolve_impact_distance( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the relative velocity at initial contact. + */ +double collresolve_impact_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the escape velocity at initial contact. + */ +double collresolve_escape_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the relative velocity at infinity. This will return a negative number if the objects are gravitationally bound. + */ +double collresolve_infinity_velocity( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the impact parameter (usually called "b"). + */ +double collresolve_impact_parameter( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Get the impact angle (0 = head-on, pi/2 = grazing). + * + * This is simply the arc-sinus of the impact parameter. + */ +double collresolve_impact_angle( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small ); + +/** + * Compute the outcome of the collision according to a model. + * + * "big" and "small" are the two bodies involved in the collision. + * The former *must* be the most massive one. The desired number + * of resulting bodies is given by "n". The last body always represents + * the other material, so there are actually ( n + 1 ) objects in "ret". + * "ret" must point to a pre-allocated area of minimal size of + * ( n + 1 ) * sizeof( struct collresolve_body ). + */ +int collresolve_resolve( struct collresolve_conf* conf, struct collresolve_body big, struct collresolve_body small, int n, struct collresolve_body ret[] ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/collresolve/collresolve_for.c b/collresolve/collresolve_for.c new file mode 100644 index 000000000..f94052d15 --- /dev/null +++ b/collresolve/collresolve_for.c @@ -0,0 +1,118 @@ +/** + * FORTRAN bindings for the collresolve library. + * + * Copyright (c) 2016-2017 University of Bern, Switzerland + * Copyright (c) 2018-2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @file + * @author Alexandre Emsenhuber + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include /* For malloc()/free() */ +#include /* For M_PI/cbrt() */ + +#include "collresolve.h" + +/** + * FORTRAN bindings for the the collresolve_resolve() function. + * + * Configuration is the following: + * - Collision model is provided as first parameter + * - Unit system is fixed to Mercury's one. + * - Relative distance after collision factor is fixed to 1.25. + * + * Interface: + * INTEGER, INTENT(IN) :: model ! collision model to apply + * DOUBLE PRECISION, INTENT(IN) :: m1 ! mass of the target + * DOUBLE PRECISION, INTENT(IN) :: m2 ! mass of the impactor + * DOUBLE PRECISION, INTENT(IN) :: r1 ! radius of the target + * DOUBLE PRECISION, INTENT(IN) :: r2 ! radius of the impactor + * DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: p1 ! position of the target + * DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: p2 ! position of the impactor + * DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: v1 ! velocity of the target + * DOUBLE PRECISION, DIMENSION(3), INTENT(IN) :: v2 ! velocity of the impactor + * INTEGER, INTENT(IN) :: n ! number of bodies to return + * DOUBLE PRECISION, DIMENSION(n+1), INTENT(OUT) :: mres ! mass of the resulting bodies + * DOUBLE PRECISION, DIMENSION(n+1), INTENT(OUT) :: rres ! radius of the resulting bodies + * DOUBLE PRECISION, DIMENSION(3,n+1), INTENT(OUT) :: pres ! position of the resulting bodies + * DOUBLE PRECISION, DIMENSION(3,n+1), INTENT(OUT) :: vres ! velocity of the resulting bodies + */ +int collresolve_resolve_( int* model, double* m1, double* m2, double* r1, double* r2, double* p1, double* p2, double* v1, double* v2, int* n, + double* mres, double* rres, double* pres, double* vres +) { + struct collresolve_conf* conf = collresolve_conf_new(); + collresolve_conf_unit_si( conf ); + collresolve_conf_model( conf, *model ); + /**collresolve_conf_sep_after( conf, 1.25 ); /* There's a factor 1.2 hardcoded in Mercury. */ + + struct collresolve_body big, small; + big.mass = *m1; + small.mass = *m2; + big.radius = *r1; + small.radius = *r2; + for ( int i = 0; i < 3; i++ ) { + big.pos[i] = p1[i]; + small.pos[i] = p2[i]; + big.vel[i] = v1[i]; + small.vel[i] = v2[i]; + } + + struct collresolve_body* ret = malloc( sizeof( struct collresolve_body ) * ( *n + 1 ) ); + + int res = collresolve_resolve( conf, big, small, *n, ret ); + + for ( int i = 0; i <= *n; i++ ) { + mres[i] = ret[i].mass; + rres[i] = ret[i].radius; + for ( int j = 0; j < 3; j++ ) { + pres[3*i+j] = ret[i].pos[j]; + vres[3*i+j] = ret[i].vel[j]; + } + } + + collresolve_conf_free( conf ); + + free( ret ); + + return res; +} + + +/** + * FORTRAN binding to retrieve the radius of a body of a given mass. + * + * Configuration is the following: + * - Collision model is provided as first parameter + * - Unit system is fixed to Mercury's one. + * + * Interface: + * INTEGER, INTENT(IN) :: model ! collision model to apply + * DOUBLE PRECISION, INTENT(IN) :: mass ! Mass of the body + */ +double collresolve_radius_( int* model, double* mass ) { + struct collresolve_conf* conf = collresolve_conf_new(); + collresolve_conf_unit_merc( conf ); + collresolve_conf_model( conf, *model ); + + double dens = collresolve_bulk_density( conf, *mass ); + + collresolve_conf_free( conf ); + + return cbrt( 3. / 4. / M_PI * (*mass) / dens ); +} diff --git a/collresolve/collresolve_python.c b/collresolve/collresolve_python.c new file mode 100644 index 000000000..7bc47ed11 --- /dev/null +++ b/collresolve/collresolve_python.c @@ -0,0 +1,754 @@ +/** + * The library's interface as a Python module. + * + * Copyright (c) 2016-2017 University of Bern, Switzerland + * Copyright (c) 2018-2019 Arizona Board of Regents + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * If you use this library in a scientific work that lead to publication, + * we would like you to acknowledge the following article: + * Emsenhuber, A., Cambioni S., Asphaug, E., Gabriel, T. S. J., Schwartz, S. R., and Furfaro, R. (in prep.). Realistic On-the-fly Outcomes of Planetary Collisions II: Bringing Machine Learning to N-body Simulations. + * + * If you use the LS2012 model, you should also cite: + * Leinhardt, Z. M. and Stewart, S. T. (2012). Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling Laws. The Astrophysical Journal, 745(1), 79. doi:10.1088/0004-637X/745/1/79 bib:2012ApJ...745...79L + * + * If you use the SL2012 model, you should also cite the same publication as for LS2012, and: + * Stewart, S. T. and Leinhardt, Z. M. (2012). Collisions between Gravity-dominated Bodies. II. The Diversity of Impact Outcomes during the End Stage of Planet Formation. The Astrophysical Journal, 751(1), 32. doi:10.1088/0004-637X/751/1/32 bib:2012ApJ...751...32S + * Genda, H., Kokubo, E., and Ida, S. (2012). Merging Criteria for Giant Impacts of Protoplanets. The Astrophysical Journal, 744(2), 137. doi:10.1088/0004-637X/744/2/137 bib:2012ApJ...744..137G + * + * If you use the C2019 model, you should also cite: + * Cambioni, S., Asphaug, E., Emsenhuber, A., Gabriel, T. S. J., Furfaro, R., and Schwartz, S. R. (2019). Realistic On-the-fly Outcomes of Planetary Collisions: Machine Learning Applied to Simulations of Giant Impacts. The Astrophysical Journal, 875(1), 40. doi:10.3847/1538-4357/ab0e8a bib:2019ApJ...875...40C + * + * @file + * @author Alexandre Emsenhuber + */ + +#include "Python.h" +#include "structmember.h" + +#include + +#include "collresolve.h" + +/** + * Common stuff + */ + +static PyObject* collresolve_Error; + +/** + * Body object + */ + +struct collresolve_BodyObject { + PyObject_HEAD + struct collresolve_body data; +}; + +static PyObject* collresolve_BodyObject_repr( struct collresolve_BodyObject* obj ) { + PyObject* pymass = PyFloat_FromDouble( obj->data.mass ); + PyObject* pyradius = PyFloat_FromDouble( obj->data.radius ); + PyObject* pyposx = PyFloat_FromDouble( obj->data.pos[0] ); + PyObject* pyposy = PyFloat_FromDouble( obj->data.pos[1] ); + PyObject* pyposz = PyFloat_FromDouble( obj->data.pos[2] ); + PyObject* pyvelx = PyFloat_FromDouble( obj->data.vel[0] ); + PyObject* pyvely = PyFloat_FromDouble( obj->data.vel[1] ); + PyObject* pyvelz = PyFloat_FromDouble( obj->data.vel[2] ); + + PyObject* ret = PyUnicode_FromFormat( "collresolve.Body(mass=%R, radius=%R, pos_x=%R, pos_y=%R, pos_z=%R, vel_x=%R, vel_y=%R, vel_z=%R)", pymass, pyradius, pyposx, pyposy, pyposz, pyvelx, pyvely, pyvelz ); + + Py_DECREF( pymass ); + Py_DECREF( pyradius ); + Py_DECREF( pyposx ); + Py_DECREF( pyposy ); + Py_DECREF( pyposz ); + Py_DECREF( pyvelx ); + Py_DECREF( pyvely ); + Py_DECREF( pyvelz ); + + return ret; +} + +static int collresolve_BodyObject_init( PyObject* self, PyObject* args, PyObject* kwds ) { + static char *kwlist[] = { "mass", "radius", "pos_x", "pos_y", "pos_z", "vel_x", "vel_y", "vel_z", NULL }; + + struct collresolve_BodyObject* pybody = (struct collresolve_BodyObject*) self; + + if ( !PyArg_ParseTupleAndKeywords( args, kwds, "|dddddddd", kwlist, &pybody->data.mass, &pybody->data.radius, &pybody->data.pos[0], &pybody->data.pos[1], &pybody->data.pos[2], &pybody->data.vel[0], &pybody->data.vel[1], &pybody->data.vel[2] ) ) { + return -1; + } + + return 0; +} + +static PyMemberDef collresolve_BodyObject_members[] = { + { "mass", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.mass), 0, "body's mass" }, + { "radius", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.radius), 0, "body's radius" }, + { "pos_x", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.pos[0]), 0, "body's position" }, + { "pos_y", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.pos[1]), 0, "body's position" }, + { "pos_z", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.pos[2]), 0, "body's position" }, + { "vel_x", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.vel[0]), 0, "body's velocity" }, + { "vel_y", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.vel[1]), 0, "body's velocity" }, + { "vel_z", T_DOUBLE, offsetof(struct collresolve_BodyObject, data.vel[2]), 0, "body's velocity" }, + { NULL } /* Sentinel */ +}; + +/** + * Object type + */ +static PyTypeObject collresolve_BodyType = { + PyVarObject_HEAD_INIT( NULL, 0 ) + "collresolve.Body", /* tp_name */ + sizeof( struct collresolve_BodyObject ), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + (reprfunc) collresolve_BodyObject_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Collision body object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + collresolve_BodyObject_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc) collresolve_BodyObject_init, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ +}; + +/** + * Configuration object + */ + +struct collresolve_ConfObject { + PyObject_HEAD + struct collresolve_conf* data; +}; + +/** + * Object methods + */ + +static void python_collresolve_conf_dealloc( struct collresolve_ConfObject* obj ) { + collresolve_conf_free( obj->data ); + Py_TYPE( obj )->tp_free( obj ); +} + +/** + * Object type + */ +static PyTypeObject collresolve_ConfType = { + PyVarObject_HEAD_INIT( NULL, 0 ) + "collresolve.Conf", /* tp_name */ + sizeof( struct collresolve_ConfObject ), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)python_collresolve_conf_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + "Collision configuration object", /* tp_doc */ +}; + +static PyObject* python_collresolve_conf_new_internal( void ) { + PyObject* self = collresolve_ConfType.tp_alloc( &collresolve_ConfType, 0 ); + + if ( self != NULL ) { + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) self; + pyconf->data = collresolve_conf_new(); + } + + return self; +} + +static PyObject* python_collresolve_conf_new( PyTypeObject* type, PyObject* args, PyObject* kwds ) { + return python_collresolve_conf_new_internal(); +} + +/** + * Module methods + */ + +static PyObject* python_collresolve_model_desc( PyObject* self, PyObject* args ) { + int model; + + if ( !PyArg_ParseTuple( args, "i", &model ) ) { + return NULL; + } + + const char* desc = collresolve_model_desc( model ); + + if ( desc == NULL ) { + PyErr_SetString( collresolve_Error, "argument is an invalid model code" ); + return NULL; + } else { + return Py_BuildValue( "s", desc ); + } +} + +static PyObject* python_collresolve_regime_desc( PyObject* self, PyObject* args ) { + int regime; + + if ( !PyArg_ParseTuple( args, "i", ®ime ) ) { + return NULL; + } + + const char* desc = collresolve_regime_desc( regime ); + + if ( desc == NULL ) { + PyErr_SetString( collresolve_Error, "argument is an invalid regime code" ); + return NULL; + } else { + return Py_BuildValue( "s", desc ); + } +} + +static PyObject* python_collresolve_error_desc( PyObject* self, PyObject* args ) { + int code; + + if ( !PyArg_ParseTuple( args, "i", &code ) ) { + return NULL; + } + + const char* desc = collresolve_error_message( code ); + + if ( desc == NULL ) { + PyErr_SetString( collresolve_Error, "argument is an invalid error code" ); + return NULL; + } else { + return Py_BuildValue( "s", desc ); + } +} + +static PyObject* python_collresolve_common_conf( PyObject* self, PyObject* args, int ( *func )( struct collresolve_conf* ) ) { + PyObject* pyconfobj = NULL; + + if ( self == NULL || PyModule_CheckExact( self ) ) { + if ( !PyArg_ParseTuple( args, "|O", &pyconfobj ) ) { + return NULL; + } + } else { + if ( !PyArg_ParseTuple( args, "" ) ) { + return NULL; + } + pyconfobj = self; + } + + if ( pyconfobj == NULL ) { + pyconfobj = python_collresolve_conf_new_internal(); + } else { + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + // We will also return it, so reference count must be incremented + Py_INCREF( pyconfobj ); + } + + if ( pyconfobj != NULL ) { + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) pyconfobj; + int res = func( pyconf->data ); + if ( res < 0 ) { + Py_DECREF( pyconfobj ); + PyErr_SetString( collresolve_Error, collresolve_error_message( res ) ); + return NULL; + } + } + + return pyconfobj; +} + +static PyObject* python_collresolve_conf_unit_si( PyObject* self, PyObject* args ) { + return python_collresolve_common_conf( self, args, collresolve_conf_unit_si ); +} + +static PyObject* python_collresolve_conf_unit_msun_au_day( PyObject* self, PyObject* args ) { + return python_collresolve_common_conf( self, args, collresolve_conf_unit_msun_au_day ); +} + +static PyObject* python_collresolve_conf_unit_m_earth( PyObject* self, PyObject* args ) { + return python_collresolve_common_conf( self, args, collresolve_conf_unit_m_earth ); +} + +static PyObject* python_collresolve_conf_unit_merc( PyObject* self, PyObject* args ) { + return python_collresolve_common_conf( self, args, collresolve_conf_unit_merc ); +} + +static PyObject* python_collresolve_conf_model( PyObject* self, PyObject* args ) { + PyObject* pyconfobj = NULL; + int model; + + if ( self == NULL || PyModule_CheckExact( self ) ) { + if ( !PyArg_ParseTuple( args, "Oi", &pyconfobj, &model ) ) { + return NULL; + } + } else { + if ( !PyArg_ParseTuple( args, "i", &model ) ) { + return NULL; + } + pyconfobj = self; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) pyconfobj; + int res = collresolve_conf_model( pyconf->data, model ); + if ( res < 0 ) { + PyErr_SetString( collresolve_Error, collresolve_error_message( res ) ); + return NULL; + } + + return Py_BuildValue( "" ); +} + +static PyObject* python_collresolve_conf_sep_after( PyObject* self, PyObject* args ) { + PyObject* pyconfobj = NULL; + double drel; + + if ( self == NULL || PyModule_CheckExact( self ) ) { + if ( !PyArg_ParseTuple( args, "Od", &pyconfobj, &drel ) ) { + return NULL; + } + } else { + if ( !PyArg_ParseTuple( args, "d", &drel ) ) { + return NULL; + } + pyconfobj = self; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) pyconfobj; + int res = collresolve_conf_sep_after( pyconf->data, drel ); + if ( res < 0 ) { + PyErr_SetString( collresolve_Error, collresolve_error_message( res ) ); + return NULL; + } + + return Py_BuildValue( "" ); +} + +static PyObject* python_collresolve_bulk_density( PyObject* self, PyObject* args ) { + PyObject* pyconfobj = NULL; + double mass; + + if ( !PyArg_ParseTuple( args, "Od", &pyconfobj, &mass ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) pyconfobj; + + double res = collresolve_bulk_density( pyconf->data, mass ); + if ( res < 0. ) { + int code = (int)( res - 0.5 ); + PyErr_SetString( collresolve_Error, collresolve_error_message( code ) ); + return NULL; + } + + return Py_BuildValue( "d", res ); +} + +static PyObject* python_collresolve_body_radius( PyObject* self, PyObject* args ) { + PyObject* pyconfobj = NULL; + PyObject* pybodyobj = NULL; + + if ( !PyArg_ParseTuple( args, "OO", &pyconfobj, &pybodyobj ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pybodyobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #2 not a collresolve.Body object" ); + return NULL; + } + + struct collresolve_ConfObject* pyconf = (struct collresolve_ConfObject*) pyconfobj; + struct collresolve_BodyObject* pybody = (struct collresolve_BodyObject*) pybodyobj; + + int res = collresolve_body_radius( pyconf->data, &( pybody->data ) ); + + if ( res < 0 ) { + PyErr_SetString( collresolve_Error, collresolve_error_message( res ) ); + return NULL; + } + + return Py_BuildValue( "" ); +} + +static PyObject* python_collresolve_setup( PyObject* self, PyObject* args, PyObject* keywds ) { + PyObject* pyconfobj = NULL; + PyObject* pybigobj = NULL; + PyObject* pysmallobj = NULL; + double velocity; + double angle; + + static char* kwlist[] = { "conf", "big", "small", "velocity", "angle", NULL }; + + if ( !PyArg_ParseTupleAndKeywords( args, keywds, "OOOdd", kwlist, &pyconfobj, &pybigobj, &pysmallobj, &velocity, &angle ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pybigobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #2 not a collresolve.Body object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pysmallobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #3 not a collresolve.Body object" ); + return NULL; + } + + struct collresolve_conf* conf = ( ( struct collresolve_ConfObject* ) pyconfobj )->data; + struct collresolve_body* big = &( ( struct collresolve_BodyObject* ) pybigobj )->data; + struct collresolve_body* small = &( ( struct collresolve_BodyObject* ) pysmallobj )->data; + + collresolve_setup( conf, big, small, velocity, angle ); + + return Py_BuildValue( "" ); +} + +static PyObject* python_collresolve_setup_dist( PyObject* self, PyObject* args, PyObject* keywds ) { + PyObject* pyconfobj = NULL; + PyObject* pybigobj = NULL; + PyObject* pysmallobj = NULL; + double distance; + double velocity; + double angle; + + static char* kwlist[] = { "conf", "big", "small", "distance", "velocity", "angle", NULL }; + + if ( !PyArg_ParseTupleAndKeywords( args, keywds, "OOOddd", kwlist, &pyconfobj, &pybigobj, &pysmallobj, &distance, &velocity, &angle ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pybigobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #2 not a collresolve.Body object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pysmallobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #3 not a collresolve.Body object" ); + return NULL; + } + + struct collresolve_conf* conf = ( ( struct collresolve_ConfObject* ) pyconfobj )->data; + struct collresolve_body* big = &( ( struct collresolve_BodyObject* ) pybigobj )->data; + struct collresolve_body* small = &( ( struct collresolve_BodyObject* ) pysmallobj )->data; + + collresolve_setup_dist( conf, big, small, distance, velocity, angle ); + + return Py_BuildValue( "" ); +} + +static PyObject* python_collresolve_common_quant( PyObject* self, PyObject* args, PyObject* keywds, double ( *func )( struct collresolve_conf*, struct collresolve_body, struct collresolve_body ), int neg_err ) { + PyObject* pyconfobj = NULL; + PyObject* pybigobj = NULL; + PyObject* pysmallobj = NULL; + + static char* kwlist[] = { "conf", "big", "small", NULL }; + + if ( !PyArg_ParseTupleAndKeywords( args, keywds, "OOO", kwlist, &pyconfobj, &pybigobj, &pysmallobj ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pybigobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #2 not a collresolve.Body object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pysmallobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #3 not a collresolve.Body object" ); + return NULL; + } + + struct collresolve_conf* conf = ( ( struct collresolve_ConfObject* ) pyconfobj )->data; + struct collresolve_body big = ( ( struct collresolve_BodyObject* ) pybigobj )->data; + struct collresolve_body small = ( ( struct collresolve_BodyObject* ) pysmallobj )->data; + + double res = func( conf, big, small ); + + if ( neg_err && res < 0. ) { + int code = (int)( res - 0.5 ); + PyErr_SetString( collresolve_Error, collresolve_error_message( code ) ); + } + + return Py_BuildValue( "d", res ); +} + +static PyObject* python_collresolve_specific_energy( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_specific_energy, 1 ); +} + +static PyObject* python_collresolve_impact_distance( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_impact_distance, 1 ); +} + +static PyObject* python_collresolve_impact_velocity( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_impact_velocity, 1 ); +} + +static PyObject* python_collresolve_escape_velocity( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_escape_velocity, 1 ); +} + +static PyObject* python_collresolve_infinity_velocity( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_infinity_velocity, 0 ); +} + +static PyObject* python_collresolve_impact_parameter( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_impact_parameter, 1 ); +} + +static PyObject* python_collresolve_impact_angle( PyObject* self, PyObject* args, PyObject* keywds ) { + return python_collresolve_common_quant( self, args, keywds, collresolve_impact_angle, 1 ); +} + +/** + * God himself. + */ + +static PyObject* python_collresolve_resolve( PyObject* self, PyObject* args, PyObject* keywds ) { + PyObject* pyconfobj = NULL; + PyObject* pybigobj = NULL; + PyObject* pysmallobj = NULL; + int n; + int r = 0; + + static char* kwlist[] = { "conf", "big", "small", "n", "r", NULL }; + + if ( !PyArg_ParseTupleAndKeywords( args, keywds, "OOOi|i", kwlist, &pyconfobj, &pybigobj, &pysmallobj, &n, &r ) ) { + return NULL; + } + + if ( !PyObject_TypeCheck( pyconfobj, &collresolve_ConfType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #1 not a collresolve.Conf object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pybigobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #2 not a collresolve.Body object" ); + return NULL; + } + + if ( !PyObject_TypeCheck( pysmallobj, &collresolve_BodyType ) ) { + PyErr_SetString( PyExc_TypeError, "arg #3 not a collresolve.Body object" ); + return NULL; + } + + struct collresolve_conf* conf = ( ( struct collresolve_ConfObject* ) pyconfobj )->data; + struct collresolve_body big = ( ( struct collresolve_BodyObject* ) pybigobj )->data; + struct collresolve_body small = ( ( struct collresolve_BodyObject* ) pysmallobj )->data; + + struct collresolve_body* res = malloc( sizeof( struct collresolve_body ) * ( n + 1 ) ); + + int status = collresolve_resolve( conf, big, small, n, res ); + if ( status < 0 ) { + free( res ); + PyErr_SetString( collresolve_Error, collresolve_error_message( status ) ); + return NULL; + } + + PyObject* ret = PyList_New( n + 1 ); + + for ( int i = 0; i <= n; i++ ) { + PyObject* entry = collresolve_BodyType.tp_alloc( &collresolve_BodyType, 0 ); + memcpy( (void*) entry + offsetof( struct collresolve_BodyObject, data ), ( void* )( res + i ), sizeof( struct collresolve_body ) ); + PyList_SET_ITEM( ret, i, entry ); + } + + free( res ); + + if ( r == 0 ) { + return ret; + } else { + return Py_BuildValue( "(Oi)", ret, status ); + } +} + +static PyMethodDef collresolve_methods[] = { + { "model_desc", python_collresolve_model_desc, METH_VARARGS, "Get a human-readable description of the model code." }, + { "regime_desc", python_collresolve_regime_desc, METH_VARARGS, "Get a human-readable description of the model code." }, + { "error_desc", python_collresolve_error_desc, METH_VARARGS, "Get a human-readable description of the error code." }, + { "conf_unit_si", python_collresolve_conf_unit_si, METH_VARARGS, "Get a configuration object for SI units." }, + { "conf_unit_msun_au_day", python_collresolve_conf_unit_msun_au_day, METH_VARARGS, "Get a configuration object for Solar mass, AU and day using their IAU definitions." }, + { "conf_unit_m_earth", python_collresolve_conf_unit_m_earth, METH_VARARGS, "Get a configuration object for Earth mass and SI units." }, + { "conf_unit_merc", python_collresolve_conf_unit_merc, METH_VARARGS, "Get a configuration object for Mercury units." }, + { "conf_model", python_collresolve_conf_model, METH_VARARGS, "Set the collision model to use." }, + { "conf_sep_after", python_collresolve_conf_sep_after, METH_VARARGS, "Set the relative distance factor for spacing after a collision." }, + { "bulk_density", python_collresolve_bulk_density, METH_VARARGS, "Retrieve the bulk density from a mass." }, + { "body_radius", python_collresolve_body_radius, METH_VARARGS, "Set a consistent radius from the body properties." }, + { "setup", (PyCFunction)python_collresolve_setup, METH_VARARGS | METH_KEYWORDS, "Setup collision geometry." }, + { "setup_dist", (PyCFunction)python_collresolve_setup_dist, METH_VARARGS | METH_KEYWORDS, "Setup collision geometry (with custom initial distance)." }, + { "specific_energy", (PyCFunction)python_collresolve_specific_energy, METH_VARARGS | METH_KEYWORDS, "Compute collision specific energy." }, + { "impact_distance", (PyCFunction)python_collresolve_impact_distance, METH_VARARGS | METH_KEYWORDS, "Compute relative distance at initial contact." }, + { "impact_velocity", (PyCFunction)python_collresolve_impact_velocity, METH_VARARGS | METH_KEYWORDS, "Compute relative velocity at initial contact." }, + { "escape_velocity", (PyCFunction)python_collresolve_escape_velocity, METH_VARARGS | METH_KEYWORDS, "Compute the mutual escape velocity." }, + { "infinity_velocity", (PyCFunction)python_collresolve_infinity_velocity, METH_VARARGS | METH_KEYWORDS, "Compute relative velocity at infinity." }, + { "impact_parameter", (PyCFunction)python_collresolve_impact_parameter, METH_VARARGS | METH_KEYWORDS, "Compute collision specific energy." }, + { "impact_angle", (PyCFunction)python_collresolve_impact_angle, METH_VARARGS | METH_KEYWORDS, "Compute collision specific energy." }, + { "resolve", (PyCFunction)python_collresolve_resolve, METH_VARARGS | METH_KEYWORDS, "Compute collisional outcome." }, + { NULL, NULL, 0, NULL } +}; + +#if PY_MAJOR_VERSION >= 3 +/** + * Module definition + */ + +static struct PyModuleDef collresolvemodule = { + PyModuleDef_HEAD_INIT, + "collresolve", /* name of module */ + NULL, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */ + collresolve_methods +}; +#endif + +/** + * Module initialisation + */ + +#if PY_MAJOR_VERSION >= 3 +PyMODINIT_FUNC PyInit_collresolve( void ) +#else +PyMODINIT_FUNC initcollresolve( void ) +#endif +{ + collresolve_BodyType.tp_new = PyType_GenericNew; + collresolve_ConfType.tp_new = python_collresolve_conf_new; + + if ( PyType_Ready( &collresolve_BodyType ) < 0 ) { +#if PY_MAJOR_VERSION >= 3 + return NULL; +#else + return; +#endif + } + + if ( PyType_Ready( &collresolve_ConfType ) < 0 ) { +#if PY_MAJOR_VERSION >= 3 + return NULL; +#else + return; +#endif + } + +#if PY_MAJOR_VERSION >= 3 + PyObject* module = PyModule_Create( &collresolvemodule ); +#else + PyObject* module = Py_InitModule( "collresolve", collresolve_methods ); +#endif + + if ( module == NULL ) { +#if PY_MAJOR_VERSION >= 3 + return NULL; +#else + return; +#endif + } + + collresolve_Error = PyErr_NewException( "collresolve.Error", NULL, NULL ); + + Py_INCREF( &collresolve_BodyType ); + Py_INCREF( &collresolve_ConfType ); + Py_INCREF( collresolve_Error ); + + PyModule_AddObject( module, "Body", (PyObject*) &collresolve_BodyType ); + PyModule_AddObject( module, "Conf", (PyObject*) &collresolve_ConfType ); + PyModule_AddObject( module, "Error", collresolve_Error ); + + PyModule_AddIntConstant( module, "MODEL_NONE", COLLRESOLVE_MODEL_NONE ); + PyModule_AddIntConstant( module, "MODEL_PERFECT_MERGE", COLLRESOLVE_MODEL_PERFECT_MERGE ); + PyModule_AddIntConstant( module, "MODEL_LS2012", COLLRESOLVE_MODEL_LS2012 ); + PyModule_AddIntConstant( module, "MODEL_SL2012", COLLRESOLVE_MODEL_SL2012 ); + PyModule_AddIntConstant( module, "MODEL_C2019", COLLRESOLVE_MODEL_C2019 ); + + PyModule_AddIntConstant( module, "REGIME_MERGE", COLLRESOLVE_REGIME_MERGE ); + PyModule_AddIntConstant( module, "REGIME_DISRUPTION", COLLRESOLVE_REGIME_DISRUPTION ); + PyModule_AddIntConstant( module, "REGIME_SUPERCATASTROPHIC", COLLRESOLVE_REGIME_SUPERCATASTROPHIC ); + PyModule_AddIntConstant( module, "REGIME_GRAZE_AND_MERGE", COLLRESOLVE_REGIME_GRAZE_AND_MERGE ); + PyModule_AddIntConstant( module, "REGIME_HIT_AND_RUN", COLLRESOLVE_REGIME_HIT_AND_RUN ); + + PyModule_AddIntConstant( module, "ERROR_GENERAL", COLLRESOLVE_ERROR_GENERAL ); + PyModule_AddIntConstant( module, "ERROR_NO_CONF", COLLRESOLVE_ERROR_NO_CONF ); + PyModule_AddIntConstant( module, "ERROR_INCORRECT_PARAMETER", COLLRESOLVE_ERROR_INCORRECT_PARAMETER ); + PyModule_AddIntConstant( module, "ERROR_INCORRECT_MODEL", COLLRESOLVE_ERROR_INCORRECT_MODEL ); + PyModule_AddIntConstant( module, "ERROR_NON_CROSSING", COLLRESOLVE_ERROR_NON_CROSSING ); + +#if PY_MAJOR_VERSION >= 3 + return module; +#endif +} diff --git a/collresolve/configure.ac b/collresolve/configure.ac new file mode 100644 index 000000000..6a067b9d4 --- /dev/null +++ b/collresolve/configure.ac @@ -0,0 +1,32 @@ +AC_PREREQ([2.69]) +AC_INIT([collresolve], [1.1]) +AC_CONFIG_AUX_DIR([aux]) +AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror]) + +# Enable non-standard functions and other goodies +AC_USE_SYSTEM_EXTENSIONS + +# Checks for programs. +AC_PROG_CC_C99 +AM_PROG_AR + +# Initialise libtool +LT_INIT + +# Checks for libraries. + +# Checks for header files. +AC_CHECK_HEADERS([stddef.h stdlib.h math.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_MALLOC +AC_FUNC_STRTOD +AC_CHECK_FUNCS([pow sqrt cbrt]) + +# Output +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/collresolve/example.py b/collresolve/example.py new file mode 100644 index 000000000..db4d0a136 --- /dev/null +++ b/collresolve/example.py @@ -0,0 +1,41 @@ +# Example script that shows the Python interface of the collresolve library + +from __future__ import print_function + +import math +import collresolve + +vel = 20.e3 +angle = math.radians( 45. ) + +conf = collresolve.Conf() + +collresolve.conf_unit_m_earth( conf ) +collresolve.conf_model( conf, 2 ) + +big = collresolve.Body( mass = 1., radius = 6.371e6 ) +small = collresolve.Body( mass = 0.1, radius = 3.4e6 ) + +collresolve.setup( conf, big, small, vel, angle ) + +models = [ collresolve.MODEL_PERFECT_MERGE, collresolve.MODEL_LS2012, collresolve.MODEL_SL2012, collresolve.MODEL_C2019 ] + +print( "impact velocity = {0:.1f} m/s".format( collresolve.impact_velocity( conf, big, small ) ) ) +print( "velocity ratio = {0:.2f}".format( collresolve.impact_velocity( conf, big, small ) / collresolve.escape_velocity( conf, big, small ) ) ) +print( "impact angle = {0:.1f} deg".format( math.degrees( collresolve.impact_angle( conf, big, small ) ) ) ) + +for model in models: + print() + print( "resulting bodies using the {0:} model:".format( collresolve.model_desc( model ) ) ) + + collresolve.conf_model( conf, model ) + res, regime = collresolve.resolve( conf, big, small, 2, 1 ) + + print( " regime =", collresolve.regime_desc( regime ) ) + + tot_m = - big.mass - small.mass + for body in res: + tot_m += body.mass + print( " ", body ) + + print( " mass change =", tot_m ) diff --git a/collresolve/setup.py b/collresolve/setup.py new file mode 100644 index 000000000..55ce82f89 --- /dev/null +++ b/collresolve/setup.py @@ -0,0 +1,14 @@ +import distutils.core + +module = distutils.core.Extension( + "collresolve", + sources = [ "collresolve.c", "collresolve_python.c", + "cambioni2019/accretion_efficiency.c", "cambioni2019/orbital_hnr.c", "cambioni2019/collision_classifier.c" ] +) + +distutils.core.setup( + name = "collresolve", + version = "1.1", + description = "Analyse and predict outcomes of collision in N-body", + ext_modules = [ module ] +) diff --git a/coord/coord_b2h.f90 b/coord/coord_b2h.f90 deleted file mode 100644 index ceadc50b1..000000000 --- a/coord/coord_b2h.f90 +++ /dev/null @@ -1,74 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_b2h -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from barycentric to heliocentric coordinates, planets only -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_b2h(npl, swifter_pl1P) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine coord_b2h.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_b2h(npl, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_b2h - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - xtmp(:) = swifter_pl1P%xb(:) - vtmp(:) = swifter_pl1P%vb(:) - swifter_plP => swifter_pl1P - DO i = 1, npl - swifter_plP%xh(:) = swifter_plP%xb(:) - xtmp(:) - swifter_plP%vh(:) = swifter_plP%vb(:) - vtmp(:) - swifter_plP => swifter_plP%nextP - END DO - - RETURN - -END SUBROUTINE coord_b2h -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_b2h_tp.f90 b/coord/coord_b2h_tp.f90 deleted file mode 100644 index fab3b7bc2..000000000 --- a/coord/coord_b2h_tp.f90 +++ /dev/null @@ -1,76 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_b2h_tp -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from barycentric to heliocentric coordinates, active test particles only -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine coord_b2h_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_b2h_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - xtmp(:) = swifter_pl1P%xb(:) - vtmp(:) = swifter_pl1P%vb(:) - swifter_tpP => swifter_tp1P - DO i = 1, ntp - swifter_tpP%xh(:) = swifter_tpP%xb(:) - xtmp(:) - swifter_tpP%vh(:) = swifter_tpP%vb(:) - vtmp(:) - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE coord_b2h_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_h2b.f90 b/coord/coord_h2b.f90 deleted file mode 100644 index 36669f74c..000000000 --- a/coord/coord_h2b.f90 +++ /dev/null @@ -1,112 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_h2b -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to barycentric coordinates, planets only -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! msys : total system mass -! Terminal : none -! File : none -! -! Invocation : CALL coord_h2b(npl, swifter_pl1P, msys) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine coord_h2b.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_h2b(npl, swifter_pl1P, msys) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_h2b - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(OUT) :: msys - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - msys = swifter_pl1P%mass - !Removed by D. minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - xtmp(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - vtmp(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - !^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P) & - !$OMP REDUCTION(+:msys,xtmp,vtmp) - DO i = 2, npl - ! Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^^ - ! Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^^ - msys = msys + swifter_plP%mass - xtmp(:) = xtmp(:) + swifter_plP%mass*swifter_plP%xh(:) - vtmp(:) = vtmp(:) + swifter_plP%mass*swifter_plP%vh(:) - END DO - !$OMP END PARALLEL DO - swifter_plP => swifter_pl1P - swifter_plP%xb(:) = -xtmp(:)/msys - swifter_plP%vb(:) = -vtmp(:)/msys - xtmp(:) = swifter_plP%xb(:) - vtmp(:) = swifter_plP%vb(:) - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P,xtmp,vtmp) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^ - swifter_plP%xb(:) = swifter_plP%xh(:) + xtmp(:) - swifter_plP%vb(:) = swifter_plP%vh(:) + vtmp(:) - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE coord_h2b -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_h2b_tp.f90 b/coord/coord_h2b_tp.f90 deleted file mode 100644 index 3b8da012f..000000000 --- a/coord/coord_h2b_tp.f90 +++ /dev/null @@ -1,76 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_h2b_tp -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to barycentric coordinates, active test particles only -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine coord_h2b_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_h2b_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - xtmp(:) = swifter_pl1P%xb(:) - vtmp(:) = swifter_pl1P%vb(:) - swifter_tpP => swifter_tp1P - DO i = 1, ntp - swifter_tpP%xb(:) = swifter_tpP%xh(:) + xtmp(:) - swifter_tpP%vb(:) = swifter_tpP%vh(:) + vtmp(:) - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE coord_h2b_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_h2j.f90 b/coord/coord_h2j.f90 deleted file mode 100644 index 1fd5f9ecb..000000000 --- a/coord/coord_h2j.f90 +++ /dev/null @@ -1,96 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_h2j -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to Jacobi coordinates, planets only -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_h2j(npl, whm_pl1P) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine coord_h2j.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_h2j(npl, whm_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => coord_h2j - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: eta - REAL(DP), DIMENSION(NDIM) :: sum, sumv, cap, capv - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - eta = whm_pl1P%swifter%mass - whm_pl1P%eta = eta - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - eta = eta + whm_plP%swifter%mass - whm_plP%eta = eta - END DO - whm_plP => whm_pl1P - whm_plP%xj(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP%vj(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - whm_plP%xj(:) = swifter_plP%xh(:) - whm_plP%vj(:) = swifter_plP%vh(:) - sum(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - sumv(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - DO i = 3, npl - sum(:) = sum(:) + swifter_plP%mass*swifter_plP%xh(:) - sumv(:) = sumv(:) + swifter_plP%mass*swifter_plP%vh(:) - cap(:) = sum(:)/whm_plP%eta - capv(:) = sumv(:)/whm_plP%eta - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - whm_plP%xj(:) = swifter_plP%xh(:) - cap(:) - whm_plP%vj(:) = swifter_plP%vh(:) - capv(:) - END DO - - RETURN - -END SUBROUTINE coord_h2j -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_j2h.f90 b/coord/coord_j2h.f90 deleted file mode 100644 index 9386830e6..000000000 --- a/coord/coord_j2h.f90 +++ /dev/null @@ -1,95 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_j2h -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from Jacobi to heliocentric coordinates, planets only -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_j2h(npl, whm_pl1P) -! -! Notes : Adapted from Martin Duncan's Swift routine coord_j2h.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_j2h(npl, whm_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => coord_j2h - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: eta - REAL(DP), DIMENSION(NDIM) :: sum, sumv - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - eta = whm_pl1P%swifter%mass - whm_pl1P%eta = eta - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - eta = eta + whm_plP%swifter%mass - whm_plP%eta = eta - END DO - whm_plP => whm_pl1P - swifter_plP => whm_plP%swifter - swifter_plP%xh(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - swifter_plP%vh(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - swifter_plP%xh(:) = whm_plP%xj(:) - swifter_plP%vh(:) = whm_plP%vj(:) - sum(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - sumv(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - DO i = 3, npl - sum(:) = sum(:) + swifter_plP%mass*whm_plP%xj(:)/whm_plP%eta - sumv(:) = sumv(:) + swifter_plP%mass*whm_plP%vj(:)/whm_plP%eta - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - swifter_plP%xh(:) = whm_plP%xj(:) + sum(:) - swifter_plP%vh(:) = whm_plP%vj(:) + sumv(:) - END DO - - RETURN - -END SUBROUTINE coord_j2h -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_vb2vh.f90 b/coord/coord_vb2vh.f90 deleted file mode 100644 index 98b7952c8..000000000 --- a/coord/coord_vb2vh.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_vb2vh -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from barycentric to heliocentric coordinates, planet velocities only -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_vb2vh(npl, swifter_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine coord_vb2h.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_vb2vh(npl, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_vb2vh - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: vtmp - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - vtmp(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P) & - !$OMP REDUCTION(+:vtmp) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^ - vtmp(:) = vtmp(:) - swifter_plP%mass*swifter_plP%vb(:) - END DO - !$OMP END PARALLEL DO - vtmp(:) = vtmp(:)/swifter_pl1P%mass - swifter_pl1P%vb(:) = vtmp(:) - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P,vtmp) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^ - swifter_plP%vh(:) = swifter_plP%vb(:) - vtmp(:) - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE coord_vb2vh -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_vb2vh_tp.f90 b/coord/coord_vb2vh_tp.f90 deleted file mode 100644 index 8370ef288..000000000 --- a/coord/coord_vb2vh_tp.f90 +++ /dev/null @@ -1,72 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_vb2vh_tp -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from barycentric to heliocentric coordinates, active test particle velocities only -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! vs : barycentric velocity of the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_vb2vh_tp(ntp, swifter_tp1P, vs) -! -! Notes : Adapted from Hal Levison's Swift routine coord_vb2h_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_vb2vh_tp(ntp, swifter_tp1P, vs) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_vb2vh_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vs - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) swifter_tpP%vh(:) = swifter_tpP%vb(:) - vs(:) - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE coord_vb2vh_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_vh2vb.f90 b/coord/coord_vh2vb.f90 deleted file mode 100644 index c0278efc5..000000000 --- a/coord/coord_vh2vb.f90 +++ /dev/null @@ -1,108 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_vh2vb -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to barycentric coordinates, planet velocities only -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! msys : total system mass -! Terminal : none -! File : none -! -! Invocation : CALL coord_vh2vb(npl, swifter_pl1P, msys) -! -! Notes : Adapted from Hal Levison's Swift routine coord_vh2b.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_vh2vb(npl, swifter_pl1P, msys) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_vh2vb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(OUT) :: msys - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP), DIMENSION(NDIM) :: vtmp - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - ! Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - vtmp(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - msys = swifter_pl1P%mass - !^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P) & - !$OMP REDUCTION(+:vtmp,msys) - DO i = 2, npl - ! Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^^ - ! Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^^ - msys = msys + swifter_plP%mass - vtmp(:) = vtmp(:) + swifter_plP%mass*swifter_plP%vh(:) - END DO - !$OMP END PARALLEL DO - swifter_plP => swifter_pl1P - swifter_plP%vb(:) = -vtmp(:)/msys - vtmp(:) = swifter_plP%vb(:) - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P,vtmp) - DO i = 2, npl - ! Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^^ - ! Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^^^^ - swifter_plP%vb(:) = swifter_plP%vh(:) + vtmp(:) - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE coord_vh2vb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_vh2vb_tp.f90 b/coord/coord_vh2vb_tp.f90 deleted file mode 100644 index e6396dd60..000000000 --- a/coord/coord_vh2vb_tp.f90 +++ /dev/null @@ -1,72 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_vh2vb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to barycentric coordinates, active test particle velocities only -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! vs : barycentric velocity of the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_vh2vb_tp(ntp, swifter_tp1P, vs) -! -! Notes : Adapted from Hal Levison's Swift routine coord_vh2b_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_vh2vb_tp(ntp, swifter_tp1P, vs) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => coord_vh2vb_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vs - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) swifter_tpP%vb(:) = swifter_tpP%vh(:) + vs(:) - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE coord_vh2vb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/coord/coord_vh2vj.f90 b/coord/coord_vh2vj.f90 deleted file mode 100644 index a887e0d95..000000000 --- a/coord/coord_vh2vj.f90 +++ /dev/null @@ -1,90 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : coord_vh2vj -! Unit Type : subroutine -! Project : Swifter -! Package : coord -! Language : Fortran 90/95 -! -! Description : Convert from heliocentric to Jacobi coordinates, planet velocities only -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL coord_vh2vj(npl, whm_pl1P) -! -! Notes : Adapted from Martin Duncan's Swift routine coord_vh2vj.f -! -!********************************************************************************************************************************** -SUBROUTINE coord_vh2vj(npl, whm_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => coord_vh2vj - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: eta - REAL(DP), DIMENSION(NDIM) :: sumv, capv - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - eta = whm_pl1P%swifter%mass - whm_pl1P%eta = eta - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - eta = eta + whm_plP%swifter%mass - whm_plP%eta = eta - END DO - whm_plP => whm_pl1P - whm_plP%vj(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - whm_plP%vj(:) = swifter_plP%vh(:) - sumv(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - DO i = 3, npl - sumv(:) = sumv(:) + swifter_plP%mass*swifter_plP%vh(:) - capv(:) = sumv(:)/whm_plP%eta - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - whm_plP%vj(:) = swifter_plP%vh(:) - capv(:) - END DO - - RETURN - -END SUBROUTINE coord_vh2vj -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/descriptionator.sh b/descriptionator.sh new file mode 100755 index 000000000..3d86c8f14 --- /dev/null +++ b/descriptionator.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for file_out in */*.f90; do + file_in="../../swifter-omp/$file_out"; + desc=$(grep "Description" $file_in | sed "s/! Description : //") + sed -i "" "s/Compute Hill sphere radii of massive bodie/$desc/" $file_out +done + diff --git a/discard/discard.f90 b/discard/discard.f90 deleted file mode 100644 index 4c5a6bb29..000000000 --- a/discard/discard.f90 +++ /dev/null @@ -1,93 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : discard -! Unit Type : subroutine -! Project : Swifter -! Package : discard -! Language : Fortran 90/95 -! -! Description : Check to see if test particles should be discarded based on their positions or because they are unbound from -! the system -! -! Input -! Arguments : t : time -! dt : time step -! npl : number of planets -! ntp : number of test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! rmin : minimum heliocentric radius for test particle -! rmax : maximum heliocentric radius for test particle -! rmaxu : maximum unbound heliocentric radius for test particle -! qmin : minimum pericenter distance for test particle -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! qmin_coord : coordinate frame to use for qmin -! lclose : logical flag indicating whether to check for planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, -! qmin_coord, lclose, lrhill_present) -! -! Notes : Adapted from Hal Levison's Swift routine discard.f -! -!********************************************************************************************************************************** -SUBROUTINE discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - REAL(DP) :: msys - -! Executable code - IF ((rmin >= 0.0_DP) .OR. (rmax >= 0.0_DP) .OR. (rmaxu >= 0.0_DP) .OR. ((qmin >= 0.0_DP) .AND. (qmin_coord == "BARY"))) THEN - CALL coord_h2b(npl, swifter_pl1P, msys) - CALL coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - END IF - IF ((rmin >= 0.0_DP) .OR. (rmax >= 0.0_DP) .OR. (rmaxu >= 0.0_DP)) CALL discard_sun(t, ntp, msys, swifter_tp1P, rmin, rmax, & - rmaxu) - IF (qmin >= 0.0_DP) CALL discard_peri(t, npl, ntp, swifter_pl1P, swifter_tp1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, & - lrhill_present) - IF (lclose) CALL discard_pl(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P) - - RETURN - -END SUBROUTINE discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/discard/discard_peri.f90 b/discard/discard_peri.f90 deleted file mode 100644 index b0f959f50..000000000 --- a/discard/discard_peri.f90 +++ /dev/null @@ -1,113 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : discard_peri -! Unit Type : subroutine -! Project : Swifter -! Package : discard -! Language : Fortran 90/95 -! -! Description : Check to see if a test particle should be discarded because its perihelion distance becomes too small -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! msys : total system mass -! qmin : minimum pericenter distance for test particle -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! qmin_coord : coordinate frame to use for qmin -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : status message -! File : none -! -! Invocation : CALL discard_peri(t, npl, ntp, swifter_pl1P, swifter_tp1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, -! lrhill_present) -! -! Notes : Adapted from Hal Levison's Swift routine discard_peri.f -! -!********************************************************************************************************************************** -SUBROUTINE discard_peri(t, npl, ntp, swifter_pl1P, swifter_tp1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => discard_peri - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lrhill_present - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, msys, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lfirst = .TRUE. - INTEGER(I4B) :: i, j, ih - REAL(DP) :: r2 - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - IF (lfirst) THEN - IF (.NOT. lrhill_present) CALL util_hills(npl, swifter_pl1P) - CALL util_peri(lfirst, ntp, swifter_tp1P, swifter_pl1P%mass, msys, qmin_coord) - lfirst = .FALSE. - ELSE - CALL util_peri(lfirst, ntp, swifter_tp1P, swifter_pl1P%mass, msys, qmin_coord) - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - IF (swifter_tpP%isperi == 0) THEN - ih = 1 - swifter_plP => swifter_pl1P - DO j = 2, npl - swifter_plP => swifter_plP%nextP - dx(:) = swifter_tpP%xh(:) - swifter_plP%xh(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - IF (r2 <= swifter_plP%rhill*swifter_plP%rhill) ih = 0 - END DO - IF (ih == 1) THEN - IF ((swifter_tpP%atp >= qmin_alo) .AND. (swifter_tpP%atp <= qmin_ahi) .AND. & - (swifter_tpP%peri <= qmin)) THEN - swifter_tpP%status = DISCARDED_PERI - WRITE(*, *) "Particle ", swifter_tpP%id, " perihelion distance too small at t = ", t - END IF - END IF - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - END IF - - RETURN - -END SUBROUTINE discard_peri -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/discard/discard_pl.f90 b/discard/discard_pl.f90 deleted file mode 100644 index 2ed382df8..000000000 --- a/discard/discard_pl.f90 +++ /dev/null @@ -1,93 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : discard_pl -! Unit Type : subroutine -! Project : Swifter -! Package : discard -! Language : Fortran 90/95 -! -! Description : Check to see if test particles should be discarded based on their positions relative to the planets -! -! Input -! Arguments : t : time -! dt : time step -! npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : status message -! File : none -! -! Invocation : CALL discard_pl(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P) -! -! Notes : Adapted from Hal Levison's Swift routine discard_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE discard_pl(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => discard_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i, j, isp - REAL(DP) :: r2min, radius - REAL(DP), DIMENSION(NDIM) :: dx, dv - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - swifter_plP => swifter_pl1P - DO j = 2, npl - swifter_plP => swifter_plP%nextP - dx(:) = swifter_tpP%xh(:) - swifter_plP%xh(:) - dv(:) = swifter_tpP%vh(:) - swifter_plP%vh(:) - radius = swifter_plP%radius - CALL discard_pl_close(dx(:), dv(:), dt, radius*radius, isp, r2min) - IF (isp /= 0) THEN - swifter_tpP%status = DISCARDED_PLR - WRITE(*, *) "Particle ", swifter_tpP%id, " too close to Planet ", swifter_plP%id, " at t = ", t - EXIT - END IF - END DO - END IF - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE discard_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/discard/discard_pl_close.f90 b/discard/discard_pl_close.f90 deleted file mode 100644 index 6484a9139..000000000 --- a/discard/discard_pl_close.f90 +++ /dev/null @@ -1,92 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : discard_pl_close -! Unit Type : subroutine -! Project : Swifter -! Package : discard -! Language : Fortran 90/95 -! -! Description : Check to see if a test particle and planet are having, or will have within the next time step, an encounter such -! that the separation distance r is less than some critical radius rcrit (or r**2 < rcrit**2 = r2crit) -! -! Input -! Arguments : dx : relative position of test particle with respect to planet -! dv : relative velocity of test particle with respect to planet -! dt : time step -! r2crit : square of the boundary of the encounter region -! Terminal : none -! File : none -! -! Output -! Arguments : iflag : flag indicating encounter (0 = NO, 1 = YES) -! r2min : square of the smallest predicted separation distance -! Terminal : none -! File : none -! -! Invocation : CALL discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) -! -! Notes : Adapted from Hal Levison's Swift routine discard_pl_close.f -! -!********************************************************************************************************************************** -SUBROUTINE discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => discard_pl_close - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r2crit - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: dx, dv - REAL(DP), INTENT(OUT) :: r2min - -! Internals - REAL(DP) :: r2, v2, vdotr, tmin - -! Executable code - r2 = DOT_PRODUCT(dx(:), dx(:)) - IF (r2 <= r2crit) THEN - iflag = 1 - ELSE - vdotr = DOT_PRODUCT(dx(:), dv(:)) - IF (vdotr > 0.0_DP) THEN - iflag = 0 - ELSE - v2 = DOT_PRODUCT(dv(:), dv(:)) - tmin = -vdotr/v2 - IF (tmin < dt) THEN - r2min = r2 - vdotr*vdotr/v2 - ELSE - r2min = r2 + 2.0_DP*vdotr*dt + v2*dt*dt - END IF - r2min = MIN(r2min, r2) - IF (r2min <= r2crit) THEN - iflag = 1 - ELSE - iflag = 0 - END IF - END IF - END IF - - RETURN - -END SUBROUTINE discard_pl_close -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/discard/discard_sun.f90 b/discard/discard_sun.f90 deleted file mode 100644 index cbe115efc..000000000 --- a/discard/discard_sun.f90 +++ /dev/null @@ -1,98 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : discard_sun -! Unit Type : subroutine -! Project : Swifter -! Package : discard -! Language : Fortran 90/95 -! -! Description : Check to see if test particles should be discarded based on their positions relative to the Sun -! or because they are unbound from the system -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! msys : total system mass -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! rmin : minimum heliocentric radius for test particle -! rmax : maximum heliocentric radius for test particle -! rmaxu : maximum unbound heliocentric radius for test particle -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : status messages -! File : none -! -! Invocation : CALL discard_sun(t, ntp, msys, swifter_tp1P, rmin, rmax, rmaxu) -! -! Notes : Adapted from Hal Levison's Swift routine discard_sun.f -! -!********************************************************************************************************************************** -SUBROUTINE discard_sun(t, ntp, msys, swifter_tp1P, rmin, rmax, rmaxu) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => discard_sun - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t, msys, rmin, rmax, rmaxu - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, rmaxu2 - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - rmin2 = rmin*rmin - rmax2 = rmax*rmax - rmaxu2 = rmaxu*rmaxu - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - rh2 = DOT_PRODUCT(swifter_tpP%xh(:), swifter_tpP%xh(:)) - IF ((rmax >= 0.0_DP) .AND. (rh2 > rmax2)) THEN - swifter_tpP%status = DISCARDED_RMAX - WRITE(*, *) "Particle ", swifter_tpP%id, " too far from Sun at t = ", t - ELSE IF ((rmin >= 0.0_DP) .AND. (rh2 < rmin2)) THEN - swifter_tpP%status = DISCARDED_RMIN - WRITE(*, *) "Particle ", swifter_tpP%id, " too close to Sun at t = ", t - ELSE IF (rmaxu >= 0.0_DP) THEN - rb2 = DOT_PRODUCT(swifter_tpP%xb(:), swifter_tpP%xb(:)) - vb2 = DOT_PRODUCT(swifter_tpP%vb(:), swifter_tpP%vb(:)) - energy = 0.5_DP*vb2 - msys/SQRT(rb2) - IF ((energy > 0.0_DP) .AND. (rb2 > rmaxu2)) THEN - swifter_tpP%status = DISCARDED_RMAXU - WRITE(*, *) "Particle ", swifter_tpP%id, " is unbound and too far from barycenter at t = ", t - END IF - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE discard_sun -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_dan.f90 b/drift/drift_dan.f90 deleted file mode 100644 index 46e5cc0f1..000000000 --- a/drift/drift_dan.f90 +++ /dev/null @@ -1,119 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_dan -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Perform Kepler drift, solving Kepler's equation in appropriate variables -! -! Input -! Arguments : mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! x0 : position of body to drift -! v0 : velocity of body to drift -! dt0 : time step -! Terminal : none -! File : none -! -! Output -! Arguments : x0 : position of body to drift -! v0 : velocity of body to drift -! iflag : error status flag for Kepler drift (0 = OK, nonzero = NO CONVERGENCE) -! Terminal : none -! File : none -! -! Invocation : CALL drift_dan(mu, x0, v0, dt0, iflag) -! -! Notes : Adapted from Hal Levison and Martin Duncan's Swift routine drift_dan.f -! -!********************************************************************************************************************************** -SUBROUTINE drift_dan(mu, x0, v0, dt0, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_dan - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: mu, dt0 - REAL(DP), DIMENSION(NDIM), INTENT(INOUT) :: x0, v0 - -! Internals - REAL(DP) :: dt, f, g, fdot, gdot, c1, c2, c3, u, alpha, fp, r0 - REAL(DP) :: v0s, a, asq, en, dm, ec, es, esq, xkep, fchk, s, c - REAL(DP), DIMENSION(NDIM) :: x, v - -! Executable code - iflag = 0 - dt = dt0 - r0 = SQRT(DOT_PRODUCT(x0(:), x0(:))) - v0s = DOT_PRODUCT(v0(:), v0(:)) - u = DOT_PRODUCT(x0(:), v0(:)) - alpha = 2.0_DP*mu/r0 - v0s - IF (alpha > 0.0_DP) THEN - a = mu/alpha - asq = a*a - en = SQRT(mu/(a*asq)) - ec = 1.0_DP - r0/a - es = u/(en*asq) - esq = ec*ec + es*es - dm = dt*en - INT(dt*en/TWOPI)*TWOPI - dt = dm/en - IF ((esq < E2MAX) .AND. (dm*dm < DM2MAX) .AND. (esq*dm*dm < E2DM2MAX)) THEN - CALL drift_kepmd(dm, es, ec, xkep, s, c) - fchk = (xkep - ec*s + es*(1.0_DP - c) - dm) -! DEK - original code compared fchk*fchk with DANBYB, but I think it should -! DEK - be compared with DANBYB*DANBYB, and I changed it accordingly - please -! DEK - check with Hal and/or Martin about this - IF (fchk*fchk > DANBYB*DANBYB) THEN - iflag = 1 - RETURN - END IF - fp = 1.0_DP - ec*c + es*s - f = a/r0*(c - 1.0_DP) + 1.0_DP - g = dt + (s - xkep)/en - fdot = -(a/(r0*fp))*en*s - gdot = (c - 1.0_DP)/fp + 1.0_DP - x(:) = x0(:)*f + v0(:)*g - v(:) = x0(:)*fdot + v0(:)*gdot - x0(:) = x(:) - v0(:) = v(:) - iflag = 0 - RETURN - END IF - END IF - CALL drift_kepu(dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - IF (iflag == 0) THEN - f = 1.0_DP - mu/r0*c2 - g = dt - mu*c3 - fdot = -mu/(fp*r0)*c1 - gdot = 1.0_DP - mu/fp*c2 - x(:) = x0(:)*f + v0(:)*g - v(:) = x0(:)*fdot + v0(:)*gdot - x0(:) = x(:) - v0(:) = v(:) - END IF - - RETURN - -END SUBROUTINE drift_dan -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepmd.f90 b/drift/drift_kepmd.f90 deleted file mode 100644 index b5edbbe63..000000000 --- a/drift/drift_kepmd.f90 +++ /dev/null @@ -1,88 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepmd -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Solve Kepler's equation in difference form for an ellipse for small input dm and eccentricity -! -! Input -! Arguments : dm : increment in mean anomaly -! es : eccentricity times the sine of eccentric anomaly -! ec : eccentricity times the cosine of eccentric anomaly -! Terminal : none -! File : none -! -! Output -! Arguments : x : solution to Kepler's equation in difference form (x = dE) -! s : sine of x -! c : cosine of x -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepmd(dm, es, ec, x, s, c) -! -! Notes : Adapted from Martin Duncan's Swift routine drift_kepmd.f -! -! Original disclaimer: built for speed, does not check how well the original equation is solved -! Can do that in calling routine by checking how close (x - ec*s + es*(1.0 - c) - dm) is to zero -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepmd(dm, es, ec, x, s, c) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepmd - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: dm, es, ec - REAL(DP), INTENT(OUT) :: x, s, c - -! Internals - REAL(DP), PARAMETER :: A0 = 39916800.0_DP, A1 = 6652800.0_DP, A2 = 332640.0_DP, A3 = 7920.0_DP, A4 = 110.0_DP - REAL(DP) :: dx, fac1, fac2, q, y, f, fp, fpp, fppp - -! Executable code - fac1 = 1.0_DP/(1.0_DP - ec) - q = fac1*dm - fac2 = es*es*fac1 - ec/3.0_DP - x = q*(1.0_DP - 0.5_DP*fac1*q*(es - q*fac2)) - y = x*x - s = x*(A0 - y*(A1 - y*(A2 - y*(A3 - y*(A4 - y)))))/A0 - c = SQRT(1.0_DP - s*s) - f = x - ec*s + es*(1.0_DP - c) - dm - fp = 1.0_DP - ec*c + es*s - fpp = ec*s + es*c - fppp = ec*c - es*s - dx = -f/fp - dx = -f/(fp + dx*fpp/2.0_DP) - dx = -f/(fp + dx*fpp/2.0_DP + dx*dx*fppp/6.0_DP) - x = x + dx - y = x*x - s = x*(A0 - y*(A1 - y*(A2 - y*(A3 - y*(A4 - y)))))/A0 - c = SQRT(1.0_DP - s*s) - - RETURN - -END SUBROUTINE drift_kepmd -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu.f90 b/drift/drift_kepu.f90 deleted file mode 100644 index 3bf5ae198..000000000 --- a/drift/drift_kepu.f90 +++ /dev/null @@ -1,80 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Solve Kepler's equation in universal variables -! -! Input -! Arguments : dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! Terminal : none -! File : none -! -! Output -! Arguments : fp : first derivative of Kepler's equation with respect to universal variable s -! c1 : Stumpff function c1 times s -! c2 : Stumpff function c2 times s**2 -! c3 : Stumpff function c3 times s**3 -! iflag : error status flag for convergence (0 = CONVERGED, nonzero = NOT CONVERGED) -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu(dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) -! -! Notes : Adapted from Hal Levison's Swift routine drift_kepu.f -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu(dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - -! Internals - REAL(DP) :: s, st, fo, fn - -! Executable code - CALL drift_kepu_guess(dt, r0, mu, alpha, u, s) - st = s - CALL drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - IF (iflag /= 0) THEN - CALL drift_kepu_fchk(dt, r0, mu, alpha, u, st, fo) - CALL drift_kepu_fchk(dt, r0, mu, alpha, u, s, fn) - IF (ABS(fo) < ABS(fn)) s = st - CALL drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - END IF - - RETURN - -END SUBROUTINE drift_kepu -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_fchk.f90 b/drift/drift_kepu_fchk.f90 deleted file mode 100644 index 4eb2b38a5..000000000 --- a/drift/drift_kepu_fchk.f90 +++ /dev/null @@ -1,73 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_fchk -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Computes the value of f, the function whose root we are trying to find in universal variables -! -! Input -! Arguments : dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! s : universal variable (approximate root of f) -! Terminal : none -! File : none -! -! Output -! Arguments : f : function value -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_fchk(dt, r0, mu, alpha, u, s, f) -! -! Notes : Adapted from Martin Duncan's Swift routine drift_kepu_fchk.f -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_fchk(dt, r0, mu, alpha, u, s, f) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_fchk - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u, s - REAL(DP), INTENT(OUT) :: f - -! Internals - REAL(DP) :: x, c0, c1, c2, c3 - -! Executable code - x = s*s*alpha - CALL drift_kepu_stumpff(x, c0, c1, c2, c3) - c1 = c1*s - c2 = c2*s*s - c3 = c3*s*s*s - f = r0*c1 + u*c2 + mu*c3 - dt - - RETURN - -END SUBROUTINE drift_kepu_fchk -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_guess.f90 b/drift/drift_kepu_guess.f90 deleted file mode 100644 index d4cb43e16..000000000 --- a/drift/drift_kepu_guess.f90 +++ /dev/null @@ -1,87 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_guess -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Compute initial guess for solving Kepler's equation using universal variables -! -! Input -! Arguments : dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! Terminal : none -! File : none -! -! Output -! Arguments : s : initial guess for the value of the universal variable -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_guess(dt, r0, mu, alpha, u, s) -! -! Notes : Adapted from Hal Levison and Martin Duncan's Swift routine drift_kepu_guess.f -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_guess(dt, r0, mu, alpha, u, s) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_guess - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: s - -! Internals - INTEGER(I4B) :: iflag - REAL(DP), PARAMETER :: THRESH = 0.4_DP, DANBYK = 0.85_DP - REAL(DP) :: y, sy, cy, sigma, es, x, a, en, ec, e - -! Executable code - IF (alpha > 0.0_DP) THEN - IF (dt/r0 <= THRESH) THEN - s = dt/r0 - (dt*dt*u)/(2.0_DP*r0*r0*r0) - ELSE - a = mu/alpha - en = SQRT(mu/(a*a*a)) - ec = 1.0_DP - r0/a - es = u/(en*a*a) - e = SQRT(ec*ec + es*es) - y = en*dt - es - CALL orbel_scget(y, sy, cy) - sigma = SIGN(1.0_DP, es*cy + ec*sy) - x = y + sigma*DANBYK*e - s = x/SQRT(alpha) - END IF - ELSE - CALL drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) - IF (iflag /= 0) s = dt/r0 - END IF - - RETURN - -END SUBROUTINE drift_kepu_guess -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_lag.f90 b/drift/drift_kepu_lag.f90 deleted file mode 100644 index 45d2cf47e..000000000 --- a/drift/drift_kepu_lag.f90 +++ /dev/null @@ -1,101 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_lag -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Solve Kepler's equation in universal variables using Laguerre's method -! -! Input -! Arguments : s : universal variable -! dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! Terminal : none -! File : none -! -! Output -! Arguments : s : universal variable -! fp : first derivative of Kepler's equation in universal variables with respect to s (see Danby, p. 175) -! c1 : Stumpff function c1 times s -! c2 : Stumpff function c2 times s**2 -! c3 : Stumpff function c3 times s**3 -! iflag : error status flag for convergence (0 = CONVERGED, nonzero = NOT CONVERGED) -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) -! -! Notes : Adapted from Hal Levison's Swift routine drift_kepu_lag.f -! -! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 178 - 180. -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_lag - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(INOUT) :: s - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - -! Internals - INTEGER(I4B) :: nc, ncmax - REAL(DP) :: ln, x, fpp, ds, c0, f, fdt - -! Executable code - IF (alpha < 0.0_DP) THEN - ncmax = NLAG2 - ELSE - ncmax = NLAG1 - END IF - ln = 5.0_DP - DO nc = 0, ncmax - x = s*s*alpha - CALL drift_kepu_stumpff(x, c0, c1, c2, c3) - c1 = c1*s - c2 = c2*s*s - c3 = c3*s*s*s - f = r0*c1 + u*c2 + mu*c3 - dt - fp = r0*c0 + u*c1 + mu*c2 - fpp = (-r0*alpha + mu)*c1 + u*c0 - ds = -ln*f/(fp + SIGN(1.0_DP, fp)*SQRT(ABS((ln - 1.0_DP)*(ln - 1.0_DP)*fp*fp - (ln - 1.0_DP)*ln*f*fpp))) - s = s + ds - fdt = f/dt - IF (fdt*fdt < DANBYB*DANBYB) THEN - iflag = 0 - RETURN - END IF - END DO - iflag = 2 - - RETURN - -END SUBROUTINE drift_kepu_lag -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_new.f90 b/drift/drift_kepu_new.f90 deleted file mode 100644 index de86aa51c..000000000 --- a/drift/drift_kepu_new.f90 +++ /dev/null @@ -1,98 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_new -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Solve Kepler's equation in universal variables using Newton's method -! -! Input -! Arguments : s : universal variable -! dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! Terminal : none -! File : none -! -! Output -! Arguments : s : universal variable -! fp : first derivative of Kepler's equation in universal variables with respect to s (see Danby, p. 175) -! c1 : Stumpff function c1 times s -! c2 : Stumpff function c2 times s**2 -! c3 : Stumpff function c3 times s**3 -! iflag : error status flag for convergence (0 = CONVERGED, nonzero = NOT CONVERGED) -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) -! -! Notes : Adapted from Hal Levison's Swift routine drift_kepu_new.f -! -! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 174 - 175. -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_new - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(INOUT) :: s - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - -! Internals - INTEGER(I4B) :: nc - REAL(DP) :: x, c0, ds, f, fpp, fppp, fdt - -! Executable code - DO nc = 0, 6 - x = s*s*alpha - CALL drift_kepu_stumpff(x, c0, c1, c2, c3) - c1 = c1*s - c2 = c2*s*s - c3 = c3*s*s*s - f = r0*c1 + u*c2 + mu*c3 - dt - fp = r0*c0 + u*c1 + mu*c2 - fpp = (-r0*alpha + mu)*c1 + u*c0 - fppp = (-r0*alpha + mu)*c0 - u*alpha*c1 - ds = -f/fp - ds = -f/(fp + ds*fpp/2.0_DP) - ds = -f/(fp + ds*fpp/2.0_DP + ds*ds*fppp/6.0_DP) - s = s + ds - fdt = f/dt - IF (fdt*fdt < DANBYB*DANBYB) THEN - iflag = 0 - RETURN - END IF - END DO - iflag = 1 - - RETURN - -END SUBROUTINE drift_kepu_new -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_p3solve.f90 b/drift/drift_kepu_p3solve.f90 deleted file mode 100644 index 6be933322..000000000 --- a/drift/drift_kepu_p3solve.f90 +++ /dev/null @@ -1,95 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_p3solve -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Computes real root of cubic involved in setting initial guess for solving Kepler's equation in universal variables -! -! Input -! Arguments : dt : time step -! r0 : distance between two bodies -! mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! alpha : twice the binding energy -! u : dot product of position and velocity vectors -! Terminal : none -! File : none -! -! Output -! Arguments : s : real solution of cubic equation -! iflag : error status flag for solution (0 = OK, nonzero = ERROR) -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) -! -! Notes : Adapted from Martin Duncan's Swift routine drift_kepu_p3solve.f -! -! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 177 - 178. -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_p3solve - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: s - -! Internals - REAL(DP) :: denom, a0, a1, a2, q, r, sq2, sq, p1, p2 - -! Executable code - denom = (mu - alpha*r0)/6.0_DP - a2 = 0.5_DP*u/denom - a1 = r0/denom - a0 = -dt/denom - q = (a1 - a2*a2/3.0_DP)/3.0_DP - r = (a1*a2 - 3.0_DP*a0)/6.0_DP - (a2*a2*a2)/27.0_DP - sq2 = q*q*q + r*r - IF (sq2 >= 0.0_DP) THEN - sq = SQRT(sq2) - IF ((r + sq) <= 0.0_DP) THEN - p1 = -(-(r + sq))**(1.0_DP/3.0_DP) - ELSE - p1 = (r + sq)**(1.0_DP/3.0_DP) - END IF - IF ((r - sq) <= 0.0_DP) THEN - p2 = -(-(r - sq))**(1.0_DP/3.0_DP) - ELSE - p2 = (r - sq)**(1.0_DP/3.0_DP) - END IF - iflag = 0 - s = p1 + p2 - a2/3.0_DP - ELSE - iflag = 1 - s = 0.0_DP - END IF - - RETURN - -END SUBROUTINE drift_kepu_p3solve -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_kepu_stumpff.f90 b/drift/drift_kepu_stumpff.f90 deleted file mode 100644 index a8c094dfc..000000000 --- a/drift/drift_kepu_stumpff.f90 +++ /dev/null @@ -1,89 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_kepu_stumpff -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Compute Stumpff functions needed for Kepler drift in universal variables -! -! Input -! Arguments : x : argument of Stumpff functions -! Terminal : none -! File : none -! -! Output -! Arguments : c0 : zeroth Stumpff function -! c1 : first Stumpff function -! c2 : second Stumpff function -! c3 : third Stumpff function -! Terminal : none -! File : none -! -! Invocation : CALL drift_kepu_stumpff(x, c0, c1, c2, c3) -! -! Notes : Adapted from Hal Levison's Swift routine drift_kepu_stumpff.f -! -! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 171 - 172. -! -!********************************************************************************************************************************** -SUBROUTINE drift_kepu_stumpff(x, c0, c1, c2, c3) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_kepu_stumpff - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: c0, c1, c2, c3 - -! Internals - INTEGER(I4B) :: i, n - REAL(DP) :: xm - -! Executable code - n = 0 - xm = 0.1_DP - DO WHILE (ABS(x) >= xm) - n = n + 1 - x = x/4.0_DP - END DO - c2 = (1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x/182.0_DP)/132.0_DP)/90.0_DP)/56.0_DP)/ & - 30.0_DP)/12.0_DP)/2.0_DP - c3 = (1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x*(1.0_DP - x/210.0_DP)/156.0_DP)/110.0_DP)/72.0_DP)/ & - 42.0_DP)/20.0_DP)/6.0_DP - c1 = 1.0_DP - x*c3 - c0 = 1.0_DP - x*c2 - IF (n /= 0) THEN - DO i = n, 1, -1 - c3 = (c2 + c0*c3)/4.0_DP - c2 = c1*c1/2.0_DP - c1 = c0*c1 - c0 = 2.0_DP*c0*c0 - 1.0_DP - x = x*4.0_DP - END DO - END IF - - RETURN - -END SUBROUTINE drift_kepu_stumpff -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/drift/drift_one.f90 b/drift/drift_one.f90 deleted file mode 100644 index 40fced66e..000000000 --- a/drift/drift_one.f90 +++ /dev/null @@ -1,77 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : drift_one -! Unit Type : subroutine -! Project : Swifter -! Package : drift -! Language : Fortran 90/95 -! -! Description : Perform Danby drift for one body, redoing drift with smaller substeps if original accuracy is insufficient -! -! Input -! Arguments : mu : G * (m1 + m2), G = gravitational constant, m1 = mass of central body, m2 = mass of body to drift -! x : position of body to drift -! v : velocity of body to drift -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : x : position of body to drift -! v : velocity of body to drift -! iflag : error status flag for Danby drift (0 = OK, nonzero = ERROR) -! Terminal : none -! File : none -! -! Invocation : CALL drift_one(mu, x, v, dt, iflag) -! -! Notes : Adapted from Hal Levison and Martin Duncan's Swift routine drift_one.f -! -!********************************************************************************************************************************** -SUBROUTINE drift_one(mu, x, v, dt, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => drift_one - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: mu, dt - REAL(DP), DIMENSION(NDIM), INTENT(INOUT) :: x, v - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: dttmp - -! Executable code - CALL drift_dan(mu, x(:), v(:), dt, iflag) - IF (iflag /= 0) THEN - dttmp = 0.1_DP*dt - DO i = 1, 10 - CALL drift_dan(mu, x(:), v(:), dttmp, iflag) - IF (iflag /= 0) RETURN - END DO - END IF - - RETURN - -END SUBROUTINE drift_one -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/example/cleanup b/example/cleanup deleted file mode 100755 index 771f32a38..000000000 --- a/example/cleanup +++ /dev/null @@ -1,4 +0,0 @@ -rm bin.dat -rm enc.dat -rm dump* -rm discard.out diff --git a/example/pl.in b/example/pl.in deleted file mode 100644 index b729f1166..000000000 --- a/example/pl.in +++ /dev/null @@ -1,4040 +0,0 @@ - 1010 - 1 39.478417604357432 - 0. 0. 0. - 0. 0. 0. - 2 6.55357523599375121E-006 1.47472141260320184E-003 - 1.98730047274502167E-005 - 0.38696130000000001 0.0000000000000000 0.0000000000000000 - -0.0000000000000000 10.101080106674772 1.76297105869353861E-005 - 3 9.66265853600731635E-005 6.75579990141486446E-003 - 4.87307387320644959E-005 - 0.72034028802905381 6.11091553656099781E-002 1.06655596424373647E-007 - -0.62469145379829361 7.3637152905277885 1.28521076999291225E-005 - 4 1.18559609828526030E-004 1.00034974028906133E-002 - 5.21694637092163038E-005 - -0.74225160567382209 0.66997206200950321 1.16932183784533220E-006 - -4.2104006332201767 -4.6646372404763117 -8.14132782575368220E-006 - 5 1.27389747494092644E-005 7.24298628936283391E-003 - 2.48017467029555864E-005 - -1.3065051111685591 0.77651937361059742 1.35528197750426552E-006 - -2.6040759285138426 -4.3813955273833383 -7.64697777850702829E-006 - 6 3.76820311681063530E-002 0.35499404182092387 - 3.56026434386322928E-004 - 3.2206014306629926 3.8121822437313071 -8.79014660050845831E-002 - -2.1400120298591467 1.9107997013286697 3.99442777609735275E-002 - 7 1.12823790534788936E-002 0.43478727769049391 - 2.38179493300108591E-004 - -8.7463966460086109 -4.2189455043391977 0.42158721331679988 - 0.77354227020944233 -1.8381019202323063 1.08140305091147804E-003 - 8 2.03295690590342762E-003 0.46996331015216247 - 1.27320322141504384E-004 - 20.008405996215117 1.5734734394919658 -0.25333454465395294 - -0.12483117763480311 1.3665469545383413 6.69521270566226113E-003 - 9 1.72337899857533789E-003 0.77748541767833557 - 1.34528258950937431E-004 - 26.166863799425222 -14.668380943770991 -0.30085588260406820 - 0.55137505402264009 1.0083952446639568 -3.33317385639450153E-002 - 10 1.93253170720146327E-004 1.17728558893560528E-003 - 6.13968839282220328E-005 - 9.10615876221524262E-002 4.13011822795847222E-002 7.20841615745822592E-008 - -8.2078460794613051 18.096806282496676 3.15848853725482807E-005 - 101 6.55357523599375162E-009 1.33069891324005606E-004 - 1.98730033637173138E-006 - 0.16457831748553620 -0.30798711671367640 -1.60716485372296592E-005 - 9.3777708892540019 5.0111545195253147 1.46427289033919058E-004 - 102 6.55357523599375162E-009 8.50103503041321925E-005 - 1.98730033637173138E-006 - 0.18328101889880188 -0.12717728176799686 1.97832329486040821E-006 - 7.5836273990715508 10.929715706127267 -2.30375248696843070E-004 - 103 6.55357523599375162E-009 1.29174218831804911E-004 - 1.98730033637173138E-006 - 0.16452883304751170 0.29641166767064003 1.94041433150345911E-006 - -9.4341734938558890 5.2380362280682871 -3.31612188945735532E-004 - 104 6.55357523599375162E-009 1.03910597706992583E-004 - 1.98730033637173138E-006 - 0.25126923063506773 -0.10596612430180880 -4.20507261442512642E-006 - 4.6758725963670003 11.085904009020156 -9.97239863068199832E-005 - 105 6.55357523599375162E-009 6.63901701201896567E-005 - 1.98730033637173138E-006 - 0.10663925011822126 -0.13776313324752246 -1.78125787108573468E-005 - 11.903454275884000 9.2155940751252654 1.00342034654370962E-003 - 106 6.55357523599375162E-009 7.66813525752459694E-005 - 1.98730033637173138E-006 - 2.88249048976911698E-002 0.19915088139911774 9.90638814751844941E-006 - -13.862326677622438 2.0070223428386802 -1.59740687790535583E-006 - 107 6.55357523599375162E-009 4.31586460770584120E-005 - 1.98730033637173138E-006 - -0.11269191391294389 -1.12592154196081151E-002 -8.65939241782642502E-006 - 1.8562664032920242 -18.578368956801850 3.32805703282134172E-004 - 108 6.55357523599375162E-009 3.84627414253198668E-005 - 1.98730033637173138E-006 - 7.84404820275039633E-002 -6.35436196384361052E-002 -2.26825201929619690E-006 - 12.447793041385125 15.364589012730226 8.16012913944893256E-004 - 109 6.55357523599375162E-009 6.46229271414427265E-005 - 1.98730033637173138E-006 - 0.13867107236819698 9.75685992187412809E-002 7.73018934497404978E-007 - -8.7808934868014745 12.480762423902204 -1.20933410755171320E-004 - 110 6.55357523599375162E-009 6.42055092795376219E-005 - 1.98730033637173138E-006 - -6.16506719533665426E-002 0.15679841685972762 -5.10368691441307649E-006 - -14.245354210470506 -5.6032009179516420 5.91789941946552342E-004 - 111 6.55357523599375162E-009 5.39443441152739385E-005 - 1.98730033637173138E-006 - -5.64620991486817422E-002 -0.12982739567469942 3.78155365138544196E-006 - 15.312198733879374 -6.6609102335105623 1.52528830027628579E-004 - 112 6.55357523599375162E-009 4.74565519646694606E-005 - 1.98730033637173138E-006 - 0.12274404778355139 -2.10337007193735284E-002 -9.09955773025029470E-006 - 3.0059576709599778 17.549478298795957 -1.43517198743353777E-003 - 113 6.55357523599375162E-009 1.21307408956661649E-004 - 1.98730033637173138E-006 - -0.26782219729464923 0.17210818042164894 -5.14273489381372439E-006 - -6.0189865515628815 -9.3687035183121985 -1.65073393301487959E-004 - 114 6.55357523599375162E-009 6.80983172259777428E-005 - 1.98730033637173138E-006 - -7.20348086894616324E-002 0.16355286669690838 2.00526636139968980E-006 - -13.601580295716294 -5.9908239181820342 8.09583714102787459E-006 - 115 6.55357523599375162E-009 7.34073600515367728E-005 - 1.98730033637173138E-006 - -0.12527697482498787 -0.14633501799473062 1.01430786517548030E-005 - 10.875152853931423 -9.3098059894496465 -2.70125224917654888E-005 - 116 6.55357523599375162E-009 9.46995955131494765E-005 - 1.98730033637173138E-006 - 3.46426275871703077E-002 -0.24608106222385814 -6.57474984167634118E-006 - 12.481350700602061 1.7553981967847021 -2.24932802033617533E-004 - 117 6.55357523599375162E-009 3.91830757445740523E-005 - 1.98730033637173138E-006 - -0.10282929202488582 4.23207107558040696E-004 -6.42743217951030645E-006 - -8.28368477402792180E-002 -19.593193375981112 -4.69023947384249174E-004 - 118 6.55357523599375162E-009 9.35441721133110953E-005 - 1.98730033637173138E-006 - 3.05913149106759735E-002 0.24357869543042943 -8.92352432247383289E-006 - -12.582141301035247 1.5797738193710895 -6.58051302239658097E-004 - 119 6.55357523599375162E-009 9.30824250318291639E-005 - 1.98730033637173138E-006 - 0.23852204577843822 -5.26883031549868625E-002 -2.51837390913380115E-006 - 2.7409440424674933 12.413781052598024 2.75917992957929077E-004 - 120 6.55357523599375162E-009 6.25573017261353868E-005 - 1.98730033637173138E-006 - -4.51675841593427996E-002 0.15783744240961398 4.92051602123388457E-006 - -14.908798391191564 -4.2642216078209287 8.50397403641604214E-004 - 121 6.55357523599375162E-009 1.16056706801528033E-004 - 1.98730033637173138E-006 - 6.01692865276608965E-002 0.29857925600187990 7.87949802056149700E-006 - -11.160487062369677 2.2470300930542879 3.92686756618415762E-004 - 122 6.55357523599375162E-009 6.93927319043629513E-005 - 1.98730033637173138E-006 - 9.57228450816625526E-002 0.15490909352703428 2.96365489527164226E-006 - -12.525721123078593 7.7400772962282129 1.43541219372150558E-004 - 123 6.55357523599375162E-009 5.30731623663794610E-005 - 1.98730033637173138E-006 - 3.58313301184151611E-002 0.13460768101672749 6.21113939061761797E-006 - -16.267649129848341 4.3290184341119646 1.45829647709950713E-004 - 124 6.55357523599375162E-009 1.29495065910201944E-004 - 1.98730033637173138E-006 - 0.11937031193331238 -0.31819341337443235 -7.52137767884659103E-006 - 10.090852447828363 3.7857377868108353 2.97392684993275102E-004 - 125 6.55357523599375162E-009 8.81691227902901180E-005 - 1.98730033637173138E-006 - -0.23064502844685178 1.83384152188510452E-002 1.43106622809495625E-006 - -1.0349179555723067 -13.021432211802626 8.23926565118657597E-004 - 126 6.55357523599375162E-009 9.58590799913103063E-005 - 1.98730033637173138E-006 - -0.15658559631495381 0.19692732131584156 1.11599645427717700E-005 - -9.8041502374654392 -7.7954009869908516 -1.52912617116635410E-004 - 127 6.55357523599375162E-009 7.44612326226477790E-005 - 1.98730033637173138E-006 - 0.18716196635998053 5.60246348241588976E-002 2.70618833430874547E-006 - -4.0757170637161870 13.619778173647200 -1.64065020526198033E-004 - 128 6.55357523599375162E-009 6.31563455816438844E-005 - 1.98730033637173138E-006 - 8.96839557811526522E-002 0.13938097612517875 -9.62757817912185637E-006 - -12.978319753486778 8.3515534968421967 -5.19259443691814405E-004 - 129 6.55357523599375162E-009 4.50599495247745794E-005 - 1.98730033637173138E-006 - -7.45564511431734134E-002 -9.17887207739380984E-002 -6.40967024065940271E-006 - 14.183333636023647 -11.517938750035480 3.06871030853157279E-005 - 130 6.55357523599375162E-009 1.04737007245795242E-004 - 1.98730033637173138E-006 - 0.22434514486570581 -0.15876337372164581 -4.20820099092179821E-006 - 6.9241871019343533 9.7828935662119534 1.14303877895850531E-004 - 131 6.55357523599375162E-009 8.89069864318167013E-005 - 1.98730033637173138E-006 - -0.20297078909483485 0.11515648563960840 -1.05749395461688648E-005 - -6.4177665660012320 -11.311381040850106 -3.47971567185194949E-004 - 132 6.55357523599375162E-009 1.00769610785086079E-004 - 1.98730033637173138E-006 - -0.20301747855348448 -0.16946840313288172 7.33274170469091439E-007 - 7.8291205865808164 -9.3798448290811400 -7.25734601532765128E-004 - 133 6.55357523599375162E-009 1.20929970473768154E-004 - 1.98730033637173138E-006 - 0.24068484555334987 -0.20688786695767114 -3.15282256171326581E-007 - 7.2697452758419505 8.4572092742708644 -3.53766266346603343E-004 - 134 6.55357523599375162E-009 9.43125583547821020E-005 - 1.98730033637173138E-006 - 0.24558396207234692 -3.06248571061227340E-002 -1.69139103904754139E-005 - 1.5626904056335458 12.533274511359217 7.34561545162098952E-004 - 135 6.55357523599375162E-009 4.87657677272718699E-005 - 1.98730033637173138E-006 - 3.98268206432828425E-002 -0.12160691045926345 -3.85764017041478351E-006 - 16.692175754147947 5.4690220450303908 -1.84086872028191273E-004 - 136 6.55357523599375162E-009 8.95795209621882824E-005 - 1.98730033637173138E-006 - -0.23502861758796878 -4.19985888969752474E-003 -2.51508724416352793E-006 - 0.23061116254760972 -12.957639491540412 -3.05235500091179893E-004 - 137 6.55357523599375162E-009 1.30736259437733778E-004 - 1.98730033637173138E-006 - -0.15608400641198453 -0.30553628377035424 -1.47158090399320353E-005 - 9.5525018914489195 -4.8795721939469878 3.09774726109113339E-004 - 138 6.55357523599375162E-009 1.33266252300264849E-004 - 1.98730033637173138E-006 - -0.32870673246507787 -0.11939733046063690 1.39137983868696796E-005 - 3.6281408678855480 -9.9861298360312851 -2.87262802407829405E-006 - 139 6.55357523599375162E-009 5.70554505334332890E-005 - 1.98730033637173138E-006 - -0.14365212104404373 4.21951317823103383E-002 -2.62991841702598804E-006 - -4.5769412699444887 -15.580149695991022 -7.60652217503347480E-004 - 140 6.55357523599375162E-009 8.34356901211908829E-005 - 1.98730033637173138E-006 - 1.90348478494151568E-002 0.21813693993028938 -5.79987524771476689E-006 - -13.376387662108661 1.1650427014465832 -1.24635386469728238E-004 - 141 6.55357523599375162E-009 9.43980275461287757E-005 - 1.98730033637173138E-006 - 5.45901402184137338E-002 0.24162410959064601 1.33245619006573286E-005 - -12.313815282879579 2.7830991647422474 -1.52855394737062481E-004 - 142 6.55357523599375162E-009 8.37443156326222825E-005 - 1.98730033637173138E-006 - -2.08927882966552930E-002 -0.21877098250018331 -1.36017478623434599E-006 - 13.342077229558349 -1.2747914531300011 -1.04420724946581098E-004 - 143 6.55357523599375162E-009 1.30625628096640173E-004 - 1.98730033637173138E-006 - -0.26911642203902447 -0.21231830012924291 -1.76113324546839482E-005 - 6.6474013040440845 -8.4251145436397259 4.04872689115635509E-004 - 144 6.55357523599375162E-009 1.21473102903841773E-004 - 1.98730033637173138E-006 - 0.31502113974202206 4.87579697946535218E-002 -1.02616886025023527E-006 - -1.7017099337284947 10.997712631770451 -9.63724458449221840E-005 - 145 6.55357523599375162E-009 9.42807745059018077E-005 - 1.98730033637173138E-006 - 0.13964192955668622 0.20422660779973612 -8.84025034898692274E-006 - -10.427640147871525 7.1303802942994867 2.36745000937867904E-004 - 146 6.55357523599375162E-009 1.01831212684120242E-004 - 1.98730033637173138E-006 - -0.26602694877450811 2.53501037146945662E-002 5.90998600130446398E-006 - -1.1527408440660833 -12.099578117510971 1.38923027803859581E-004 - 147 6.55357523599375162E-009 6.94974096282289627E-005 - 1.98730033637173138E-006 - -4.20484111786459391E-002 0.17745620990200223 -5.00076189337500032E-006 - -14.316643675752783 -3.3935773670802436 5.54343965518287800E-005 - 148 6.55357523599375162E-009 1.24658060033380595E-004 - 1.98730033637173138E-006 - -0.19065638786976036 0.26579732838069320 -9.68189423522449163E-006 - -8.9264367669581848 -6.4045397885915198 -4.56749853167414267E-004 - 149 6.55357523599375162E-009 4.85496558728992097E-005 - 1.98730033637173138E-006 - -5.56770368836791707E-002 0.11460000468674138 -8.65463237127644774E-006 - -15.831771473308665 -7.6942058648905416 -2.73328039546645672E-004 - 150 6.55357523599375162E-009 9.60221571901961993E-005 - 1.98730033637173138E-006 - 0.15029583378637756 0.20226725033381976 3.51715370204279629E-006 - -10.046342224867201 7.4651836288712596 -8.46181122654923431E-004 - 151 6.55357523599375162E-009 1.06300941837660415E-004 - 1.98730033637173138E-006 - 0.26327083142994695 9.23006136953856415E-002 -1.72116111841165124E-005 - -3.9368642414642068 11.224863905419500 1.46597912343630866E-004 - 152 6.55357523599375162E-009 6.39540930034506892E-005 - 1.98730033637173138E-006 - 9.60750855524678260E-002 0.13762279835414454 2.86776648836647259E-008 - -12.574980324119235 8.7788791908023072 8.33702927135178900E-005 - 153 6.55357523599375162E-009 4.61808481249393872E-005 - 1.98730033637173138E-006 - 7.56994687515195885E-002 9.46384649298881997E-002 5.59698021357159314E-006 - -14.095055185723457 11.273270140204781 7.13306669986576232E-004 - 154 6.55357523599375162E-009 8.97886813240781305E-005 - 1.98730033637173138E-006 - -0.16009490272200491 0.17290096622933124 -5.42430720274322945E-006 - -9.4978546507478381 -8.7932270747208712 -9.10070859853994558E-005 - 155 6.55357523599375162E-009 1.12029713026659181E-004 - 1.98730033637173138E-006 - 0.27726795104268226 9.78003397395445090E-002 2.78667559118501166E-005 - -3.8552726966165687 10.927175887050694 -7.68898087230236336E-004 - 156 6.55357523599375162E-009 1.26884674576592462E-004 - 1.98730033637173138E-006 - 0.28291408759375808 -0.17549392698471356 3.88502088486366107E-006 - 5.7410194910411887 9.2541457342591862 1.45091836925531926E-005 - 157 6.55357523599375162E-009 1.02077656830970533E-004 - 1.98730033637173138E-006 - -0.24429469467741957 0.10991436298185296 3.09135655128471170E-006 - -4.9812784263287426 -11.070440369402013 3.57425635984836708E-004 - 158 6.55357523599375162E-009 7.82870668093689004E-005 - 1.98730033637173138E-006 - -0.12849250676594545 0.16031689528156029 -1.81804360475917783E-007 - -10.816443176353960 -8.6685648876928205 2.72437061404540897E-004 - 159 6.55357523599375162E-009 6.70409620488065806E-005 - 1.98730033637173138E-006 - -0.16702058013980223 5.53781237293428999E-002 -7.88167973611232466E-006 - -4.7130972084002973 -14.216340371858063 1.18042029704995728E-003 - 160 6.55357523599375162E-009 7.12153748385814268E-005 - 1.98730033637173138E-006 - -0.13168594849457804 0.13259859661592138 -1.67364588055200216E-005 - -10.314413061202510 -10.240710710852809 -9.74744309538188095E-004 - 161 6.55357523599375162E-009 8.36359181578366607E-005 - 1.98730033637173138E-006 - 1.96280961362663153E-005 0.21949239386195973 3.99421895415890227E-006 - -13.410880817729039 1.38357460322158232E-003 9.82811205611484754E-004 - 162 6.55357523599375162E-009 1.33114504771210493E-004 - 1.98730033637173138E-006 - 0.16331853346237044 -0.30881375238445197 2.10853005675603280E-007 - 9.3971710734701190 4.9694708262676990 -4.98571955378908208E-004 - 163 6.55357523599375162E-009 1.32182769802380453E-004 - 1.98730033637173138E-006 - 9.10447384992630615E-002 0.33472300511372294 3.00290841137949528E-005 - -10.294216531594770 2.7991931446331937 2.18666112559857441E-004 - 164 6.55357523599375162E-009 1.03733344772367642E-004 - 1.98730033637173138E-006 - 0.25619852289234418 9.21497462816293078E-002 9.79006210533498856E-006 - -4.0759586872696261 11.329622066213446 -6.13362703878465767E-005 - 165 6.55357523599375162E-009 1.27693059719860010E-004 - 1.98730033637173138E-006 - -7.78706919762191113E-002 0.32589476027794229 -5.49256454737836451E-006 - -10.557779536902123 -2.5227519623871664 1.68612343314628033E-004 - 166 6.55357523599375162E-009 4.45484072115334015E-005 - 1.98730033637173138E-006 - 7.26289220115259801E-003 0.11667861683495236 6.52407383017923309E-006 - -18.341181406054801 1.1405768940868606 -1.17566032495211212E-003 - 167 6.55357523599375162E-009 1.02392370628846086E-004 - 1.98730033637173138E-006 - 6.25275717411131193E-002 -0.26135430123694908 1.59916637026680671E-005 - 11.787519180631225 2.8188235382368623 -7.03789051126445871E-004 - 168 6.55357523599375162E-009 1.04331203443837190E-004 - 1.98730033637173138E-006 - -5.92938195426051945E-002 -0.26730797886637836 1.14201604146210549E-006 - 11.722843800694950 -2.5981569286062296 -6.02502920104852537E-004 - 169 6.55357523599375162E-009 1.26854865976641716E-004 - 1.98730033637173138E-006 - 0.33104649659078444 -3.47532985942901329E-002 1.65566253874747458E-005 - 1.1363978329428193 10.831477830040734 4.83204019074378298E-004 - 170 6.55357523599375162E-009 9.93852205667306900E-005 - 1.98730033637173138E-006 - 0.15964500514815289 -0.20625649103213542 6.86761738720097358E-006 - 9.7289204231940758 7.5300623046471191 3.61145217348781496E-004 - 171 6.55357523599375162E-009 1.11256385720932388E-004 - 1.98730033637173138E-006 - 0.24659790722441102 -0.15632067506931918 -1.13803119429843247E-005 - 6.2256723953788633 9.8209375215110164 -3.89508785773077734E-004 - 172 6.55357523599375162E-009 8.41964622955630553E-005 - 1.98730033637173138E-006 - 0.14050941701094283 0.17051053763176857 -7.75058107091279500E-006 - -10.315962659718650 8.5008807696297364 -5.88515647497684985E-004 - 173 6.55357523599375162E-009 4.23118288776354212E-005 - 1.98730033637173138E-006 - -9.94797766569674030E-002 4.93378792493889759E-002 -3.15725962705856641E-006 - -8.3784315276674359 -16.890976752444608 6.15139921257065541E-004 - 174 6.55357523599375162E-009 7.66572416413921525E-005 - 1.98730033637173138E-006 - -0.13792501676546731 -0.14645030941193096 -6.36361568967214944E-006 - 10.198197788388365 -9.6035835983328468 -1.66087424327373732E-005 - 175 6.55357523599375162E-009 8.80974845252837936E-005 - 1.98730033637173138E-006 - -0.21241073077690553 -9.12150714049730360E-002 -1.31195154551575686E-005 - 5.1578356040749087 -12.007900485163589 -2.18519272336383018E-004 - 176 6.55357523599375162E-009 4.77808779828653926E-005 - 1.98730033637173138E-006 - -9.33517447398560518E-002 -8.37195346912290167E-002 1.21318292475945904E-006 - 11.844722503749161 -13.210782857749198 -3.28867812138596168E-004 - 177 6.55357523599375162E-009 8.70616984444987552E-005 - 1.98730033637173138E-006 - -8.77784296085965254E-002 -0.21092591984390360 -5.99078810103557816E-006 - 12.136445914599385 -5.0510806911774937 8.16243315397091281E-005 - 178 6.55357523599375162E-009 8.04289914133139217E-005 - 1.98730033637173138E-006 - -0.18697655944320660 9.79195415173194084E-002 2.69039804787769460E-006 - -6.3465536524496446 -12.114613962060602 1.49047435110533457E-004 - 179 6.55357523599375162E-009 1.19579284972513443E-004 - 1.98730033637173138E-006 - 7.52769182237890133E-002 0.30462640669756053 -1.15932442086327748E-006 - -10.889380387137059 2.6904533530791319 -2.40550840804513273E-004 - 180 6.55357523599375162E-009 6.09371897276520422E-005 - 1.98730033637173138E-006 - -4.93531276190710272E-002 -0.15208774485868534 8.86528217487549366E-006 - 14.946789966920800 -4.8500700359221911 -1.17236461358957776E-003 - 181 6.55357523599375162E-009 9.55095625812286015E-005 - 1.98730033637173138E-006 - 0.13550328040108678 0.21086127663723570 8.59597942330279220E-006 - -10.558306139198153 6.7840736972869111 -1.50895636603118658E-003 - 182 6.55357523599375162E-009 9.50145602078001202E-005 - 1.98730033637173138E-006 - -0.10336770386612490 -0.22689235898827456 -1.57750931019482693E-007 - 11.451179806204784 -5.2168611043581690 -2.65180275943159766E-004 - 183 6.55357523599375162E-009 7.88658427634588436E-005 - 1.98730033637173138E-006 - -0.20232667481639532 -4.35051067672618391E-002 5.83241968217023613E-006 - 2.9042961253899016 -13.503214008622706 6.44582423241310152E-004 - 184 6.55357523599375162E-009 5.74440622275442989E-005 - 1.98730033637173138E-006 - 4.39137100831251681E-002 -0.14420919159253731 -4.30596176081078939E-006 - 15.479962539184180 4.7174097799623684 1.33973793335870660E-005 - 185 6.55357523599375162E-009 4.33570105944642759E-005 - 1.98730033637173138E-006 - 8.84585710380171447E-002 -7.15488398448420881E-002 -5.00743971088444296E-006 - 11.713236071029398 14.484943465754654 2.07478408660555057E-004 - 186 6.55357523599375162E-009 4.51225237172182193E-005 - 1.98730033637173138E-006 - 2.49190463852189473E-002 0.11574902573478539 -1.78256798385647683E-006 - -17.852019133915888 3.8425450533307206 6.99502589886585689E-005 - 187 6.55357523599375162E-009 8.32786674728620136E-005 - 1.98730033637173138E-006 - -0.18156122638233141 -0.12168094159202827 2.74828934269117306E-006 - 7.4821384813922487 -11.163502529896373 -4.84804002579752901E-004 - 188 6.55357523599375162E-009 6.71099257218458697E-005 - 1.98730033637173138E-006 - 0.12735351757339466 0.12164424962055451 3.59663338245191386E-006 - -10.340072231112572 10.827881210468753 -1.19850045700926441E-004 - 189 6.55357523599375162E-009 3.91185757462500332E-005 - 1.98730033637173138E-006 - -8.30486482213599747E-002 -6.03497310954306115E-002 8.59617503925397748E-007 - 11.527760710473025 -15.863389381324621 3.78096803685448507E-004 - 190 6.55357523599375162E-009 1.08899533457755741E-004 - 1.98730033637173138E-006 - 0.11546797019515356 -0.26144338211443391 1.03703878798213209E-005 - 10.750440280659365 4.7479826228649378 1.22917542736516224E-003 - 191 6.55357523599375162E-009 9.04529528719259698E-005 - 1.98730033637173138E-006 - -0.21761414800443504 -9.48636104687632514E-002 -1.91578369738017886E-006 - 5.1528886726854326 -11.820824432819004 -4.94212420988315989E-004 - 192 6.55357523599375162E-009 1.06743607093141415E-004 - 1.98730033637173138E-006 - -2.52270308008288591E-003 -0.28013047185899365 -2.28196647912867318E-006 - 11.870134416961827 -0.10718684914118981 6.38090450221073758E-004 - 193 6.55357523599375162E-009 1.27671398612686876E-004 - 1.98730033637173138E-006 - 0.13591479135493212 0.30623810481194397 2.27483843206930200E-005 - -9.9213958178256441 4.4039026212436791 -5.83496516255849022E-004 - 194 6.55357523599375162E-009 4.60658844697007605E-005 - 1.98730033637173138E-006 - -8.70570778282685198E-002 8.38389247082493155E-002 5.58620725581839110E-006 - -12.537708375076109 -13.019534704030775 -9.83026920743022126E-005 - 195 6.55357523599375162E-009 6.21731367738630848E-005 - 1.98730033637173138E-006 - -3.72640798666060216E-002 0.15881172719418574 -7.81383797999993623E-006 - -15.147287719689160 -3.5523590577723727 -8.91478017131279920E-004 - 196 6.55357523599375162E-009 8.80097201890034353E-005 - 1.98730033637173138E-006 - -5.05870715365620907E-002 0.22535211512702982 -1.00901834210660418E-005 - -12.756654017190700 -2.8630856116287422 1.03779605457960051E-004 - 197 6.55357523599375162E-009 4.13693335782291090E-005 - 1.98730033637173138E-006 - 4.16832776425864193E-002 -0.10023123746918652 -1.03718227955589775E-006 - 17.609578448373881 7.3220028139141089 1.09614716302349705E-003 - 198 6.55357523599375162E-009 4.60630682515997548E-005 - 1.98730033637173138E-006 - -8.38224134774470941E-002 8.70936221541712408E-002 -4.37504535341548927E-006 - -13.022917630742976 -12.530190517842216 -4.28498671732257196E-004 - 199 6.55357523599375162E-009 5.37875697624810224E-005 - 1.98730033637173138E-006 - 0.12615651918470919 -6.33182366823998449E-002 -7.52543342969382757E-006 - 7.5025363113087735 14.946090826614224 5.18514794351923082E-004 - 200 6.55357523599375162E-009 4.50736965311884669E-005 - 1.98730033637173138E-006 - 0.11658822247235556 1.99516035854149787E-002 -1.12352320266002804E-007 - -3.0816296859654546 18.007417610519280 -1.69165421085527860E-005 - 201 6.55357523599375162E-009 4.31295183988732734E-005 - 1.98730033637173138E-006 - -0.10376937319289428 4.51655136404968960E-002 7.63937706435597903E-007 - -7.4512139668438415 -17.127215882828917 -6.12642225617834033E-004 - 202 6.55357523599375162E-009 5.62513786219565214E-005 - 1.98730033637173138E-006 - 3.13223030857753132E-002 -0.14426882846702821 2.11862648127820517E-006 - 15.979850268513818 3.4690797821391213 -4.32089967308167731E-004 - 203 6.55357523599375162E-009 7.32142271561186974E-005 - 1.98730033637173138E-006 - 6.86114602563909215E-002 -0.17944091409712554 -1.05351215140242608E-006 - 13.389959540716942 5.1213496199690152 -8.60240727957704279E-004 - 204 6.55357523599375162E-009 5.31901849537097138E-005 - 1.98730033637173138E-006 - 0.12854991099369129 -5.43580129888066865E-002 7.84867576819136433E-006 - 6.5504777980188686 15.491086428667861 7.82686365997578158E-005 - 205 6.55357523599375162E-009 8.50275633485967459E-005 - 1.98730033637173138E-006 - 0.21940482809689957 -4.05242341445717497E-002 -7.15606706742904680E-006 - 2.4177217726064386 13.080836250396917 5.26834437389720150E-004 - 206 6.55357523599375162E-009 3.97371521067404137E-005 - 1.98730033637173138E-006 - -4.63718418560962256E-002 -9.34060580920306333E-002 -1.52640862031808527E-006 - 17.427694010495227 -8.6503429843023589 5.67565498788340076E-004 - 207 6.55357523599375162E-009 7.11051557181406027E-005 - 1.98730033637173138E-006 - 0.15533993239352731 0.10339626963400785 -8.01227229963518400E-006 - -8.0584611059794877 12.108392379462538 -1.02910743539156094E-003 - 208 6.55357523599375162E-009 6.90855293635411950E-005 - 1.98730033637173138E-006 - -7.51445883585341867E-002 -0.16500020214570879 -5.31690640147681232E-006 - 13.428936030925641 -6.1152986814097954 -1.23566223218122195E-003 - 209 6.55357523599375162E-009 1.30481325728144245E-004 - 1.98730033637173138E-006 - -0.23410619424808460 0.24989562732826720 -1.82059251041943391E-007 - -7.8364350809924970 -7.3401657406444638 -1.72322754258825192E-004 - 210 6.55357523599375162E-009 9.79359364115289555E-005 - 1.98730033637173138E-006 - -0.24766242205330435 -6.86252842039083433E-002 6.46975282165106186E-006 - 3.3100028872039617 -11.944314825017241 -2.16909388793254393E-004 - 211 6.55357523599375162E-009 3.84352842208134229E-005 - 1.98730033637173138E-006 - 0.10086730027648745 6.41519123663267243E-004 8.31997302714366404E-007 - -0.12480254019578219 19.782336880681747 -1.25855143553768502E-003 - 212 6.55357523599375162E-009 4.72169322040954950E-005 - 1.98730033637173138E-006 - 5.00962008280310886E-002 -0.11333403901638633 4.69947367893829215E-007 - 16.325560016558871 7.2155930196835421 2.78338696721421540E-004 - 213 6.55357523599375162E-009 4.12742605151440148E-005 - 1.98730033637173138E-006 - -1.43282020194961286E-002 -0.10735617441408002 2.71892065784501436E-007 - 18.924196148568910 -2.5282572867978557 6.38697412488964183E-005 - 214 6.55357523599375162E-009 1.14220731311568229E-004 - 1.98730033637173138E-006 - 0.29754955571008779 3.62633676863049481E-002 -1.50501556812232194E-005 - -1.3879183507943136 11.391799913432370 -2.07424739592705355E-004 - 215 6.55357523599375162E-009 9.64397588923458587E-005 - 1.98730033637173138E-006 - 0.25007954547793709 3.87417701619119648E-002 -9.00087725198773215E-006 - -1.9129785344207377 12.343156067992389 -1.99270759145761317E-004 - 216 6.55357523599375162E-009 8.65163891996972878E-005 - 1.98730033637173138E-006 - -0.10687007012446367 -0.20033872675011224 -3.53531245096114259E-006 - 11.632907291605122 -6.2068347403439876 3.77607251606490544E-004 - 217 6.55357523599375162E-009 1.02338224766587200E-004 - 1.98730033637173138E-006 - -0.14205357882239419 -0.22789752371829369 -5.48742571151638173E-006 - 10.289697126056337 -6.4138849258518373 1.09814224424033139E-004 - 218 6.55357523599375162E-009 4.61972074652884231E-005 - 1.98730033637173138E-006 - -0.11886820027113602 2.37559060154245300E-002 -6.37215601255293448E-006 - -3.5364485402579655 -17.697675069925143 6.73153340954997645E-004 - 219 6.55357523599375162E-009 1.14280709051123896E-004 - 1.98730033637173138E-006 - 0.23627902570866005 -0.18473863405798582 -4.90407466139491267E-006 - 7.0667352366105529 9.0374488940787128 8.82437908300617304E-005 - 220 6.55357523599375162E-009 1.13671948402319979E-004 - 1.98730033637173138E-006 - 0.22146536362724201 -0.19990209805194639 8.45021801705693293E-006 - 7.7070734536821801 8.5386791697574846 7.04005583006683680E-004 - 221 6.55357523599375162E-009 1.03758174812627459E-004 - 1.98730033637173138E-006 - 2.34558877439810659E-002 0.27126245757110318 -1.13171620294136384E-006 - -11.996768232697258 1.0381416957289469 -2.96480208282287095E-004 - 222 6.55357523599375162E-009 1.14614403355777378E-004 - 1.98730033637173138E-006 - 0.19386903423592244 -0.22993551077810154 1.56468043718857412E-005 - 8.7593031466049336 7.3854172540644365 -4.23803994072645320E-004 - 223 6.55357523599375162E-009 8.12865847624324805E-005 - 1.98730033637173138E-006 - 0.12054681900081124 0.17597475405665308 3.05256898435235167E-007 - -11.224401484289709 7.6877840646552276 -4.26046368267978415E-004 - 224 6.55357523599375162E-009 9.50716397101336591E-005 - 1.98730033637173138E-006 - -0.21655617601746466 -0.12381637992108994 -1.40306508105003426E-005 - 6.2433587650379705 -10.922580554394933 1.16420461940087093E-004 - 225 6.55357523599375162E-009 1.02035071516968151E-004 - 1.98730033637173138E-006 - 6.15862807698931702E-002 0.26061767797778335 6.53444932274237826E-006 - -11.815497601049135 2.7921464682402450 -4.74094246228714817E-004 - 226 6.55357523599375162E-009 7.02297118206264033E-005 - 1.98730033637173138E-006 - 9.06133322752446790E-002 0.16047066017359729 7.77810903068934426E-006 - -12.745230815401243 7.1969121163541399 2.31102738884155287E-005 - 227 6.55357523599375162E-009 6.53718508594592322E-005 - 1.98730033637173138E-006 - 0.11805436200025264 0.12448153908379274 9.56783290354662396E-006 - -11.006461561518593 10.438487343963448 -2.13919122556466518E-004 - 228 6.55357523599375162E-009 1.02539657459765492E-004 - 1.98730033637173138E-006 - 6.25798451853396276E-002 -0.26168645992220585 3.80525128674947372E-006 - 11.781071796615553 2.8182833560203502 -1.00363394048863888E-003 - 229 6.55357523599375162E-009 7.58064831208084402E-005 - 1.98730033637173138E-006 - -0.19895368338287744 8.09390680643534699E-004 -9.33357070725971346E-006 - -5.77087651463070728E-002 -14.085566485227551 -5.18690563551539238E-004 - 230 6.55357523599375162E-009 7.49949996201002711E-005 - 1.98730033637173138E-006 - -0.18400669247300946 -6.97240716422539569E-002 -1.14495213228671198E-005 - 5.0189915512078915 -13.246461898352493 -2.75535835872130338E-004 - 231 6.55357523599375162E-009 1.05203879067062336E-004 - 1.98730033637173138E-006 - 0.23691040913251546 -0.14173895370627240 -3.59832274079844717E-008 - 6.1407159850989199 10.261291937682593 -2.36432773528437798E-005 - 232 6.55357523599375162E-009 9.89872291526870934E-005 - 1.98730033637173138E-006 - -0.12548712378211305 0.22744006558954455 5.47781663937638692E-006 - -10.794621833887476 -5.9546270552206089 -1.97413115504437627E-004 - 233 6.55357523599375162E-009 5.71503290739496490E-005 - 1.98730033637173138E-006 - -0.10456706605043488 0.10749662704262943 -5.17746628002032250E-006 - -11.630523744318838 -11.313550269703631 2.26404225644445385E-004 - 234 6.55357523599375162E-009 1.25750079611625039E-004 - 1.98730033637173138E-006 - -0.33002388458433418 1.80579318519991094E-003 4.50426451961350642E-005 - -6.13195804460699989E-002 -10.936435558643016 5.78359928233178116E-005 - 235 6.55357523599375162E-009 7.43890043835389238E-005 - 1.98730033637173138E-006 - -0.11300266227000676 -0.15918935174453927 7.05531894527171253E-006 - 11.596455210151362 -8.2304740208753948 -3.59764844088759765E-004 - 236 6.55357523599375162E-009 1.10653857636330537E-004 - 1.98730033637173138E-006 - 0.11239013678593211 0.26778021107880046 5.61866954912679539E-006 - -10.750175423160083 4.5122646463945904 6.61283892288932335E-004 - 237 6.55357523599375162E-009 1.22295040965120152E-004 - 1.98730033637173138E-006 - -0.17843281403892947 0.26682475952373758 6.60605343174254244E-006 - -9.2178565367153098 -6.1642984865649222 3.58932450451457830E-004 - 238 6.55357523599375162E-009 9.81777823457235155E-005 - 1.98730033637173138E-006 - -0.25764387431244562 -1.37752272390372077E-003 2.17735781099653790E-005 - 6.54110380620407383E-002 -12.378125547115925 -9.57467785066919283E-004 - 239 6.55357523599375162E-009 5.40657643439036790E-005 - 1.98730033637173138E-006 - 0.14156277555509220 -9.70913934595885736E-003 5.13266200485785954E-006 - 1.1380970910658483 16.640256582886252 -1.00841217923087535E-003 - 240 6.55357523599375162E-009 1.15971262386108532E-004 - 1.98730033637173138E-006 - -0.30283683047943599 3.03705077757343012E-002 -1.36695749618281726E-005 - -1.1360021990385034 -11.331892910886030 -6.13927286301911329E-004 - 241 6.55357523599375162E-009 1.03523977266946286E-004 - 1.98730033637173138E-006 - -0.16172102435089897 0.21830164124691365 1.15092884212778559E-005 - -9.6858949782286246 -7.1757790799948724 -2.00765278905941954E-004 - 242 6.55357523599375162E-009 6.07110386254504556E-005 - 1.98730033637173138E-006 - -0.14891381638033999 5.66073061926705354E-002 -2.08072487379211573E-007 - -5.5934875841285940 -14.715160736003423 6.85915669752215976E-004 - 243 6.55357523599375162E-009 9.57525629443481202E-005 - 1.98730033637173138E-006 - 0.23594935800425565 -8.64849603749804768E-002 1.82070748190851200E-006 - 4.3135169234519406 11.767554304649529 7.11093418683854178E-004 - 244 6.55357523599375162E-009 9.02318641514529476E-005 - 1.98730033637173138E-006 - -0.20313206724522193 0.12169400196844517 -1.28734733213842571E-005 - -6.6350180696814318 -11.076611157423693 -2.67850425145041979E-004 - 245 6.55357523599375162E-009 1.29376924895452708E-004 - 1.98730033637173138E-006 - 0.30348555240152786 0.15225043477822092 2.29526240450290169E-005 - -4.8354960963540528 9.6375919361119990 2.68343585811629663E-005 - 246 6.55357523599375162E-009 1.32163556086230206E-004 - 1.98730033637173138E-006 - -4.97806461699112912E-002 -0.34321738330001555 1.89280884767648426E-006 - 10.558977507718321 -1.5321079389164849 7.42643569543138371E-005 - 247 6.55357523599375162E-009 6.38409906183354746E-005 - 1.98730033637173138E-006 - 3.79049160005861113E-002 -0.16319071940273017 -6.51330753608029977E-006 - 14.952631676349418 3.4725770888033214 8.24193846831918880E-005 - 248 6.55357523599375162E-009 1.23716289008757280E-004 - 1.98730033637173138E-006 - -0.29185272467521112 -0.14230514335614511 1.69560153640711366E-006 - 4.8317117637190883 -9.9108598046713787 2.73714856612884347E-004 - 249 6.55357523599375162E-009 6.39326675857213332E-005 - 1.98730033637173138E-006 - 0.11223025147928670 -0.12469850672754836 -1.16252785792387623E-006 - 11.402019413003398 10.262736965280974 -7.87072470337284082E-004 - 250 6.55357523599375162E-009 1.24936209391676359E-004 - 1.98730033637173138E-006 - 0.31588914314704852 -8.78493183624363128E-002 1.95216435319256732E-005 - 2.9408655087996718 10.571251290184431 5.11490839293939330E-004 - 251 6.55357523599375162E-009 8.30103286029678408E-005 - 1.98730033637173138E-006 - 0.21266420297449809 -4.72411347488342070E-002 -6.18455697376596398E-006 - 2.9190752108124207 13.141169755835460 -4.46612028770479366E-004 - 252 6.55357523599375162E-009 7.52640523923209806E-005 - 1.98730033637173138E-006 - 0.12174776758184903 -0.15554840056641586 1.48518891038607701E-005 - 11.131978952911616 8.7132291936617090 -6.49605680847818810E-004 - 253 6.55357523599375162E-009 5.07524699455429545E-005 - 1.98730033637173138E-006 - -6.74972057369354755E-002 -0.11480521298353670 3.15916785273096786E-006 - 14.842649225490568 -8.7264707351758730 7.74202195841246200E-004 - 254 6.55357523599375162E-009 6.73222807740599029E-005 - 1.98730033637173138E-006 - -0.12568009680020317 0.12415586008514029 1.60751197137125494E-006 - -10.505943675740552 -10.634723660507525 -3.00321609679170742E-004 - 255 6.55357523599375162E-009 5.06228441203857702E-005 - 1.98730033637173138E-006 - 0.12055284839232906 -5.58212283009193247E-002 -6.51287143998851983E-006 - 7.2435678560283385 15.642524529157859 -3.91011014569286777E-005 - 256 6.55357523599375162E-009 6.54706962904908629E-005 - 1.98730033637173138E-006 - 0.10688804358666276 0.13453499057752444 5.40867166652981139E-006 - -11.867873326688056 9.4279276525782691 5.30054697229336838E-004 - 257 6.55357523599375162E-009 9.50917429264053329E-005 - 1.98730033637173138E-006 - -0.10209941677305132 0.22772114556032544 -4.81656158161623939E-006 - -11.476340317984167 -5.1450717234321885 -1.03843393490863690E-003 - 258 6.55357523599375162E-009 9.02150375806863819E-005 - 1.98730033637173138E-006 - -0.12637203029409083 0.20019375972041450 -2.77613193610785969E-006 - -10.920149264218132 -6.8925536257018400 7.58198252064934755E-004 - 259 6.55357523599375162E-009 7.55847538781415399E-005 - 1.98730033637173138E-006 - 0.18347148355518794 7.54192042137651619E-002 1.86867083897113688E-005 - -5.3612004094441472 13.048257061141996 4.08761057662155594E-004 - 260 6.55357523599375162E-009 6.19858607874029284E-005 - 1.98730033637173138E-006 - -0.15250548564224495 -5.65927328240986779E-002 -6.76590606457936849E-007 - 5.4177200857227001 -14.606120737048133 2.30082005486926015E-004 - 261 6.55357523599375162E-009 5.80408446519064619E-005 - 1.98730033637173138E-006 - -2.14343941862111462E-002 -0.15078108215074656 -1.22856950151841274E-007 - 15.940980453023675 -2.2651828629016295 3.75905281061608395E-004 - 262 6.55357523599375162E-009 5.25299599000136737E-005 - 1.98730033637173138E-006 - 3.51643918681215917E-003 0.13778979569008246 -4.24998914698329787E-006 - -16.919326244487706 0.43334346659040968 -1.24092081911885929E-003 - 263 6.55357523599375162E-009 7.06649986072123833E-005 - 1.98730033637173138E-006 - 9.63052264086100701E-002 0.15846251227175398 -7.68091787858495446E-006 - -12.470199275316665 7.5765251167506928 -1.78154261803580770E-004 - 264 6.55357523599375162E-009 1.30815275867336136E-004 - 1.98730033637173138E-006 - -0.31073950286603957 -0.14582304476863855 1.11369732945386479E-005 - 4.5565094301940547 -9.7088621966696991 2.48426871798116604E-004 - 265 6.55357523599375162E-009 8.26857322617612761E-005 - 1.98730033637173138E-006 - 0.20913571769453343 -5.78428960560537636E-002 6.89155661441862292E-006 - 3.5953900885915351 13.000408766758376 -8.40427875438083281E-004 - 266 6.55357523599375162E-009 4.71871822729896508E-005 - 1.98730033637173138E-006 - 5.41517865111099464E-002 -0.11133830854317255 4.96555568267102491E-006 - 16.059816440815414 7.8103747601731301 -2.01704499664511595E-004 - 267 6.55357523599375162E-009 1.10230422871015270E-004 - 1.98730033637173138E-006 - -0.16036185271588438 0.24071897868655834 1.16996402912940681E-005 - -9.7236912349570375 -6.4769572574705787 -3.28654236447738885E-005 - 268 6.55357523599375162E-009 1.14916183382789228E-004 - 1.98730033637173138E-006 - -0.22686226443851742 0.19862512178969879 -3.33283860943053654E-006 - -7.5377129791396378 -8.6097743130319415 2.48802853242167520E-004 - 269 6.55357523599375162E-009 9.96916198741429192E-005 - 1.98730033637173138E-006 - 0.25312644030837494 -6.60940028474453906E-002 4.23240786931344293E-007 - 3.1025625022237846 11.886041998723426 -4.30341161397127588E-004 - 270 6.55357523599375162E-009 8.12995994167365108E-005 - 1.98730033637173138E-006 - -9.69664038434496778E-002 0.19000309076508759 -5.86856484104454955E-006 - -12.119203888400754 -6.1825047566328468 8.56562373574286146E-006 - 271 6.55357523599375162E-009 9.48993975203514891E-005 - 1.98730033637173138E-006 - 0.18051457972273144 -0.17153504995171948 1.16400789644636930E-005 - 8.6742538950698940 9.1272384560784428 -1.49963524466517904E-004 - 272 6.55357523599375162E-009 1.21332839073997345E-004 - 1.98730033637173138E-006 - -0.20115255123901424 0.24677764393508334 -2.52809846033370505E-006 - -8.6313467493304792 -7.0365089904041644 -4.72676625484450528E-004 - 273 6.55357523599375162E-009 1.26167483366553082E-004 - 1.98730033637173138E-006 - -0.32624425127260115 5.64065777403633811E-002 2.87564394239435524E-005 - -1.8597598879504922 -10.760276781263109 1.23317367276140394E-004 - 274 6.55357523599375162E-009 4.60787203541211153E-005 - 1.98730033637173138E-006 - -0.12077853478149969 5.77757742908637656E-003 1.13678236333101533E-006 - -0.86404188400135951 -18.048761288412031 -1.08090023376336379E-003 - 275 6.55357523599375162E-009 1.17331374197271996E-004 - 1.98730033637173138E-006 - -0.24683319534965287 0.18407637603810068 -2.60575159907422251E-006 - -6.7701290782626184 -9.0760131017195178 8.53063506932278206E-005 - 276 6.55357523599375162E-009 9.16317027002317471E-005 - 1.98730033637173138E-006 - -0.10717057623890999 -0.21531568093736303 1.97945468891846516E-006 - 11.468691264546058 -5.7076561125368528 3.91102841030111870E-004 - 277 6.55357523599375162E-009 5.59233460939695840E-005 - 1.98730033637173138E-006 - -4.02542218252858741E-002 0.14112881625250243 3.14566989386505978E-007 - -15.772196903855985 -4.4987393529702295 5.17418961699862281E-004 - 278 6.55357523599375162E-009 4.94951624941460680E-005 - 1.98730033637173138E-006 - 0.10852471283296944 -7.13522240089076165E-002 -4.10372285593927715E-007 - 9.5762951300652084 14.569537344669147 -1.51955766962751657E-003 - 279 6.55357523599375162E-009 3.95289035226548989E-005 - 1.98730033637173138E-006 - 1.47927214945146671E-002 -0.10266954783884102 6.44200235305893472E-007 - 19.309429265295257 2.7831650064811546 -7.70109142639705300E-005 - 280 6.55357523599375162E-009 5.17793592460636968E-005 - 1.98730033637173138E-006 - -7.37953049919262138E-002 -0.11409414966100956 -8.22146523124566640E-006 - 14.314285565455872 -9.2543986476077738 6.33221214465053790E-004 - 281 6.55357523599375162E-009 6.16551889364537269E-005 - 1.98730033637173138E-006 - -0.15538183652138010 -4.51732691158184402E-002 -4.05152367119429081E-006 - 4.3635077456767890 -14.996828984405369 3.40865051918324169E-004 - 282 6.55357523599375162E-009 1.10784891505308149E-004 - 1.98730033637173138E-006 - -0.10583786272881698 0.27079660915153247 -4.75015546295917786E-006 - -10.853384495729795 -4.2400956125643905 4.21943696963196827E-005 - 283 6.55357523599375162E-009 8.56950933159408563E-005 - 1.98730033637173138E-006 - -3.23715588256904413E-002 -0.22254711770802427 7.16588905357685598E-006 - 13.111324796011779 -1.9064595465850727 -7.11018898628031039E-004 - 284 6.55357523599375162E-009 1.12672847463136553E-004 - 1.98730033637173138E-006 - 5.55244214232107069E-002 -0.29043015922162835 -1.42364662101194605E-005 - 11.349331499525681 2.1680423251138290 -2.28216151119005898E-004 - 285 6.55357523599375162E-009 5.94893099733211799E-005 - 1.98730033637173138E-006 - 9.97176392521465643E-002 -0.12011045767852192 1.06560964003050962E-005 - 12.236621636089168 10.156821049432180 9.13632702407994450E-004 - 286 6.55357523599375162E-009 4.95041635130935874E-005 - 1.98730033637173138E-006 - -4.69399116440994829E-002 -0.12111301877041324 3.16404867343560561E-007 - 16.256826221912455 -6.3003401944591735 -4.58126295240195516E-004 - 287 6.55357523599375162E-009 6.32340353136170053E-005 - 1.98730033637173138E-006 - -3.70326721167058524E-003 0.16589718603240747 4.68579683428349456E-006 - -15.420626292685146 -0.34172257072164736 3.78660223614209624E-005 - 288 6.55357523599375162E-009 5.77932102093081651E-005 - 1.98730033637173138E-006 - 4.92215916702131717E-002 0.14343396259994062 4.51986746781268699E-006 - -15.262128656645949 5.2376770913809345 -1.12506899451561446E-004 - 289 6.55357523599375162E-009 8.28392473619884474E-005 - 1.98730033637173138E-006 - 3.86108531521396625E-003 -0.21736709242322538 -5.26075456069156260E-007 - 13.473120977108746 0.23831979243630652 -2.35586355390321315E-004 - 290 6.55357523599375162E-009 8.36966222911417727E-005 - 1.98730033637173138E-006 - 0.21961300066089737 3.56118174092030781E-003 -8.28170540584400127E-006 - -0.21663900283352433 13.404866392820814 -2.18714016054655469E-004 - 291 6.55357523599375162E-009 3.95545387825277218E-005 - 1.98730033637173138E-006 - 9.99220006963798257E-002 2.80946902918733192E-002 -2.12511940783199470E-008 - -5.2805384147516170 18.774263208340326 1.10833388777123020E-003 - 292 6.55357523599375162E-009 4.86180654117438800E-005 - 1.98730033637173138E-006 - -0.10854853734917874 -6.70442954652626238E-002 2.54817083205478575E-006 - 9.2444970469798324 -14.965659085912980 -1.86955278965296137E-004 - 293 6.55357523599375162E-009 4.53867815459358198E-005 - 1.98730033637173138E-006 - 7.56194930278721589E-002 9.20163570252454793E-002 -1.18696709142516461E-005 - -14.066628100742729 11.558770898495139 7.97619499568705693E-006 - 294 6.55357523599375162E-009 8.97728486309719526E-005 - 1.98730033637173138E-006 - -9.62938124010095237E-002 0.21499191989969649 1.57740897856664226E-006 - -11.814997890035325 -5.2915247360021596 3.72196071110670614E-004 - 295 6.55357523599375162E-009 6.98416246306711046E-005 - 1.98730033637173138E-006 - 6.34266896734145547E-002 0.17194242228385798 5.76177575129383918E-007 - -13.770329617068841 5.0799567867625015 1.49585400367477763E-004 - 296 6.55357523599375162E-009 1.21426299496496369E-004 - 1.98730033637173138E-006 - 0.23378533772679028 0.21648420393132478 -1.93595521436901631E-005 - -7.5621430746438847 8.1686723846976541 -2.88226755447297750E-004 - 297 6.55357523599375162E-009 1.26369702329779440E-004 - 1.98730033637173138E-006 - -0.30319257879081551 -0.13437907539634195 -4.68266124658996808E-006 - 4.4207804115264429 -9.9745744141438397 -1.01740373378240650E-004 - 298 6.55357523599375162E-009 4.92099686825512756E-005 - 1.98730033637173138E-006 - -2.92649726590182430E-002 0.12579369415230315 -1.82730223446354271E-006 - -17.028372098426249 -3.9586442403584048 2.09905831145365237E-004 - 299 6.55357523599375162E-009 1.25660197060209797E-004 - 1.98730033637173138E-006 - 0.10079856109331091 -0.31399240260644790 -2.40145263205769641E-006 - 10.417230993457039 3.3450296753140134 5.24169475077905294E-004 - 300 6.55357523599375162E-009 4.76279853062766556E-005 - 1.98730033637173138E-006 - -0.12390933193904695 1.65209375689775312E-002 -2.18633468692210206E-006 - -2.3501038260830329 -17.613651770942287 7.95299273869964321E-004 - 301 6.55357523599375162E-009 6.67314921952190387E-005 - 1.98730033637173138E-006 - -0.11719866839372559 -0.13012844105488197 1.62540329632072444E-005 - 11.155424566977935 -10.048716115659838 -9.57109624143204392E-004 - 302 6.55357523599375162E-009 6.24318464128872604E-005 - 1.98730033637173138E-006 - -0.15283746891171271 5.89225500550325798E-002 -8.67411588980633728E-006 - -5.5841271177420735 -14.487194716426286 -2.47057750554317498E-004 - 303 6.55357523599375162E-009 1.00329357808924994E-004 - 1.98730033637173138E-006 - 0.17624161116720150 -0.19560470558886517 1.68054451232969007E-005 - 9.0967358077405613 8.1968772555945080 -3.94957514554921383E-004 - 304 6.55357523599375162E-009 1.01923373483552943E-004 - 1.98730033637173138E-006 - -0.24730210897807467 0.10188201033960492 6.45886996484483490E-006 - -4.6280885071214657 -11.233169207846801 -1.02965678031307511E-003 - 305 6.55357523599375162E-009 6.73751044723396448E-005 - 1.98730033637173138E-006 - 6.82099805370675605E-002 -0.16311677200625579 7.25355670685974412E-006 - 13.786005853783921 5.7653540219830663 6.93226510470296370E-004 - 306 6.55357523599375162E-009 1.12978187904096540E-004 - 1.98730033637173138E-006 - -5.69490345498646355E-002 -0.29098215867102883 -9.61395099577022145E-006 - 11.323861303176674 -2.2151759758885330 2.10073727529394875E-004 - 307 6.55357523599375162E-009 1.27681556425967435E-004 - 1.98730033637173138E-006 - 0.20627909193736346 -0.26407857186213712 -1.43296440105926547E-005 - 8.5527679217517871 6.6822422767161127 7.04370668229320029E-004 - 308 6.55357523599375162E-009 6.13246316007929449E-005 - 1.98730033637173138E-006 - -0.11044073238040467 0.11703588578381705 -7.19822647934690317E-006 - -11.390199300368598 -10.752396437430516 -1.28663583016316190E-003 - 309 6.55357523599375162E-009 8.62955048314053977E-005 - 1.98730033637173138E-006 - -0.22644758302028892 2.20542645755462258E-003 -1.06366251207401683E-005 - -0.12735606077638872 -13.202797615909342 -2.51705300822274768E-004 - 310 6.55357523599375162E-009 5.51750178919147829E-005 - 1.98730033637173138E-006 - 0.11008798680433170 9.40688691708788799E-002 2.76890511288321373E-007 - -10.726728856483344 12.551730760585547 -1.07302442649772158E-003 - 311 6.55357523599375162E-009 1.14752863602099746E-004 - 1.98730033637173138E-006 - 0.30015884194395498 2.39816789086191307E-002 1.29230126927014141E-005 - -0.91142523385729479 11.414295820512312 7.34194755167105306E-005 - 312 6.55357523599375162E-009 5.71638755244002474E-005 - 1.98730033637173138E-006 - -0.13953934858034822 -5.50930069988898041E-002 6.38366629419107209E-007 - 5.9591603480899780 -15.087121515695072 -3.08498891121507625E-004 - 313 6.55357523599375162E-009 1.14216812443982294E-004 - 1.98730033637173138E-006 - -0.29580739104320575 4.81520245267350877E-002 5.62952122129086673E-006 - -1.8447832853196200 -11.328542222177884 -2.44916087211898914E-004 - 314 6.55357523599375162E-009 8.21435162674993347E-005 - 1.98730033637173138E-006 - -8.52323367896652695E-002 -0.19799915673977098 -3.73730442723058932E-006 - 12.430696969956365 -5.3493534509144505 -8.27882635557136703E-004 - 315 6.55357523599375162E-009 9.05238105170645978E-005 - 1.98730033637173138E-006 - 0.19243859922848586 -0.13928636206483794 -7.56914814730060812E-006 - 7.5592536861518234 10.442281916244731 3.95558359013042557E-004 - 316 6.55357523599375162E-009 7.76435060208240265E-005 - 1.98730033637173138E-006 - 6.77814196829735482E-002 0.19213313914883468 -8.96704927530003770E-006 - -13.128013088384446 4.6302961750180840 -9.69759014905732623E-004 - 317 6.55357523599375162E-009 5.93556706974762187E-005 - 1.98730033637173138E-006 - 3.53870694941570973E-002 -0.15169404357957642 -7.35699364087210750E-007 - 15.503144534362278 3.6181503986896368 -4.38658902037723732E-004 - 318 6.55357523599375162E-009 5.53436775760548361E-005 - 1.98730033637173138E-006 - -0.14242095793788143 2.84362733538953381E-002 -8.65910432611032143E-006 - -3.2289002733977914 -16.168122830041103 4.99452370521769572E-005 - 319 6.55357523599375162E-009 9.35987815293568356E-005 - 1.98730033637173138E-006 - -0.18968642709421760 -0.15599242316002787 1.41015994997808972E-005 - 8.0536345983680580 -9.7933810784186655 -2.75506662963652957E-004 - 320 6.55357523599375162E-009 8.90567875538556762E-005 - 1.98730033637173138E-006 - 0.16154111386251072 0.16890702047206713 4.52041433195205948E-006 - -9.3908515107798376 8.9841053588616955 -7.68710932989482253E-004 - 321 6.55357523599375162E-009 6.91116996338749325E-005 - 1.98730033637173138E-006 - -0.18134383316791219 3.38282107687527811E-003 3.70177825713786528E-006 - -0.27459169483445223 -14.750358463453667 6.03754356011480245E-006 - 322 6.55357523599375162E-009 1.15259163447343159E-004 - 1.98730033637173138E-006 - -0.27614187183466021 0.12342773723785083 -8.37554328150704185E-006 - -4.6619346373139994 -10.429947663228932 4.46683586605447071E-004 - 323 6.55357523599375162E-009 9.21726984554689557E-005 - 1.98730033637173138E-006 - -5.77075144115329897E-002 0.23487421970602454 1.35664120790821492E-006 - -12.407271419621722 -3.0501347305782605 1.28222467166023762E-003 - 324 6.55357523599375162E-009 5.72200482292332539E-005 - 1.98730033637173138E-006 - 0.14754606031391296 2.79320497244507880E-002 -8.53981960719682466E-006 - -3.0158500823078405 15.930697848455907 -1.54214717501109210E-004 - 325 6.55357523599375162E-009 6.56424222236027800E-005 - 1.98730033637173138E-006 - -3.99033595590439771E-002 -0.16758369347383856 3.18476684038077601E-006 - 14.726384282131875 -3.5056807520069206 6.98478287442521380E-004 - 326 6.55357523599375162E-009 8.45159648937324047E-005 - 1.98730033637173138E-006 - 2.34600704546436833E-002 0.22054313097142542 5.66927763547352652E-006 - -13.266927195745843 1.4110320538825061 6.10623711845197396E-004 - 327 6.55357523599375162E-009 4.65945471034291106E-005 - 1.98730033637173138E-006 - -0.10772030673926508 -5.78717874020646186E-002 -1.31233115407917096E-006 - 8.5048133066392744 -15.827114152921931 3.45283538152742903E-004 - 328 6.55357523599375162E-009 1.30712798960725492E-004 - 1.98730033637173138E-006 - 0.13459320558287347 -0.31547353902948666 1.20044622336649256E-006 - 9.8686884336679981 4.2098618650669399 1.97796527498055112E-004 - 329 6.55357523599375162E-009 6.77828645550352380E-005 - 1.98730033637173138E-006 - -0.12735210479214071 0.12419590548281148 -6.51998167859934788E-006 - -10.400756285905564 -10.665193309657282 -3.85548551755760481E-005 - 330 6.55357523599375162E-009 1.00947858974670873E-004 - 1.98730033637173138E-006 - -0.16815378326571420 -0.20464309696471095 1.03660059047116379E-005 - 9.4341605349805651 -7.7505334981156153 4.88064757919781157E-004 - 331 6.55357523599375162E-009 6.55930448177018165E-005 - 1.98730033637173138E-006 - 0.16917106518585667 -3.16914237849964114E-002 8.82175584664054844E-006 - 2.7882995795116150 14.886967300229774 -8.78583383515216709E-004 - 332 6.55357523599375162E-009 1.22417952952159854E-004 - 1.98730033637173138E-006 - -0.30029844262068311 -0.11401662118051727 3.93286585536967100E-006 - 3.9357668007067943 -10.364725557775186 2.13264150362771885E-004 - 333 6.55357523599375162E-009 8.27322394015547936E-005 - 1.98730033637173138E-006 - -2.60932363355259635E-002 0.21553354119387311 6.85714254501554774E-007 - -13.387056053125017 -1.6203812010889884 4.07159359666166298E-004 - 334 6.55357523599375162E-009 1.28412855635061097E-004 - 1.98730033637173138E-006 - -0.23704406470890954 -0.23949571836910835 8.76869417875762974E-006 - 7.6924060837095345 -7.6150903285807860 5.64028419458596601E-004 - 335 6.55357523599375162E-009 1.24759541778086643E-004 - 1.98730033637173138E-006 - -3.10160921146369895E-002 -0.32593054007125960 3.03912986993750631E-006 - 10.931461819950419 -1.0399341430729603 1.56653129249086261E-003 - 336 6.55357523599375162E-009 9.17297851849284304E-005 - 1.98730033637173138E-006 - 0.13545240402691217 -0.19896047878191309 -1.25804952556521251E-005 - 10.586638285830910 7.2084939475887122 -3.15748275775728994E-004 - 337 6.55357523599375162E-009 6.02508287510137929E-005 - 1.98730033637173138E-006 - -3.54569214818632183E-002 0.15406911795401210 -2.51098347151660121E-006 - -15.400593624755610 -3.5435562897486812 -2.90030945823764943E-004 - 338 6.55357523599375162E-009 5.05860520026336986E-005 - 1.98730033637173138E-006 - 1.67806315636903000E-002 -0.13168314267184392 -1.88812464241155970E-007 - 17.106743440606014 2.1807074655931538 -6.57569498293488657E-005 - 339 6.55357523599375162E-009 1.14542787107695863E-004 - 1.98730033637173138E-006 - 0.29647709616362661 4.95194040655274476E-002 1.08603498725213163E-005 - -1.8870187077744234 11.303934812387078 2.26613813673566696E-004 - 340 6.55357523599375162E-009 9.02191617825077172E-005 - 1.98730033637173138E-006 - 0.20277527140293494 -0.12223572900470278 -1.93099794007941269E-006 - 6.6645511114641742 11.059510866888507 3.13929347741595023E-004 - 341 6.55357523599375162E-009 9.93548392749427675E-005 - 1.98730033637173138E-006 - -0.13258512443728018 -0.22445912858865194 1.95209928143429132E-005 - 10.597156094230252 -6.2576465603442450 2.54672048721180414E-004 - 342 6.55357523599375162E-009 5.58953871905315959E-005 - 1.98730033637173138E-006 - 0.13246037884711140 -6.30070981465289670E-002 5.19264908604209121E-006 - 7.0484427820496780 14.814248914048582 7.39959878131936193E-004 - 343 6.55357523599375162E-009 1.09466362632249260E-004 - 1.98730033637173138E-006 - -0.25690558295513516 0.12849988097669668 8.14988516276009842E-006 - -5.2441422837404605 -10.485291718908686 6.30269717529592308E-006 - 344 6.55357523599375162E-009 6.84757291830003282E-005 - 1.98730033637173138E-006 - 9.32468534034845524E-003 -0.17945101200270680 -5.44829593364174558E-006 - 14.802387655819476 0.76914443630789209 2.06851180102686835E-004 - 345 6.55357523599375162E-009 4.57537271184680703E-005 - 1.98730033637173138E-006 - 6.77694180840318766E-002 9.91275482975688127E-002 1.14413312265102980E-006 - -14.966410644329454 10.234597702204557 -7.78405404234971910E-004 - 346 6.55357523599375162E-009 1.04542853054497161E-004 - 1.98730033637173138E-006 - -8.99505415417756193E-002 0.25917460498702760 -6.65902228997070481E-006 - -11.332880940398196 -3.9333002855395933 3.02103944607861729E-004 - 347 6.55357523599375162E-009 4.01097446071001587E-005 - 1.98730033637173138E-006 - 8.37776177389014387E-002 -6.37227292293675307E-002 6.62961469335611008E-007 - 11.724125266773251 15.414396326389648 -4.00112283457572295E-004 - 348 6.55357523599375162E-009 9.87949276804321770E-005 - 1.98730033637173138E-006 - 0.20816256639916927 -0.15452601367623559 7.10572890585290768E-006 - 7.3548868317421920 9.9092027294040967 -6.86253917573046167E-005 - 349 6.55357523599375162E-009 8.09345537848713345E-005 - 1.98730033637173138E-006 - 0.13215903937306356 -0.16626222147786526 -1.45762409597184537E-005 - 10.673231126437038 8.4829874409595067 -9.18988729964168895E-004 - 350 6.55357523599375162E-009 1.04418878574476614E-004 - 1.98730033637173138E-006 - -0.25138041920224186 0.10905619104131771 -4.61807190563742949E-006 - -4.7771158072939128 -11.011483936255260 3.36335873914275036E-004 - 351 6.55357523599375162E-009 9.32141090138085654E-005 - 1.98730033637173138E-006 - -0.10644227192712022 -0.22028786313331078 1.34817687555600062E-006 - 11.437226777013032 -5.5249634594658374 4.69755078229890587E-004 - 352 6.55357523599375162E-009 1.17846353140517570E-004 - 1.98730033637173138E-006 - 0.30580817624179285 -4.59630099268260872E-002 1.02444587922015908E-005 - 1.6802463305194086 11.173330597480769 9.48971610823092442E-005 - 353 6.55357523599375162E-009 1.13182481097424270E-004 - 1.98730033637173138E-006 - -0.29445465045624475 3.90934181328027319E-002 -2.75450328324148973E-006 - -1.5168547170649793 -11.427859951282073 7.16587499491953090E-004 - 354 6.55357523599375162E-009 1.28109066407895326E-004 - 1.98730033637173138E-006 - 0.23545793853986932 -0.23993310606940974 4.34018912873675595E-006 - 7.7343101561326284 7.5910640805480680 3.93371656292995859E-004 - 355 6.55357523599375162E-009 5.42856727896890245E-005 - 1.98730033637173138E-006 - -0.13280286736238145 5.15401229166842015E-002 3.75966732293283148E-007 - -6.0220300185240179 -15.520169577106405 -4.13639253887892414E-004 - 356 6.55357523599375162E-009 8.62707551757688142E-005 - 1.98730033637173138E-006 - 7.43757306938572504E-002 -0.21381822990238714 3.99594030267881391E-006 - 12.472852314708264 4.3383841502308638 -1.83774031486715137E-004 - 357 6.55357523599375162E-009 1.32227984831188747E-004 - 1.98730033637173138E-006 - -7.27223168918083723E-002 0.33922825992494554 1.92281833543885598E-005 - -10.431225558225991 -2.2363043183789428 1.04067737087274861E-005 - 358 6.55357523599375162E-009 1.14242519535815134E-004 - 1.98730033637173138E-006 - -0.23982681225859576 0.17993003476109978 -8.65721837828167345E-006 - -6.8862243716179998 -9.1784778503144917 1.40818890109945351E-004 - 359 6.55357523599375162E-009 5.05910912658239428E-005 - 1.98730033637173138E-006 - -5.08300394205269054E-002 -0.12263818561425464 9.88249013424321432E-006 - 15.931285077694616 -6.6022671297997402 -9.53358053677248263E-004 - 360 6.55357523599375162E-009 9.97462579537380717E-005 - 1.98730033637173138E-006 - -1.49220541541329466E-002 -0.26133012232127023 1.27217520648971024E-005 - 12.261085886282977 -0.69841140424472847 -3.95527030191025742E-004 - 361 6.55357523599375162E-009 6.07477087566895749E-005 - 1.98730033637173138E-006 - 4.87560698243135523E-003 0.15936157953183924 2.19694628459572591E-005 - -15.727340260100993 0.48126666366965726 1.39385660829356131E-003 - 362 6.55357523599375162E-009 3.97865848676101413E-005 - 1.98730033637173138E-006 - 8.19611497793842486E-002 -6.46645232120200697E-002 1.94127035044744025E-006 - 12.044384916633710 15.268230805230704 -2.22544518928659404E-004 - 363 6.55357523599375162E-009 1.23235123294160412E-004 - 1.98730033637173138E-006 - -0.18747489740297546 0.26353412743639315 6.24039579803248944E-006 - -9.0034880394890973 -6.4029572412351374 2.06378448420738321E-004 - 364 6.55357523599375162E-009 9.75322048060758400E-005 - 1.98730033637173138E-006 - 0.17917788700844411 -0.18280421256134260 1.32347056396791742E-006 - 8.8687743269711508 8.6924016605211580 -3.11563384568697577E-004 - 365 6.55357523599375162E-009 1.04880590377601338E-004 - 1.98730033637173138E-006 - -4.08396659275775953E-002 0.27215164280873005 -1.03736340209779210E-005 - -11.845232714790244 -1.7779171728452949 -4.81554317796558469E-004 - 366 6.55357523599375162E-009 1.25150751702232421E-004 - 1.98730033637173138E-006 - 0.11483000273788309 -0.30769672636287743 -2.05810784184982922E-006 - 10.272033613723963 3.8327364033933362 1.09617711847918438E-004 - 367 6.55357523599375162E-009 4.18448649310558353E-005 - 1.98730033637173138E-006 - -0.10954975534929136 7.78163087330886218E-003 3.65399171853055338E-006 - -1.3432139773330254 -18.910557594416566 -1.27103704276461155E-003 - 368 6.55357523599375162E-009 7.84151648322537089E-005 - 1.98730033637173138E-006 - -7.03490922832923637E-002 0.19338965860480151 -2.56949260201915965E-006 - -13.015347446074340 -4.7363738308259702 -1.13972606530579460E-003 - 369 6.55357523599375162E-009 4.21576522033698594E-005 - 1.98730033637173138E-006 - 2.36584585861200902E-002 -0.10808482728114846 -3.83832456342174322E-006 - 18.451771971374519 4.0370360403901779 -4.09512769392254828E-004 - 370 6.55357523599375162E-009 5.03665632615744047E-005 - 1.98730033637173138E-006 - 0.10123336047502379 -8.49898315875586563E-002 2.63739651175471323E-006 - 11.112659352167420 13.235048852678382 -4.32292901105662609E-004 - 371 6.55357523599375162E-009 9.74850070347380596E-005 - 1.98730033637173138E-006 - 5.03086444922303325E-002 -0.25081046605430141 1.49955587171913914E-006 - 12.180750903716495 2.4430483425288698 2.30160511394630858E-004 - 372 6.55357523599375162E-009 6.11732845898358606E-005 - 1.98730033637173138E-006 - 0.14288685498790293 7.31663397746458444E-002 4.48535564104624016E-006 - -7.1480316736265159 13.958296501153404 -1.08066695850228718E-003 - 373 6.55357523599375162E-009 1.02519315992892401E-004 - 1.98730033637173138E-006 - 0.23857401440842749 0.12438917877028877 1.52032840656894059E-005 - -5.5999293465297448 10.740569615372106 3.13110913462231273E-004 - 374 6.55357523599375162E-009 1.04375881818191143E-004 - 1.98730033637173138E-006 - 0.12340125741501635 -0.24453934874312178 -1.30555747573880891E-005 - 10.717116697685965 5.4100865226440975 9.45102032055322228E-004 - 375 6.55357523599375162E-009 6.88951398900134425E-005 - 1.98730033637173138E-006 - 3.26564331515499864E-002 -0.17781358153496182 8.60879004887549406E-006 - 14.534375834974316 2.6705431342174375 1.00631320222363736E-003 - 376 6.55357523599375162E-009 4.41553435511607658E-005 - 1.98730033637173138E-006 - 8.21705320038057796E-002 8.17326215951582891E-002 -2.73068044772671009E-006 - -13.013292169146693 13.084964089911391 1.45705508985855751E-003 - 377 6.55357523599375162E-009 4.14253704628386393E-005 - 1.98730033637173138E-006 - -5.89650954315181774E-002 -9.13292649912316457E-002 1.12877739999363017E-006 - 16.010335771811643 -10.335341080145536 1.63544140300652638E-005 - 378 6.55357523599375162E-009 1.07384195231900728E-004 - 1.98730033637173138E-006 - 0.15653331398551784 0.23433706321818068 2.14883641860908081E-005 - -9.8418877736434158 6.5743263986452796 1.52502911605451063E-004 - 379 6.55357523599375162E-009 9.66814655495757964E-005 - 1.98730033637173138E-006 - 8.95347458513216371E-002 0.23741720494057866 -9.69340967514460109E-006 - -11.669677370235014 4.4034229757616004 9.88666559189531726E-004 - 380 6.55357523599375162E-009 6.15901883227427201E-005 - 1.98730033637173138E-006 - 9.97363271383233108E-002 0.12720074816612481 -1.44889462861827006E-005 - -12.298357210156013 9.6419829311586387 -2.61504592618280046E-004 - 381 6.55357523599375162E-009 8.06988475077419698E-005 - 1.98730033637173138E-006 - 0.19266758461143907 -8.78714015937417658E-002 1.58825006901594787E-006 - 5.6646016781537938 12.423898403045811 2.27684818320244924E-004 - 382 6.55357523599375162E-009 7.90683464567424140E-005 - 1.98730033637173138E-006 - -4.16034977040649623E-002 -0.20325780639501709 9.80683521839065024E-006 - 13.514646797230817 -2.7671239508267007 1.22100012333925382E-003 - 383 6.55357523599375162E-009 7.27679827936667504E-005 - 1.98730033637173138E-006 - -0.19077050343370217 -9.12789878383223063E-003 -1.52313121523793994E-006 - 0.68779743750747091 -14.359692261468005 1.07568216036505631E-004 - 384 6.55357523599375162E-009 8.70861853784819057E-005 - 1.98730033637173138E-006 - 0.15162382930453244 -0.17099181810614750 -7.11131601408041123E-006 - 9.8347747691441736 8.7190993888767618 -2.70690905962404406E-004 - 385 6.55357523599375162E-009 6.03941407839591278E-005 - 1.98730033637173138E-006 - 5.02858465590940718E-002 0.15029931548101949 -2.18683761891046328E-006 - -14.966888492061726 5.0084859600938350 -3.24955824942062775E-004 - 386 6.55357523599375162E-009 6.01916413252911656E-005 - 1.98730033637173138E-006 - -0.12850903615697945 -9.18396219136763114E-002 -8.52923204839691520E-006 - 9.1925233586196704 -12.862396306709837 -1.23695383470124936E-003 - 387 6.55357523599375162E-009 4.31607776779678465E-005 - 1.98730033637173138E-006 - 4.42559525807409079E-002 0.10426097393419034 2.11439125383333893E-006 - -17.184552997824792 7.2963301364876489 -7.26234086014719625E-004 - 388 6.55357523599375162E-009 1.30280032190190678E-004 - 1.98730033637173138E-006 - -0.30345907843924963 -0.15754304676230307 -1.37176263012820334E-005 - 4.9511606182007650 -9.5360834336383657 5.76652973619644522E-004 - 389 6.55357523599375162E-009 1.01755729641024741E-004 - 1.98730033637173138E-006 - -0.25127373603477404 -9.04545407042784827E-002 -2.29387952144521566E-006 - 4.1175394064149717 -11.439244712063783 -2.18606845628742594E-005 - 390 6.55357523599375162E-009 1.05027367261092112E-004 - 1.98730033637173138E-006 - -6.51282904197668377E-002 -0.26778814511911747 -8.17232957296494819E-006 - 11.630329828353974 -2.8275019648397022 -1.10714269933222053E-004 - 391 6.55357523599375162E-009 6.13883798216464948E-005 - 1.98730033637173138E-006 - 0.12279486984327259 -0.10426778968143509 6.80942098205561667E-006 - 10.133533847164589 11.932690901500671 7.58072834399356292E-004 - 392 6.55357523599375162E-009 5.62220780645162954E-005 - 1.98730033637173138E-006 - -4.01552215665929718E-002 0.14197612637530399 -2.05311672740003766E-006 - -15.739464132173721 -4.4526437322300065 4.70354630360184166E-004 - 393 6.55357523599375162E-009 5.70627034408400388E-005 - 1.98730033637173138E-006 - 5.28453972042870618E-002 -0.14011856329376138 5.02825880335372302E-006 - 15.190994462935027 5.7310645151790895 9.42804012085064389E-004 - 394 6.55357523599375162E-009 9.01653633994815016E-005 - 1.98730033637173138E-006 - -0.23006161309047329 5.53467108661804957E-002 9.19230849709600343E-006 - -3.0230886980435980 -12.557557322795120 6.78363095823338491E-004 - 395 6.55357523599375162E-009 1.25760111029719532E-004 - 1.98730033637173138E-006 - -0.32504226710462231 5.71881896420117913E-002 1.73618058648941759E-005 - -1.8941986185927591 -10.771565008391034 4.06597986544067654E-004 - 396 6.55357523599375162E-009 1.32403833677591790E-004 - 1.98730033637173138E-006 - 0.26184154112582159 -0.22842965055199138 2.06042870126740147E-005 - 7.0082153804314347 8.0307034974715616 1.43497035620778401E-003 - 397 6.55357523599375162E-009 5.44879985288891124E-005 - 1.98730033637173138E-006 - 1.23159016838155534E-002 0.14243575072147380 -9.26748359092188586E-006 - -16.556848419586039 1.4312614465813351 -1.09288016206911059E-005 - 398 6.55357523599375162E-009 1.26907606926388971E-004 - 1.98730033637173138E-006 - -0.15620759361773945 0.29415248097897639 -3.79572196770504957E-006 - -9.6151750711217687 -5.1062966024118293 -5.36864428247124680E-004 - 399 6.55357523599375162E-009 1.15142691541302280E-004 - 1.98730033637173138E-006 - 8.94579103140301785E-002 -0.28863416967893080 -8.31539457533884404E-006 - 10.916997765438204 3.3847460004228105 -5.93736871720634135E-004 - 400 6.55357523599375162E-009 9.87378210419300682E-005 - 1.98730033637173138E-006 - -0.12494562921341829 -0.22699994304965707 1.78543838223355162E-005 - 10.813707670148546 -5.9514736311815692 6.68075806130482858E-004 - 401 6.55357523599375162E-009 8.37875008052018088E-005 - 1.98730033637173138E-006 - 2.84287365862151281E-002 0.21801101854779342 1.47198144270412353E-006 - -13.288399908168357 1.7318758583427440 2.53470809235885222E-004 - 402 6.55357523599375162E-009 7.30486978797013437E-005 - 1.98730033637173138E-006 - 0.15444993447199085 0.11357968648393181 -8.07067702631690463E-006 - -8.4998678927839926 11.560784571005394 2.60276164138644774E-004 - 403 6.55357523599375162E-009 5.64386158684819760E-005 - 1.98730033637173138E-006 - 6.07218782187003217E-002 -0.13508607258311681 -9.75635295062308431E-007 - 14.891521817270982 6.6933207516767101 -2.92484618154859033E-004 - 404 6.55357523599375162E-009 1.20968771084937517E-004 - 1.98730033637173138E-006 - 2.90129052643995633E-002 -0.31610708337212673 -1.61214742710364420E-005 - 11.105600239284396 1.0186190879397072 -1.67114961893291471E-004 - 405 6.55357523599375162E-009 4.83920648884130836E-005 - 1.98730033637173138E-006 - 8.05109143606345251E-002 9.82175578548524914E-002 -3.60904229131740090E-007 - -13.634318407955696 11.177855582971965 8.90505041175522721E-004 - 406 6.55357523599375162E-009 7.24077726052224066E-005 - 1.98730033637173138E-006 - -0.17124047919136046 8.23596701141532939E-002 -8.21263390125206175E-006 - -6.2454655644080903 -12.990533736873910 2.23583569113770505E-004 - 407 6.55357523599375162E-009 7.45070621861677380E-005 - 1.98730033637173138E-006 - 9.80802002717527238E-002 0.16913200054177460 3.73335108004218363E-006 - -12.292891913441871 7.1286383211585340 -6.30288419397857813E-004 - 408 6.55357523599375162E-009 6.14055920997102301E-005 - 1.98730033637173138E-006 - -7.18724921210833478E-002 0.14420626846965592 1.09895007069492565E-006 - -14.009968538465706 -6.9832367964258193 -5.51086366849159125E-004 - 409 6.55357523599375162E-009 7.67084422401591098E-005 - 1.98730033637173138E-006 - -0.19233411159616531 -5.94055832715314341E-002 1.57190139831095736E-006 - 4.1324703160771659 -13.380636411116633 4.66754116844216808E-004 - 410 6.55357523599375162E-009 9.76316241743970241E-005 - 1.98730033637173138E-006 - 0.22922624828902427 -0.11443343694729496 -2.13375252920846695E-006 - 5.5444026545257659 11.106451217515620 5.19491593506098289E-006 - 411 6.55357523599375162E-009 1.10915214114480084E-004 - 1.98730033637173138E-006 - 0.26959214412773269 0.10980849881090292 2.80993801549683802E-005 - -4.3927246012861678 10.784646416299859 -1.12742999240925801E-004 - 412 6.55357523599375162E-009 6.85781157463330433E-005 - 1.98730033637173138E-006 - -0.10033706080014093 0.14937335238778032 1.06587270945021816E-006 - -12.296419668417780 -8.2592466464185748 1.56766490413689689E-004 - 413 6.55357523599375162E-009 6.00456890076939018E-005 - 1.98730033637173138E-006 - -3.25328046081368102E-002 -0.15419139003308091 -1.49472969629580529E-006 - 15.486071400389591 -3.2682010060070397 5.57681938055591296E-004 - 414 6.55357523599375162E-009 8.59201287607729220E-005 - 1.98730033637173138E-006 - 7.04149741729190870E-002 -0.21418704619704371 -5.78061775673238768E-006 - 12.570531097815094 4.1336000212144555 4.97523034861014507E-004 - 415 6.55357523599375162E-009 1.01450031904831641E-004 - 1.98730033637173138E-006 - 0.16830752607610791 -0.20629959146577123 3.01686846241213957E-006 - 9.4353805525357171 7.6968391692539200 3.96690763850988265E-004 - 416 6.55357523599375162E-009 4.81711994014989172E-005 - 1.98730033637173138E-006 - -4.36805038685857266E-002 -0.11862688926864155 1.04201903552319918E-006 - 16.584121889720247 -6.1041085499735956 5.67766028563353978E-004 - 417 6.55357523599375162E-009 6.34592049473655599E-005 - 1.98730033637173138E-006 - -1.75536390484399320E-002 -0.16559510750000808 2.00072380345047056E-006 - 15.311831263523976 -1.6231789070191107 -4.08973006327876851E-005 - 418 6.55357523599375162E-009 4.94947097106069310E-005 - 1.98730033637173138E-006 - 3.76505823139390572E-003 -0.12982105080030207 6.29719988587370764E-006 - 17.428131285274503 0.50361416457216457 1.73038891109243654E-003 - 419 6.55357523599375162E-009 8.18454212704397289E-005 - 1.98730033637173138E-006 - 7.27644514361266564E-002 0.20208664114333039 -2.04579478085396007E-006 - -12.755951316227314 4.5915284188800429 8.67120830742931781E-004 - 420 6.55357523599375162E-009 1.01231782428900797E-004 - 1.98730033637173138E-006 - 0.22916334283859949 -0.13438215513297699 -4.23819036235843121E-006 - 6.1660330818470070 10.515893064191026 1.37307058422308972E-003 - 421 6.55357523599375162E-009 5.47550671647389263E-005 - 1.98730033637173138E-006 - -0.10161884992370916 -0.10159415173372691 -4.63565015533152876E-006 - 11.718613944608075 -11.722110173072824 -7.92868455327992608E-004 - 422 6.55357523599375162E-009 5.24587000889416508E-005 - 1.98730033637173138E-006 - -0.13258084529862971 3.70761695972779970E-002 3.21362888958379809E-006 - -4.5591615007189059 -16.308654957895108 -7.77586375673174242E-004 - 423 6.55357523599375162E-009 1.29994735216603584E-004 - 1.98730033637173138E-006 - -0.31473890034974839 0.13161990879711721 2.43704854788943718E-005 - -4.1502252030341049 -9.9242735542888276 5.43324013961063619E-004 - 424 6.55357523599375162E-009 1.32575720918503480E-004 - 1.98730033637173138E-006 - 0.10014392574898580 -0.33317406305033426 -8.71994012295720716E-006 - 10.201388691360785 3.0677964491372851 -1.53608675566153702E-004 - 425 6.55357523599375162E-009 4.37396046620212951E-005 - 1.98730033637173138E-006 - -0.11478915247878782 1.38075026092480263E-003 -2.02157784466910472E-006 - -0.22105647262422856 -18.541918358969987 1.17983855514319628E-003 - 426 6.55357523599375162E-009 5.65759145219294098E-005 - 1.98730033637173138E-006 - 9.63802794534406315E-002 0.11292963529812830 -2.16091031122177118E-006 - -12.402974159770569 10.586650065730216 -4.86929233443333172E-004 - 427 6.55357523599375162E-009 5.37784282989979851E-005 - 1.98730033637173138E-006 - 5.03746115330582431E-002 0.13183331977177401 -5.98571503157776808E-006 - -15.623526983481428 5.9691206273111623 4.87105313770810921E-004 - 428 6.55357523599375162E-009 5.22075334394742573E-005 - 1.98730033637173138E-006 - -0.10263990587016381 -9.07355234446422659E-002 -2.83948441223240581E-006 - 11.244224684898350 -12.718379850819389 2.53464341835491565E-004 - 429 6.55357523599375162E-009 1.15428956032878182E-004 - 1.98730033637173138E-006 - -0.28930615010325167 -8.96701982005404519E-002 -3.36811369422406468E-005 - 3.3805193604543367 -10.905297923512752 -2.21793842482063681E-004 - 430 6.55357523599375162E-009 4.11296878656496588E-005 - 1.98730033637173138E-006 - -8.68028129725349346E-002 -6.41541760473345601E-002 3.04434551375225509E-006 - 11.366814908419858 -15.379701006546796 2.10026186400263183E-004 - 431 6.55357523599375162E-009 1.17011748932687671E-004 - 1.98730033637173138E-006 - 0.25038566371280918 -0.17784031197604860 -2.51033325460703520E-005 - 6.5649516685121467 9.2426098855288803 3.43947195511666256E-005 - 432 6.55357523599375162E-009 4.26922969870062262E-005 - 1.98730033637173138E-006 - 3.02129101551078041E-002 0.10789097566830398 2.98514516988052957E-006 - -18.074658617436334 5.0635380579133127 2.84593588005907180E-004 - 433 6.55357523599375162E-009 7.17436251382779156E-005 - 1.98730033637173138E-006 - 6.31323253545859331E-002 -0.17737973850779781 -2.53137099118911740E-005 - 13.642140071347031 4.8540994115203695 -2.20665239295701299E-004 - 434 6.55357523599375162E-009 4.77650436944600926E-005 - 1.98730033637173138E-006 - 5.50046066860958929E-002 -0.11261521287730068 9.28776128584994790E-006 - 15.949786372068228 7.7871109818774551 -2.54516826592802656E-004 - 435 6.55357523599375162E-009 4.64199713982221116E-005 - 1.98730033637173138E-006 - -2.37038705429546692E-002 0.11949052089596364 -6.03220543598483330E-006 - -17.658508944086474 -3.4992635388627171 7.48727341333525059E-004 - 436 6.55357523599375162E-009 6.11168739208334477E-005 - 1.98730033637173138E-006 - -0.15586843342339904 3.77922774774307052E-002 -7.51589714853887234E-007 - -3.6976830208229492 -15.247138217741600 -1.31645314387665075E-004 - 437 6.55357523599375162E-009 8.96733756903805455E-005 - 1.98730033637173138E-006 - 1.34989240087436957E-002 -0.23493332310711021 -5.07673356126827155E-006 - 12.931155185192033 0.74234414146298366 -3.92165579513286408E-004 - 438 6.55357523599375162E-009 9.48808001646625829E-005 - 1.98730033637173138E-006 - 0.15291249350449101 -0.19653888730087443 -8.86566592819855104E-007 - 9.9361918823530946 7.7324147094469202 -8.38967232081740252E-004 - 439 6.55357523599375162E-009 1.20761598365554159E-004 - 1.98730033637173138E-006 - 0.31327031243280018 -4.80289928383664244E-002 1.83685892641740134E-005 - 1.6908590740221232 11.031587988431101 5.87161047150961844E-005 - 440 6.55357523599375162E-009 1.04541912457681624E-004 - 1.98730033637173138E-006 - -0.24888723570720889 -0.11539755161003154 -1.46137573921079037E-005 - 5.0462085799032783 -10.883091288482746 -4.23392748059435442E-004 - 441 6.55357523599375162E-009 9.13748429985475238E-005 - 1.98730033637173138E-006 - 0.21454132616261626 -0.10715967376811952 -8.81012502368764292E-006 - 5.7316425877277659 11.478252488723976 -3.08629846780937946E-004 - 442 6.55357523599375162E-009 5.41843704571223436E-005 - 1.98730033637173138E-006 - 7.76540926869908610E-002 -0.11910093065940140 1.09251196812857605E-005 - 13.958983454220604 9.1013554954124398 -4.98469358379049067E-004 - 443 6.55357523599375162E-009 7.69829619231491148E-005 - 1.98730033637173138E-006 - -3.76476169329260923E-002 -0.19850466061138933 -3.21027784551172690E-006 - 13.732657366700860 -2.6054218408516423 -5.53349835812625345E-004 - 444 6.55357523599375162E-009 8.98550344148056672E-005 - 1.98730033637173138E-006 - -2.91334668445951059E-002 -0.23399767634317242 -1.04500703260738014E-005 - 12.839830416936859 -1.5986878874260491 -1.33119307800382719E-003 - 445 6.55357523599375162E-009 1.31844795263669418E-004 - 1.98730033637173138E-006 - 8.04423101211496072E-003 0.34586460935983987 -2.40783279387921671E-006 - -10.679968969469932 0.24932583752594617 -4.87408461912019315E-004 - 446 6.55357523599375162E-009 8.42549831628806129E-005 - 1.98730033637173138E-006 - 9.09333583943890411E-002 0.20151034611928892 1.18289559137571477E-005 - -12.180760439160013 5.4975543293650535 -3.45469007080428144E-004 - 447 6.55357523599375162E-009 6.66965308351238228E-005 - 1.98730033637173138E-006 - 0.15677560318466172 -7.77969614902461193E-002 3.05513538860115222E-006 - 6.6770632508868726 13.453560629276279 -4.85797695469161424E-004 - 448 6.55357523599375162E-009 6.38056209378353459E-005 - 1.98730033637173138E-006 - 6.58213076812889653E-002 -0.15396644300321941 -8.99259322695695208E-007 - 14.118437548534461 6.0357406160299840 7.94544577737079857E-004 - 449 6.55357523599375162E-009 1.03636505003977473E-004 - 1.98730033637173138E-006 - -0.24674549546960398 0.11433025511144063 -1.38498206411008881E-005 - -5.0651009310398445 -10.932747478596568 -1.33900901603830648E-003 - 450 6.55357523599375162E-009 8.52990778871964730E-005 - 1.98730033637173138E-006 - -7.69621591676596523E-002 -0.21018498633522084 9.13949725112606624E-006 - 12.471701570936695 -4.5651721277063215 7.84656251403463806E-004 - 451 6.55357523599375162E-009 7.43920753044708993E-005 - 1.98730033637173138E-006 - -7.18839110505375273E-003 0.19507148451402923 -8.50737593168354638E-008 - -14.212164537828928 -0.52402963714699435 4.28551107404826946E-004 - 452 6.55357523599375162E-009 9.32672405436744972E-005 - 1.98730033637173138E-006 - -7.28120393785447184E-002 -0.23371078200270151 4.50810286125423057E-007 - 12.123649495528257 -3.7772579950357441 1.95231519559563017E-004 - 453 6.55357523599375162E-009 9.69797489575431273E-005 - 1.98730033637173138E-006 - -1.25991907249346242E-002 0.25418260855766672 -4.85124340405165687E-006 - -12.439778986867712 -0.61467977023366793 -3.26101210767207209E-004 - 454 6.55357523599375162E-009 5.02540373374240362E-005 - 1.98730033637173138E-006 - 0.10594577223165270 -7.85477109793561584E-002 -1.49212695251915371E-006 - 10.304532268203294 13.897118513729563 -5.17311325448232065E-004 - 455 6.55357523599375162E-009 5.83842367483767440E-005 - 1.98730033637173138E-006 - 0.14441850532831385 -5.11207961715130013E-002 5.58712058163601105E-006 - 5.3575903588948348 15.133171837459457 1.05811293321646173E-003 - 456 6.55357523599375162E-009 7.29732376749289805E-005 - 1.98730033637173138E-006 - -0.15444880704222402 0.11322000808137277 -8.07847076580536609E-006 - -8.4892185272512144 -11.579267877348414 -1.27585071493536506E-003 - 457 6.55357523599375162E-009 7.45391570612333892E-005 - 1.98730033637173138E-006 - -0.10375960265403333 -0.16586580545030058 5.89279469365939806E-007 - 12.042742038955044 -7.5310506057806048 -4.56157293246269176E-004 - 458 6.55357523599375162E-009 6.88537075185870521E-005 - 1.98730033637173138E-006 - -2.07772773963529056E-002 0.17948885900040412 -5.60783580866117126E-006 - -14.683399609779752 -1.6994410834058147 1.63247503123360943E-004 - 459 6.55357523599375162E-009 9.74820567536962515E-005 - 1.98730033637173138E-006 - -0.14839378169846465 -0.20839380729065668 -2.22971124605824455E-005 - 10.119656536384914 -7.2041049878123768 4.18907750790821270E-005 - 460 6.55357523599375162E-009 6.05248444603353499E-005 - 1.98730033637173138E-006 - -0.15881411528908257 -7.73237048900130008E-004 -1.10990171456083990E-005 - 7.47941019611655378E-002 -15.766963933186357 -1.88497618756131111E-004 - 461 6.55357523599375162E-009 5.29442472879821445E-005 - 1.98730033637173138E-006 - 2.93840747269990751E-002 0.13579646335273196 5.13653725635065503E-006 - -16.475022114102302 3.5653913809780882 2.01464560503254020E-004 - 462 6.55357523599375162E-009 5.19365492980350754E-005 - 1.98730033637173138E-006 - 0.10661120480103659 8.49335071817050868E-002 -8.83835019895553016E-006 - -10.604801896713861 13.309270221710390 -6.04851605178561343E-004 - 463 6.55357523599375162E-009 7.09881966589347071E-005 - 1.98730033637173138E-006 - -7.23259655450496919E-002 0.17167079617663766 1.83415231721620250E-005 - -13.415556593929267 -5.6527315590628460 -2.23561764637655489E-004 - 464 6.55357523599375162E-009 9.77275308807809805E-005 - 1.98730033637173138E-006 - 0.25602923328948085 1.46389957968531687E-002 -5.45961739235375800E-006 - -0.70889179044192918 12.387411302603869 -7.76200391664841078E-004 - 465 6.55357523599375162E-009 4.80058427991044573E-005 - 1.98730033637173138E-006 - 0.11835509424366705 -4.31356563402990195E-002 -2.09693047972361338E-006 - 6.0617364047104791 16.633325767476592 2.61805152877489142E-004 - 466 6.55357523599375162E-009 4.82434529720642211E-005 - 1.98730033637173138E-006 - -9.87783498254986153E-002 -7.91707809984316807E-002 7.41753050100326968E-006 - 11.046329099291347 -13.779148836370407 3.41875921297169470E-004 - 467 6.55357523599375162E-009 9.47552008040060287E-005 - 1.98730033637173138E-006 - -0.14966252510155814 -0.19855828628758454 -9.63728634119868803E-007 - 10.063797817396093 -7.5830915585229448 -6.17183055374530254E-004 - 468 6.55357523599375162E-009 8.58899492901583255E-005 - 1.98730033637173138E-006 - -8.35602723237309220E-002 -0.20931121458876337 -6.12028817457305015E-006 - 12.292616620698054 -4.9067063134426911 5.69654981831918018E-004 - 469 6.55357523599375162E-009 1.06893276784272457E-004 - 1.98730033637173138E-006 - 0.26302014198210472 -9.74998712435695136E-002 -2.51033986209187238E-005 - 4.1240531902663209 11.123454812649777 -6.60429371127622966E-005 - 470 6.55357523599375162E-009 1.06931747136948090E-004 - 1.98730033637173138E-006 - 0.27125903174402322 7.17940656686395229E-002 2.35081749955487144E-005 - -3.0344781103409924 11.467004610950310 -5.36973689910668359E-004 - 471 6.55357523599375162E-009 1.05829228061047335E-004 - 1.98730033637173138E-006 - -4.34680108621780525E-002 0.27430868184177615 -1.31465114482354178E-005 - -11.774986182366778 -1.8680864433393931 -3.64118646633259795E-005 - 472 6.55357523599375162E-009 1.18480485128378540E-004 - 1.98730033637173138E-006 - 0.23341986765951070 0.20538904874241268 -3.85305408800452221E-006 - -7.4433757601892987 8.4599718854124930 1.59805815158645017E-004 - 473 6.55357523599375162E-009 4.49756122640683926E-005 - 1.98730033637173138E-006 - -5.51483173946666974E-002 -0.10436108966370967 -1.04163450839165200E-005 - 16.168749715550049 -8.5441488622865780 -9.78405793087065538E-004 - 474 6.55357523599375162E-009 6.35414641471333596E-005 - 1.98730033637173138E-006 - 0.16207805423915325 3.91973364469214644E-002 -1.28232844000452018E-005 - -3.6185044333837570 14.955032570708068 -9.75157244716529201E-005 - 475 6.55357523599375162E-009 9.29460551220909610E-005 - 1.98730033637173138E-006 - 0.19126161933269331 0.15139127392019197 -3.89006475664941750E-006 - -7.8943915225735983 9.9756477393674778 1.11056453758026077E-003 - 476 6.55357523599375162E-009 4.73423935071446228E-005 - 1.98730033637173138E-006 - 0.11887036277676084 -3.61250480202135876E-002 -1.07368209173226118E-006 - 5.1834173314651908 17.055560862927774 6.68814552402613124E-004 - 477 6.55357523599375162E-009 1.10546936848036263E-004 - 1.98730033637173138E-006 - 0.14661824037924945 0.25034831893811726 5.85531724724472991E-006 - -10.065040808725843 5.8956924159694646 -3.84246398944986943E-004 - 478 6.55357523599375162E-009 8.25548523533028023E-005 - 1.98730033637173138E-006 - 0.10395269758823268 -0.19004136759966420 -2.24385263948683183E-006 - 11.843620552605552 6.4810477799141886 2.60430822228470150E-005 - 479 6.55357523599375162E-009 5.77849731445701767E-005 - 1.98730033637173138E-006 - -0.13865198238712387 6.13461619840356479E-002 -4.28098242429704593E-006 - -6.5293893859989156 -14.757719186373203 2.97209645358560096E-004 - 480 6.55357523599375162E-009 7.46462167970627136E-005 - 1.98730033637173138E-006 - 0.15355358318089493 0.12160832778036965 -4.31062925440724189E-006 - -8.8141142732581343 11.129816735086283 -5.42288637912784156E-004 - 481 6.55357523599375162E-009 7.95594028110162472E-005 - 1.98730033637173138E-006 - -0.17575876598640555 0.11273541458623504 -6.06973771306071066E-006 - -7.4247842781785991 -11.572208643397179 -1.90536526728435818E-004 - 482 6.55357523599375162E-009 7.89763879678007054E-005 - 1.98730033637173138E-006 - -4.02694618794383757E-002 -0.20333244317677085 -2.08320909736896747E-005 - 13.536874238608302 -2.6801687164705710 1.49689839267021815E-004 - 483 6.55357523599375162E-009 1.28668654463266372E-004 - 1.98730033637173138E-006 - -9.48536040903180111E-002 -0.32408830603250349 1.54245884542978527E-005 - 10.377245838326042 -3.0351743870557710 -2.10686337397602284E-004 - 484 6.55357523599375162E-009 8.33738089100886139E-005 - 1.98730033637173138E-006 - -0.19134788467987804 -0.10613365351840853 1.28518161506721146E-005 - 6.5147731433125546 -11.745797805598192 9.90602115679696359E-005 - 485 6.55357523599375162E-009 5.17310037158172757E-005 - 1.98730033637173138E-006 - -9.75428294199601198E-002 -9.44157512891591055E-002 1.96179427193608795E-006 - 11.858762736504030 -12.254839437066090 6.49893758046801674E-004 - 486 6.55357523599375162E-009 5.26233272131239473E-005 - 1.98730033637173138E-006 - 0.13733191379969292 -1.46500875225470950E-002 -3.79855492062266863E-006 - 1.7942935989178821 16.810514059292025 -4.47961785407900693E-004 - 487 6.55357523599375162E-009 5.64027445834108508E-005 - 1.98730033637173138E-006 - 2.84568809709364740E-002 0.14524089793132963 2.88101878922974615E-006 - -16.028133306720061 3.1401601591604482 -3.50083831585309133E-004 - 488 6.55357523599375162E-009 1.29685008904061695E-004 - 1.98730033637173138E-006 - 0.17586955524501185 -0.29134586458041201 -2.96892861190029034E-006 - 9.2204970673512481 5.5670753016934178 -2.07436859455733277E-004 - 489 6.55357523599375162E-009 1.07053573392793444E-004 - 1.98730033637173138E-006 - -5.14403561510693164E-002 -0.27620888476681160 -7.77440632288628902E-006 - 11.653052727820082 -2.1695970470386747 -7.34320868977529476E-004 - 490 6.55357523599375162E-009 5.83542011667458697E-005 - 1.98730033637173138E-006 - 7.17026392716520189E-002 0.13533180995583535 -2.57882064189271259E-006 - -14.186368159336091 7.5156893841445633 6.59844499125672467E-004 - 491 6.55357523599375162E-009 7.82249449134796978E-005 - 1.98730033637173138E-006 - -0.19375169979329618 6.78179435052429502E-002 -5.35943354532631173E-006 - -4.5810580283715154 -13.089413629000749 2.33832776269632972E-004 - 492 6.55357523599375162E-009 6.91658509027782840E-005 - 1.98730033637173138E-006 - -9.47190496968805529E-003 -0.18126733595281777 -1.40960606605065948E-005 - 14.727235519522361 -0.77035941123394291 3.80422817659045070E-004 - 493 6.55357523599375162E-009 8.96794170533373196E-005 - 1.98730033637173138E-006 - 0.23503043410393420 1.15215502199725178E-002 2.22604695586721372E-005 - -0.63163514210718930 12.937921348714173 -5.04464385309747691E-004 - 494 6.55357523599375162E-009 4.39757521012261652E-005 - 1.98730033637173138E-006 - 5.35094644223455887E-002 -0.10225606007640262 -5.75622677028677355E-006 - 16.385132158915539 8.5774718516338524 -1.01600597763549681E-003 - 495 6.55357523599375162E-009 1.02716657569733823E-004 - 1.98730033637173138E-006 - 0.18652000017510065 -0.19458666492887614 -1.48949699051851107E-005 - 8.7365127983981914 8.3750679857107837 2.65686405647255210E-004 - 496 6.55357523599375162E-009 1.16889442267115209E-004 - 1.98730033637173138E-006 - -0.19884805081611578 0.23357660839692657 1.11337375312107051E-005 - -8.6382393754966937 -7.3534506507057991 1.08052321172702015E-003 - 497 6.55357523599375162E-009 6.41014241698626607E-005 - 1.98730033637173138E-006 - 3.57588645422793339E-003 0.16818698445964261 -1.62211826272351317E-005 - -15.315331666316782 0.32419380949907683 -2.00448904648543944E-004 - 498 6.55357523599375162E-009 9.81313576565940649E-005 - 1.98730033637173138E-006 - -0.24475278663016806 8.01722931701861485E-002 -6.92773506373755267E-006 - -3.8547313331865976 -11.764693609936099 3.08559931004177910E-004 - 499 6.55357523599375162E-009 9.26135869413079231E-005 - 1.98730033637173138E-006 - -0.19934986986205955 -0.13906729388638311 -2.08196143659857363E-007 - 7.2917833137337649 -10.451459555295420 -2.73337033968816653E-004 - 500 6.55357523599375162E-009 4.39919346094836289E-005 - 1.98730033637173138E-006 - -7.70876959736120498E-002 -8.59491976076548203E-002 -7.65886759358837548E-006 - 13.765941326719089 -12.345369413990028 -3.29551407764356002E-004 - 501 6.55357523599375162E-009 9.95790844464536443E-005 - 1.98730033637173138E-006 - -8.45644739413137503E-002 -0.24726770593025282 -1.24291342362777932E-005 - 11.629041426129614 -3.9784018521929867 9.60379106323715919E-004 - 502 6.55357523599375162E-009 8.75704903192987431E-005 - 1.98730033637173138E-006 - -0.14480619995934893 0.17846321428630813 -2.37205412350441600E-006 - -10.176057992429996 -8.2591609744318646 6.49164453275802018E-004 - 503 6.55357523599375162E-009 5.51221391434012062E-005 - 1.98730033637173138E-006 - 0.14347723925520200 -1.83655125475060410E-002 -5.16154039458327392E-006 - 2.0983161895680889 16.387013371299751 -4.63764006328477375E-004 - 504 6.55357523599375162E-009 4.32606676519989021E-005 - 1.98730033637173138E-006 - 6.52096329420701060E-002 9.29241413434717112E-002 3.13237220066430065E-006 - -15.264480099990537 10.713004999180667 -1.55906331633859705E-004 - 505 6.55357523599375162E-009 6.26720375952598713E-005 - 1.98730033637173138E-006 - -0.11815404619473423 -0.11439725696270221 9.04161501289522044E-006 - 10.778009167448197 -11.130639150006365 -4.42956742722214073E-004 - 506 6.55357523599375162E-009 1.22800088914580969E-004 - 1.98730033637173138E-006 - -8.62549217130313683E-002 0.31049317743054849 2.37958776541622482E-005 - -10.664880844214798 -2.9613967699055697 2.87816057939677887E-004 - 507 6.55357523599375162E-009 5.28706740776174481E-005 - 1.98730033637173138E-006 - -5.00531177573390537E-002 0.12940247945183295 1.18512484300817555E-005 - -15.731847414550943 -6.0864849478018979 6.19580217860250674E-004 - 508 6.55357523599375162E-009 7.40799945986400535E-005 - 1.98730033637173138E-006 - 0.13736754476836635 -0.13753718603995971 -2.93926805678353102E-006 - 10.083279012394708 10.071519673528590 3.57567708591887247E-006 - 509 6.55357523599375162E-009 1.01648469405866485E-004 - 1.98730033637173138E-006 - -0.26613818203180445 1.81686592139696096E-002 -5.28838621722277425E-006 - -0.82943238581426115 -12.136742336350796 1.15136442920070659E-004 - 510 6.55357523599375162E-009 4.00118081712831915E-005 - 1.98730033637173138E-006 - 7.50002648850610354E-002 7.34920475296071823E-002 -4.55076553900766750E-006 - -13.570162300004725 13.849090300978585 -3.63099945350240554E-004 - 511 6.55357523599375162E-009 8.01459170594464470E-005 - 1.98730033637173138E-006 - 0.15652398652142180 0.14046306088057170 -7.90187315212455462E-007 - -9.1512284983791545 10.197201713612587 3.26282678254627054E-004 - 512 6.55357523599375162E-009 1.06084561891156456E-004 - 1.98730033637173138E-006 - -0.27557277502066024 -3.95090539054396145E-002 5.23765669034812257E-007 - 1.6913382873861698 -11.787636914606649 -1.39900706546386639E-003 - 513 6.55357523599375162E-009 1.20579082550359816E-004 - 1.98730033637173138E-006 - 0.28623125434088392 0.13481802873683688 1.58774961627096021E-005 - -4.7592347790970519 10.106424871463533 -5.74869048952257491E-004 - 514 6.55357523599375162E-009 1.26569438710390675E-004 - 1.98730033637173138E-006 - 0.32622001745734819 -6.23049301463896310E-002 -8.51386998837604949E-006 - 2.0443667123244724 10.709831787415389 4.54410072997686598E-007 - 515 6.55357523599375162E-009 5.97675393516922742E-005 - 1.98730033637173138E-006 - 9.07905478379753272E-002 0.12789206335324760 9.17688910172747290E-006 - -12.937677387644291 9.1830358042935529 -1.31736334751882410E-004 - 516 6.55357523599375162E-009 8.15414080428805417E-005 - 1.98730033637173138E-006 - 0.20743928946338658 -5.26434076736139664E-002 -2.25980495778320185E-006 - 3.3401580289659303 13.163643917795106 8.49489041033424310E-004 - 517 6.55357523599375162E-009 5.51252533595620746E-005 - 1.98730033637173138E-006 - 0.14415141630592448 -1.20894704903591610E-002 -1.68574720578555195E-006 - 1.3812220253706045 16.462338118007008 -3.40528524229620559E-005 - 518 6.55357523599375162E-009 6.16920432263022626E-005 - 1.98730033637173138E-006 - 3.68294342914648881E-002 -0.15763679930384478 5.41006958934955080E-006 - 15.207291432260723 3.5535516784087591 1.26155756741227229E-003 - 519 6.55357523599375162E-009 4.80778192313827105E-005 - 1.98730033637173138E-006 - 0.12617442136924525 1.08375878362897138E-004 2.89446361251911697E-006 - -1.49097192472815721E-002 17.688097055004732 -2.49166109592775656E-004 - 520 6.55357523599375162E-009 6.42345494292621323E-005 - 1.98730033637173138E-006 - -6.08816379742791597E-003 0.16842765851906588 7.03122559539878174E-006 - -15.296202485282905 -0.55348405962097003 -4.74250756400343139E-004 - 521 6.55357523599375162E-009 4.89770605918540936E-005 - 1.98730033637173138E-006 - 0.12634439457381888 -2.35962950406981564E-002 -1.02196858258018585E-005 - 3.2185350291023322 17.227644813825052 5.21235415142741140E-004 - 522 6.55357523599375162E-009 1.15307847076023487E-004 - 1.98730033637173138E-006 - -0.15197287900145331 -0.26169044182974383 -1.41950894932064471E-005 - 9.8761380851495009 -5.7365239447246594 -4.28923015314873067E-004 - 523 6.55357523599375162E-009 1.29925024343256090E-004 - 1.98730033637173138E-006 - -0.26497160924393848 0.21446206855510702 7.09189659625621535E-006 - -6.7707428521409163 -8.3660114674876080 7.05185663686711103E-006 - 524 6.55357523599375162E-009 7.29880749226446398E-005 - 1.98730033637173138E-006 - 0.16549471853361467 9.64102961288695326E-002 -3.63124488487823831E-006 - -7.2280947265070914 12.405050022919633 5.14930305103263215E-004 - 525 6.55357523599375162E-009 1.06836686059119608E-004 - 1.98730033637173138E-006 - 0.26736835246217572 -8.43464359637931677E-002 6.54181713884149664E-006 - 3.5690839288155218 11.317221280074094 5.04115939561793270E-005 - 526 6.55357523599375162E-009 7.43992732030240638E-005 - 1.98730033637173138E-006 - 0.16718828849409662 0.10086207363860825 3.59091123504517184E-006 - -7.3445231315716297 12.174928332549142 9.00995390894968008E-004 - 527 6.55357523599375162E-009 1.17079134113272891E-004 - 1.98730033637173138E-006 - -0.12782112052216790 -0.27939754864849553 7.16441058508287130E-006 - 10.307279925859422 -4.7167772182335934 -1.30933211024222742E-004 - 528 6.55357523599375162E-009 1.01735391172153928E-004 - 1.98730033637173138E-006 - 0.26559443802808919 2.72044973491835443E-002 1.35229676787004025E-006 - -1.2404112826326621 12.096498142431185 -4.41020021420740374E-004 - 529 6.55357523599375162E-009 9.21436841805289652E-005 - 1.98730033637173138E-006 - 0.12731914601879044 -0.20560027636001871 5.05855995659641046E-006 - 10.862485488717242 6.7259915745480354 3.89288397047240792E-005 - 530 6.55357523599375162E-009 1.01308983546552158E-004 - 1.98730033637173138E-006 - 9.96875079134104947E-002 0.24650039755181447 6.49559396081716510E-006 - -11.295843169157010 4.5669391629163290 -2.71193851346509163E-004 - 531 6.55357523599375162E-009 8.87569290034072577E-005 - 1.98730033637173138E-006 - 0.23153958361778598 -2.52423062015678795E-002 3.07069031059457043E-006 - 1.4105777700951210 12.942750024053794 6.92775913539952094E-004 - 532 6.55357523599375162E-009 3.98715776544037061E-005 - 1.98730033637173138E-006 - -2.19806927356093681E-002 -0.10229798291006052 5.44038382164887139E-006 - 18.990940961315513 -4.0798797506955289 -1.46272139657161051E-004 - 533 6.55357523599375162E-009 6.00137957150585777E-005 - 1.98730033637173138E-006 - 8.10761667075544229E-002 0.13503641103280806 -7.50480802545535085E-006 - -13.573543625483655 8.1473697949733221 2.01968003279664587E-004 - 534 6.55357523599375162E-009 5.23174814942773178E-005 - 1.98730033637173138E-006 - 6.69197556678002708E-002 -0.11987115713213160 4.79575516154812791E-006 - 14.805279167589177 8.2693897421576903 1.25114329183682112E-004 - 535 6.55357523599375162E-009 1.27074570596577146E-004 - 1.98730033637173138E-006 - 2.25103655928246063E-002 0.33271063930867995 1.84086318955388040E-005 - -10.855757309428434 0.73425695178693351 -4.64403914542489541E-004 - 536 6.55357523599375162E-009 8.15783402897286841E-005 - 1.98730033637173138E-006 - 0.21264337315113707 2.45846363478374429E-002 1.22094280653298914E-005 - -1.5597369052823873 13.491165016046642 -5.34718968916622064E-004 - 537 6.55357523599375162E-009 3.87971214539495330E-005 - 1.98730033637173138E-006 - 3.67266680494442305E-002 9.49584367393251083E-002 -5.00921933854071184E-006 - -18.364567902192199 7.1057678756789118 6.71274619061476910E-004 - 538 6.55357523599375162E-009 7.40215101820263877E-005 - 1.98730033637173138E-006 - 3.52993301126957870E-002 0.19103541117894696 -1.46754979704004844E-005 - -14.017081998261425 2.5913503604993338 -7.15527172902331323E-004 - 539 6.55357523599375162E-009 1.28889358495551420E-004 - 1.98730033637173138E-006 - -0.33817576244628023 5.09805055251769113E-003 6.66733083444512464E-006 - -0.16349257641409487 -10.803073974390703 -2.63473500659301143E-004 - 540 6.55357523599375162E-009 1.31654649861894370E-004 - 1.98730033637173138E-006 - 0.16985288995987835 -0.30088075820343563 -2.73780907804497445E-005 - 9.3083839083477624 5.2542487002176106 1.23137678822677536E-004 - 541 6.55357523599375162E-009 6.40909282925758558E-005 - 1.98730033637173138E-006 - -0.16371533775975469 3.84980184662282385E-002 -4.60583624091058347E-006 - -3.5054314260799320 -14.915130232793640 4.56648027158589677E-005 - 542 6.55357523599375162E-009 1.28366075410696063E-004 - 1.98730033637173138E-006 - -0.22409884212261039 -0.25150448583504731 -5.66728859118911000E-006 - 8.0829408303426771 -7.2015097505565251 5.66254890056972111E-004 - 543 6.55357523599375162E-009 6.28741059438224080E-005 - 1.98730033637173138E-006 - 0.15951476274734100 4.20730284802875859E-002 -3.02583237096566267E-006 - -3.9454239398817244 14.959200211596563 2.23911011674926465E-003 - 544 6.55357523599375162E-009 9.91770248990856172E-005 - 1.98730033637173138E-006 - 0.22042473310158106 0.13836291444739268 -8.68247589872475433E-006 - -6.5475338383902946 10.432092685021043 7.54626242148609102E-004 - 545 6.55357523599375162E-009 1.08622839728331661E-004 - 1.98730033637173138E-006 - 0.22524031239387499 -0.17469811944417110 -6.60863301607823963E-006 - 7.2121184859695404 9.2996586818474221 -1.90217612964460695E-004 - 546 6.55357523599375162E-009 1.01257566559109384E-004 - 1.98730033637173138E-006 - -0.13644599956373110 -0.22802610521192596 -7.52814193853560970E-006 - 10.458620936787058 -6.2591489503285391 7.31103194934818379E-005 - 547 6.55357523599375162E-009 1.01841758057955956E-004 - 1.98730033637173138E-006 - -0.22698572876359752 0.14109452386914917 -1.38643017090366381E-005 - -6.4173254529291128 -10.321153798818660 1.01019656787410987E-004 - 548 6.55357523599375162E-009 7.33981142078300058E-005 - 1.98730033637173138E-006 - -0.10549155976923766 0.16113497379402167 -5.31249144942600608E-006 - -11.979698203883551 -7.8413663326638048 6.49767394710452895E-004 - 549 6.55357523599375162E-009 6.76565995186366432E-005 - 1.98730033637173138E-006 - 1.37374347954462364E-002 0.17699112665753103 -5.81499053068213466E-006 - -14.868794083672396 1.1539426751830799 4.31171264061103003E-004 - 550 6.55357523599375162E-009 1.23890638027858148E-004 - 1.98730033637173138E-006 - 0.24830136485323540 -0.20991366792369381 -7.93107044308991149E-006 - 7.1146246698880020 8.4137824497046232 5.31329012645817425E-004 - 551 6.55357523599375162E-009 1.03964925166099718E-004 - 1.98730033637173138E-006 - -8.66269468132605108E-002 -0.25870558436833035 2.68601513145120697E-006 - 11.406635493038115 -3.8201503662429741 7.34304288624584595E-004 - 552 6.55357523599375162E-009 7.16901552368961862E-005 - 1.98730033637173138E-006 - 8.74238320542681108E-002 0.16657836362342429 -4.58491773985334759E-006 - -12.826903785868208 6.7325930181589984 4.87642097621091594E-004 - 553 6.55357523599375162E-009 5.39029337744010838E-005 - 1.98730033637173138E-006 - -9.45582711026658751E-002 0.10518636943893357 -3.32716472428812591E-006 - -12.424009173755639 -11.170761437966428 1.81011997690216160E-004 - 554 6.55357523599375162E-009 1.01891436526690206E-004 - 1.98730033637173138E-006 - -0.25100818522519225 -9.21147276649464941E-002 2.85074953774037169E-006 - 4.1872795666314442 -11.407142481278781 4.69283977002582812E-004 - 555 6.55357523599375162E-009 1.09348731507031446E-004 - 1.98730033637173138E-006 - -0.10490106322743076 -0.26708840164091863 -1.06189925070071434E-005 - 10.918067360128102 -4.2869211916828744 -2.77988133655816133E-004 - 556 6.55357523599375162E-009 8.41795734273164623E-005 - 1.98730033637173138E-006 - 0.10692575791304842 0.19331327851681018 1.54805883313502894E-005 - -11.697545568717624 6.4703494973664517 1.15069545851138221E-004 - 557 6.55357523599375162E-009 1.19525016458873427E-004 - 1.98730033637173138E-006 - 0.31284366436682920 -2.24236392670144474E-002 1.12092780230212182E-005 - 0.80227330424518772 11.190679559775571 4.22945840979470399E-004 - 558 6.55357523599375162E-009 6.77757273177247583E-005 - 1.98730033637173138E-006 - -0.17467495670359875 3.34908450026557766E-002 2.66635799638147282E-006 - -2.8043058039029489 -14.632366968817143 -8.21205571240915229E-005 - 559 6.55357523599375162E-009 5.57633759128145766E-005 - 1.98730033637173138E-006 - -8.91260023184103356E-002 0.11608660206101956 -2.30945065029186299E-008 - -13.026294075891284 -10.001361627661968 -4.28483033916079211E-004 - 560 6.55357523599375162E-009 6.18869817446423377E-005 - 1.98730033637173138E-006 - 2.37231619224951701E-002 0.16066256345902297 -5.16394693022247702E-006 - -15.424112943716578 2.2769991406402346 -2.78068250230789670E-004 - 561 6.55357523599375162E-009 7.22533397403498268E-005 - 1.98730033637173138E-006 - 0.17459370657093354 7.39983550856275207E-002 6.74853439809354452E-007 - -5.6300784368759640 13.284217923965482 1.07352152157118102E-003 - 562 6.55357523599375162E-009 4.13575584670571625E-005 - 1.98730033637173138E-006 - -5.03575701791118754E-002 9.61486839608138022E-002 6.87243902403095751E-007 - -16.894018694961574 -8.8487710957063097 -1.96208506359428416E-004 - 563 6.55357523599375162E-009 7.14490921057728783E-005 - 1.98730033637173138E-006 - -0.16040561635522665 -9.70906365148730272E-002 1.93067384870523878E-007 - 7.5138372976726338 -12.413310143333387 -1.88387865913615995E-004 - 564 6.55357523599375162E-009 1.02752075583591152E-004 - 1.98730033637173138E-006 - 0.16757220520967941 -0.21126815147429095 9.99172372936960577E-007 - 9.4797824106311435 7.5186265366438443 5.96844205313904461E-004 - 565 6.55357523599375162E-009 1.18044951016134316E-004 - 1.98730033637173138E-006 - -0.29807840100571614 8.42433219899285241E-002 -2.00856882130446193E-005 - -3.0710270857941699 -10.864103023314033 4.30618959923419144E-004 - 566 6.55357523599375162E-009 6.12882564722722257E-005 - 1.98730033637173138E-006 - 0.13964428056052172 7.97771266129781303E-002 -9.85083376590040552E-007 - -7.7716107865173445 13.604712027311525 6.55772652098685050E-004 - 567 6.55357523599375162E-009 1.14627843880303674E-004 - 1.98730033637173138E-006 - 0.25141142332510091 -0.16504690997022844 1.28263497675237994E-005 - 6.2890315346006229 9.5783049991240947 -1.22519827366707505E-004 - 568 6.55357523599375162E-009 1.11515369414953047E-004 - 1.98730033637173138E-006 - -0.28371592897551517 7.14413504119663645E-002 -7.05516759112995485E-006 - -2.8370232069713528 -11.265818914536062 3.14534810715849590E-004 - 569 6.55357523599375162E-009 6.98874301935220442E-005 - 1.98730033637173138E-006 - -0.10530374444066126 0.15015194209742586 -5.33939521100865050E-006 - -12.012297873156875 -8.4243990401149116 -5.46239552813901873E-004 - 570 6.55357523599375162E-009 1.17135874350426394E-004 - 1.98730033637173138E-006 - -0.28914334809871423 0.10431991909752703 -1.81183648912146846E-005 - -3.8486564896324746 -10.659365723503335 2.93770635229966502E-004 - 571 6.55357523599375162E-009 1.15658394702243731E-004 - 1.98730033637173138E-006 - 0.16505170044216971 -0.25466098897050699 1.75596906535183330E-005 - 9.5722624590893339 6.2032375236838408 -2.96247334355376906E-004 - 572 6.55357523599375162E-009 7.96704012634670349E-005 - 1.98730033637173138E-006 - 0.20844798593774719 1.63344767770175064E-002 -1.54387548827894702E-005 - -1.0728023415027508 13.698533096869635 -6.23273015747854661E-004 - 573 6.55357523599375162E-009 1.07056029814072882E-004 - 1.98730033637173138E-006 - 0.20647783940894401 -0.19049364410058461 -5.29504024655303099E-006 - 8.0372613672415874 8.7141193357158482 -3.58882413708097548E-004 - 574 6.55357523599375162E-009 7.78364442765382792E-005 - 1.98730033637173138E-006 - -0.18499660504812038 8.65452360783520308E-002 2.05210525643081305E-006 - -5.8915740517992550 -12.593790070856157 5.47695985476124377E-004 - 575 6.55357523599375162E-009 5.29150088118905728E-005 - 1.98730033637173138E-006 - 9.69826924801253654E-002 9.93895035007528321E-002 -3.95423130242601736E-006 - -12.068131776759870 11.774503529283708 -2.85517982851280936E-004 - 576 6.55357523599375162E-009 7.33749929371611825E-005 - 1.98730033637173138E-006 - -0.18640923599612630 -4.82761332844452995E-002 1.23988624659433047E-006 - 3.5900651906423091 -13.860887847650774 4.21695168299873312E-004 - 577 6.55357523599375162E-009 7.23127483010695680E-005 - 1.98730033637173138E-006 - 0.15654118389647548 0.10727096751845004 -4.99410263304611998E-007 - -8.1543306482252689 11.896926823162064 6.86604858286300919E-004 - 578 6.55357523599375162E-009 4.18241873253663441E-005 - 1.98730033637173138E-006 - -0.10974629835011403 1.70401191072948321E-003 -7.08798005055656057E-007 - -0.29343639392355136 -18.962688404741328 2.36819694762170738E-004 - 579 6.55357523599375162E-009 9.87773290467440279E-005 - 1.98730033637173138E-006 - 0.23023871284775616 -0.11898586464050066 2.64735712773660554E-006 - 5.6655061268951652 10.966210733435377 8.21275969762767024E-005 - 580 6.55357523599375162E-009 1.23533391383219505E-004 - 1.98730033637173138E-006 - -0.32270205424908316 -3.14298360888524975E-002 -2.46546141909567926E-005 - 1.0704486372075062 -10.981639116718382 -1.84306424006066281E-004 - 581 6.55357523599375162E-009 6.82978555632370238E-005 - 1.98730033637173138E-006 - 0.17918184352637670 -2.93632212726893660E-003 1.72186528719553285E-006 - 0.24288266601526720 14.841351238234200 -8.78921402952967390E-004 - 582 6.55357523599375162E-009 5.64141027619260562E-005 - 1.98730033637173138E-006 - 0.13829032189719340 5.28456323578668577E-002 -5.87423138602857524E-006 - -5.8283262002355629 15.254440119404046 8.42998031362629041E-004 - 583 6.55357523599375162E-009 6.62987557355947853E-005 - 1.98730033637173138E-006 - 0.10485867782999833 0.13881815017165910 7.19952058998782454E-006 - -12.020725451159201 9.0798413852913562 1.70329407904248859E-004 - 584 6.55357523599375162E-009 1.33206859888486938E-004 - 1.98730033637173138E-006 - 0.30523708211638706 0.17042498699772368 -1.15244361977573576E-006 - -5.1796553754533123 9.2784521424535598 3.79427152061580827E-004 - 585 6.55357523599375162E-009 9.47149783689165775E-005 - 1.98730033637173138E-006 - 0.24853700984454158 4.66512611614339212E-003 -1.04771120540275082E-005 - -0.23728986346583980 12.599262574769558 -6.79688362187736523E-005 - 586 6.55357523599375162E-009 5.09687254755613565E-005 - 1.98730033637173138E-006 - -4.67796341790161496E-002 -0.12531591551046567 -5.23300858186406023E-006 - 16.094171432099543 -6.0079595732089714 -3.85876155716985913E-004 - 587 6.55357523599375162E-009 1.17997117648281418E-004 - 1.98730033637173138E-006 - 0.24452718904394069 0.19003635328244547 -1.55195860965747949E-006 - -6.9263934024646554 8.9155434665818394 3.68825531849088241E-004 - 588 6.55357523599375162E-009 5.60174381393679897E-005 - 1.98730033637173138E-006 - 0.14385227705108777 3.02909007972138183E-002 8.50456878380259041E-007 - -3.3760000031419271 16.035663519665057 -2.29531231467149967E-004 - 589 6.55357523599375162E-009 4.62227287856276838E-005 - 1.98730033637173138E-006 - -5.77675348740614575E-002 -0.10670324189665989 -1.18946282329204651E-006 - 15.859767928194389 -8.5864454344269046 1.68823788389851822E-004 - 590 6.55357523599375162E-009 1.11757039289565830E-004 - 1.98730033637173138E-006 - 0.13959961236731361 0.25789288783419750 9.19140805822283404E-006 - -10.204052286647903 5.5236661924180890 2.10623186872851021E-004 - 591 6.55357523599375162E-009 8.19471940000898166E-005 - 1.98730033637173138E-006 - -7.16022525822516964E-003 -0.21490976939103823 2.97746629535580985E-006 - 13.542838575134107 -0.45096011455004570 4.31923433405491473E-004 - 592 6.55357523599375162E-009 1.31893557277019729E-004 - 1.98730033637173138E-006 - 9.40848048244855018E-002 -0.33305751463783956 -1.21773878320927912E-005 - 10.278504321713674 2.9035424065884565 -4.60750682926704125E-004 - 593 6.55357523599375162E-009 7.07443483906049653E-005 - 1.98730033637173138E-006 - -0.16765121376706657 -7.97036082068877522E-002 3.21349097793050043E-006 - 6.2612885215339915 -13.171330235311798 -3.48220837324653241E-004 - 594 6.55357523599375162E-009 1.10620916689795152E-004 - 1.98730033637173138E-006 - 3.56392412664956679E-002 0.28809401834272286 1.46281201771985043E-005 - -11.573819128886010 1.4300585717583683 1.17792525856458299E-005 - 595 6.55357523599375162E-009 5.56944916403277927E-005 - 1.98730033637173138E-006 - 1.77374739274832986E-002 0.14507852045959468 -5.12222563103992084E-006 - -16.313384359203134 1.9931206837429247 4.87734658608484294E-004 - 596 6.55357523599375162E-009 1.29705425315794850E-004 - 1.98730033637173138E-006 - 0.15835083235402370 0.30127422419453614 -5.02783134231156661E-007 - -9.5337266468824691 5.0107420151212718 5.02590235729935162E-004 - 597 6.55357523599375162E-009 6.71745218635872197E-005 - 1.98730033637173138E-006 - -6.72898621716959688E-002 0.16290940232642456 -1.14561770834208166E-005 - -13.833018529151945 -5.7143674540254992 7.59561356265577980E-005 - 598 6.55357523599375162E-009 9.17379861646365572E-005 - 1.98730033637173138E-006 - 0.22078893705079911 9.59235642556781343E-002 1.51395645165209976E-005 - -5.1044774257340748 11.745283178256383 2.38129496005205288E-004 - 599 6.55357523599375162E-009 4.77338968589227720E-005 - 1.98730033637173138E-006 - 0.12512070239471171 5.65420671570786987E-003 -3.56826903044605845E-006 - -0.80161223028522199 17.736934569810341 -7.75314199935710929E-004 - 600 6.55357523599375162E-009 1.06174405761530377E-004 - 1.98730033637173138E-006 - 9.10983449051987054E-002 -0.26331235235536893 -5.09116212709992109E-006 - 11.249544255447363 3.8906807988425265 1.65197844182242079E-004 - 601 6.55357523599375162E-009 4.51188616543090986E-005 - 1.98730033637173138E-006 - -9.54728946524548150E-002 -7.00343914726617445E-002 -1.94014138708027983E-006 - 10.801460792607919 -14.721926188682428 -3.13984113034708771E-004 - 602 6.55357523599375162E-009 8.35418664185509776E-005 - 1.98730033637173138E-006 - 0.18709272571369231 0.11422426336284530 -4.82680613659913554E-006 - -6.9930524536672074 11.455039334775318 -1.18768660976217470E-004 - 603 6.55357523599375162E-009 1.13288922723350029E-004 - 1.98730033637173138E-006 - 0.13769821024399681 0.26346470412646716 4.74821542269804150E-006 - -10.213715719799765 5.3373369609067325 -6.24383591933645168E-004 - 604 6.55357523599375162E-009 6.72574233801001673E-005 - 1.98730033637173138E-006 - 0.17649811008616001 -2.88570865206435115E-003 5.42696479930763028E-006 - 0.24466849779742295 14.951826241757756 2.05209807451554627E-004 - 605 6.55357523599375162E-009 1.17459530238134299E-004 - 1.98730033637173138E-006 - -0.10496712305361008 -0.28981426247335473 9.76923523094108039E-006 - 10.640636043032444 -3.8543270630596007 2.95942054300353920E-004 - 606 6.55357523599375162E-009 9.08403645395074714E-005 - 1.98730033637173138E-006 - 0.13435652982691279 0.19690056877928097 4.81133627929452436E-006 - -10.630494338923558 7.2538229237413132 -1.75342873994789053E-005 - 607 6.55357523599375162E-009 8.35779787514798092E-005 - 1.98730033637173138E-006 - -2.29109533526802092E-002 -0.21809376612500678 -1.17613109441334461E-005 - 13.344883871684933 -1.4024111942180308 5.84629868339457876E-004 - 608 6.55357523599375162E-009 5.34447586492149335E-005 - 1.98730033637173138E-006 - -9.16633599902672291E-002 -0.10616491650635868 -3.87657777543583385E-006 - 12.699606861874624 -10.961925047232537 -1.90854270762543177E-004 - 609 6.55357523599375162E-009 1.12269105643677161E-004 - 1.98730033637173138E-006 - -0.21890946050085328 0.19723791641672273 6.13530489189648570E-006 - -7.7471627951674815 -8.5990180683093946 -1.88212550717605518E-004 - 610 6.55357523599375162E-009 6.60586650483993906E-005 - 1.98730033637173138E-006 - -0.15833249391177259 -7.06269280711379899E-002 -8.80501392948075600E-006 - 6.1468809030336011 -13.780557293629828 2.61033153451145134E-005 - 611 6.55357523599375162E-009 5.49415394171063069E-005 - 1.98730033637173138E-006 - 1.82582236913042123E-002 0.14301970205087239 -7.34708758335309742E-006 - -16.413785030068201 2.0969980464865614 1.75645373729943336E-003 - 612 6.55357523599375162E-009 6.30794065202108963E-005 - 1.98730033637173138E-006 - -0.14206543301307756 -8.50273568090032517E-002 -8.75177282335436470E-006 - 7.9303740155326725 -13.247936861878214 -5.52373860223858608E-004 - 613 6.55357523599375162E-009 9.66091696130146424E-005 - 1.98730033637173138E-006 - -0.13526545116507999 -0.21437035168319851 6.43177301699255102E-006 - 10.555014861362038 -6.6607977129777201 -5.31328128521848999E-005 - 614 6.55357523599375162E-009 7.19010453982795654E-005 - 1.98730033637173138E-006 - -5.74973994404181787E-002 -0.17970680569846711 -7.31836572849525707E-006 - 13.776904648265930 -4.4084726039654267 1.77690575503082081E-004 - 615 6.55357523599375162E-009 7.40371679059937516E-005 - 1.98730033637173138E-006 - -0.10810519007814892 0.16144184583119578 2.76284167137432091E-006 - -11.843573304245812 -7.9318719161805955 1.22201512968932771E-004 - 616 6.55357523599375162E-009 1.24535745772724933E-004 - 1.98730033637173138E-006 - -6.49072723440617394E-002 0.32027053948332596 9.54744875670700961E-006 - -10.772798088395295 -2.1833630978198726 7.22692934879777852E-005 - 617 6.55357523599375162E-009 7.34763618625716448E-005 - 1.98730033637173138E-006 - 0.19087076313357298 -2.72594304238005930E-002 -2.26883691301902368E-006 - 2.0223772923861256 14.166061465173012 -6.46889747164069539E-004 - 618 6.55357523599375162E-009 9.52567018464634311E-005 - 1.98730033637173138E-006 - -2.43004954071445317E-002 0.24877694328940136 8.65225461559208148E-006 - -12.508262649024127 -1.2208838949196483 2.36890274465185351E-004 - 619 6.55357523599375162E-009 1.07550465225954886E-004 - 1.98730033637173138E-006 - 0.25056344872051478 -0.12989717977819293 -1.08775455106979515E-005 - 5.4425521260463743 10.500451026966473 -6.67622309033443352E-004 - 620 6.55357523599375162E-009 1.08665358199300005E-004 - 1.98730033637173138E-006 - -0.26254347863498528 0.11130513919690621 1.05897813830540819E-005 - -4.5926325160885355 -10.832775068066697 2.81094193551498304E-004 - 621 6.55357523599375162E-009 5.23601442055918241E-005 - 1.98730033637173138E-006 - -4.42327092305771288E-002 -0.13007337875717423 5.45460348823047194E-006 - 16.049548616720010 -5.4584391902250573 -3.38819010214998792E-005 - 622 6.55357523599375162E-009 5.70214626018878147E-005 - 1.98730033637173138E-006 - -0.13455049234022934 -6.54662279915185635E-002 -1.37046918689891676E-006 - 7.1073917974564820 -14.605875944396717 1.14354226013391094E-003 - 623 6.55357523599375162E-009 9.62620031028209051E-005 - 1.98730033637173138E-006 - -0.11375851061309998 -0.22552636884725280 -6.58147815013810888E-007 - 11.162494320962738 -5.6306278985483766 5.86525668786759113E-004 - 624 6.55357523599375162E-009 1.21071450571877003E-004 - 1.98730033637173138E-006 - 0.25294089915550161 -0.19228813802752642 -1.04989937400322757E-005 - 6.7457216945808502 8.8735822228508550 -2.67760581183053639E-004 - 625 6.55357523599375162E-009 6.70596522053679557E-005 - 1.98730033637173138E-006 - 4.19202372575477877E-005 -0.17599081009984918 -1.88551303941381918E-006 - 14.976868172442941 2.72500201751046944E-003 2.23678896950119560E-004 - 626 6.55357523599375162E-009 3.94478961359234596E-005 - 1.98730033637173138E-006 - 6.06369311720142690E-002 -8.38888501937669062E-002 -1.77279897145826088E-006 - 15.827888521867669 11.441920492248732 -1.21965545111680043E-003 - 627 6.55357523599375162E-009 6.94568136225717618E-005 - 1.98730033637173138E-006 - -0.16226208554437757 8.30042210172927675E-002 8.11660892633282287E-007 - -6.7038899647459980 -13.102487082643210 -5.74304344007708586E-004 - 628 6.55357523599375162E-009 1.32252959201400945E-004 - 1.98730033637173138E-006 - 0.29877739317616603 -0.17649319666245028 9.14495042561195818E-006 - 5.4258620970654121 9.1838189387655174 1.27680031968448074E-003 - 629 6.55357523599375162E-009 1.30255953158704653E-004 - 1.98730033637173138E-006 - -1.90872724297708601E-002 -0.34127602701163362 -1.21592263728180669E-005 - 10.730483080592887 -0.59913577350257530 2.59871826246480691E-004 - 630 6.55357523599375162E-009 1.29707850609500001E-004 - 1.98730033637173138E-006 - -5.96477977544342397E-002 0.33513009871181226 1.14675147354811220E-005 - -10.602565924776329 -1.8863491482112500 1.75687130020902845E-004 - 631 6.55357523599375162E-009 1.29531492004511300E-004 - 1.98730033637173138E-006 - -0.14744459870533505 -0.30629226113400593 1.16346431201806375E-005 - 9.7106755290649893 -4.6726553570544986 3.11989720533278913E-004 - 632 6.55357523599375162E-009 6.70343795765261440E-005 - 1.98730033637173138E-006 - 0.10870846761785387 0.13831625105962816 3.41594025883088120E-006 - -11.777482975923288 9.2566595038075974 -2.75172927239997309E-004 - 633 6.55357523599375162E-009 4.48365793802805505E-005 - 1.98730033637173138E-006 - 2.12327244486210272E-002 0.11572089181504455 -6.76419492872046758E-007 - -18.017918159826834 3.3059927871689432 7.74228307852488904E-004 - 634 6.55357523599375162E-009 1.04217227359286151E-004 - 1.98730033637173138E-006 - 0.23598146433147610 0.13818216351876739 -5.89523580679830270E-006 - -6.0702190924295794 10.369763817296782 -3.10154593604114443E-005 - 635 6.55357523599375162E-009 1.12473144576832052E-004 - 1.98730033637173138E-006 - -0.12729673997582444 -0.26628756200891684 -4.25192404196625301E-006 - 10.434176869434193 -4.9887125101359402 -3.23616269745478585E-005 - 636 6.55357523599375162E-009 1.01352926260225992E-004 - 1.98730033637173138E-006 - -6.54230800909295640E-002 -0.25780365394997701 4.18108413673148974E-006 - 11.808710502562562 -2.9969618998282836 5.01945984868197012E-005 - 637 6.55357523599375162E-009 6.63605141550073420E-005 - 1.98730033637173138E-006 - -0.11258658552839554 0.13283885251572361 -1.96771022652366891E-005 - -11.486481496232198 -9.7361897550640695 -1.09510196471332292E-003 - 638 6.55357523599375162E-009 9.05730909593825787E-005 - 1.98730033637173138E-006 - -0.20098980902220417 0.12684146019831338 4.22633097073650530E-006 - -6.8808330394069293 -10.898351251272134 -7.10108103733956414E-004 - 639 6.55357523599375162E-009 6.11482386684985841E-005 - 1.98730033637173138E-006 - -0.14630326190554593 6.58766453844715494E-002 -6.42501249295334098E-007 - -6.4411041368689874 -14.303294592191492 1.92363053940065523E-004 - 640 6.55357523599375162E-009 6.07247671988526817E-005 - 1.98730033637173138E-006 - 0.15371838682875336 -4.19849652810063700E-002 1.98181457251905856E-006 - 4.1442054044130563 15.184990109284872 4.97330457113824478E-004 - 641 6.55357523599375162E-009 9.62174551845700667E-005 - 1.98730033637173138E-006 - 3.11224746881737235E-002 0.25059554904102083 2.00961527772262163E-006 - -12.407396652921822 1.5422763198816645 4.47314961818309222E-005 - 642 6.55357523599375162E-009 1.13107316410534980E-004 - 1.98730033637173138E-006 - 0.24130748819882691 -0.17278998440896609 2.01355822893894213E-005 - 6.7139738688398651 9.3782454450168480 -6.25719604132900990E-004 - 643 6.55357523599375162E-009 8.39725940806043328E-005 - 1.98730033637173138E-006 - -7.25131453791782732E-002 0.20809348636568581 4.84865524627911548E-006 - -12.639015372798035 -4.4048336602780305 -3.51011812141192869E-005 - 644 6.55357523599375162E-009 8.42803760891667938E-005 - 1.98730033637173138E-006 - 0.13912300683741749 0.17192474639270844 -1.97544909170322333E-006 - -10.387413682157861 8.4030101660661707 1.21156286589105098E-004 - 645 6.55357523599375162E-009 6.29675517019276273E-005 - 1.98730033637173138E-006 - 1.23165015115875923E-002 0.16476993752756441 3.34293337067642053E-006 - -15.414893011283892 1.1524529098026468 -1.14047799798578807E-004 - 646 6.55357523599375162E-009 1.02031550061600543E-004 - 1.98730033637173138E-006 - -9.69462805869596017E-002 0.24956924282442991 -4.76297805451755935E-006 - -11.318690726229471 -4.3986450060025248 3.49802282433319431E-004 - 647 6.55357523599375162E-009 4.93332163691198290E-005 - 1.98730033637173138E-006 - -8.94917257101554842E-002 9.35369688593277737E-002 6.77566979303897134E-006 - -12.617651490584507 -12.073969118207248 1.77442244324281225E-004 - 648 6.55357523599375162E-009 8.16782951725428339E-005 - 1.98730033637173138E-006 - -0.19033877036417046 9.85621500416666296E-002 -6.27787594096299687E-006 - -6.2402346956060866 -12.051574830912170 6.67735353006438563E-004 - 649 6.55357523599375162E-009 1.07923270254366957E-004 - 1.98730033637173138E-006 - 0.27744613729433565 5.67742930573756632E-002 -1.35390515349070252E-006 - -2.3659966145322526 11.567844955833159 -4.33627356874492862E-004 - 650 6.55357523599375162E-009 5.37731348456683042E-005 - 1.98730033637173138E-006 - -0.11415433928284738 8.29605685197231241E-002 4.19013587303952671E-008 - -9.8337037483533969 -13.529645428625393 1.01037599422192353E-003 - 651 6.55357523599375162E-009 6.27552615303243657E-005 - 1.98730033637173138E-006 - 4.09150207186579767E-002 0.15951393015712112 -2.06954238105409210E-006 - -14.998404211841763 3.8455710663459177 -3.33198460989431134E-004 - 652 6.55357523599375162E-009 7.86533896963651776E-005 - 1.98730033637173138E-006 - 0.18599158112462633 -8.94675203808064506E-002 7.53634432894985007E-006 - 5.9938067700699360 12.464587748015411 3.40458612488548566E-004 - 653 6.55357523599375162E-009 5.43372106573856173E-005 - 1.98730033637173138E-006 - -8.58204210319560984E-002 0.11387531980579020 -1.77157995670125544E-006 - -13.288622407707285 -10.013683442056486 -4.58288766999716453E-004 - 654 6.55357523599375162E-009 7.53560473658431421E-005 - 1.98730033637173138E-006 - -6.68246937828434473E-003 -0.19764170232375608 6.47820869420338157E-006 - 14.120978945873764 -0.47728782763170585 -6.91261741108771663E-004 - 655 6.55357523599375162E-009 5.15123950945796020E-005 - 1.98730033637173138E-006 - 0.10975669093365988 7.89084790658068219E-002 -9.13836636021217454E-006 - -9.9757822765373643 13.875739351624629 3.94437651951067166E-004 - 656 6.55357523599375162E-009 5.21556575425227275E-005 - 1.98730033637173138E-006 - -0.13526975340283703 2.07082215873961029E-002 -4.62929232574330941E-006 - -2.5729707876401307 -16.790349896408227 2.63104853429137371E-005 - 657 6.55357523599375162E-009 5.30766233167895995E-005 - 1.98730033637173138E-006 - -8.20071578123328926E-002 0.11257427917203272 2.85355372708658207E-006 - -13.607823019074738 -9.9143860431151207 -2.84189521688161433E-004 - 658 6.55357523599375162E-009 1.21933603644848001E-004 - 1.98730033637173138E-006 - -1.63022796538002113E-002 -0.31953577512831421 -2.40214283757984491E-005 - 11.094176010341787 -0.56529323702227252 1.27859596710242006E-004 - 659 6.55357523599375162E-009 1.09686702127035677E-004 - 1.98730033637173138E-006 - 0.26655028185481344 0.10871754895317719 1.10230343564261489E-005 - -4.4218136925367961 10.843208963911742 -8.62828972715623706E-004 - 660 6.55357523599375162E-009 1.02492996517022702E-004 - 1.98730033637173138E-006 - 0.25025290998125077 9.85398963043570969E-002 1.40750399719031931E-005 - -4.4380679951628839 11.273580390821447 -2.32537672183147278E-004 - 661 6.55357523599375162E-009 7.06577774418774748E-005 - 1.98730033637173138E-006 - 1.81734372292199561E-002 -0.18456306412291329 5.83627277434522951E-006 - 14.518702934450607 1.4286508942754770 -7.87552799693733011E-005 - 662 6.55357523599375162E-009 1.10936621843534601E-004 - 1.98730033637173138E-006 - 0.21179459558382510 0.19969936229711802 -5.51589204572793825E-006 - -7.9895716653297555 8.4734419730783905 -3.07815118047511998E-004 - 663 6.55357523599375162E-009 1.31933123495528188E-004 - 1.98730033637173138E-006 - -0.19436399921270853 0.28652873694477732 3.00487261629266005E-006 - -8.8364498424562257 -5.9947826485291715 -3.31557262040783993E-004 - 664 6.55357523599375162E-009 7.76715067196892344E-005 - 1.98730033637173138E-006 - -0.17977479954929323 -9.60481964776012109E-002 -7.19339115220221017E-006 - 6.5588397821845890 -12.274918768094023 4.07973666569499201E-004 - 665 6.55357523599375162E-009 5.40521781872278954E-005 - 1.98730033637173138E-006 - 0.12727546497827064 -6.26226824892349709E-002 4.61521728518957974E-006 - 7.3642432413737771 14.969301902558175 -4.78796737356517073E-006 - 666 6.55357523599375162E-009 1.05445555272542401E-004 - 1.98730033637173138E-006 - 0.19574393038142351 -0.19556744469550846 -6.63989108581143332E-006 - 8.4426344485546423 8.4501773174385182 7.08251967730703642E-004 - 667 6.55357523599375162E-009 1.22112089280671898E-004 - 1.98730033637173138E-006 - -0.16932515043891089 -0.27208800784791054 -1.43004197020276641E-005 - 9.4234521049043529 -5.8632385714228885 -7.58375200916550855E-005 - 668 6.55357523599375162E-009 8.72868717528170593E-005 - 1.98730033637173138E-006 - 6.94036722435632525E-002 -0.21831972459588597 -3.62573338280944760E-006 - 12.509307967702966 3.9784566718144125 1.03078546421621483E-004 - 669 6.55357523599375162E-009 1.17792103019809155E-004 - 1.98730033637173138E-006 - 0.21310652262826793 -0.22390139687083821 6.24965154226772281E-006 - 8.1867237812899898 7.7909478095242344 -5.78230615562954774E-004 - 670 6.55357523599375162E-009 4.07118604561647313E-005 - 1.98730033637173138E-006 - 6.94953110895130954E-002 -8.11220985858169402E-002 8.75518082112539840E-007 - 14.599932358010296 12.509347171967368 -1.31351830333795183E-003 - 671 6.55357523599375162E-009 1.25789702581971373E-004 - 1.98730033637173138E-006 - 0.13872165957170687 0.29954855171102290 4.99082140757497102E-006 - -9.9238851426186638 4.5939393824968437 -4.46544332538710814E-004 - 672 6.55357523599375162E-009 4.12829344057416198E-005 - 1.98730033637173138E-006 - -7.68829588262479602E-002 7.63610545153609321E-002 -2.45048578206638999E-007 - -13.449660629822423 -13.540603355406118 3.72271882357811410E-004 - 673 6.55357523599375162E-009 1.20900113621752331E-004 - 1.98730033637173138E-006 - -2.47358863760774733E-002 -0.31630961354853454 -3.61812114454773319E-006 - 11.120793857237121 -0.86890907828931807 -6.59439108800303402E-005 - 674 6.55357523599375162E-009 3.94282592680960357E-005 - 1.98730033637173138E-006 - 7.44491820201180904E-002 -7.18805606203265363E-002 -6.33016509444580846E-006 - 13.565207883180390 14.049963927710959 -8.61975751387779944E-005 - 675 6.55357523599375162E-009 1.33278907824126467E-004 - 1.98730033637173138E-006 - -0.19335406692787163 0.29140534043189964 -1.35442168310236572E-005 - -8.8535827183792488 -5.8746815552437708 -3.45819371675774498E-004 - 676 6.55357523599375162E-009 1.30925216862744204E-004 - 1.98730033637173138E-006 - 0.28370243873700218 0.19371859120516294 -5.92503664893788229E-006 - -6.0447595863899757 8.8541198574572419 -4.40566177217231649E-004 - 677 6.55357523599375162E-009 8.95130735491057655E-005 - 1.98730033637173138E-006 - -0.23488162280837063 4.41518834526047343E-003 -1.77911527248657092E-005 - -0.24328666082793937 -12.960487757326035 -1.81680279859536135E-004 - 678 6.55357523599375162E-009 8.70789934709799429E-005 - 1.98730033637173138E-006 - 0.22846684962313335 -3.12980775587771987E-003 2.13598621272672709E-006 - 0.18216890894103166 13.144117112270397 3.77334593142110951E-004 - 679 6.55357523599375162E-009 1.28727178364450274E-004 - 1.98730033637173138E-006 - 0.29646273594777295 0.16186733805761808 6.19842546940152557E-006 - -5.1813181020846155 9.4891702337232999 -1.54063848973364176E-004 - 680 6.55357523599375162E-009 1.20467592232586780E-004 - 1.98730033637173138E-006 - -0.18710599796727206 -0.25478617086739686 1.57085249246529792E-005 - 9.0084850867340762 -6.6140772639441270 -3.68637326650720959E-004 - 681 6.55357523599375162E-009 5.27091038165226119E-005 - 1.98730033637173138E-006 - -0.10486575347456140 -9.02134354127979710E-002 1.16482707977318515E-006 - 11.018176088800724 -12.805146130922608 -6.71618669735616811E-004 - 682 6.55357523599375162E-009 3.89562603052648489E-005 - 1.98730033637173138E-006 - -0.10162974261715510 1.10345639536098827E-002 7.05676826893100654E-006 - -2.1227827190206883 -19.536853677033740 4.01622306017473431E-004 - 683 6.55357523599375162E-009 5.69087579544002843E-005 - 1.98730033637173138E-006 - -0.12633037987802373 -7.96785433871995408E-002 -8.86143395300200345E-006 - 8.6721677866171110 -13.750714872378225 -3.63106462757480368E-004 - 684 6.55357523599375162E-009 1.20114787316016414E-004 - 1.98730033637173138E-006 - -9.02364186208849672E-002 -0.30204620419036754 -1.87487589393581359E-006 - 10.721626807992845 -3.2045529295194459 1.98172013436886003E-004 - 685 6.55357523599375162E-009 5.80977836847854987E-005 - 1.98730033637173138E-006 - -1.90721246251835744E-002 0.15125940105116698 6.77365626439554935E-007 - -15.965663392026345 -2.0132494186336460 -4.63729684427466218E-004 - 686 6.55357523599375162E-009 1.19948892048827761E-004 - 1.98730033637173138E-006 - 0.30736377378703283 6.77712414626398807E-002 -2.11433264961754265E-005 - -2.4117592273754260 10.937233209155252 9.51019271325081322E-005 - 687 6.55357523599375162E-009 8.03495277873919557E-005 - 1.98730033637173138E-006 - -0.17399192555680262 0.11910461861120225 -1.18509777963156833E-005 - -7.7305615705782085 -11.290343180026857 -6.83104894070562239E-005 - 688 6.55357523599375162E-009 6.63739897703023349E-005 - 1.98730033637173138E-006 - 9.32018208268688975E-002 -0.14716853792430465 1.12019086326560035E-005 - 12.718081898151564 8.0532769066274366 -1.31892449937604048E-003 - 689 6.55357523599375162E-009 1.31371833171208566E-004 - 1.98730033637173138E-006 - -0.11918604850431774 0.32346071877784593 2.27478961634020121E-005 - -10.041531399509070 -3.7013815104138588 -4.78422394678647452E-004 - 690 6.55357523599375162E-009 1.18532067801658367E-004 - 1.98730033637173138E-006 - 0.30208481967923428 7.41392310595228726E-002 -1.15491016922111051E-005 - -2.6849803931460254 10.941342839440122 -2.67893446073465551E-004 - 691 6.55357523599375162E-009 9.67523162097015281E-005 - 1.98730033637173138E-006 - -0.10725762306487277 0.23013466450271522 4.04444338642017686E-006 - -11.303066458631893 -5.2655800230613474 1.64086208623273849E-004 - 692 6.55357523599375162E-009 6.59590820277039888E-005 - 1.98730033637173138E-006 - 0.12135309169413640 0.12347134194117763 6.92444627177746355E-006 - -10.767376510735595 10.585723305562166 -8.89142378155659881E-004 - 693 6.55357523599375162E-009 5.23952100860322455E-005 - 1.98730033637173138E-006 - -1.67690851998209128E-002 0.13645145627384075 -2.19779557840246326E-006 - -16.820632619577331 -2.0657360518088828 4.19356280150589319E-004 - 694 6.55357523599375162E-009 5.15455077187043680E-005 - 1.98730033637173138E-006 - 8.21893759025813103E-002 -0.10743813697797612 7.21680936755832502E-006 - 13.568442032441649 10.379726892086250 7.30988789685518164E-004 - 695 6.55357523599375162E-009 1.31844384407623537E-004 - 1.98730033637173138E-006 - 0.29180352163312434 -0.18592504252727751 2.27371442947463338E-005 - 5.7394755035389080 9.0084963737103507 5.99071704071674834E-005 - 696 6.55357523599375162E-009 5.11933954954211715E-005 - 1.98730033637173138E-006 - 0.10619638885036758 8.22677426474749257E-002 -1.82135185296580404E-005 - -10.497781901953994 13.553531906744402 3.81763846224820276E-004 - 697 6.55357523599375162E-009 3.88958583234612758E-005 - 1.98730033637173138E-006 - 8.62138647171850486E-002 5.46485130661939489E-002 2.40996620967202994E-006 - -10.526097965240709 16.611663694500734 5.49446473069163796E-004 - 698 6.55357523599375162E-009 1.26476012593176109E-004 - 1.98730033637173138E-006 - 0.12686456792905515 0.30668227920032076 1.26274758225002530E-005 - -10.079101964092631 4.1675698990462919 4.85081649724920024E-004 - 699 6.55357523599375162E-009 7.77484480387031314E-005 - 1.98730033637173138E-006 - -0.12744394044408000 0.15934622363690013 1.80327597520638799E-005 - -10.863040588734560 -8.6870033905012711 1.80039252254145308E-004 - 700 6.55357523599375162E-009 1.30966110032384184E-004 - 1.98730033637173138E-006 - -0.11182489237168680 0.32497683256601101 1.79102710299601729E-005 - -10.134284599685383 -3.4883568994697027 4.43162521950305334E-004 - 701 6.55357523599375162E-009 8.96781827220695892E-005 - 1.98730033637173138E-006 - -0.10853529795171568 0.20880539642472887 7.27588143371429692E-006 - -11.492734718224851 -5.9733264948464466 4.96780009591682968E-004 - 702 6.55357523599375162E-009 6.59787455890721689E-005 - 1.98730033637173138E-006 - 5.90713814692140488E-003 0.17303496939501037 6.59379631048797042E-007 - -15.091809504146717 0.51658995242589789 4.57793252400507463E-004 - 703 6.55357523599375162E-009 8.16299997695579132E-005 - 1.98730033637173138E-006 - -0.19640069484520029 8.55021639006492973E-002 -3.55821234178952519E-006 - -5.4181908740775491 -12.448050129635504 -6.03315669361432702E-004 - 704 6.55357523599375162E-009 4.83968501713236357E-005 - 1.98730033637173138E-006 - 0.10618089813864956 -6.96782830261555575E-002 4.38491655758170111E-007 - 9.6738042126394941 14.740179266610220 -6.16878154758019074E-004 - 705 6.55357523599375162E-009 4.74320889127939459E-005 - 1.98730033637173138E-006 - 9.23003688550662754E-002 8.35225950863721783E-002 8.36126158911790571E-007 - -11.948669242325611 13.204335030968783 1.35839443352404584E-003 - 706 6.55357523599375162E-009 6.76039283332311927E-005 - 1.98730033637173138E-006 - 6.44048348551213845E-002 -0.16530206111339804 -1.69407637799465975E-006 - 13.899607797798593 5.4162437218190753 -4.90011104216963667E-004 - 707 6.55357523599375162E-009 9.87607942874371020E-005 - 1.98730033637173138E-006 - 0.18779113152998328 -0.17860809582560522 -1.09683160828293107E-005 - 8.5071458853554507 8.9421078497813085 2.33012486141511322E-004 - 708 6.55357523599375162E-009 8.33243037900500044E-005 - 1.98730033637173138E-006 - 0.14065463098074196 0.16738994512655431 -7.24665997953735197E-006 - -10.287177841560837 8.6461953228696729 4.99898693444516574E-004 - 709 6.55357523599375162E-009 1.12594191243174291E-004 - 1.98730033637173138E-006 - -8.25491297210754066E-002 -0.28372816542509266 1.43497742634615260E-006 - 11.097808889260500 -3.2297586234687570 -6.48453753707575742E-004 - 710 6.55357523599375162E-009 8.21126400230934588E-005 - 1.98730033637173138E-006 - -0.18106093812392701 -0.11683951786314339 2.94498254398276792E-006 - 7.3392254203760539 -11.372665922672518 4.15758515121321913E-004 - 711 6.55357523599375162E-009 9.47415095175376242E-005 - 1.98730033637173138E-006 - 0.10056003015444254 0.22735055372257773 -1.74225710820756686E-005 - -11.525537430149132 5.0973672855092191 9.82186109487202200E-004 - 712 6.55357523599375162E-009 4.17169409136306177E-005 - 1.98730033637173138E-006 - 7.57784760888167985E-002 -7.90137962962925156E-002 -1.97461725470971009E-006 - 13.704466345424752 13.144529740023374 -1.10324096856034880E-004 - 713 6.55357523599375162E-009 5.03359574994028156E-005 - 1.98730033637173138E-006 - -1.48225239375267548E-002 -0.13124945805949997 -9.10086781488344849E-006 - 17.179750312601882 -1.9405906482603790 8.36168766965602228E-004 - 714 6.55357523599375162E-009 9.02262737222645671E-005 - 1.98730033637173138E-006 - -0.22865082125964281 6.14707469270264276E-002 1.21266110514033770E-005 - -3.3510968056737500 -12.470402062438080 2.45642941200253494E-004 - 715 6.55357523599375162E-009 1.05098152272569231E-004 - 1.98730033637173138E-006 - -4.24784449225463281E-002 -0.27251726614799293 1.56387782133914281E-005 - 11.821262711937779 -1.8415933594112537 -6.62485905325277240E-005 - 716 6.55357523599375162E-009 1.22439015354615377E-004 - 1.98730033637173138E-006 - 0.17519580986792163 -0.26935315064086052 9.52017874165288261E-006 - 9.2917388328988011 6.0435293572342816 -1.40535974560370401E-004 - 717 6.55357523599375162E-009 1.00225554160558231E-004 - 1.98730033637173138E-006 - -0.25898248937613266 -4.59381909831268476E-002 8.80994113862277173E-006 - 2.1400986441699148 -12.062648255540518 5.65761937001810580E-004 - 718 6.55357523599375162E-009 1.03044885746955692E-004 - 1.98730033637173138E-006 - -0.21259895969963086 -0.16706940474088969 1.36985038016066051E-005 - 7.4673661056835918 -9.5003569112141459 -2.44857555860489978E-004 - 719 6.55357523599375162E-009 6.54571464578246619E-005 - 1.98730033637173138E-006 - -0.10937852630069896 0.13246578663851830 -6.83382522164181001E-006 - -11.688609451666482 -9.6524120341429587 1.44045000581486922E-003 - 720 6.55357523599375162E-009 1.12171329190363791E-004 - 1.98730033637173138E-006 - -0.29125661854582086 4.25486908059028585E-002 -1.99439662411003978E-005 - -1.6754172216561267 -11.459545337665570 -2.76840767457805787E-004 - 721 6.55357523599375162E-009 8.35526188172122371E-005 - 1.98730033637173138E-006 - 0.21803461534939100 -2.31084730026264867E-002 -3.22135187241664120E-007 - 1.4146136288518241 13.343892990065143 -4.97621990082576645E-004 - 722 6.55357523599375162E-009 9.35387525834354826E-005 - 1.98730033637173138E-006 - 9.34837269593963016E-002 0.22696550272062913 -4.43855714519911630E-006 - -11.726535873677511 4.8292858370825869 2.21698027451301856E-004 - 723 6.55357523599375162E-009 5.15716477998360559E-005 - 1.98730033637173138E-006 - 9.63612567487611010E-002 9.50223457331550447E-002 -6.81055024694208339E-007 - -11.992004233859284 12.162034369229204 4.35708325520919989E-004 - 724 6.55357523599375162E-009 1.11767236089492563E-004 - 1.98730033637173138E-006 - 0.26593339291401297 0.12373998955457946 -2.91540019823776485E-007 - -4.8935187642001354 10.518744592864072 -3.24112023790547430E-004 - 725 6.55357523599375162E-009 3.96074191190249223E-005 - 1.98730033637173138E-006 - 0.10394369238964352 -6.74349753372923376E-004 6.97309109284200292E-007 - 0.12647523528582216 19.487324388289451 -1.22724234515682724E-004 - 726 6.55357523599375162E-009 9.42029475219487503E-005 - 1.98730033637173138E-006 - 0.11715485589683484 0.21766055279417379 -5.30255055446232821E-006 - -11.128616256743522 5.9899408452410752 -4.87570158576534603E-004 - 727 6.55357523599375162E-009 4.64605663421063217E-005 - 1.98730033637173138E-006 - 1.77919749228229868E-002 0.12060858226539670 -3.50764125274355074E-006 - -17.803296688977490 2.6247150485236226 -7.83079928283531316E-004 - 728 6.55357523599375162E-009 6.79728573939190791E-005 - 1.98730033637173138E-006 - -0.13348259627438833 0.11832766078818184 -2.31985334946310773E-006 - -9.8682146871074945 -11.132497596697974 -4.15252771702083489E-004 - 729 6.55357523599375162E-009 5.59118716284885160E-005 - 1.98730033637173138E-006 - 0.14522323426396183 2.10790980677184048E-002 1.81487321460843585E-006 - -2.3539107499778629 16.231145356830059 6.83982263867757151E-004 - 730 6.55357523599375162E-009 1.29104502111154036E-004 - 1.98730033637173138E-006 - -0.31894267555666428 0.11434527419486207 1.78003401716235820E-005 - -3.6421568803071582 -10.160936774410699 1.78921430106797797E-004 - 731 6.55357523599375162E-009 7.71201142676344376E-005 - 1.98730033637173138E-006 - -3.51760524894170201E-002 -0.19932695721429838 4.71389858879392086E-006 - 13.752214793136591 -2.4281246373138741 3.12684633048005485E-004 - 732 6.55357523599375162E-009 1.32424524749675941E-004 - 1.98730033637173138E-006 - 0.27588800449106116 0.21133981420113460 -1.36465247113669746E-005 - -6.4806661242817922 8.4611241226479610 -2.92842495038472643E-004 - 733 6.55357523599375162E-009 5.90610594371078531E-005 - 1.98730033637173138E-006 - -9.76970280114787121E-002 -0.12030273323593574 -1.12317720262801847E-005 - 12.390836504731517 -10.061279473847721 -4.10059807615473411E-004 - 734 6.55357523599375162E-009 1.30707959412608286E-004 - 1.98730033637173138E-006 - 0.31546530064217254 -0.13477086363250623 -9.62493941730318539E-006 - 4.2148831409542931 9.8642141781344783 -2.13561541648315498E-004 - 735 6.55357523599375162E-009 1.27584947513258856E-004 - 1.98730033637173138E-006 - 0.19792012155541522 0.27004266572566221 -1.17581167395226218E-005 - -8.7584555666564228 6.4191388783605063 1.97057079131204458E-004 - 736 6.55357523599375162E-009 5.59490995293772419E-005 - 1.98730033637173138E-006 - -8.67551665643068182E-002 0.11844137827577882 4.39018977916963465E-006 - -13.229624369269480 -9.6896125045416301 6.19464768429523914E-005 - 737 6.55357523599375162E-009 7.07728528437027559E-005 - 1.98730033637173138E-006 - 5.57131262491891502E-002 -0.17717743361951457 -1.28507792973962840E-006 - 13.908170119839619 4.3718286736447158 -4.90657348293802899E-004 - 738 6.55357523599375162E-009 1.02583606484132978E-004 - 1.98730033637173138E-006 - 0.26404735298664284 -5.24577304550146450E-002 1.25793799436527176E-006 - 2.3618358640747137 11.877098959632951 -1.96390222647111016E-004 - 739 6.55357523599375162E-009 5.21691683088857034E-005 - 1.98730033637173138E-006 - 0.12964208338631211 -4.40151458974997953E-002 1.71214759882873615E-006 - 5.4582011623960751 16.079390843682400 6.16084531754850363E-004 - 740 6.55357523599375162E-009 9.23507133202837221E-005 - 1.98730033637173138E-006 - 8.41881456643949200E-002 -0.22723712283439032 7.84787950669297867E-006 - 11.969584463502267 4.4330776168714205 3.82656285306237935E-004 - 741 6.55357523599375162E-009 9.13553054408982365E-005 - 1.98730033637173138E-006 - -5.16145157340767574E-002 -0.23411975026045789 1.99914714212424415E-005 - 12.531283085177702 -2.7629954078785035 4.33378180651758740E-004 - 742 6.55357523599375162E-009 4.52395800478864028E-005 - 1.98730033637173138E-006 - -8.99977458818939369E-002 -7.74266018692908176E-002 9.64447269351921224E-006 - 11.892000058921710 -13.824255860297034 -3.46572206369685245E-004 - 743 6.55357523599375162E-009 4.78710925669347993E-005 - 1.98730033637173138E-006 - -6.26583065060237476E-002 -0.10889587659255703 -2.96746249323132233E-006 - 15.362132946976033 -8.8433720346800833 -9.09780195141289745E-004 - 744 6.55357523599375162E-009 7.42794135057248171E-005 - 1.98730033637173138E-006 - -0.11858759678522243 -0.15473692439836670 -6.77659844889475556E-006 - 11.294857797505305 -8.6545343523141121 8.08631749662702551E-004 - 745 6.55357523599375162E-009 1.31438756700185040E-004 - 1.98730033637173138E-006 - -0.15523322144633833 -0.30803482428458695 1.18417640946500913E-005 - 9.5539743765823069 -4.8132529251123755 2.60652691892281069E-005 - 746 6.55357523599375162E-009 7.15250470344405687E-005 - 1.98730033637173138E-006 - -0.18082707705982892 -5.03843253197075527E-002 -1.35443920569289998E-005 - 3.8903740374819740 -13.969809082603771 9.74562221038004629E-005 - 747 6.55357523599375162E-009 9.92382204775775343E-005 - 1.98730033637173138E-006 - -0.22175830495870788 0.13658627686961514 -1.27083853355837090E-005 - -6.4564192299422665 -10.482392614305143 -4.11625795887233116E-004 - 748 6.55357523599375162E-009 6.62158684487763275E-005 - 1.98730033637173138E-006 - -2.42624900037707383E-002 -0.17205782542899484 6.59829360116512227E-006 - 14.925909716920488 -2.1035213093521037 -1.59105002145683099E-003 - 749 6.55357523599375162E-009 5.25654432327180544E-005 - 1.98730033637173138E-006 - -3.74148156596989384E-002 0.13276682168323006 -9.58863516959398098E-006 - -16.283615945826401 -4.5890427526948585 5.44209861995763322E-004 - 750 6.55357523599375162E-009 7.01384692531094989E-005 - 1.98730033637173138E-006 - 0.17653541949780541 -5.20391340309890385E-002 4.13300255360525704E-007 - 4.1393165954175890 14.049376248865617 2.07053556888832856E-004 - 751 6.55357523599375162E-009 5.56371348751203931E-005 - 1.98730033637173138E-006 - 3.56447867395945500E-002 -0.14157454454463053 -1.04157572594988672E-005 - 15.947682158547160 4.0132525549496947 7.86315079975778816E-004 - 752 6.55357523599375162E-009 9.92596530122862459E-005 - 1.98730033637173138E-006 - 8.76568382839380267E-002 -0.24527344501977127 1.05100350479095575E-005 - 11.593004130433359 4.1446399604133504 -6.84771071548585341E-004 - 753 6.55357523599375162E-009 4.35356897838114928E-005 - 1.98730033637173138E-006 - 8.65632475478107094E-002 7.45573309591728295E-002 4.99815986785949625E-006 - -12.132324102159128 14.084439089335490 4.92085605211301392E-004 - 754 6.55357523599375162E-009 5.28340261157087058E-005 - 1.98730033637173138E-006 - -8.53908453679408375E-003 0.13837478879525394 -2.47800860644504330E-006 - -16.843324043460626 -1.0405017805995396 -3.10453999745851619E-005 - 755 6.55357523599375162E-009 3.92667992312176046E-005 - 1.98730033637173138E-006 - -8.23307041451119548E-002 6.19723538137869484E-002 -9.81711668693877356E-007 - -11.772196480273429 -15.636814135840950 1.50939951623895699E-003 - 756 6.55357523599375162E-009 6.35238434586154192E-005 - 1.98730033637173138E-006 - 3.75820370109051990E-002 -0.16241425663242431 9.45314353105145196E-006 - 14.992050811762308 3.4708005394817096 7.18602609166805041E-004 - 757 6.55357523599375162E-009 5.93569053151459140E-005 - 1.98730033637173138E-006 - 8.74885803895829317E-002 -0.12886688151631764 -1.92024320674393642E-006 - 13.171546393817893 8.9431113035172505 -1.08364250279622949E-004 - 758 6.55357523599375162E-009 1.14869259371350299E-004 - 1.98730033637173138E-006 - -0.23201968044386223 -0.19245041172974497 1.00471905865066651E-005 - 7.3063843022946937 -8.8078342331308495 -3.71052615080003990E-005 - 759 6.55357523599375162E-009 7.79858146173072100E-005 - 1.98730033637173138E-006 - -0.11928648251166379 0.16628681205662754 -2.52469026551708343E-006 - -11.285688847482277 -8.0961250668783986 1.25628507759851051E-003 - 760 6.55357523599375162E-009 9.98071063275202358E-005 - 1.98730033637173138E-006 - 0.15579887914435706 -0.21057323957334417 -1.06417199204825322E-005 - 9.8675176156264826 7.3027354703126646 -5.71539187993849577E-004 - 761 6.55357523599375162E-009 5.68809603240698152E-005 - 1.98730033637173138E-006 - 0.14006722094862473 -5.16055918644329342E-002 6.83593435411069361E-006 - 5.6222276756352612 15.259724973240116 7.48439113236334854E-004 - 762 6.55357523599375162E-009 1.12269541496424772E-004 - 1.98730033637173138E-006 - 0.22004426052990061 0.19593897126433005 1.48295432393643791E-005 - -7.6983032316182287 8.6439412967804152 -2.12073807541282556E-004 - 763 6.55357523599375162E-009 5.90886174855833907E-005 - 1.98730033637173138E-006 - -0.12415599421817111 -9.28413404822910765E-002 -4.97981599398804789E-006 - 9.5576562743476678 -12.781017827795333 -5.43585229116553170E-004 - 764 6.55357523599375162E-009 9.08544324126670010E-005 - 1.98730033637173138E-006 - 0.13071505339707326 0.19943010563691910 -2.17944433575476099E-005 - -10.761660564334676 7.0518827981843879 -2.38752801380877734E-004 - 765 6.55357523599375162E-009 1.03678299913369400E-004 - 1.98730033637173138E-006 - -0.13621497827717105 0.23548648466478922 1.82278638147949419E-005 - -10.428391403220834 -6.0317588454037896 -5.06790393924137685E-004 - 766 6.55357523599375162E-009 1.18179200093887878E-004 - 1.98730033637173138E-006 - -1.22405314899376970E-002 -0.30989205162703320 1.39180276540637004E-005 - 11.273673736973874 -0.44394134510442518 -6.12658550786400837E-004 - 767 6.55357523599375162E-009 4.70672792997971930E-005 - 1.98730033637173138E-006 - -0.12332762504431011 6.98393990601415410E-003 -3.96757306081893351E-006 - -1.0086947167124052 -17.848093591053189 1.23103797888948589E-003 - 768 6.55357523599375162E-009 5.88878523748628040E-005 - 1.98730033637173138E-006 - 1.47782875737069077E-002 0.15382683581709780 -8.51151238332750050E-006 - -15.910161024022280 1.5271776092091549 4.98712329412820160E-004 - 769 6.55357523599375162E-009 1.24040452194075138E-004 - 1.98730033637173138E-006 - 9.21457407395052525E-002 -0.31220124803616256 1.04885901428702644E-006 - 10.562031978695531 3.1178496638391375 3.47412738398736375E-004 - 770 6.55357523599375162E-009 1.31677262400975236E-004 - 1.98730033637173138E-006 - 0.13724423338363598 0.31711662090232667 -1.05660438981278341E-005 - -9.8099208959978004 4.2449224593207671 2.67003681700791985E-004 - 771 6.55357523599375162E-009 1.08493309804439243E-004 - 1.98730033637173138E-006 - 6.60383798167022973E-002 -0.27697903447826927 -2.28038202138162878E-005 - 11.453139642460199 2.7305521740609895 3.20949666372417051E-004 - 772 6.55357523599375162E-009 6.46960137737873054E-005 - 1.98730033637173138E-006 - -0.16157839694097148 -5.21046125841919186E-002 -3.97721448076117750E-006 - 4.6795379951388094 -14.513681932121255 -8.02563625145278486E-004 - 773 6.55357523599375162E-009 1.05715408740911235E-004 - 1.98730033637173138E-006 - 0.26432338020056373 -8.42972361598296055E-002 -2.17125771943883370E-006 - 3.6236819480894358 11.364622920664193 4.57515245534671940E-004 - 774 6.55357523599375162E-009 5.19991101495362559E-005 - 1.98730033637173138E-006 - -6.75678496981413773E-002 0.11854962446874361 -4.71474208024239554E-006 - -14.778017967499114 -8.4224750631033629 -1.52176957184655434E-003 - 775 6.55357523599375162E-009 4.25012559187156001E-005 - 1.98730033637173138E-006 - 9.37546357176083228E-002 -6.04270881920718900E-002 -8.66930041461914823E-006 - 10.190763927222154 15.813275095015591 -2.36610576605771105E-004 - 776 6.55357523599375162E-009 4.11668101362047759E-005 - 1.98730033637173138E-006 - -2.61100411016155290E-002 -0.10484784079104507 6.13404796684520991E-006 - 18.546643973072399 -4.6183645146148882 7.83475524919928544E-004 - 777 6.55357523599375162E-009 4.84510491501962361E-005 - 1.98730033637173138E-006 - -0.12115007768655689 -3.85411182059644947E-002 7.02430366474739940E-006 - 5.3424697547998807 -16.793453806343091 -1.57750149431860805E-004 - 778 6.55357523599375162E-009 1.10474569019338605E-004 - 1.98730033637173138E-006 - 0.28275574337555681 -6.42224933869999098E-002 -1.11587223497886648E-005 - 2.5842127342880814 11.377698515843047 -4.34711448269043053E-005 - 779 6.55357523599375162E-009 9.40819187146681255E-005 - 1.98730033637173138E-006 - -1.58655376054311209E-002 0.24638603977320811 8.20195935608731125E-006 - -12.618898283362036 -0.81204949950555960 -1.54830584702927439E-004 - 780 6.55357523599375162E-009 5.60751798797089887E-005 - 1.98730033637173138E-006 - -0.14689046979757378 -8.48115326437662471E-003 2.82321324148292534E-007 - 0.94419233370970257 -16.354105266540142 -6.28199995747237019E-004 - 781 6.55357523599375162E-009 6.26745071369467387E-005 - 1.98730033637173138E-006 - -2.23726232819139448E-002 -0.16293725609581744 -5.64539890295536149E-006 - 15.349373919098912 -2.1083837006786057 6.83112540709538004E-005 - 782 6.55357523599375162E-009 1.31353250130090889E-004 - 1.98730033637173138E-006 - -0.24608086344977084 -0.24136223603406892 3.56823874072850288E-006 - 7.4937392485280974 -7.6406894144789588 -4.86323634265685206E-004 - 783 6.55357523599375162E-009 8.97258935074675033E-005 - 1.98730033637173138E-006 - -0.14746735443826725 0.18350319367915138 -2.51456242606933843E-006 - -10.095404589617878 -8.1125309049697059 5.93551874669138329E-004 - 784 6.55357523599375162E-009 5.99935320222034254E-005 - 1.98730033637173138E-006 - -0.15059910166670221 -4.58929569299080659E-002 -2.74796578922966672E-006 - 4.6159640095901473 -15.147626374502451 6.61618357077187907E-004 - 785 6.55357523599375162E-009 7.80929431250277923E-005 - 1.98730033637173138E-006 - 1.79249270007584144E-002 -0.20413891311297644 -1.34277643805511579E-005 - 13.826893528142715 1.2141820086393482 -4.92434604563255504E-005 - 786 6.55357523599375162E-009 1.02621529250153840E-004 - 1.98730033637173138E-006 - -8.59540791208990296E-002 0.25522153356788568 1.08295309024056906E-005 - -11.474525052903948 -3.8633392269207016 5.74153621764238392E-004 - 787 6.55357523599375162E-009 4.07753758252359851E-005 - 1.98730033637173138E-006 - 4.18795790189803244E-002 -9.84703477172278879E-002 1.20088494575095351E-006 - 17.675716954610120 7.5164452929093075 2.73687368291336065E-004 - 788 6.55357523599375162E-009 3.91528131311387703E-005 - 1.98730033637173138E-006 - 8.99588789794497495E-002 -4.96337993539046757E-002 -6.88522601978699800E-006 - 9.4709447544657586 17.162642669424216 -9.66851883407237028E-004 - 789 6.55357523599375162E-009 7.64825239530053354E-005 - 1.98730033637173138E-006 - -0.19616207093580446 4.25467268704864121E-002 -1.39039409742674453E-005 - -2.9732204975639047 -13.704940355655928 -7.54573669667578687E-004 - 790 6.55357523599375162E-009 1.07078545784027734E-004 - 1.98730033637173138E-006 - -0.27677156099220246 4.86591203541394124E-002 9.44280284554642062E-006 - -2.0519951710016038 -11.673242953495699 -9.11336620989233672E-004 - 791 6.55357523599375162E-009 1.22066615792131459E-004 - 1.98730033637173138E-006 - 3.66469773240995778E-002 0.31820258167495286 2.05680323200542870E-005 - -11.029353060906340 1.2708040301002956 -1.66035547295292939E-004 - 792 6.55357523599375162E-009 1.23050666890432752E-004 - 1.98730033637173138E-006 - -0.23593857684971964 -0.22046925359670344 6.93499090111352911E-006 - 7.5496210317193988 -8.0783132890028941 -4.71290608991558268E-004 - 793 6.55357523599375162E-009 6.34826552423410845E-005 - 1.98730033637173138E-006 - 0.16480424696960999 2.45181314072947590E-002 9.98225945665263339E-006 - -2.2647465421674760 15.224142628654771 -7.92364452226385833E-004 - 794 6.55357523599375162E-009 6.05603803894202557E-005 - 1.98730033637173138E-006 - 0.14052284643258367 -7.42446716331903039E-002 -1.52797977851382516E-005 - 7.3622537731493871 13.935108896631258 7.61736913397642731E-004 - 795 6.55357523599375162E-009 1.12951655692386762E-004 - 1.98730033637173138E-006 - 2.11143913955172402E-003 -0.29638828614781060 -2.42654258513682362E-005 - 11.540993735953668 8.36501913927900631E-002 2.76133930591384029E-004 - 796 6.55357523599375162E-009 7.46915403659085880E-005 - 1.98730033637173138E-006 - -8.72545619677179835E-002 0.17551442037486845 2.51543182996581855E-006 - -12.707385337446048 -6.3195281775241448 8.13592375797774544E-004 - 797 6.55357523599375162E-009 3.90980546698242680E-005 - 1.98730033637173138E-006 - -3.86318585611905574E-003 -0.10253650512109955 4.09209663803478769E-006 - 19.600291809616742 -0.73948687472161900 -1.05091100691393022E-004 - 798 6.55357523599375162E-009 6.39347673997988188E-005 - 1.98730033637173138E-006 - -5.97381442375178109E-003 -0.16765437700705099 2.74694785439753126E-006 - 15.331429815562085 -0.54659976031628954 -2.66154170824352927E-004 - 799 6.55357523599375162E-009 4.20668456705032629E-005 - 1.98730033637173138E-006 - -9.57768705851378965E-002 5.48727607937216921E-002 7.67000333881875716E-007 - -9.4017764599332470 -16.410154534330410 -1.21318881323392635E-004 - 800 6.55357523599375162E-009 4.45124508423623205E-005 - 1.98730033637173138E-006 - -9.74892591310388690E-002 -6.43590739545987500E-002 -5.68934293800896797E-006 - 10.128117822375266 -15.341219557957640 2.49693695592930419E-004 - 801 6.55357523599375162E-009 9.36353111547584197E-005 - 1.98730033637173138E-006 - -0.13855539921788632 0.20293925900852758 -3.52264681473956367E-006 - -10.466397548839328 -7.1490685240585545 -4.91053419566282626E-004 - 802 6.55357523599375162E-009 6.88474574596306416E-005 - 1.98730033637173138E-006 - 4.14330990652268388E-002 0.17585138493800345 -7.30115594164212363E-006 - -14.388287281968594 3.3908863186186124 -1.87561635258096712E-004 - 803 6.55357523599375162E-009 9.03560907553482644E-005 - 1.98730033637173138E-006 - 0.19370003096878460 -0.13676302415013630 -2.25946181599100810E-005 - 7.4428255070733007 10.540305143488686 1.13411261271856864E-003 - 804 6.55357523599375162E-009 1.12554113278204857E-004 - 1.98730033637173138E-006 - 0.28543642831480553 -7.59554821760770327E-002 -1.46773020033173280E-005 - 2.9727278656220464 11.172266526543297 3.42811473930638381E-005 - 805 6.55357523599375162E-009 6.39329320233283037E-005 - 1.98730033637173138E-006 - -2.38290143409997102E-002 0.16606085671596535 -1.48308120151210118E-005 - -15.185209101821851 -2.1797302148402240 1.45018582322653652E-004 - 806 6.55357523599375162E-009 6.13287332789783698E-005 - 1.98730033637173138E-006 - 0.16094626303624515 -7.37708784313978461E-004 1.24165610390601746E-005 - 7.20447044427325878E-002 15.661101719091839 -4.25881209214695397E-004 - 807 6.55357523599375162E-009 6.58246148917877405E-005 - 1.98730033637173138E-006 - -1.74214698499818230E-002 -0.17184296294315904 -9.21002879171074858E-006 - 15.041925752239326 -1.5244241492216548 -3.58808795754755232E-004 - 808 6.55357523599375162E-009 7.03271844517566362E-005 - 1.98730033637173138E-006 - 9.31901992981564314E-002 -0.15928692090031796 -4.88054723708946049E-006 - 12.623636483051046 7.3877167017334413 -1.99288652167741950E-004 - 809 6.55357523599375162E-009 7.48388730086699028E-005 - 1.98730033637173138E-006 - -0.18996707740249785 4.98282365407541269E-002 3.41994971587029130E-006 - -3.5973661467357392 -13.714107125823073 -1.12001017295025465E-003 - 810 6.55357523599375162E-009 6.77126564399761527E-005 - 1.98730033637173138E-006 - -0.10852457740115209 0.14069420484319967 8.30375467482656749E-006 - -11.804367076778565 -9.1019688977754321 -8.88463202301675772E-004 - 811 6.55357523599375162E-009 9.27412797765998488E-005 - 1.98730033637173138E-006 - -0.21673588723297729 -0.11069224210055080 2.62397540960850153E-006 - 5.7949341628280990 -11.342035216912141 1.95202695050462774E-004 - 812 6.55357523599375162E-009 5.58320651903868514E-005 - 1.98730033637173138E-006 - -1.82235872985461317E-002 -0.14538645131857725 -2.24605625186662629E-006 - 16.286220621142874 -2.0437061240929877 1.23732337508402615E-003 - 813 6.55357523599375162E-009 1.00406245176160543E-004 - 1.98730033637173138E-006 - -0.23113551443764102 -0.12648274913692859 7.10779825161112883E-007 - 5.8764260865514810 -10.738132509671210 3.28562202024118317E-004 - 814 6.55357523599375162E-009 1.16185241531926119E-004 - 1.98730033637173138E-006 - -0.20375254481894328 0.22684220540793382 -7.72869567873995782E-006 - -8.4655463857942781 -7.6026955860086449 6.23408963082022326E-004 - 815 6.55357523599375162E-009 4.97636694360150083E-005 - 1.98730033637173138E-006 - 4.93528658034507253E-002 -0.12092756058257564 1.44693664199600561E-006 - 16.095805574213919 6.5680520654276853 -2.25194227097069146E-003 - 816 6.55357523599375162E-009 1.02096711179542034E-004 - 1.98730033637173138E-006 - -3.26446095402147529E-002 -0.26594639585076557 8.42357580025576965E-006 - 12.047497605582500 -1.4789215851032536 -7.33989140190695203E-004 - 817 6.55357523599375162E-009 7.94628950591649201E-005 - 1.98730033637173138E-006 - 0.11028894307449329 0.17698836031302254 2.26568126761451064E-006 - -11.676736069809843 7.2769317668540054 9.80668793335300688E-005 - 818 6.55357523599375162E-009 5.89688005947676606E-005 - 1.98730033637173138E-006 - -6.80882557831976182E-002 0.13894871199922168 -1.03263861814786199E-005 - -14.344336096276781 -7.0283607059470050 6.79602284419887561E-004 - 819 6.55357523599375162E-009 1.32511960606462409E-004 - 1.98730033637173138E-006 - -4.47059484878212787E-002 0.34486495070550888 -5.23876830502193672E-006 - -10.566328344088532 -1.3692077583883187 -1.42070348461467770E-004 - 820 6.55357523599375162E-009 1.05375440829392941E-004 - 1.98730033637173138E-006 - 9.13096790560027766E-002 0.26098509365811690 -5.92658782634365209E-006 - -11.279357576524726 3.9462641272419425 5.91260874090563412E-004 - 821 6.55357523599375162E-009 4.03089310734660214E-005 - 1.98730033637173138E-006 - 3.84322197563552875E-002 -9.85357219021915087E-002 9.86816194871284668E-007 - 18.000753785414336 7.0204812236979404 -1.45363503828055987E-004 - 822 6.55357523599375162E-009 9.94371245741351907E-005 - 1.98730033637173138E-006 - 0.26052042052325675 1.49410004079276425E-002 -1.75765580171611680E-006 - -0.70299367786450651 12.279744386800436 7.36346245481968032E-005 - 823 6.55357523599375162E-009 9.57650027376507793E-005 - 1.98730033637173138E-006 - 0.25106713791932045 1.17100795730504352E-002 1.48256897808339996E-005 - -0.58369198912046305 12.518447233127006 3.13719228592217051E-004 - 824 6.55357523599375162E-009 4.43167400308964329E-005 - 1.98730033637173138E-006 - -7.49305321478584280E-002 8.89247899824152921E-002 1.95591834742298871E-006 - -14.090117036481077 -11.874379926826981 3.97671481533463109E-004 - 825 6.55357523599375162E-009 7.48615804076210265E-005 - 1.98730033637173138E-006 - 0.14036052145489109 0.13746021044434042 -2.09761090563127148E-007 - -9.9183490021270977 10.127657764855128 -2.49658294462299475E-004 - 826 6.55357523599375162E-009 5.76286420666674500E-005 - 1.98730033637173138E-006 - -0.11747418199067716 -9.52280247135550706E-002 1.14281113615393321E-005 - 10.174776072642851 -12.551730350093244 1.74235934258954963E-004 - 827 6.55357523599375162E-009 6.53517989245991571E-005 - 1.98730033637173138E-006 - 0.13956696854263717 -9.96295104783416763E-002 3.64176520826406952E-007 - 8.8151298474315816 12.350801993668320 -1.10713868600536906E-005 - 828 6.55357523599375162E-009 1.01211572975289519E-004 - 1.98730033637173138E-006 - -1.71541299985033049E-003 -0.26559846076050569 -1.15217154532937927E-005 - 12.191356046966659 -7.77389832973900408E-002 -5.96708147235477764E-004 - 829 6.55357523599375162E-009 3.99393932425093275E-005 - 1.98730033637173138E-006 - 0.10472328476706284 4.27716970355018246E-003 1.39253521480007180E-006 - -0.79031728255448375 19.391684448244369 5.84185604336240750E-004 - 830 6.55357523599375162E-009 8.68055327178968470E-005 - 1.98730033637173138E-006 - -8.52491432545017525E-003 0.22762267041513856 7.23729343081956984E-006 - -13.156211064983331 -0.49190656630613194 -3.71883891651084337E-004 - 831 6.55357523599375162E-009 9.81105096336371246E-005 - 1.98730033637173138E-006 - 2.84453394799986797E-002 0.25586569486297606 1.71859672827317124E-006 - -12.308138438424516 1.3680661976232935 -3.00617960311463364E-004 - 832 6.55357523599375162E-009 4.58070822408010464E-005 - 1.98730033637173138E-006 - 3.89710590462905085E-002 -0.11371329219361884 -5.55863142859118590E-007 - 17.143804454642723 5.8753080812682157 -6.46383328107195758E-004 - 833 6.55357523599375162E-009 8.10365183950951894E-005 - 1.98730033637173138E-006 - -0.18528738313914772 -0.10432825791558914 5.11956007339996343E-006 - 6.6835621779465724 -11.874513957703307 -4.20062482100756469E-004 - 834 6.55357523599375162E-009 1.32588783118286905E-004 - 1.98730033637173138E-006 - -9.79938086990707613E-002 0.33391775361681914 9.22661760996588324E-006 - -10.219587452946948 -2.9975375901995664 -5.50550515214311012E-004 - 835 6.55357523599375162E-009 1.01548794986197082E-004 - 1.98730033637173138E-006 - -6.31791863155011651E-002 -0.25885621040150014 4.81609546326332443E-006 - 11.825684384090792 -2.8866613731676969 3.45178773892377151E-006 - 836 6.55357523599375162E-009 1.05291639447241365E-004 - 1.98730033637173138E-006 - -0.13628556875327724 0.24037559285224003 -1.58674569298064669E-005 - -10.396915235447825 -5.8964244660428271 -3.77566449401073561E-004 - 837 6.55357523599375162E-009 5.28184338561667874E-005 - 1.98730033637173138E-006 - 0.11560208765110395 -7.64841781866938270E-002 6.19596077474854235E-006 - 9.3124773204921993 14.073914683588624 2.40857165027978995E-004 - 838 6.55357523599375162E-009 1.16934022485147359E-004 - 1.98730033637173138E-006 - 0.27560367467625818 0.13495916257346957 7.75170438383788262E-006 - -4.9866857668516928 10.186999756767959 3.56557194132274839E-004 - 839 6.55357523599375162E-009 5.19529357713315436E-005 - 1.98730033637173138E-006 - -0.11149606886304751 -7.84269762616127963E-002 3.01101552535431128E-006 - 9.7933092743378189 -13.919114981924457 5.79437270211271790E-004 - 840 6.55357523599375162E-009 4.41821140818818585E-005 - 1.98730033637173138E-006 - -6.00575520528516191E-003 0.11579876415568172 1.32597096954690009E-006 - -18.426098912699338 -0.95537881413413528 -7.80044961021196244E-004 - 841 6.55357523599375162E-009 5.58022946623296437E-005 - 1.98730033637173138E-006 - 7.08251714146583555E-002 -0.12814616608009904 2.61158847907555443E-006 - 14.374124226040230 7.9408101524771340 -7.11319774326976966E-004 - 842 6.55357523599375162E-009 1.22494291819561147E-004 - 1.98730033637173138E-006 - 6.35833153614557001E-002 -0.31509181110222728 -3.03992683110076805E-006 - 10.863711857841201 2.1907844693918563 2.53578343468627472E-004 - 843 6.55357523599375162E-009 1.13083848718237699E-004 - 1.98730033637173138E-006 - -9.18030954932402693E-002 -0.28222477401452101 -1.07735293003354609E-005 - 10.966954690370477 -3.5690173529886744 4.43289814932518525E-004 - 844 6.55357523599375162E-009 4.34268587024963846E-005 - 1.98730033637173138E-006 - 7.72243784329097877E-002 8.37949362191610647E-002 -1.60918571483414602E-006 - -13.685969412951220 12.616189420367036 -9.76623477356108015E-004 - 845 6.55357523599375162E-009 1.17892073748880716E-004 - 1.98730033637173138E-006 - 9.94782028553637954E-002 -0.29291563782583990 -4.80769971828614697E-006 - 10.697331300120087 3.6328274343028326 5.86533219249890680E-004 - 846 6.55357523599375162E-009 8.40579761473715913E-005 - 1.98730033637173138E-006 - -0.13027366754131542 -0.17796958142901037 5.62030343066930188E-006 - 10.797343595695311 -7.9018690911753273 -1.02453356221105006E-003 - 847 6.55357523599375162E-009 6.90260246946231498E-005 - 1.98730033637173138E-006 - -0.18022068062766533 1.82790587611587757E-002 -1.18494931527205675E-006 - -1.4909600661304561 -14.687010453570929 -7.78034088091023339E-004 - 848 6.55357523599375162E-009 1.33287043015621555E-004 - 1.98730033637173138E-006 - 0.11894375144169508 -0.32888965320525931 -8.25517018176884535E-006 - 9.9916760089959755 3.6137199224958407 2.59996924468945009E-005 - 849 6.55357523599375162E-009 1.06345787498625960E-004 - 1.98730033637173138E-006 - 5.26737444769480520E-002 0.27403572642027418 -2.09314299270636086E-005 - -11.680925672638530 2.2452028418718553 -3.50179931886749078E-004 - 850 6.55357523599375162E-009 1.08087196258181104E-004 - 1.98730033637173138E-006 - 0.28241452318369092 2.60353365363771017E-002 1.24200901216276099E-006 - -1.0837009437101841 11.749061677925765 6.89892443426999547E-004 - 851 6.55357523599375162E-009 1.04510693358515636E-004 - 1.98730033637173138E-006 - 0.23932170545291792 0.13394591527733044 -3.42379502244594981E-006 - -5.8583052729612577 10.470404704080925 -8.34976031016025302E-006 - 852 6.55357523599375162E-009 8.43569763748038730E-005 - 1.98730033637173138E-006 - -0.21673047735182652 -4.51800375345491681E-002 -1.01549070744529009E-005 - 2.7248294764230354 -13.072181516162617 -4.48441795464752985E-004 - 853 6.55357523599375162E-009 9.81295064509078989E-005 - 1.98730033637173138E-006 - -0.19625705859307660 0.16671426502779027 -1.85394061507656885E-005 - -8.0166863510509874 -9.4363901175004106 3.42160528381057431E-004 - 854 6.55357523599375162E-009 1.18374992824948869E-004 - 1.98730033637173138E-006 - -0.23464308400921069 0.20359194190668206 -6.60920660962701266E-006 - -7.3876290222588858 -8.5145981732440532 -2.79120857611340068E-005 - 855 6.55357523599375162E-009 3.90639593779503483E-005 - 1.98730033637173138E-006 - -2.90441030201354644E-002 9.83110592783422027E-002 -2.13471549522632557E-006 - -18.820593757477738 -5.5588548647814298 1.68052276430203490E-003 - 856 6.55357523599375162E-009 5.94301522627355469E-005 - 1.98730033637173138E-006 - 7.22496315796669480E-002 -0.13819435549317571 -1.24185520120795643E-005 - 14.100482164241949 7.3733071157774939 -6.29395602485361989E-004 - 857 6.55357523599375162E-009 5.10908871511746933E-005 - 1.98730033637173138E-006 - -9.25214954370486842E-002 -9.70287472230962067E-002 5.22218961197088638E-006 - 12.417432163861852 -11.843844767769076 -1.07333700446337948E-003 - 858 6.55357523599375162E-009 1.10566375632515705E-004 - 1.98730033637173138E-006 - -0.18742012050230891 0.22150948046952545 -4.05925979639340413E-006 - -8.9048172028406878 -7.5337600003870424 1.40288683625894143E-004 - 859 6.55357523599375162E-009 8.36001938541086951E-005 - 1.98730033637173138E-006 - -0.19000131023924122 -0.10965832221461740 -1.47940671845046003E-005 - 6.7038216967693085 -11.620065930021612 -3.75419078754601573E-004 - 860 6.55357523599375162E-009 7.71719082599843498E-005 - 1.98730033637173138E-006 - -0.11707658899080578 0.16523245555772248 1.00473346043117031E-005 - -11.393181499592824 -8.0718498335841957 1.07211645725764160E-003 - 861 6.55357523599375162E-009 8.20541532590798764E-005 - 1.98730033637173138E-006 - 0.13734742232743050 0.16580839687343818 3.89788407371953640E-006 - -10.430000024318598 8.6367588194296303 -9.16659591410202068E-004 - 862 6.55357523599375162E-009 4.11752487452874137E-005 - 1.98730033637173138E-006 - -3.55853411166776046E-002 -0.10202051079053875 -5.83641741284171844E-007 - 18.049161319833509 -6.2943976866070352 -5.50243234426438937E-004 - 863 6.55357523599375162E-009 4.82507236735165251E-005 - 1.98730033637173138E-006 - -0.12280127347749620 3.08816557682733417E-002 1.63074005786219764E-006 - -4.3067974772498863 -17.123564514922528 5.51731847235070749E-005 - 864 6.55357523599375162E-009 1.07469853234173104E-004 - 1.98730033637173138E-006 - -8.59891274281556484E-002 0.26858703759041747 -1.14552631351627540E-006 - -11.268140897763287 -3.6082890542808288 -4.17555025175857597E-005 - 865 6.55357523599375162E-009 1.06412944696431769E-004 - 1.98730033637173138E-006 - 1.69210430167196502E-003 0.27927116243328920 1.53001508164882018E-006 - -11.888737222682931 7.12812547547461151E-002 4.35689170084249374E-004 - 866 6.55357523599375162E-009 4.94295985903362852E-005 - 1.98730033637173138E-006 - 0.10906130039137044 7.02666707877047242E-002 7.60692383138817711E-006 - -9.4478550205248339 14.662168682435111 -3.63212993137950098E-004 - 867 6.55357523599375162E-009 7.55859256386954962E-005 - 1.98730033637173138E-006 - 3.10944665089008115E-002 -0.19590391233211568 6.06515189302467900E-006 - 13.933196118757095 2.2117974892897774 -8.81913306490255278E-004 - 868 6.55357523599375162E-009 4.96935580842217733E-005 - 1.98730033637173138E-006 - -6.61349118614991960E-002 -0.11239798438556189 3.15819158952212718E-006 - 14.994470483998324 -8.8248460074354114 -1.20703576522021569E-004 - 869 6.55357523599375162E-009 8.32381351711130907E-005 - 1.98730033637173138E-006 - -0.17481577382587093 -0.13101106636024706 -8.24754516944051989E-006 - 8.0615733763175719 -10.756595993803582 -3.81685971296471952E-004 - 870 6.55357523599375162E-009 6.10402766344015686E-005 - 1.98730033637173138E-006 - -0.15384019252734532 -4.45772805650338222E-002 9.48338578852104663E-006 - 4.3702429704487269 -15.079937775575328 -4.75323081242892123E-004 - 871 6.55357523599375162E-009 4.90438960756250418E-005 - 1.98730033637173138E-006 - 6.19000034730102233E-005 0.12870186692501925 -4.04746290987352880E-006 - -17.514103278334478 8.19738164691319326E-003 -5.89455972757356125E-004 - 872 6.55357523599375162E-009 8.58247780306530027E-005 - 1.98730033637173138E-006 - 0.11039160169741957 -0.19628338995636363 7.96732308464173950E-006 - 11.540384617961823 6.4920742025357630 -3.15194996109159544E-004 - 873 6.55357523599375162E-009 4.82693269736304508E-005 - 1.98730033637173138E-006 - 9.04096027126276430E-002 -8.87139958889233415E-002 -7.68716888555787873E-007 - 12.365229623344332 12.601079666376574 -1.61894503681409588E-004 - 874 6.55357523599375162E-009 5.20150465765021588E-005 - 1.98730033637173138E-006 - -1.69347853043078089E-003 -0.13648675450092129 -1.47898606187177975E-005 - 17.005424320929286 -0.21108696425153628 6.55155742602985870E-004 - 875 6.55357523599375162E-009 9.77737027077976045E-005 - 1.98730033637173138E-006 - 0.20244742864242318 -0.15771624359681960 1.58963810106429627E-005 - 7.6221432547144836 9.7829476145843870 3.58354396776944652E-005 - 876 6.55357523599375162E-009 1.27259606700723496E-004 - 1.98730033637173138E-006 - -0.19106249649856225 -0.27394093710976658 4.98877109249527388E-006 - 8.9164587638606800 -6.2200169079979286 -2.90937774498699342E-004 - 877 6.55357523599375162E-009 4.73270705817985669E-005 - 1.98730033637173138E-006 - -8.27746883085199447E-004 0.12417625844000385 -4.09657599723178119E-006 - -17.831076754823126 -0.11724881718111035 -1.34202428012658939E-004 - 878 6.55357523599375162E-009 9.97948446678168649E-005 - 1.98730033637173138E-006 - 4.82396320701372894E-002 -0.25739825435765745 -4.67156356394041785E-006 - 12.068254368565508 2.2605489342875540 -6.48396222378804638E-005 - 879 6.55357523599375162E-009 6.74756213176393329E-005 - 1.98730033637173138E-006 - -0.11304660563836716 0.13631247291943294 -2.26351771507385323E-006 - -11.494303307402015 -9.5282518847160986 1.96927908724033908E-004 - 880 6.55357523599375162E-009 6.90969557730942719E-005 - 1.98730033637173138E-006 - 0.14527695092087092 -0.10849117708313002 -1.00544328840798702E-005 - 8.8293428289620817 11.823101977582615 2.12596455007615307E-004 - 881 6.55357523599375162E-009 3.81732915454352566E-005 - 1.98730033637173138E-006 - 7.07361995531853444E-002 7.09143270814841103E-002 2.61609742199501267E-006 - -14.058357454163215 14.019969263862317 3.31154354947880124E-004 - 882 6.55357523599375162E-009 7.04628458721812627E-005 - 1.98730033637173138E-006 - -8.45871895596976564E-002 -0.16442651624566557 -1.13977848919349269E-006 - 12.993407615814078 -6.6840431650632475 7.36434498384899326E-004 - 883 6.55357523599375162E-009 1.10125654672351547E-004 - 1.98730033637173138E-006 - 0.14544277382211010 -0.24971371024144062 5.24374591715540672E-006 - 10.100070530232093 5.8827363985020416 -2.07297796849876452E-004 - 884 6.55357523599375162E-009 1.18638950768989402E-004 - 1.98730033637173138E-006 - 0.26711879100099517 0.15992910520343140 9.51307638238091295E-006 - -5.7837155101664148 9.6618851566153801 -8.52882310962473230E-004 - 885 6.55357523599375162E-009 4.80232406864356502E-005 - 1.98730033637173138E-006 - -0.11706666353633353 -4.66794846928087481E-002 -4.47063496265879724E-006 - 6.5557693519173910 -16.439350840744655 -6.28513361047404570E-004 - 886 6.55357523599375162E-009 4.10173051166502179E-005 - 1.98730033637173138E-006 - 1.29348723775361066E-002 0.10687364102649675 -2.93893566005936103E-006 - -19.009565745472514 2.3027934353363548 -7.52356318151900039E-005 - 887 6.55357523599375162E-009 8.48939106365537144E-005 - 1.98730033637173138E-006 - -0.11539700311131207 0.19060873541766951 1.32571205371066804E-005 - -11.385607169677394 -6.8931182817699757 3.20699817303920153E-004 - 888 6.55357523599375162E-009 4.20671540682148262E-005 - 1.98730033637173138E-006 - -9.52017595819305285E-002 -5.59065450360252403E-002 3.22333265635186850E-006 - 9.5739916946620305 -16.306143222441762 -2.47795812919592300E-004 - 889 6.55357523599375162E-009 1.17877754444647756E-004 - 1.98730033637173138E-006 - -0.12764807936717354 0.28178519618275255 1.82260135424319680E-005 - -10.289837516165420 -4.6617751297055818 3.07825287188949882E-004 - 890 6.55357523599375162E-009 6.43841729235426985E-005 - 1.98730033637173138E-006 - 0.12984127845293708 -0.10810872202334917 -6.85664533940686122E-006 - 9.7807585910229378 11.747348173976293 2.75703004689298510E-004 - 891 6.55357523599375162E-009 7.75496337493583159E-005 - 1.98730033637173138E-006 - -0.20317078124142252 -1.16012861275515203E-002 3.25776129500424984E-006 - 0.79389868896709848 -13.905784899036913 1.03324800083268208E-004 - 892 6.55357523599375162E-009 5.91383711293902155E-005 - 1.98730033637173138E-006 - -0.10373701251149137 0.11544035712292916 -7.71504976864605399E-006 - -11.862828344710286 -10.659434938790687 -1.24549508770985305E-004 - 893 6.55357523599375162E-009 5.55841843435973549E-005 - 1.98730033637173138E-006 - 0.14568004492595910 -7.43466517472889804E-003 -4.26218326709495155E-006 - 0.83950262447352397 16.429520251630972 -4.68325832726755511E-004 - 894 6.55357523599375162E-009 8.33161611160265937E-005 - 1.98730033637173138E-006 - -0.14950096866341131 0.15954561498867562 -1.02682852303301578E-005 - -9.8058617833458559 -9.1870425271996030 -7.80425871551127231E-004 - 895 6.55357523599375162E-009 1.00211814883061819E-004 - 1.98730033637173138E-006 - 8.56039862532241430E-002 0.24863302077266075 8.84880169408168224E-006 - -11.586297703471267 3.9877797546803295 -3.21233572501242680E-004 - 896 6.55357523599375162E-009 1.21580193501823734E-004 - 1.98730033637173138E-006 - -5.74085085691806926E-002 -0.31382277434476730 -1.20089199647576018E-006 - 10.942863062715807 -2.0019265404148472 6.29240085185397025E-004 - 897 6.55357523599375162E-009 1.04948541700357705E-004 - 1.98730033637173138E-006 - -4.43388842670265973E-002 -0.27182574869401643 2.08953706110958275E-005 - 11.816270694723858 -1.9263027352683242 -1.75496465553304378E-004 - 898 6.55357523599375162E-009 8.22965416541573036E-005 - 1.98730033637173138E-006 - 0.21137427524707642 -4.41782453799997588E-002 5.80221303557459334E-006 - 2.7645642755699411 13.236179092168181 5.58792660595121152E-004 - 899 6.55357523599375162E-009 9.30318631826147926E-005 - 1.98730033637173138E-006 - -0.23660884708570015 6.01997874147034498E-002 2.75644104944868576E-006 - -3.1354969723486246 -12.323192525388981 3.42540618026375367E-004 - 900 6.55357523599375162E-009 1.07115617973448801E-004 - 1.98730033637173138E-006 - -0.22559238891461722 -0.16774768359305103 7.86980820971971886E-006 - 7.0717952602112124 -9.5081628569650380 2.03918261528810498E-004 - 901 6.55357523599375162E-009 1.18773785428993704E-004 - 1.98730033637173138E-006 - -4.83610691220768413E-003 -0.31161479590667601 -2.47642194084993396E-005 - 11.254289513608931 -0.17452604823217266 1.11853621523260653E-003 - 902 6.55357523599375162E-009 8.86077418601062783E-005 - 1.98730033637173138E-006 - 0.18333316406875597 -0.14302606457116063 5.85794816187414559E-006 - 8.0146872308785522 10.273681138483992 4.63634469876167692E-004 - 903 6.55357523599375162E-009 4.22986394197000026E-005 - 1.98730033637173138E-006 - -8.10682799605549759E-002 -7.58441383783221290E-002 4.09347554027628570E-006 - 12.882300134947963 -13.770013714856058 1.13788236754568806E-004 - 904 6.55357523599375162E-009 7.28225413311593027E-005 - 1.98730033637173138E-006 - -0.11698824035009932 0.15108620163884645 8.40479053501138969E-007 - -11.365033158932839 -8.8009983057375258 1.06569214992967049E-004 - 905 6.55357523599375162E-009 3.86864450283502597E-005 - 1.98730033637173138E-006 - 9.34628454867928449E-002 -3.96074951340555856E-002 -6.62366323947340201E-007 - 7.6953439160212422 18.158947478644418 -2.33108933284375907E-004 - 906 6.55357523599375162E-009 6.05822691692274178E-005 - 1.98730033637173138E-006 - 6.29863435933988719E-002 0.14596648581998095 -1.68533666063062829E-006 - -14.468488366345760 6.2449649316695401 5.61032238332985771E-004 - 907 6.55357523599375162E-009 1.30102844826040690E-004 - 1.98730033637173138E-006 - -0.31164706353446636 0.13937043460763834 -1.34922815947698872E-005 - -4.3888702067548611 -9.8176894315313330 -1.05621311506098577E-003 - 908 6.55357523599375162E-009 1.27864656855282779E-004 - 1.98730033637173138E-006 - -0.18604965996018036 -0.27921549647738514 3.50473877444152178E-006 - 9.0272857815474676 -6.0148372375803936 9.10802897939152882E-004 - 909 6.55357523599375162E-009 5.35766670207625406E-005 - 1.98730033637173138E-006 - -6.13841312247305482E-002 0.12649819030334231 -3.53232052052511336E-006 - -15.075209892773536 -7.3141845815128548 4.43795173836230867E-004 - 910 6.55357523599375162E-009 9.59629108052578614E-005 - 1.98730033637173138E-006 - -2.43002550480786728E-002 0.25061639958505721 1.73310982875466067E-007 - -12.463918827176308 -1.2097130632847533 -2.91408080021267552E-004 - 911 6.55357523599375162E-009 8.19972278088466780E-005 - 1.98730033637173138E-006 - -0.16878778661632057 0.13349270140021607 4.38428041843229386E-006 - -8.4002498243110733 -10.624196384992585 -3.76239634633833767E-005 - 912 6.55357523599375162E-009 6.57179489145057227E-005 - 1.98730033637173138E-006 - -0.16160317985470110 6.02360362318243511E-002 -4.52636667133041939E-006 - -5.2829446324158811 -14.177112510386106 2.25659345661206434E-004 - 913 6.55357523599375162E-009 3.81976731903379540E-005 - 1.98730033637173138E-006 - -4.07688119114233555E-002 9.15847499354634914E-002 -9.67213275346803464E-007 - -18.129119483978599 -8.0684820614249180 6.71088506405082713E-004 - 914 6.55357523599375162E-009 1.15333238525283226E-004 - 1.98730033637173138E-006 - -0.24941117872624469 0.17146639733786009 1.20566791208044032E-005 - -6.4704206390833781 -9.4109969092668919 -9.40441555005364343E-006 - 915 6.55357523599375162E-009 7.12123069671599380E-005 - 1.98730033637173138E-006 - -0.13280009175430896 -0.13146915161629300 -9.93537497207747899E-006 - 10.226365906931973 -10.329241938919083 3.86980389263714183E-004 - 916 6.55357523599375162E-009 1.03901534931907547E-004 - 1.98730033637173138E-006 - 0.25277452483603635 0.10223014930992452 -6.28737745229381126E-006 - -4.5126493118654274 11.154441933835377 -9.93426761119415105E-005 - 917 6.55357523599375162E-009 3.88832265283112189E-005 - 1.98730033637173138E-006 - -0.10032401029614288 1.86717005071733166E-002 6.22235511488294073E-006 - -3.5980038621091328 -19.336193801106681 2.38414578987070471E-004 - 918 6.55357523599375162E-009 8.97885941393504992E-005 - 1.98730033637173138E-006 - -0.23526472935891329 -1.32060554721297602E-002 -9.81152935494353410E-006 - 0.72615887945186586 -12.923092694781200 -2.14190510840598400E-005 - 919 6.55357523599375162E-009 7.33110129646498648E-005 - 1.98730033637173138E-006 - -2.44240321468525146E-002 -0.19081065785695733 4.89745834976106981E-006 - 14.210221901960795 -1.8198415988409584 3.28013983740690028E-004 - 920 6.55357523599375162E-009 9.47758459042645897E-005 - 1.98730033637173138E-006 - 0.11873734643728523 -0.21854001982758151 -8.98998788580839247E-006 - 11.069950059212823 6.0155404866619913 1.81941958440154172E-004 - 921 6.55357523599375162E-009 9.75257702617087711E-005 - 1.98730033637173138E-006 - -0.25585108115787525 -4.53018715462341365E-003 -2.01711230729614160E-005 - 0.21988592350000563 -12.419859419223249 -2.58490790702125954E-004 - 922 6.55357523599375162E-009 1.25921485067963961E-004 - 1.98730033637173138E-006 - -0.11711484158779106 0.30905843817789480 -1.51612075356223995E-005 - -10.218905580684154 -3.8732560740643618 4.25634137349545621E-004 - 923 6.55357523599375162E-009 1.00519715151516339E-004 - 1.98730033637173138E-006 - -0.24341954558065376 -0.10169548324809607 2.98235197619632941E-006 - 4.7136507278028628 -11.287898744305000 1.53270505235153954E-004 - 924 6.55357523599375162E-009 7.39780521821522511E-005 - 1.98730033637173138E-006 - -0.16611299673737803 0.10051225612510374 1.04828561680440104E-005 - -7.3814322399003442 -12.199494182164420 -3.58137706047446979E-004 - 925 6.55357523599375162E-009 9.18518588577160104E-005 - 1.98730033637173138E-006 - -0.21846404233889052 -0.10179313002950519 8.43879366922823833E-006 - 5.4059926609970139 -11.601397151671506 -8.58352204650230218E-005 - 926 6.55357523599375162E-009 5.44384037458136335E-005 - 1.98730033637173138E-006 - -0.12643959355219905 -6.64967262524296110E-002 -2.04278056272829688E-006 - 7.7386827274889924 -14.712447242607007 1.86381413123350040E-004 - 927 6.55357523599375162E-009 6.91131547178331366E-005 - 1.98730033637173138E-006 - 6.43820140363925292E-002 0.16957158514963588 5.00870002257569301E-006 - -13.792191208527720 5.2356217204479627 -8.00688085155969219E-004 - 928 6.55357523599375162E-009 1.13111158297905337E-004 - 1.98730033637173138E-006 - 0.27286576799247980 0.11694901492984840 4.73085877060521863E-006 - -4.5412411147938698 10.599031014184149 -7.59734905683347465E-005 - 929 6.55357523599375162E-009 4.78908120710137906E-005 - 1.98730033637173138E-006 - -2.13988261564133607E-002 0.12385559457150803 1.28026632327700604E-005 - -17.462979750615759 -3.0167341298750014 -8.35961032648206486E-004 - 930 6.55357523599375162E-009 1.04789678074620733E-004 - 1.98730033637173138E-006 - 0.18943602271259505 -0.19932758093765438 -4.53210338651902154E-006 - 8.6849517005904247 8.2546588355552011 -1.37604581937478179E-004 - 931 6.55357523599375162E-009 1.08907817289973728E-004 - 1.98730033637173138E-006 - 0.26586799540978268 -0.10475762532279316 1.24005195039525396E-005 - 4.3091712949461964 10.936181255367863 2.17868954415081169E-004 - 932 6.55357523599375162E-009 5.47332607090621871E-005 - 1.98730033637173138E-006 - -6.95985516282402045E-002 -0.12564827255265898 -3.81560933185991210E-007 - 14.503300069976349 -8.0309294825343187 -9.12885387938532967E-004 - 933 6.55357523599375162E-009 8.12136842406449344E-005 - 1.98730033637173138E-006 - -0.13896762786980593 0.16163918713783243 -8.43069361838150698E-007 - -10.318807472345691 -8.8705833704342130 -5.36760311298673529E-004 - 934 6.55357523599375162E-009 4.77747840461161853E-005 - 1.98730033637173138E-006 - 1.97679551491739512E-002 -0.12380649758086507 -1.94951744801998607E-006 - 17.522966955166019 2.7967103911581930 -1.05872740870922768E-003 - 935 6.55357523599375162E-009 5.05257242446646829E-005 - 1.98730033637173138E-006 - 0.13108292263917531 1.99650923894523907E-002 1.68301357970473612E-006 - -2.5985048400591735 17.058045993726410 -1.14906743872001424E-003 - 936 6.55357523599375162E-009 4.85267878681891761E-005 - 1.98730033637173138E-006 - -9.16004363628827173E-002 -8.84522099161465652E-002 6.21192011590519277E-006 - 12.232791304261852 -12.665507371330992 -4.50944621100303348E-005 - 937 6.55357523599375162E-009 1.10825892502115029E-004 - 1.98730033637173138E-006 - -0.27629976001027523 9.07877724477392928E-002 5.62025027184037011E-006 - -3.6372024627880948 -11.068542951434079 -2.06631439780607175E-004 - 938 6.55357523599375162E-009 5.66248047826922276E-005 - 1.98730033637173138E-006 - 5.09396235485151255E-002 -0.13959349845846153 5.77234543718324050E-006 - 15.312083149631938 5.5867358008466113 6.65207627573589574E-004 - 939 6.55357523599375162E-009 7.01805067265082834E-005 - 1.98730033637173138E-006 - -9.58340151471347712E-002 -0.15726791686717861 -1.96284870947606984E-006 - 12.502808182635178 -7.6187572711767046 9.32230350208392922E-004 - 940 6.55357523599375162E-009 1.28038034839916294E-004 - 1.98730033637173138E-006 - -0.32183590731591832 -9.64560743657149888E-002 -4.37884449429291431E-006 - 3.1118180345660287 -10.383954739349438 3.84162896331776988E-004 - 941 6.55357523599375162E-009 1.00844303638183118E-004 - 1.98730033637173138E-006 - 0.26404224095335671 -1.74316479079601391E-002 5.50502149748340019E-006 - 0.80442279259076988 12.188337089406419 6.79936761405503984E-004 - 942 6.55357523599375162E-009 1.13716431829727189E-004 - 1.98730033637173138E-006 - 0.26960568867207296 -0.12795706897820433 -1.12763849923535934E-006 - 4.9313940747952740 10.390532028843742 -9.47180610263287625E-005 - 943 6.55357523599375162E-009 1.07102677294571683E-004 - 1.98730033637173138E-006 - -0.22842528475896265 0.16373636558874943 -1.54234464217357270E-006 - -6.9051328403032342 -9.6330136734137639 7.10778048985783221E-004 - 944 6.55357523599375162E-009 8.21656636343367168E-005 - 1.98730033637173138E-006 - -4.21892757134815846E-002 -0.21146254632541908 -2.86478092830819499E-006 - 13.269311255043196 -2.6460827297940046 3.02273407931340330E-004 - 945 6.55357523599375162E-009 8.94751288677360281E-005 - 1.98730033637173138E-006 - 4.30483512355538736E-002 -0.23080136951095584 1.44174889556827554E-005 - 12.747936521300456 2.3779733902771354 6.20774180873625691E-004 - 946 6.55357523599375162E-009 9.80975069611496613E-005 - 1.98730033637173138E-006 - 0.18251311062235959 0.18160822969773988 4.34639685115532225E-006 - -8.7319031493966399 8.7782662603632229 -4.08618987357800686E-004 - 947 6.55357523599375162E-009 8.83998100244924329E-005 - 1.98730033637173138E-006 - 0.17437810681845636 0.15296657438807776 2.21941147710432556E-006 - -8.6043081083004012 9.8067759838224724 3.84680061590651995E-004 - 948 6.55357523599375162E-009 4.47692687132138619E-005 - 1.98730033637173138E-006 - 0.11056628085434672 -3.97287881262535364E-002 -8.06213204396203773E-006 - 6.1995364611167645 17.250524492911271 7.91678401481359963E-004 - 949 6.55357523599375162E-009 8.32718796289551473E-005 - 1.98730033637173138E-006 - 0.18292148662293192 -0.11958324229967464 -2.51933619462485473E-005 - 7.3544368550664547 11.249119935722860 3.44016891202103753E-004 - 950 6.55357523599375162E-009 6.00246789617894872E-005 - 1.98730033637173138E-006 - 0.13552314119545805 8.02619576507899862E-002 1.57683510118848923E-006 - -8.0685947249381655 13.622064889403759 4.66914671799104812E-004 - 951 6.55357523599375162E-009 5.29934681151245432E-005 - 1.98730033637173138E-006 - 0.13694941022842810 -2.42323872365114573E-002 -9.85228846558231786E-006 - 2.9356767362807159 16.589815141329215 -3.37517597753462519E-004 - 952 6.55357523599375162E-009 1.14598785754140996E-004 - 1.98730033637173138E-006 - 0.25779964098920016 0.15481853937293261 6.41605421179315095E-006 - -5.8989149213552228 9.8230640324894161 6.45377960822854477E-004 - 953 6.55357523599375162E-009 9.36109381552002333E-005 - 1.98730033637173138E-006 - -0.17472399961278820 0.17267047140088931 -1.67439663616542160E-006 - -8.9119122173881777 -9.0162519110129100 5.29621885394950434E-006 - 954 6.55357523599375162E-009 1.28828377869208329E-004 - 1.98730033637173138E-006 - -0.33356855716616518 5.51648370799515675E-002 -1.57582711567037467E-005 - -1.7645427080918750 -10.660375230878232 -9.21028523079221761E-005 - 955 6.55357523599375162E-009 8.93396288294583731E-005 - 1.98730033637173138E-006 - -0.23097487012679951 -4.00997073716846536E-002 -9.65256042956430102E-006 - 2.2184586388335150 -12.786426756082790 3.29672133807938292E-004 - 956 6.55357523599375162E-009 6.96252818637274791E-005 - 1.98730033637173138E-006 - 7.53965235763319613E-002 0.16643774706336045 -1.17209111186737933E-005 - -13.388983905027859 6.0653587946929424 1.59499735626335846E-004 - 957 6.55357523599375162E-009 4.71204658955522835E-005 - 1.98730033637173138E-006 - 0.10779696305634937 6.05456509302998783E-002 7.06496267871510550E-006 - -8.7530081362013057 15.580201148233009 -4.96476634141169407E-004 - 958 6.55357523599375162E-009 4.78002992489562386E-005 - 1.98730033637173138E-006 - 5.70146672783162084E-002 0.11172889085095546 -1.71214758486893289E-006 - -15.802697836839700 8.0631623419837055 -1.25150087907747684E-003 - 959 6.55357523599375162E-009 5.37213593746188386E-005 - 1.98730033637173138E-006 - -0.11371390405629817 8.33556888176466559E-002 9.80586061010422957E-006 - -9.8919920014071447 -13.495157070648746 -6.25484903486959120E-004 - 960 6.55357523599375162E-009 8.07225114885925192E-005 - 1.98730033637173138E-006 - 0.19332008477568297 -8.66110267241722714E-002 -2.33909658229070275E-005 - 5.5817366114757370 12.458213865712244 1.79319805886056559E-004 - 961 6.55357523599375162E-009 9.97661119024111857E-005 - 1.98730033637173138E-006 - 0.25371870681412168 6.45403678660354113E-002 9.64520412096604543E-006 - -3.0279153860208377 11.901014341453029 -6.23538485964293199E-004 - 962 6.55357523599375162E-009 8.06625601592991483E-005 - 1.98730033637173138E-006 - -5.79127149690894377E-002 0.20364391298292120 -3.87128609459209917E-006 - -13.133199015207857 -3.7348059585847948 -2.74156907339408423E-004 - 963 6.55357523599375162E-009 5.13317568751537245E-005 - 1.98730033637173138E-006 - 9.63413242380635332E-002 -9.41549776912472824E-002 -2.99879764601963859E-006 - 11.964370020076156 12.243655988145525 -9.89147423063245577E-004 - 964 6.55357523599375162E-009 1.16914953645676396E-004 - 1.98730033637173138E-006 - 0.17505438826060180 0.25191730552964031 6.30107496490033497E-006 - -9.3169162716871803 6.4734009720464352 -4.44708721532892121E-004 - 965 6.55357523599375162E-009 6.18209094670840411E-005 - 1.98730033637173138E-006 - -5.66160251854940094E-002 -0.15203088234785769 -1.30012803580006540E-007 - 14.618785274527227 -5.4443294475552513 2.09402141423476742E-004 - 966 6.55357523599375162E-009 3.83101683333958784E-005 - 1.98730033637173138E-006 - -2.09563481418225464E-002 -9.83202117794542557E-002 4.46566501761809002E-006 - 19.382199595774942 -4.1304191493068076 7.85463459236174178E-005 - 967 6.55357523599375162E-009 1.33320312095465957E-004 - 1.98730033637173138E-006 - 0.20121921364406997 -0.28615863264254143 -2.29662933312825154E-005 - 8.6905812712493233 6.1105851072621915 -4.47446507427648075E-004 - 968 6.55357523599375162E-009 1.18936116526533161E-004 - 1.98730033637173138E-006 - 0.19134301173382234 0.24662171835128321 8.16936641912055262E-006 - -8.8842176858557860 6.8944375228907617 9.36716859257030526E-004 - 969 6.55357523599375162E-009 5.60026277291430832E-005 - 1.98730033637173138E-006 - 0.14199561199261809 -3.78791340337145677E-002 -5.11052926892879736E-006 - 4.2234564446810818 15.836612146182015 -1.51556395844058578E-004 - 970 6.55357523599375162E-009 8.27552402568578822E-005 - 1.98730033637173138E-006 - -0.21607773932890997 -2.22675243074136539E-002 2.14359084554667438E-005 - 1.3810680775468458 -13.408574426130000 -3.29136937218046444E-004 - 971 6.55357523599375162E-009 1.05347614459313488E-004 - 1.98730033637173138E-006 - 0.26974585579188337 6.06579073761974868E-002 -1.75536303465471347E-005 - -2.6226968339807835 11.657464391913717 2.41699751500878241E-004 - 972 6.55357523599375162E-009 9.67708731785607302E-005 - 1.98730033637173138E-006 - -0.23623276052768094 9.31406768263423057E-002 -1.44907468705917110E-005 - -4.5746778459759421 -11.599644485489330 3.38681942691097457E-004 - 973 6.55357523599375162E-009 7.11976077028747599E-005 - 1.98730033637173138E-006 - -0.18626963750011771 -1.44799573904581397E-002 7.41295075742687411E-007 - 1.1256981945368878 -14.492944502885912 -7.83159993866104284E-004 - 974 6.55357523599375162E-009 8.77990524666593037E-005 - 1.98730033637173138E-006 - 0.22910382290223757 -2.43077481661641004E-002 -5.96891089508155738E-007 - 1.3820657137697161 13.017517567871407 -8.12278071600336274E-004 - 975 6.55357523599375162E-009 7.34966265907275619E-005 - 1.98730033637173138E-006 - -5.52932029349630927E-002 -0.18479420352518311 -8.68254258504171816E-006 - 13.704870733380183 -4.1020515569053755 5.11964051462145261E-004 - 976 6.55357523599375162E-009 1.26570532996393416E-004 - 1.98730033637173138E-006 - -0.32063191329593038 -8.67202145443653483E-002 -7.30081173874059189E-006 - 2.8459141457759713 -10.524071045789174 2.27509459749868689E-004 - 977 6.55357523599375162E-009 4.99469067263802233E-005 - 1.98730033637173138E-006 - 2.01781725824878716E-002 -0.12951235998180016 -8.77127153464702778E-007 - 17.147673826605111 2.6721696998932538 4.37569559515797895E-005 - 978 6.55357523599375162E-009 1.30234203126484071E-004 - 1.98730033637173138E-006 - -0.28685130302366008 -0.18575673808466464 1.01065490685515907E-005 - 5.8434259311367507 -9.0211548863743225 3.67911645848740599E-004 - 979 6.55357523599375162E-009 4.40929638504981573E-005 - 1.98730033637173138E-006 - 0.11389164175480067 -2.05011977823525704E-002 -3.14959458845732298E-006 - 3.2748747944637016 18.176564659087550 -5.46353067494354905E-004 - 980 6.55357523599375162E-009 4.87954627146872815E-005 - 1.98730033637173138E-006 - 0.10325921856492762 7.57319317377758428E-002 3.20553186393901111E-006 - -10.386621748084751 14.156440454681290 1.48277486585621259E-004 - 981 6.55357523599375162E-009 1.22420300111660007E-004 - 1.98730033637173138E-006 - 0.32075856486801091 1.69083811704935777E-002 -1.95016995219816725E-005 - -0.58442361310887403 11.071898333526597 2.21929630278551920E-004 - 982 6.55357523599375162E-009 5.29677689064886941E-005 - 1.98730033637173138E-006 - 8.45846072171899666E-002 0.11032632713572979 -2.75890666032991084E-008 - -13.371674829096584 10.253494989358829 -8.76872755152753049E-004 - 983 6.55357523599375162E-009 5.42283428517082561E-005 - 1.98730033637173138E-006 - -0.13177246865965084 5.37469957434772994E-002 2.16182451641652018E-006 - -6.2891052136270540 -15.422235936709482 -5.09167515757609078E-004 - 984 6.55357523599375162E-009 4.75295649985828095E-005 - 1.98730033637173138E-006 - 9.62384190180215204E-002 7.93638554522573120E-002 6.16523146545856920E-006 - -11.316767290217726 13.725113001584049 -3.22822044047628236E-004 - 985 6.55357523599375162E-009 9.84517314298728285E-005 - 1.98730033637173138E-006 - -0.19605696898781999 -0.16816171755873738 1.22757513215898002E-005 - 8.0493003060525297 -9.3855399326608762 7.01930264118971211E-005 - 986 6.55357523599375162E-009 1.30539431454650454E-004 - 1.98730033637173138E-006 - -0.29322394503493227 -0.17718575654500163 -1.62213612392790490E-005 - 5.5522770501132443 -9.1865050101060088 4.70826610367794753E-004 - 987 6.55357523599375162E-009 3.82949799693384885E-005 - 1.98730033637173138E-006 - -0.10043839127236659 3.12854476614879071E-003 1.43265331136009806E-006 - -0.61747354015182943 -19.812082780215427 5.03914051470065569E-004 - 988 6.55357523599375162E-009 7.79655485208621032E-005 - 1.98730033637173138E-006 - -0.14589665821070855 0.14346051651069242 -5.87919135335216480E-006 - -9.7386286740795818 -9.9038694166758354 -6.20373165722594628E-004 - 989 6.55357523599375162E-009 5.63156773501113556E-005 - 1.98730033637173138E-006 - -0.11768505441422267 8.94015810607313444E-002 8.69799648141786320E-006 - -9.8864734194440835 -13.014114769383880 6.43671171478000159E-004 - 990 6.55357523599375162E-009 1.21549443030668979E-004 - 1.98730033637173138E-006 - -2.14274508626269150E-002 -0.31825823835467609 2.15184966419855930E-005 - 11.099739896798305 -0.74739428818557263 -3.84763692232717534E-004 - 991 6.55357523599375162E-009 4.53443416339214476E-005 - 1.98730033637173138E-006 - -5.12634335962937615E-002 -0.10739135189442545 -4.65701017464087392E-006 - 16.437578511075131 -7.8449766261005323 -5.75483004749777509E-004 - 992 6.55357523599375162E-009 1.06924322665989761E-004 - 1.98730033637173138E-006 - -0.22102531433769662 -0.17286783508296827 6.06206552101520564E-007 - 7.3080695402152225 -9.3425514907087273 9.61872325457041968E-004 - 993 6.55357523599375162E-009 4.53634529012257381E-005 - 1.98730033637173138E-006 - 0.11479430179177345 -3.14459308562637790E-002 -1.28886052116878561E-006 - 4.8139635125461355 17.566127210426203 -1.98276974141508352E-003 - 994 6.55357523599375162E-009 9.04361885417081786E-005 - 1.98730033637173138E-006 - -0.23070082312982501 5.57161947977267286E-002 6.95652472431747782E-006 - -3.0269973798660494 -12.536859489650050 -8.17019505463062673E-005 - 995 6.55357523599375162E-009 6.35258339626406840E-005 - 1.98730033637173138E-006 - -0.15850534750746428 -5.16725964499453252E-002 1.16478298891753638E-005 - 4.7670131676266809 -14.630918141141077 3.50048319173977551E-004 - 996 6.55357523599375162E-009 1.30623283315653150E-004 - 1.98730033637173138E-006 - 0.25992130112348488 0.22346394192997818 1.40986058433884401E-005 - -6.9963658649195803 8.1379752242642791 7.95247659157310885E-004 - 997 6.55357523599375162E-009 9.78637620116183638E-005 - 1.98730033637173138E-006 - -0.22655389659144776 -0.12100801235054914 7.82361075380494672E-007 - 5.8405142965062975 -10.935079432656728 -3.49082477052910809E-004 - 998 6.55357523599375162E-009 1.12834784713854318E-004 - 1.98730033637173138E-006 - -0.20949779919171085 -0.20918442236508406 -1.65445218786776896E-005 - 8.1599521148509098 -8.1723383079812724 2.54875607376818763E-004 - 999 6.55357523599375162E-009 1.29444700934586078E-004 - 1.98730033637173138E-006 - -0.32088285893014867 0.11139589583272254 1.04051079939498418E-005 - -3.5363864441822548 -10.184701642489040 7.99745809490522066E-004 - 1000 6.55357523599375162E-009 5.87439907531768699E-005 - 1.98730033637173138E-006 - -0.14121394658450331 -6.18462373885492189E-002 5.38227417712669997E-006 - 6.4194610697978627 -14.658186731205470 -5.40039140112075992E-004 - 1001 6.55357523599375162E-009 6.62728993536888301E-005 - 1.98730033637173138E-006 - -0.17165710271444309 2.79278780334123733E-002 4.59784361357425527E-006 - -2.4195802288120971 -14.870984983998994 3.34587712858052874E-004 - 1002 6.55357523599375162E-009 4.90294625748389958E-005 - 1.98730033637173138E-006 - -0.12657374137345517 -2.31331013134577559E-002 -7.47761548140731943E-006 - 3.1504087196966344 -17.230176074648053 -3.14681411814687418E-005 - 1003 6.55357523599375162E-009 1.31012550068997200E-004 - 1.98730033637173138E-006 - -3.13143479983352124E-002 -0.34230679269879927 -4.19494589198512683E-007 - 10.673520614188771 -0.97486193341357463 2.40022928081307013E-006 - 1004 6.55357523599375162E-009 1.25032765550963732E-004 - 1.98730033637173138E-006 - 8.30085427058028930E-002 -0.31740360455891037 3.77553350958752831E-006 - 10.613568990978315 2.7744304837440086 1.65868331038529357E-004 - 1005 6.55357523599375162E-009 5.52410574725806651E-005 - 1.98730033637173138E-006 - 0.14498609847998933 1.65202677474024506E-004 2.73522217607109958E-006 - -2.06233003518256908E-002 16.500016224211183 1.09717354289437649E-003 - 1006 6.55357523599375162E-009 4.67358487786934400E-005 - 1.98730033637173138E-006 - 7.33821779611636277E-002 9.82448830924002592E-002 5.86811841805153718E-006 - -14.377260120717601 10.737307075258443 5.38319317976744755E-004 - 1007 6.55357523599375162E-009 6.62878846602858339E-005 - 1.98730033637173138E-006 - -9.97198651146467691E-002 -0.14254618751807913 7.11779039483014687E-006 - 12.342121522536091 -8.6367722289282014 -4.63259120533755819E-004 - 1008 6.55357523599375162E-009 1.14182647779079155E-004 - 1.98730033637173138E-006 - -0.13032990383292206 -0.26983884166668054 5.05743024039544714E-006 - 10.336302994842994 -4.9892305618277550 -3.42035253656450906E-004 - 1009 6.55357523599375162E-009 4.69124408945130515E-005 - 1.98730033637173138E-006 - -5.38152394731220493E-002 -0.11069992979416199 9.75571715434464395E-007 - 16.107064587484331 -7.8327538617943908 -5.04456047205112997E-004 - 1010 6.55357523599375162E-009 1.32130795094017505E-004 - 1.98730033637173138E-006 - 0.30843292207734196 -0.15841678079778643 -1.50021349385331770E-006 - 4.8754769736699970 9.4914574125934656 4.48450187372135037E-004 - 1011 6.55357523599375162E-009 7.66224585844923193E-005 - 1.98730033637173138E-006 - 0.15068944871447498 -0.13310182160119094 -3.68637242688702318E-006 - 9.2765803083801011 10.503286653398973 -5.92029216532542757E-004 - 1012 6.55357523599375162E-009 1.28627179583179897E-004 - 1.98730033637173138E-006 - -7.16161719097902633E-002 0.32985443999207881 1.19368468470746871E-005 - -10.568820178745293 -2.2939031684437636 -8.46534713537075911E-004 - 1013 6.55357523599375162E-009 1.28518007912423692E-004 - 1.98730033637173138E-006 - 0.32473757381083634 -9.11474075387136984E-002 -1.53327445823834831E-005 - 2.9246854033997240 10.415566589684140 9.12414876713186812E-004 - 1014 6.55357523599375162E-009 1.04492280027376180E-004 - 1.98730033637173138E-006 - 0.25171250293744879 0.10866354664765210 -1.30779312274838579E-005 - -4.7554789490006071 11.018340447265929 1.59599354891506767E-005 - 1015 6.55357523599375162E-009 9.29984844767546733E-005 - 1.98730033637173138E-006 - 0.22202641660608102 -0.10127713761250128 -1.25911743459590719E-005 - 5.2773890116444715 11.572932638866309 2.70400362005374746E-004 - 1016 6.55357523599375162E-009 9.50086892672384278E-005 - 1.98730033637173138E-006 - 4.70248227789262854E-002 -0.24484148763538369 1.19541144422898353E-005 - 12.357899735591031 2.3735690089811654 4.02249761565303798E-004 - 1017 6.55357523599375162E-009 1.18806333453994465E-004 - 1.98730033637173138E-006 - -0.16932659634085589 0.26181573940131941 9.87472731601153243E-006 - -9.4474890047090074 -6.1114230300538068 2.47861387533322318E-005 - 1018 6.55357523599375162E-009 1.01915353295423044E-004 - 1.98730033637173138E-006 - -0.23027111789754703 -0.13596086900443954 -1.75059114042717102E-005 - 6.1772039079465726 -10.463837259742876 2.23819105917731528E-004 - 1019 6.55357523599375162E-009 9.83269037526105562E-005 - 1.98730033637173138E-006 - 0.22780379096258685 0.12119322565253399 -1.82989176799581193E-005 - -5.8097661347876155 10.919726887815880 -4.01816959759566732E-004 - 1020 6.55357523599375162E-009 8.18214454284632396E-005 - 1.98730033637173138E-006 - 0.21338153009887012 -2.38536999550602799E-002 4.31147616405708035E-006 - 1.5064925719399880 13.476074781349087 -8.21336280985543736E-004 - 1021 6.55357523599375162E-009 1.04007043898564426E-004 - 1.98730033637173138E-006 - -0.27000773981506432 -3.97539177836884888E-002 -3.32680951887986402E-006 - 1.7519184754795702 -11.899315782091660 -4.86465807105269878E-004 - 1022 6.55357523599375162E-009 1.12729821382670807E-004 - 1.98730033637173138E-006 - -5.41076409064602526E-002 -0.29086519354855345 -3.61339488654538363E-006 - 11.356197002729990 -2.1126172033898882 -6.56401132356389770E-004 - 1023 6.55357523599375162E-009 3.83810133488011334E-005 - 1.98730033637173138E-006 - -5.39067004628988114E-002 -8.50703251261040877E-002 2.26519329108334957E-006 - 16.724727563877284 -10.597637341959901 5.01083788740287099E-004 - 1024 6.55357523599375162E-009 5.44927779191893376E-005 - 1.98730033637173138E-006 - 0.14032508282486050 -2.73183216967989827E-002 -2.43552983567585069E-006 - 3.1763561572424344 16.313874698061728 4.43342029861721763E-004 - 1025 6.55357523599375162E-009 7.05461568010593313E-005 - 1.98730033637173138E-006 - -8.38106998183694718E-002 -0.16505563772737328 -1.94179799510688732E-005 - 13.021197169840317 -6.6127585074280093 9.99200725972668050E-004 - 1026 6.55357523599375162E-009 9.12504010992498378E-005 - 1.98730033637173138E-006 - -0.15131907687963905 0.18554830402812267 2.15406530846389431E-006 - -9.9519795418294947 -8.1159081725949047 -5.50088877086573193E-004 - 1027 6.55357523599375162E-009 4.14109402169829694E-005 - 1.98730033637173138E-006 - -1.80086069239094593E-002 0.10717189046012499 1.80156854409339138E-006 - -18.795807362482492 -3.1592400203665241 -7.16417439423241943E-004 - 1028 6.55357523599375162E-009 9.48322791458831150E-005 - 1.98730033637173138E-006 - 0.20024398754971817 -0.14774250905047911 -3.81554737375978934E-006 - 7.4780777425539853 10.135631260418318 -3.83033898899165785E-004 - 1029 6.55357523599375162E-009 5.08228666039821603E-005 - 1.98730033637173138E-006 - -0.11584008888901659 -6.60687823806763719E-002 7.44471680422223268E-007 - 8.5247810308529779 -14.946412205649512 1.92872130794749725E-004 - 1030 6.55357523599375162E-009 8.65312873726799080E-005 - 1.98730033637173138E-006 - -0.15967732020217257 -0.16145965555565800 1.54225238471730699E-005 - 9.3741085830449471 -9.2722255173911030 -5.65194882536544587E-004 - 1031 6.55357523599375162E-009 1.28578299515250236E-004 - 1.98730033637173138E-006 - 0.19910603635906260 -0.27246396211172996 3.16232743971407365E-007 - 8.7318109351021373 6.3818021102910008 6.34210108760321022E-004 - 1032 6.55357523599375162E-009 5.94530918532020343E-005 - 1.98730033637173138E-006 - 1.47096338228674753E-002 0.15531537352318239 1.81101091298831390E-006 - -15.836899854269777 1.5017778460714348 2.44204982927687412E-004 - 1033 6.55357523599375162E-009 5.89586607740990727E-005 - 1.98730033637173138E-006 - -0.13861128541975151 6.87460123346763929E-002 5.22243255683750352E-007 - -7.0953337657209223 -14.311153776693045 -8.35885768852370737E-004 - 1034 6.55357523599375162E-009 1.18689855049302197E-004 - 1.98730033637173138E-006 - -0.21881345155904561 -0.22155144394432663 1.29732232578290285E-006 - 8.0124997304315784 -7.9127978048393883 9.01917046186301844E-005 - 1035 6.55357523599375162E-009 9.62810351026273159E-005 - 1.98730033637173138E-006 - -0.21323974995839010 -0.13549619473637128 1.13039793977931585E-005 - 6.7043205635225602 -10.550898229020978 -2.01258994200590808E-004 - 1036 6.55357523599375162E-009 5.53947929245349018E-005 - 1.98730033637173138E-006 - -1.97347053697361705E-002 -0.14402167950809003 -1.29731810025952673E-006 - 16.326836708707749 -2.2389239409337049 3.85216955589461936E-005 - 1037 6.55357523599375162E-009 5.14826286202480044E-005 - 1.98730033637173138E-006 - -6.73737373065969730E-002 0.11711991838050603 6.86204899361331418E-007 - -14.815230969331541 -8.5241350451551234 2.10656568608182359E-004 - 1038 6.55357523599375162E-009 4.23378797968116617E-005 - 1.98730033637173138E-006 - 0.10099702856476503 4.62825949646391566E-002 6.28377211215485746E-006 - -7.8537388621752751 17.137510604550453 1.43151617402737050E-003 - 1039 6.55357523599375162E-009 4.99870794226634746E-005 - 1.98730033637173138E-006 - 3.75002417348615294E-002 -0.12570497831762042 -1.81306771307667441E-006 - 16.624236764742498 4.9578479210278399 4.80276446952616811E-004 - 1040 6.55357523599375162E-009 5.36054828063881435E-005 - 1.98730033637173138E-006 - -4.12219929270882940E-002 -0.13450967123546662 -3.58813154204011534E-006 - 16.015097376758732 -4.9102336680733627 1.84399019281990522E-004 - 1041 6.55357523599375162E-009 7.16846712347040229E-005 - 1.98730033637173138E-006 - 0.15296114487805440 -0.10950846699793176 3.76045531008771505E-006 - 8.4331560801547720 11.778595773833658 4.36210518648139653E-004 - 1042 6.55357523599375162E-009 4.47962222079730261E-005 - 1.98730033637173138E-006 - -0.11506616748781417 2.40225305096685784E-002 3.89102504260340329E-007 - -3.7454827636031625 -17.940100754555420 6.63355272508791812E-004 - 1043 6.55357523599375162E-009 5.53005259704663341E-005 - 1.98730033637173138E-006 - -0.13502166262458484 5.31626922117323999E-002 1.01974712419154397E-005 - -6.0419658180046216 -15.348326574450226 -3.02151040838847347E-005 - 1044 6.55357523599375162E-009 4.72018050187818033E-005 - 1.98730033637173138E-006 - -5.40090409050708875E-002 -0.11148673792847560 -3.16189307712090457E-006 - 16.065185300860605 -7.7821418880486721 7.87517866769374755E-004 - 1045 6.55357523599375162E-009 1.26376491109112698E-004 - 1.98730033637173138E-006 - -7.13680410481297434E-002 -0.32387608979602006 5.89911162279483370E-006 - 10.654476296778304 -2.3490117765507015 -3.73180145257855035E-004 - 1046 6.55357523599375162E-009 6.36295122540916127E-005 - 1.98730033637173138E-006 - -6.99679435411191819E-002 -0.15161138957628328 1.22561605394532429E-005 - 13.961085162761776 -6.4434625645212158 -5.25509166030950774E-004 - 1047 6.55357523599375162E-009 4.28780918528168413E-005 - 1.98730033637173138E-006 - 9.33067698839263882E-002 6.28927801389090602E-002 2.24548908391241863E-006 - -10.468797898868736 15.531951898135286 -4.96395252748018539E-004 - 1048 6.55357523599375162E-009 7.78133971484848565E-005 - 1.98730033637173138E-006 - -0.18567244803346855 8.49296040876055952E-002 -3.95893141999762276E-006 - -5.7843430140468346 -12.645999357712265 -8.53558824373161452E-004 - 1049 6.55357523599375162E-009 9.83675506505291366E-005 - 1.98730033637173138E-006 - -0.24801276765950681 -7.14739189013133824E-002 3.83304976169306773E-006 - 3.4261524514327180 -11.884220959476556 -3.80679638874803435E-005 - 1050 6.55357523599375162E-009 1.03294197047092568E-004 - 1.98730033637173138E-006 - -0.26299179935407019 -6.57681494085024521E-002 5.12809690294564459E-006 - 2.9282434002310809 -11.706446575543069 -3.92831620585050206E-004 - 1051 6.55357523599375162E-009 4.66078233355537021E-005 - 1.98730033637173138E-006 - -7.42398690256238086E-002 -9.72008922603587455E-002 4.77093852012057970E-006 - 14.278675708880074 -10.903889222165668 -1.01154737723135922E-003 - 1052 6.55357523599375162E-009 8.25162917046262548E-005 - 1.98730033637173138E-006 - -5.51472776368085171E-003 -0.21647533464475394 -1.12830652826650497E-006 - 13.497713862262488 -0.34364385007673981 1.07730102087546452E-004 - 1053 6.55357523599375162E-009 7.38910968149544242E-005 - 1.98730033637173138E-006 - -0.16467110262390833 0.10239959912197413 -6.38295735456645563E-006 - -7.5351998804787552 -12.116212091135203 -3.34775940761117003E-005 - 1054 6.55357523599375162E-009 9.71454168838099222E-005 - 1.98730033637173138E-006 - 7.39233613691200470E-002 -0.24402335037330791 -6.60524213811016516E-006 - 11.907697240355370 3.6073843416241127 1.00082965737340366E-004 - 1055 6.55357523599375162E-009 1.13553053626182991E-004 - 1.98730033637173138E-006 - -0.20544420727816756 -0.21587045882503289 5.19459401596173242E-006 - 8.3368412622528787 -7.9350446958120378 7.26023964924976629E-004 - 1056 6.55357523599375162E-009 1.25079729343804047E-004 - 1.98730033637173138E-006 - 0.21200765598611113 0.25063135261769770 -7.81735430285432372E-007 - -8.3725602025010097 7.0815191748741357 -1.96386761057295201E-004 - 1057 6.55357523599375162E-009 1.05954011392489405E-004 - 1.98730033637173138E-006 - 0.24306636183487118 0.13499068580422591 1.15340755456885539E-005 - -5.7851326937318914 10.417712584733277 -2.08379241501439145E-004 - 1058 6.55357523599375162E-009 8.76797730866922363E-005 - 1.98730033637173138E-006 - -0.15370692626841254 -0.17122446825824011 1.06401451636687880E-005 - 9.7472912379367749 -8.7499885168256490 -2.98603658764217371E-004 - 1059 6.55357523599375162E-009 6.97013146326925419E-005 - 1.98730033637173138E-006 - 0.12465044533866400 0.13385169311400730 7.15049005595476919E-006 - -10.751019312776018 10.013307100121917 -9.33321536718407325E-004 - 1060 6.55357523599375162E-009 1.33335327852180757E-004 - 1.98730033637173138E-006 - 0.32864151555264592 0.12012719066326429 -1.63969883602635323E-005 - -3.6470536528686361 9.9760706754687849 -2.23614397776612285E-004 - 1061 6.55357523599375162E-009 4.75718242678310147E-005 - 1.98730033637173138E-006 - 0.12337575631609948 1.91036993762090240E-002 -4.31200266426678901E-006 - -2.7199124934781649 17.572750179915861 -1.08763892509812629E-003 - 1062 6.55357523599375162E-009 6.57564577596941353E-005 - 1.98730033637173138E-006 - -6.39622082190725583E-002 -0.16026747739386932 3.16549749404235761E-006 - 14.047762561095654 -5.6072957763134985 -7.04788724308939515E-005 - 1063 6.55357523599375162E-009 4.59661147621676170E-005 - 1.98730033637173138E-006 - -0.11926536705036014 1.81294630733432813E-002 -4.05848483621499965E-006 - -2.7186927403701908 -17.883944879326627 -6.10804513497192740E-004 - 1064 6.55357523599375162E-009 9.15609968397846513E-005 - 1.98730033637173138E-006 - 0.20816199401305541 -0.12002758221727072 -9.93650997044938319E-006 - 6.4018282193306657 11.104318116136271 -4.60324494874623776E-004 - 1065 6.55357523599375162E-009 4.91571637863733973E-005 - 1.98730033637173138E-006 - -1.93589220279795637E-002 0.12752647024098537 -6.05514041743958747E-007 - -17.297518878138405 -2.6245362403712891 -8.86437413620849279E-004 - 1066 6.55357523599375162E-009 6.96525571577513215E-005 - 1.98730033637173138E-006 - 8.28372019644429136E-002 -0.16291949770805203 -8.85748598587982476E-006 - 13.100904567800876 6.6621334265176948 -5.44788982615990137E-004 - 1067 6.55357523599375162E-009 5.14058081816783725E-005 - 1.98730033637173138E-006 - -0.12575495473525991 4.88364368567839324E-002 -2.53320018348206178E-006 - -6.1935249728596418 -15.945837807184130 -2.26536448165288952E-004 - 1068 6.55357523599375162E-009 9.71593228021156135E-005 - 1.98730033637173138E-006 - -0.16738972678804978 -0.19235067394852404 7.96236598188592482E-006 - 9.3851127628185580 -8.1690823004363970 2.26466080447951181E-004 - 1069 6.55357523599375162E-009 8.96094717987699761E-005 - 1.98730033637173138E-006 - 0.22273376931531974 -7.53541632440687115E-002 7.38903848345891043E-006 - 4.1538612210637424 12.274219231255618 -3.08268322460632791E-004 - 1070 6.55357523599375162E-009 5.60572046896604600E-005 - 1.98730033637173138E-006 - 7.99746759080735142E-002 0.12349448593153731 -6.63935862137513824E-006 - -13.747801364700795 8.9041439175558761 -9.80770837368658086E-004 - 1071 6.55357523599375162E-009 4.83168550893695332E-005 - 1.98730033637173138E-006 - -0.11735994856035653 4.79998231169376302E-002 -5.63037398130845454E-006 - -6.6774356274020601 -16.332764968235832 8.59956568462234144E-004 - 1072 6.55357523599375162E-009 1.00656077193525003E-004 - 1.98730033637173138E-006 - 6.73238833795942876E-002 -0.25544325179074767 3.33227407959338718E-006 - 11.820448085082859 3.1160803129313810 -7.76280879497421032E-004 - 1073 6.55357523599375162E-009 1.11944162986272127E-004 - 1.98730033637173138E-006 - 0.26360753724273794 -0.12966540012473399 -1.41968428653805085E-005 - 5.1164898145933950 10.402092386195665 -1.15661988164812051E-004 - 1074 6.55357523599375162E-009 4.63915692294813577E-005 - 1.98730033637173138E-006 - -6.74368625426520624E-002 0.10136931196939863 -1.69421927926352547E-006 - -14.991326868937248 -9.9743530106800868 -1.59461557406131299E-003 - 1075 6.55357523599375162E-009 4.69836667176842492E-005 - 1.98730033637173138E-006 - 9.64101046687413504E-002 -7.68624991995151968E-002 1.19146675273356733E-005 - 11.154066686649497 13.991437717249962 -7.16120190755761008E-004 - 1076 6.55357523599375162E-009 5.94800461305631685E-005 - 1.98730033637173138E-006 - -0.12078893819635422 -9.88833903146267290E-002 -2.69339111441849110E-006 - 10.073223041314371 -12.304874354184754 -5.44521066941471639E-004 - 1077 6.55357523599375162E-009 1.31733112450211124E-004 - 1.98730033637173138E-006 - -6.18541539650543926E-002 0.34011956920204578 -2.01304879510321041E-005 - -10.513971459036885 -1.9118498331746896 -2.10524371012387661E-004 - 1078 6.55357523599375162E-009 5.61395853046087952E-005 - 1.98730033637173138E-006 - 0.12450438916725105 -7.87586984465725864E-002 3.10037345263730742E-006 - 8.7512659076379133 13.834175065523084 -9.62231995260550321E-004 - 1079 6.55357523599375162E-009 7.74832113363993524E-005 - 1.98730033637173138E-006 - -1.97507902154033799E-002 -0.20239220255564180 -1.94260379532050302E-006 - 13.866794350043969 -1.3525647215010874 -3.25252702674088832E-004 - 1080 6.55357523599375162E-009 4.01027564694471380E-005 - 1.98730033637173138E-006 - -6.05656759499100528E-002 -8.60534608820351099E-002 -2.06815763693596718E-006 - 15.839591692578329 -11.148977961195168 2.97960381983634610E-004 - 1081 6.55357523599375162E-009 5.52960531863234896E-005 - 1.98730033637173138E-006 - -0.11342669100831125 -9.05040651220062192E-002 6.26673680382541863E-006 - 10.286616697940707 -12.893669974945126 1.06005340636914041E-003 - 1082 6.55357523599375162E-009 7.41730624848260795E-005 - 1.98730033637173138E-006 - 1.08920749030164965E-002 -0.19434600243146091 5.92792714178388295E-006 - 14.218866249769929 0.79742366373719076 3.86572842829771481E-004 - 1083 6.55357523599375162E-009 5.96490661182316962E-005 - 1.98730033637173138E-006 - 0.15218606782773980 -3.66422800105732013E-002 -1.41493770572486437E-005 - 3.7169911389758425 15.439603849413249 2.89956151979462069E-004 - 1084 6.55357523599375162E-009 1.00340360411857861E-004 - 1.98730033637173138E-006 - 0.25231957409448830 7.53713562948158527E-002 1.45927006017926365E-005 - -3.5031684511619914 11.731683489019703 -1.29398409799446083E-004 - 1085 6.55357523599375162E-009 7.25278036992108667E-005 - 1.98730033637173138E-006 - 0.18480922822656681 4.55107201638589656E-002 -2.31247663320245414E-005 - -3.4444285254201326 13.984098693074891 5.31647283859462737E-004 - 1086 6.55357523599375162E-009 8.95076180070683672E-005 - 1.98730033637173138E-006 - -0.17423846980800695 -0.15753730172912384 -6.23525660199872707E-006 - 8.6929236389653894 -9.6172906293384361 -4.21673400581898286E-004 - 1087 6.55357523599375162E-009 8.45311816513688677E-005 - 1.98730033637173138E-006 - -0.13118513110499380 0.17887526071788429 -9.36503228221416309E-006 - -10.757337411560060 -7.8902036644626481 -6.09144090654212917E-004 - 1088 6.55357523599375162E-009 6.42855501451089511E-005 - 1.98730033637173138E-006 - -7.21329022109081647E-002 0.15249043297252152 4.71237012310669832E-006 - -13.828289667911918 -6.5436892616572244 1.04170591902897925E-004 - 1089 6.55357523599375162E-009 1.06520039306466221E-004 - 1.98730033637173138E-006 - -5.86636537150766121E-002 0.27333254553824898 -1.07404271541773981E-005 - -11.618333004028084 -2.4939448198894434 -3.59921567225181998E-005 - 1090 6.55357523599375162E-009 7.83376903051315573E-005 - 1.98730033637173138E-006 - 0.17536388136494729 0.10732537252834017 2.38437824628302926E-005 - -7.2331420487523248 11.818426596556140 -5.06889440958111989E-007 - 1091 6.55357523599375162E-009 7.41748544456584852E-005 - 1.98730033637173138E-006 - 0.19387110966091295 1.73021945304057262E-002 1.14935154064734545E-005 - -1.2664025090805779 14.185648147872197 -7.11599877713879050E-004 - 1092 6.55357523599375162E-009 9.82598221164416913E-005 - 1.98730033637173138E-006 - -0.23800865294061146 -9.92114535073480575E-002 -1.43428716491603320E-007 - 4.7614561097594095 -11.420507439083732 6.85170131841564251E-005 - 1093 6.55357523599375162E-009 5.11018741724345103E-005 - 1.98730033637173138E-006 - -0.13215809265913905 2.25841984157741996E-002 4.78546823559483126E-007 - -2.8930755144973652 -16.915858852985711 2.89013777413271960E-004 - 1094 6.55357523599375162E-009 7.30309151872334889E-005 - 1.98730033637173138E-006 - 0.16069585287596516 -0.10444064427423351 1.83827354597103381E-006 - 7.8222287004148416 12.033174838165380 9.99556192931786184E-004 - 1095 6.55357523599375162E-009 7.26060404442682304E-005 - 1.98730033637173138E-006 - 0.16142686480080773 -0.10122245593100457 -4.00264190162310864E-006 - 7.6475746670866744 12.194504910519068 -6.81502275907149295E-004 - 1096 6.55357523599375162E-009 4.21054303220152218E-005 - 1.98730033637173138E-006 - -9.04659432634002392E-002 6.34348449221535937E-002 -8.77116040900356245E-006 - -10.852449878722490 -15.477077196104874 6.16996408792026894E-004 - 1097 6.55357523599375162E-009 6.65182524497095497E-005 - 1.98730033637173138E-006 - 0.16202830717885425 6.48945335459264749E-002 4.42125239476146676E-006 - -5.5904240625729287 13.962633182371579 -1.12886179982550215E-003 - 1098 6.55357523599375162E-009 7.20654037423202519E-005 - 1.98730033637173138E-006 - -9.17552223412848450E-002 0.16536004690651424 8.70556744938256572E-007 - -12.634458966632449 -7.0095427272721871 8.47737417255628152E-005 - 1099 6.55357523599375162E-009 5.24313659773114376E-005 - 1.98730033637173138E-006 - -9.81336140446079086E-002 9.64109318483072075E-002 2.43198177809445978E-008 - -11.874173441557478 -12.083972649440916 6.05662198933766679E-004 - 1100 6.55357523599375162E-009 6.88304349029260804E-005 - 1.98730033637173138E-006 - -6.08812854198784170E-003 0.18050584589967211 6.50253750493075336E-007 - -14.777008423801494 -0.49745354253479679 -1.29785527205172110E-003 diff --git a/example/runjob b/example/runjob deleted file mode 100644 index 9e91a6abd..000000000 --- a/example/runjob +++ /dev/null @@ -1,11 +0,0 @@ -#PBS -q daminton -#PBS -l walltime=720:00:00 -#PBS -l nodes=1:ppn=24 -#PBS -N testrun -#PBS -j oe -source /etc/profile -module load intel -export PARALLEL=1 -export OMP_NUM_THREADS=24 -cd $PBS_O_WORKDIR -./swifter_symba_omp < start.in > term.out diff --git a/example/start.in b/example/start.in deleted file mode 100644 index 24836fc01..000000000 --- a/example/start.in +++ /dev/null @@ -1,2 +0,0 @@ -param.in -7e-9 diff --git a/example/swifter_symba_omp b/example/swifter_symba_omp deleted file mode 120000 index be3a6ed38..000000000 --- a/example/swifter_symba_omp +++ /dev/null @@ -1 +0,0 @@ -../bin/swifter_symba_omp \ No newline at end of file diff --git a/example/tp.in b/example/tp.in deleted file mode 100644 index 214247050..000000000 --- a/example/tp.in +++ /dev/null @@ -1 +0,0 @@ - 0 diff --git a/examples/helio_gr_test/cb.swiftest.in b/examples/helio_gr_test/cb.swiftest.in new file mode 100644 index 000000000..e4a010b1e --- /dev/null +++ b/examples/helio_gr_test/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +39.476926408897626 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/helio_gr_test/init_cond.py b/examples/helio_gr_test/init_cond.py new file mode 100755 index 000000000..8d197c6f4 --- /dev/null +++ b/examples/helio_gr_test/init_cond.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +import swiftest + +sim = swiftest.Simulation() +sim.param['PL_IN'] = "pl.swiftest.in" +sim.param['TP_IN'] = "tp.swiftest.in" +sim.param['CB_IN'] = "cb.swiftest.in" +sim.param['BIN_OUT'] = "bin.swiftest.dat" +sim.param['ENC_OUT'] = "enc.swiftest.dat" + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.YR2S +sim.param['DU2M'] = swiftest.AU2M +sim.param['T0'] = 0.0 +sim.param['DT'] = 0.25 * swiftest.JD2S / swiftest.YR2S +sim.param['TSTOP'] = 1000.0 +sim.param['ISTEP_OUT'] = 1461 +sim.param['ISTEP_DUMP'] = 1461 +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['OUT_FORM'] = "EL" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'YES' + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +sim.save("param.swiftest.in") +sim.param['PL_IN'] = "pl.swifter.in" +sim.param['TP_IN'] = "tp.swifter.in" +sim.param['BIN_OUT'] = "bin.swifter.dat" +sim.param['ENC_OUT'] = "enc.swifter.dat" +sim.save("param.swifter.in", codename="Swifter") + + diff --git a/examples/helio_gr_test/param.swifter.in b/examples/helio_gr_test/param.swifter.in new file mode 100644 index 000000000..789250f41 --- /dev/null +++ b/examples/helio_gr_test/param.swifter.in @@ -0,0 +1,27 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 1000.0 +DT 0.0006844626967830253 +ISTEP_OUT 1461 +ISTEP_DUMP 1461 +OUT_FORM EL +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.swifter.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +C 63241.07708426628 +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +RHILL_PRESENT YES diff --git a/examples/helio_gr_test/param.swiftest.in b/examples/helio_gr_test/param.swiftest.in new file mode 100644 index 000000000..ace6f3cad --- /dev/null +++ b/examples/helio_gr_test/param.swiftest.in @@ -0,0 +1,35 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 1000.0 +DT 0.0006844626967830253 +ISTEP_OUT 1461 +ISTEP_DUMP 1461 +OUT_FORM EL +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 31557600.0 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR YES +YARKOVSKY NO +YORP NO +MTINY 0.0 diff --git a/examples/helio_gr_test/pl.swifter.in b/examples/helio_gr_test/pl.swifter.in new file mode 100644 index 000000000..782e57140 --- /dev/null +++ b/examples/helio_gr_test/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 6.5537098095653139645e-06 0.0014751234419554511911 +1.6306381826061645943e-05 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 +2 9.663313399581537916e-05 0.00675908960945781479 +4.0453784346544178454e-05 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 +3 0.000120026935827952453094 0.010044837538502923644 +4.25875607065040958e-05 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 +4 1.2739802010675941456e-05 0.0072467236860282326973 +2.265740805092889601e-05 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 +5 0.037692251088985676735 0.35527094075555771578 +0.00046732617030490929307 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 +6 0.011285899820091272997 0.43765464106459166412 +0.00038925687730393611812 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 +7 0.0017236589478267730203 0.46956055286931676728 +0.00016953449859497231466 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 +8 0.0020336100526728302319 0.7813163071687303693 +0.000164587904124493665 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/helio_gr_test/pl.swiftest.in b/examples/helio_gr_test/pl.swiftest.in new file mode 100644 index 000000000..10d425453 --- /dev/null +++ b/examples/helio_gr_test/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 6.5537098095653139645e-06 +1.6306381826061645943e-05 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 +2 9.663313399581537916e-05 +4.0453784346544178454e-05 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 +3 0.000120026935827952453094 +4.25875607065040958e-05 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 +4 1.2739802010675941456e-05 +2.265740805092889601e-05 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 +5 0.037692251088985676735 +0.00046732617030490929307 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 +6 0.011285899820091272997 +0.00038925687730393611812 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 +7 0.0017236589478267730203 +0.00016953449859497231466 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 +8 0.0020336100526728302319 +0.000164587904124493665 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/helio_gr_test/swiftest_relativity.ipynb b/examples/helio_gr_test/swiftest_relativity.ipynb new file mode 100644 index 000000000..03948cdf7 --- /dev/null +++ b/examples/helio_gr_test/swiftest_relativity.ipynb @@ -0,0 +1,192 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import swiftest\n", + "from astroquery.jplhorizons import Horizons" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.000e+03\n", + "Creating Dataset\n", + "Successfully converted 1001 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.000e+03\n", + "Creating Dataset\n", + "Successfully converted 1001 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swifterdat['varpi'] = swifterdat['omega'] + swifterdat['capom']\n", + "swiftestdat['varpi'] = swiftestdat['omega'] + swiftestdat['capom']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "obj = Horizons(id='1', id_type='majorbody',location='@sun',\n", + " epochs={'start':'2021-01-28', 'stop':'3021-02-05',\n", + " 'step':'1y'})\n", + "el = obj.elements()\n", + "t = (el['datetime_jd']-el['datetime_jd'][0]) / 365.25\n", + "varpi_obs = el['w'] + el['Omega']" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "varpiswiftest = swiftestdat['varpi'].sel(id=1) * 180.0 / np.pi\n", + "varpiswifter = swifterdat['varpi'].sel(id=1) * 180.0 / np.pi\n", + "tsim = swiftestdat['time']" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "dvarpi_swiftest = np.diff(varpiswiftest) * 3600 * 100 \n", + "dvarpi_swifter = np.diff(varpiswifter) * 3600 * 100 \n", + "dvarpi_obs = np.diff(varpi_obs) / np.diff(t) * 3600 * 100 " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mean precession rate for Mercury long. peri. (arcsec/100 y)\n", + "JPL Horizons : 571.3210506300043\n", + "Swifter GR : 571.6183105524942\n", + "Swiftest GR : 571.6157754511288\n", + "Obs - Swifter : -0.2972599224899675\n", + "Obs - Swiftest : -0.2947248211246545\n", + "Swiftest - Swifter: -0.0025351013653107657\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "ax.plot(t, varpi_obs, label=\"JPL Horizons\")\n", + "ax.plot(tsim, varpiswifter, label=\"Swifter GR\")\n", + "ax.plot(tsim, varpiswiftest, label=\"Swiftest GR\")\n", + "ax.set_xlabel('Time (y)')\n", + "ax.set_ylabel('Mercury $\\\\varpi$ (deg)')\n", + "ax.legend()\n", + "print('Mean precession rate for Mercury long. peri. (arcsec/100 y)')\n", + "print(f'JPL Horizons : {np.mean(dvarpi_obs)}')\n", + "print(f'Swifter GR : {np.mean(dvarpi_swifter)}')\n", + "print(f'Swiftest GR : {np.mean(dvarpi_swiftest)}')\n", + "print(f'Obs - Swifter : {np.mean(dvarpi_obs - dvarpi_swifter)}')\n", + "print(f'Obs - Swiftest : {np.mean(dvarpi_obs - dvarpi_swiftest)}')\n", + "print(f'Swiftest - Swifter: {np.mean(dvarpi_swiftest - dvarpi_swifter)}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/helio_gr_test/tp.swifter.in b/examples/helio_gr_test/tp.swifter.in new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/examples/helio_gr_test/tp.swifter.in @@ -0,0 +1 @@ +0 diff --git a/examples/helio_gr_test/tp.swiftest.in b/examples/helio_gr_test/tp.swiftest.in new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/examples/helio_gr_test/tp.swiftest.in @@ -0,0 +1 @@ +0 diff --git a/examples/helio_swifter_comparison/.idea/.gitignore b/examples/helio_swifter_comparison/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/helio_swifter_comparison/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/helio_swifter_comparison/cb.swiftest.in b/examples/helio_swifter_comparison/cb.swiftest.in new file mode 100644 index 000000000..e4a010b1e --- /dev/null +++ b/examples/helio_swifter_comparison/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +39.476926408897626 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/helio_swifter_comparison/init_cond.py b/examples/helio_swifter_comparison/init_cond.py new file mode 100755 index 000000000..4680d9e0a --- /dev/null +++ b/examples/helio_swifter_comparison/init_cond.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +import swiftest + +sim = swiftest.Simulation() + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.YR2S +sim.param['DU2M'] = swiftest.AU2M +sim.param['T0'] = 0.0 +sim.param['TSTOP'] = 1.0 +sim.param['DT'] = 0.25 * swiftest.JD2S / swiftest.YR2S +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['ISTEP_OUT'] = 1 +sim.param['ISTEP_DUMP'] = 1 +sim.param['OUT_FORM'] = "XV" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'NO' + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, + "Ceres": 101, + "Pallas": 102, + "Juno": 103, + "Vesta": 104 +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +sim.param['PL_IN'] = "pl.swiftest.in" +sim.param['TP_IN'] = "tp.swiftest.in" +sim.param['CB_IN'] = "cb.swiftest.in" +sim.param['BIN_OUT'] = "bin.swiftest.dat" +sim.param['ENC_OUT'] = "enc.swiftest.dat" +sim.save("param.swiftest.in") +sim.param['PL_IN'] = "pl.swifter.in" +sim.param['TP_IN'] = "tp.swifter.in" +sim.param['BIN_OUT'] = "bin.swifter.dat" +sim.param['ENC_OUT'] = "enc.swifter.dat" +sim.save("param.swifter.in", codename="Swifter") + + diff --git a/examples/helio_swifter_comparison/param.swifter.in b/examples/helio_swifter_comparison/param.swifter.in new file mode 100644 index 000000000..5cf0cb8b9 --- /dev/null +++ b/examples/helio_swifter_comparison/param.swifter.in @@ -0,0 +1,26 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 1.0 +DT 0.0006844626967830253 +ISTEP_OUT 1 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.swifter.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +RHILL_PRESENT YES diff --git a/examples/helio_swifter_comparison/param.swiftest.in b/examples/helio_swifter_comparison/param.swiftest.in new file mode 100644 index 000000000..73818e198 --- /dev/null +++ b/examples/helio_swifter_comparison/param.swiftest.in @@ -0,0 +1,35 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 1.0 +DT 0.0006844626967830253 +ISTEP_OUT 1 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 31557600.0 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR NO +YARKOVSKY NO +YORP NO +MTINY 0.0 diff --git a/examples/helio_swifter_comparison/pl.swifter.in b/examples/helio_swifter_comparison/pl.swifter.in new file mode 100644 index 000000000..e0ef4e881 --- /dev/null +++ b/examples/helio_swifter_comparison/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 6.5537098095653139645e-06 0.0014751243077781048702 +1.6306381826061645943e-05 +0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 +-4.2340114788918336805 10.486553514018327622 1.2453138107251555947 +2 9.663313399581537916e-05 0.006759104275397271956 +4.0453784346544178454e-05 +-0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 +0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 +3 0.000120026935827952453094 0.010044787321379672528 +4.25875607065040958e-05 +0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 +5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 +4 1.2739802010675941456e-05 0.007246743835971885302 +2.265740805092889601e-05 +-1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 +-1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 +5 0.037692251088985676735 0.35527126534549128905 +0.00046732617030490929307 +4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 +1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 +6 0.011285899820091272997 0.4376527512949726007 +0.00038925687730393611812 +6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 +1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 +7 0.0017236589478267730203 0.4695362423191493196 +0.00016953449859497231466 +14.856082147529010129 13.007589275314199284 -0.14417795763685259391 +-0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 +8 0.0020336100526728302319 0.7812870996943599397 +0.000164587904124493665 +29.55744967800954015 -4.629377558152945049 -0.58590957207831262377 +0.17162147939801157335 1.1422848961108499101 -0.027445465472921385952 diff --git a/examples/helio_swifter_comparison/pl.swiftest.in b/examples/helio_swifter_comparison/pl.swiftest.in new file mode 100644 index 000000000..9d49cc3da --- /dev/null +++ b/examples/helio_swifter_comparison/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 6.5537098095653139645e-06 +1.6306381826061645943e-05 +0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 +-4.2340114788918336805 10.486553514018327622 1.2453138107251555947 +2 9.663313399581537916e-05 +4.0453784346544178454e-05 +-0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 +0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 +3 0.000120026935827952453094 +4.25875607065040958e-05 +0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 +5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 +4 1.2739802010675941456e-05 +2.265740805092889601e-05 +-1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 +-1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 +5 0.037692251088985676735 +0.00046732617030490929307 +4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 +1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 +6 0.011285899820091272997 +0.00038925687730393611812 +6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 +1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 +7 0.0017236589478267730203 +0.00016953449859497231466 +14.856082147529010129 13.007589275314199284 -0.14417795763685259391 +-0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 +8 0.0020336100526728302319 +0.000164587904124493665 +29.55744967800954015 -4.629377558152945049 -0.58590957207831262377 +0.17162147939801157335 1.1422848961108499101 -0.027445465472921385952 diff --git a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb new file mode 100644 index 000000000..9a4c22cb1 --- /dev/null +++ b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb @@ -0,0 +1,230 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import swiftest" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.000e+00\n", + "Creating Dataset\n", + "Successfully converted 1462 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.000e+00\n", + "Creating Dataset\n", + "Successfully converted 1462 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestsim.ds - swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (y)'})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff['dr'] = np.sqrt(swiftdiff['px']**2 + swiftdiff['py']**2 + swiftdiff['pz']**2)\n", + "swiftdiff['dv'] = np.sqrt(swiftdiff['vx']**2 + swiftdiff['vy']**2 + swiftdiff['vz']**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "plidx = swiftdiff.id.values[swiftdiff.id.values < 10]\n", + "tpidx = swiftdiff.id.values[swiftdiff.id.values > 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['dr'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Helio integrator \\n Planets only\")\n", + "#legend = ax.legend()\n", + "fig.savefig(\"helio_swifter_comparison-pl-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['dr'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Helio integrator \\n Test Particles only\")\n", + "fig.savefig(\"helio_swifter_comparison-tp-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['dv'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Helio integrator \\n Planets only\")\n", + "fig.savefig(\"helio_swifter_comparison-pl-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['dv'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Helio integrator \\n Test Particles only\")\n", + "fig.savefig(\"helio_swifter_comparison-tp-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/helio_swifter_comparison/tp.swifter.in b/examples/helio_swifter_comparison/tp.swifter.in new file mode 100644 index 000000000..b37f04011 --- /dev/null +++ b/examples/helio_swifter_comparison/tp.swifter.in @@ -0,0 +1,13 @@ +4 +101 +2.2759060918449769417 1.6823262546111898974 -0.3661544509052930274 +-2.3097811686367798667 2.7916683305060454227 0.51377483806222698173 +102 +3.0206599411327550442 -1.0715345879373190385 0.4820489106686373093 +0.64736314289225124926 2.5354787229381968757 -1.8109825958052419904 +103 +-0.47156753362343428737 -3.1411451968218520037 0.73253063903937232215 +3.067486522793096946 -0.061867034122113133084 -0.11064022385054755856 +104 +-2.0454358521790818592 -0.83017357434175576003 0.27369621627497042748 +1.8825682786003801814 -3.9015333153827542793 -0.112405737336568095776 diff --git a/examples/helio_swifter_comparison/tp.swiftest.in b/examples/helio_swifter_comparison/tp.swiftest.in new file mode 100644 index 000000000..b37f04011 --- /dev/null +++ b/examples/helio_swifter_comparison/tp.swiftest.in @@ -0,0 +1,13 @@ +4 +101 +2.2759060918449769417 1.6823262546111898974 -0.3661544509052930274 +-2.3097811686367798667 2.7916683305060454227 0.51377483806222698173 +102 +3.0206599411327550442 -1.0715345879373190385 0.4820489106686373093 +0.64736314289225124926 2.5354787229381968757 -1.8109825958052419904 +103 +-0.47156753362343428737 -3.1411451968218520037 0.73253063903937232215 +3.067486522793096946 -0.061867034122113133084 -0.11064022385054755856 +104 +-2.0454358521790818592 -0.83017357434175576003 0.27369621627497042748 +1.8825682786003801814 -3.9015333153827542793 -0.112405737336568095776 diff --git a/examples/restart/param.restart.in b/examples/restart/param.restart.in new file mode 100644 index 000000000..e69de29bb diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in new file mode 100644 index 000000000..96c7f920c Binary files /dev/null and b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in differ diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py new file mode 100755 index 000000000..b292ed42f --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/init_cond.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 +""" +For testing RMVS, the code generates clones of test particles based on one that is fated to impact Mercury. +To use the script, modify the variables just after the "if __name__ == '__main__':" line +""" +import numpy as np +import swiftest +from scipy.io import FortranFile +import sys + +swifter_input = "param.swifter.in" +swifter_pl = "pl.swifter.in" +swifter_tp = "tp.swifter.in" +swifter_bin = "bin.swifter.dat" +swifter_enc = "enc.swifter.dat" + +swiftest_input = "param.swiftest.in" +swiftest_pl = "pl.swiftest.in" +swiftest_tp = "tp.swiftest.in" +swiftest_cb = "cb.swiftest.in" +swiftest_bin = "bin.swiftest.dat" +swiftest_enc = "enc.swiftest.dat" + +MU2KG = swiftest.MSun +TU2S = swiftest.YR2S +DU2M = swiftest.AU2M + +GMSun = swiftest.GMSunSI * TU2S**2 / DU2M**3 + +# Simple initial conditions of a circular planet with one test particle in a close encounter state +# Simulation start, stop, and output cadence times +t_0 = 0 # simulation start time +deltaT = 0.25 * swiftest.JD2S / TU2S # simulation step size +end_sim = 0.15 +t_print = deltaT #output interval to print results + +iout = int(np.ceil(t_print / deltaT)) +rmin = swiftest.RSun / swiftest.AU2M +rmax = 1000.0 + +npl = 1 +plid = 2 +tpid = 100 + +radius = np.double(4.25875607065041e-05) +mass = np.double(0.00012002693582795244940133) +apl = np.longdouble(1.0) +atp = np.longdouble(1.01) +vpl = np.longdouble(2 * np.pi) +vtp = np.longdouble(2 * np.pi / np.sqrt(atp)) + +p_pl = np.array([apl, 0.0, 0.0], dtype=np.double) +v_pl = np.array([0.0, vpl, 0.0], dtype=np.double) + +p_tp = np.array([atp, 0.0, 0.0], dtype=np.double) +v_tp = np.array([0.0, vtp, 0.0], dtype=np.double) + +Rhill = apl * 0.0100447248332378922085 + +#Make Swifter files +plfile = open(swifter_pl, 'w') +print(npl+1, f'! Planet input file generated using init_cond.py',file=plfile) +print(1,GMSun,file=plfile) +print('0.0 0.0 0.0',file=plfile) +print('0.0 0.0 0.0',file=plfile) +print(plid,"{:.23g}".format(mass),Rhill, file=plfile) +print(radius, file=plfile) +print(*p_pl, file=plfile) +print(*v_pl, file=plfile) +plfile.close() + +tpfile = open(swifter_tp, 'w') +print(1,file=tpfile) +print(tpid, file=tpfile) +print(*p_tp, file=tpfile) +print(*v_tp, file=tpfile) +tpfile.close() + +sys.stdout = open(swifter_input, "w") +print(f'! Swifter input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'PL_IN {swifter_pl}') +print(f'TP_IN {swifter_tp}') +print(f'IN_TYPE ASCII') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swifter_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT UNKNOWN') +print(f'J2 {swiftest.J2Sun}') +print(f'J4 {swiftest.J4Sun}') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swifter_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'RHILL_PRESENT yes') +sys.stdout = sys.__stdout__ + +#Now make Swiftest files +cbfile = FortranFile(swiftest_cb, 'w') +Msun = np.double(1.0) +cbfile.write_record(0) +cbfile.write_record(np.double(GMSun)) +cbfile.write_record(np.double(rmin)) +cbfile.write_record(np.double(swiftest.J2Sun)) +cbfile.write_record(np.double(swiftest.J4Sun)) +cbfile.close() + +plfile = FortranFile(swiftest_pl, 'w') +plfile.write_record(npl) + +plfile.write_record(plid) +plfile.write_record(p_pl[0]) +plfile.write_record(p_pl[1]) +plfile.write_record(p_pl[2]) +plfile.write_record(v_pl[0]) +plfile.write_record(v_pl[1]) +plfile.write_record(v_pl[2]) +plfile.write_record(mass) +plfile.write_record(radius) +plfile.close() +tpfile = FortranFile(swiftest_tp, 'w') +ntp = 1 +tpfile.write_record(ntp) +tpfile.write_record(tpid) +tpfile.write_record(p_tp[0]) +tpfile.write_record(p_tp[1]) +tpfile.write_record(p_tp[2]) +tpfile.write_record(v_tp[0]) +tpfile.write_record(v_tp[1]) +tpfile.write_record(v_tp[2]) + +tpfile.close() + +sys.stdout = open(swiftest_input, "w") +print(f'! Swiftest input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'CB_IN {swiftest_cb}') +print(f'PL_IN {swiftest_pl}') +print(f'TP_IN {swiftest_tp}') +print(f'IN_TYPE REAL8') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swiftest_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT REPLACE') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swiftest_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'ROTATION no') +print(f'GR no') +print(f'MU2KG {MU2KG}') +print(f'DU2M {DU2M}') +print(f'TU2S {TU2S}') + + + + + diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in new file mode 100644 index 000000000..d1a0c9f27 --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT UNKNOWN +J2 2.198e-07 +J4 -4.805e-09 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swifter.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in new file mode 100644 index 000000000..36937896f --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/param.swiftest.in @@ -0,0 +1,29 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in new file mode 100644 index 000000000..95513c9fd --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swifter.in @@ -0,0 +1,8 @@ +2 ! Planet input file generated using init_cond.py +1 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +2 0.00012002693582795244940133 0.010044724833237891545 +4.25875607065041e-05 +1.0 0.0 0.0 +0.0 6.283185307179586 0.0 diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in new file mode 100644 index 000000000..6f4bc1337 Binary files /dev/null and b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in differ diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb new file mode 100644 index 000000000..29dcf43aa --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb @@ -0,0 +1,138 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import swiftest\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.355e-01\n", + "Creating Dataset\n", + "Successfully converted 199 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.506e-01\n", + "Creating Dataset\n", + "Successfully converted 221 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestsim.ds - swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (y)'})\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "swiftdiff['px'].plot.line(x=\"time (y)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swifter.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swifter.in new file mode 100644 index 000000000..9c026369e --- /dev/null +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swifter.in @@ -0,0 +1,4 @@ +1 +100 +1.01 0.0 0.0 +0.0 6.252003053624663 0.0 diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in new file mode 100644 index 000000000..e1506974a Binary files /dev/null and b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in differ diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.in new file mode 100644 index 000000000..81c636655 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.in @@ -0,0 +1,5 @@ +0 +0.00029591220819207774 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in new file mode 100644 index 000000000..2e8d49f62 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +0.00029591220819207774 +0.004650467260962157 +0.0 +0.0 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/init_cond.py b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/init_cond.py new file mode 100755 index 000000000..094b261f0 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/init_cond.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +import numpy as np +import swiftest +import swiftest.io as swio +import astropy.constants as const +import sys +import xarray as xr + +# Both codes use the same tp input file +tpin = "tp.in" + +swifter_input = "param.swifter.in" +swifter_pl = "pl.swifter.in" +swifter_bin = "bin.swifter.dat" +swifter_enc = "enc.swifter.dat" + +swiftest_input = "param.swiftest.in" +swiftest_pl = "pl.swiftest.in" +swiftest_cb = "cb.swiftest.in" +swiftest_bin = "bin.swiftest.dat" +swiftest_enc = "enc.swiftest.dat" + +sim = swiftest.Simulation() + +sim.param['T0'] = 0.0 +sim.param['DT'] = 1.0 +sim.param['TSTOP'] = 365.25e1 +sim.param['ISTEP_OUT'] = 10 +sim.param['ISTEP_DUMP'] = 10 +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['OUT_FORM'] = "XV" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'NO' +sim.param['CHK_CLOSE'] = 'YES' + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.JD2S +sim.param['DU2M'] = swiftest.AU2M + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +ds = sim.ds +cb = ds.sel(id=0) +pl = ds.where(ds.id > 0, drop=True) +npl = pl.id.size + +ntp = 16 +dims = ['time', 'id', 'vec'] +tp = [] +t = np.array([0.0]) +clab, plab, tlab = swio.make_swiftest_labels(sim.param) + +# For each planet, we will initialize a pair of test particles. One on its way in, and one on its way out. We will also initialize two additional particles that don't encounter anything +tpnames = np.arange(101, 101 + ntp) +tpxv1 = np.empty((6)) +tpxv2 = np.empty((6)) + +p1 = [] +p2 = [] +p3 = [] +p4 = [] +p5 = [] +p6 = [] + +for i in pl.id: + pli = pl.sel(id=i) + rstart = 2 * np.double(pli['Radius']) # Start the test particles at a multiple of the planet radius away + vstart = 1.5 * np.sqrt(2 * np.double(pli['Mass']) / rstart) # Start the test particle velocities at a multiple of the escape speed + xvstart = np.array([rstart / np.sqrt(2.0), rstart / np.sqrt(2.0), 0.0, vstart, 0.0, 0.0]) + # The positions and velocities of each pair of test particles will be in reference to a planet + plvec = np.array([np.double(pli['px']), + np.double(pli['py']), + np.double(pli['pz']), + np.double(pli['vx']), + np.double(pli['vy']), + np.double(pli['vz'])]) + tpxv1 = plvec + xvstart + tpxv2 = plvec - xvstart + p1.append(tpxv1[0]) + p1.append(tpxv2[0]) + p2.append(tpxv1[1]) + p2.append(tpxv2[1]) + p3.append(tpxv1[2]) + p3.append(tpxv2[2]) + p4.append(tpxv1[3]) + p4.append(tpxv2[3]) + p5.append(tpxv1[4]) + p5.append(tpxv2[4]) + p6.append(tpxv1[5]) + p6.append(tpxv2[5]) + +tvec = np.vstack([p1, p2, p3, p4, p5, p6]) +tpframe = np.expand_dims(tvec.T, axis=0) +tpxr = xr.DataArray(tpframe, dims = dims, coords = {'time' : t, 'id' : tpnames, 'vec' : tlab}) + +tp = [tpxr] +tpda = xr.concat(tp,dim='time') +tpds = tpda.to_dataset(dim = 'vec') + +sim.ds = xr.combine_by_coords([sim.ds, tpds]) +swio.swiftest_xr2infile(sim.ds, sim.param) + +sim.param['PL_IN'] = swiftest_pl +sim.param['TP_IN'] = tpin +sim.param['CB_IN'] = swiftest_cb +sim.param['BIN_OUT'] = swiftest_bin +sim.param['ENC_OUT'] = swiftest_enc +sim.save(swiftest_input) + +sim.param['PL_IN'] = swifter_pl +sim.param['TP_IN'] = tpin +sim.param['BIN_OUT'] = swifter_bin +sim.param['ENC_OUT'] = swifter_enc +sim.save(swifter_input, codename="Swifter") diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swifter.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swifter.in new file mode 100644 index 000000000..6a283276e --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swifter.in @@ -0,0 +1,26 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 3652.5 +DT 1.0 +ISTEP_OUT 10 +ISTEP_DUMP 10 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +J2 0.0 +J4 0.0 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swiftest.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swiftest.in new file mode 100644 index 000000000..b08b66850 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/param.swiftest.in @@ -0,0 +1,36 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 3652.5 +DT 1.0 +ISTEP_OUT 10 +ISTEP_DUMP 10 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 86400 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR NO +YARKOVSKY NO +YORP NO +MTINY 0.0 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.in new file mode 100644 index 000000000..86a616119 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.in @@ -0,0 +1,33 @@ +8 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swifter.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swifter.in new file mode 100644 index 000000000..595cdc169 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 0.00029591220819207775568 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in new file mode 100644 index 000000000..86a616119 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb new file mode 100644 index 000000000..124ae2910 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb @@ -0,0 +1,642 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import swiftest\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 3.650e+03\n", + "Creating Dataset\n", + "Successfully converted 366 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swifter.in'\n", + "swiftersim = swiftest.Simulation(param_file=inparfile, codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 3.650e+03\n", + "Creating Dataset\n", + "Successfully converted 366 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swiftest.in'\n", + "swiftestsim = swiftest.Simulation(param_file=inparfile)\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestdat - swifterdat" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (d)'})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff['rmag'] = np.sqrt(swiftdiff['px']**2 + swiftdiff['py']**2 + swiftdiff['pz']**2)\n", + "swiftdiff['vmag'] = np.sqrt(swiftdiff['vx']**2 + swiftdiff['vy']**2 + swiftdiff['vz']**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "plidx = swiftdiff.id.values[swiftdiff.id.values < 10]\n", + "tpidx = swiftdiff.id.values[swiftdiff.id.values > 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Planets only\")\n", + "fig.savefig(\"rmvs_swifter_comparison-8pl_16tp-planets-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Planets only\")\n", + "fig.savefig(\"rmvs_swifter_comparison-8pl_16tp-planets-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXwAAAElCAYAAADnZln1AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAmMElEQVR4nO3debwcVZ338c83NyEhgATIFcIaFgGXRxYjwqCMG4K4gDI6bjg6IOM4is7IIOo8mEFxmXnG7TXqTEQEFGFQwW0UxQVxRYKEHWQTExPgRogkQLbu3/NHnRuaTvfN7U53VXfV9/169etWdy3nV1X3/m71qVPnKCIwM7Pym1J0AGZmlg8nfDOzinDCNzOrCCd8M7OKcMI3M6sIJ3wzs4pwwq8YSfMlfTlN7y5plaSRouOaiKTnSLqt6Dhg07HkeUwlXSHppDT9ekk/aJh3uKTbUyzHSdpR0pWSVkr6j37HZoPJCX/ISPq9pBc2ffYmST/vdFsR8YeI2Doiar2LsDOSQtI+Ey0TET+LiP3yimkizbE0n4+ijmlEXBARL2r46EzgP1Ms3wBOBpYDT4iId+cZmw0OJ3wbaJKmFh3DkNoDuKnp/c3RxZOWPgfl4YRfQpJ2lvR1SWOS7pZ0Spvl5qYr7KkN631L0gOS7pD0loZlRyS9T9KdqVrgGkm7pXn7S7o8rXebpFc3rHeupM9I+t+03lWS9k7zrkyLXZeqHv5a0nMlLZH0Hkn3Al8c/6xhm7tJuiTt358k/Web/Zsv6WuS/ieV/VtJBzTMf3KqFlkh6SZJL2+Yd4ykm9N6f5R0avp8QyySvgTsDnw7xX9ah8d0vqSLJZ2fyrlJ0rwJzuuRkm6V9Oe0z2qYt+FbnqQ7gb0a4roQ+BvgtPT+hZKmSDo9nc8/pTi2b/q9OFHSH4Afp8//VtItkh6U9H1JezSUH5LemqqRHkznvDG+t6R1V6bjenDD8Wn5uyrpEEkLJT0k6T5JH293bGySIsKvIXoBvwde2PTZm4Cfp+kpwDXAGcAWZH/4dwFHpfnzgS+n6blAAFPT+58CnwVmAAcCY8AL0rx/Bm4A9iNLNAcAOwBbAYuBNwNTgYPJqg6emtY7F3gAOCTNvwC4qCH2APZpeP9cYD3wMWA6sGX6bEmaPwJcB3wilT0DeHabYzUfWAf8FTANOBW4O01PA+4A3peO0/OBlcB+ad1lwHPS9HbAwQ3xLWl3Pjo8pvOB1cAxab8+Avy6zb7MBh5q2Jd/TMfppObfgTZxnQt8qOH9u4BfA7um4/zfwIVN+3B+OsZbAsel4/XkdB7/Bfhl03n8DjCL7J/gGHB0mvcq4I/AM8l+d/Yh+8axqd/VXwEnpOmtgUOL/vsb9lfhAfjV4QnL/pBXASsaXo/wWMJ/FvCHpnXeC3wxTc+nRcIHdgNqwDYN630EODdN3wYc2yKevwZ+1vTZfwMfSNPnAmc3zDsGuLXhfauEvxaY0fTZeMI/LCWTqZM4VvNpSKApwSwDnpNe9wJTGuZfCMxP038A/o6szptWsTScj5YJfxLHdD7ww4Z5TwEebbMvb2zaFwFL6D7h30L6x5PezyH75zi1YR/2apj/PeDEpmP5CLBHw3l8dsP8i4HT0/T3gXe22KdN/a5eCfwrMLvov7uyvFylM5yOi4hZ4y/gbQ3z9gB2TtUUKyStILuK3XET29wZeCAiVjZ8dg+wS5reDbizxXp7AM9qKu/1wE4Ny9zbMP0I2dXaRMYiYnWbebsB90TE+k1sY9zi8YmIqJMlyZ3Ta3H6bFzj/h5P9s/pHkk/lXTYJMtrtKljChsfmxlqXWe+c9O+ROP7LuwBXNpwzm4h++fU+HuyuGn5TzUs/wDZP52J9mX8PE/0uzPR7+qJwL7ArZKulvTSjvfSHsc3Y8pnMXB3RDypw/WWAttL2qYhQe1O9lV8fLt7Aze2KO+nEXFktwG3MNGNxcXA7pKmTjLp7zY+IWkKWRXG0vF5kqY0JP3dgd8BRMTVwLGSpgFvJ7ti3bCtSca6qWPaiWVN+6I28UzWYuBvI+IXzTMkzU2T0bT8WRFxQZdl7d3m87a/qxFxO/DadN5eCXxN0g4R8XAXMRi+aVtGvwEeSjc9t1R2s/Vpkp450UoRsRj4JfARSTMkPZ3sCmv8D/xs4IOSnqTM0yXtQFZvu6+kEyRNS69nSnryJOO9j6zutpP9WwZ8VNJWKdbDJ1j+GZJema6a3wWsIau7vgp4mOxG5jRJzwVeBlwkaQtl7dq3jYh1ZHXn7ZpZto1/Ese0E/8LPLVhX07h8d+iOvVfwFnjN14ljUo6dhPLv1fSU9Py20p61STLOhs4VdIz0u/OPqncCX9XJb1B0mj6h7wibauwJsRl4IRfMpG1/34Z2Q3Cu8luoJ4NbDuJ1V9LVn+7FLiUrB7+8jTv42RXuT8gS4BfALZMV64vAl6T1ruXx264TsZ84Lz0lf7Vm1q4Yf/2IatnX0J2H6Gdb6b5DwInAK+MiHURsRZ4OfBismP0WeCNEXFrWu8E4PeSHgLeCryhzfY/AvxLiv/UFvMnOqaTFhHLyW5+fhT4E/AkYKOr8w58CvgW8ANJK8n+CT5rgvIvJTuvF6VjciPZsZtM7F8FzgK+QnZj/BvA9pP4XT0auEnSqhTvayao6rNJULo5YlY6kuaT3RBul6zNKsVX+GZmFeGEb2ZWEa7SMTOrCF/hm5lVhBO+WRfU1B3xBMtt6I56ECjr2+hDRcdhxXDCt77TY33Ej79C0sMN75/TxTY36ia6af5zJdXT9lcq69TtzV3G/7gO0aBld8RmA89P2lrfRcQfaOhOQVIAB0TEHX0uemlE7JqeSj2W7EnNqyLi5sluoE03B2ZDyVf4VihJ0yX9P0l/UNYF7n9J2jLNmy3pO+mhpgck/UxZt74bdUs8URmR+QbZw1dPkfQSSdcq63Z3cWqvPx5Pq66Bx7txXpHKO0xNg85Ieqoe6yL6Pknva7O/h0r6Zdqn69ITvuPz3iTprvSN5G5Jr5/gmH1S0tL0+qSk6WneePfS75Z0v6Rl7b7ZSLpR0ssa3k+TtFzSgRMdTxteTvhWtI+RdZB1INnTs7uQdZcL8G6yJ2lHyTrUeh9Z/j6B7Cnbl0U2otO/TVRA+ifxCrKue28g61Lhjen9S4C/l3Rc02p/SdYV8FHAEemzWam8XzVtfxvgh8BlZJ2c7QP8qEUcu5B1kfAhYHuy7pq/nro12Ar4NPDiiNgG+AtgUZtdej9wKNkxO4Cs6+l/aZi/E9nTqruQdeXwGUnbtdjO+Tz+CeJjgGUR0a5cG3IDn/AlnZOuVJo77ep2e5elq6vvNH1+brqqWpReB/aiPGsvVbW8BfjHiBjvVfLDZN00QNZd7xyyLnjXRTa8YCftiHdW1gPjcuADZH2r3xYRV0TEDRFRj4jrybpF/sumdedHxMMR8egkynkpcG9E/EdErI6IlRFxVYvl3gB8NyK+m8q+HFhIlmgB6sDTJG0ZEcsi4qYW24CsN9IzI+L+iBgj60L4hIb569L8dRHxXbLutFsNEfll4BhJT0jvTwC+NIn9tSE18AmfrB/vo3u4vX/n8X8cjf45Ig5Mr0U9LNNaGwVmAtfose5xL0ufQ3au7iDr7+UuSad3uP2lqQvp7dM5vQhA0rMk/UTZKEt/JusrZ3bTup10Pdyu+99mewCv0uO7A342MCf1APnXKZZlykYI27/NdnYm62Z53D3ps3F/aupJtGWX1BGxlKw/nuMlzSLrG6ebjt1sSAx8wo+IK8n63t5A0t7pSv2aVK/b7g+j1fZ+RNaBkxVvOfAo2ehY4/37bxsRWwOkK+V3R8ReZJ1s/ZOkF6R1N+eJwa+QdRy2W0RsS9YTpJqWiTbTrbTr/rfVcl9qHMsgIraKiI8CRMT3UzfTc4Bbgc+32c5Ssn8e43bnsS6fO3Ue2TePVwG/iohuum62ITHwCb+NBcA7IuIZZPWgn+3Rds+SdL2kT4zfBLP+Sd3efh74hKQnQlbPLemoNP1SZV3pise6KB7vHrfTbpUbbUM2MMlqSYcAr9vE8mNk1S3tyvsOsJOkd6UbqttIatXz5JeBl0k6SllXwDPSTdZdJe0o6eWpLn8NWTVMu66ALyTroXNU0myyex7dtvX/BtmwlO8kq9O3Ehu6hC9pa7IbWl+VtIhsOL05ad4rU8uD5tf3J7Hp9wL7k427uT3wnv7sgTV5D1m1za+Vdbv7Qx6rb35Ser+KbHzTz0bEFWneprolnsjbgDOVdQt8Blm3z21FxCNk3fv+IpV3aNP8lcCRZN9C7gVuB57XYjuLyZqHvo/sn8hisrGCp6TXu8mu1B8gu6fwtuZtJB8iq/u/nuwm9G/TZx1L9yi+DuwJXNLNNmx4DEVfOspG4PlORDwt3WC6LSLmbMb2ngucGhEth0zb1HyzMpF0BrCvu5Euv6G7wo+Ih4C7lUbbUeaAzd2upPFvCQKOY+Oh/MxKR9L2ZE03FxQdi/XfwCd8SReSfZ3fLz1QciJZs7QTJV0H3ET2NXmy2/sZ8FXgBWl7R6VZF0i6gewr8my6/IpsNiwkvYWsWul7qXGEldxQVOmYmdnmG/grfDMz642B7hhq9uzZMXfu3KLDMDMbGtdcc83yiBhtNW+gE/7cuXNZuHBh0WGYmQ0NSfe0m+cqHTOzinDCNzOrCCd8M7OKcMI3M6sIJ3wzs4pwwjczqwgnfDOzihjodvhmZkWLCB688EJqy5fnVuaUmTPZ4aSTer7d3BK+pP2A/2n4aC/gjIj4ZF4xmJl1av39Y9x35gezN2oeGK0/RmbvMNwJPyJuAw4EkDQC/BG4NK/yzcy6sn4dAHM+/GFmvfIVBQezeYqqw38BcGdEtH0E2MxsEGzoUXhKPlf3/VRUwn8N2bicG5F0sqSFkhaOjY3lHJaZWZNaNrSwpgx/G5fc90DSFsDLyQYh2UhELIiIeRExb3S0ZYdvZma5iXo9m5ATfjdeDPw2Iu4roGwzs864SmezvJY21TlmZgMnXeG7SqdDkmYCRwKX5FmumVm3ylSlk+uDVxHxCLBDnmWamW2W8SqdkeFP+MO/B2Zm/eRWOmZm1RD1dIVfgiqd4d8DM7N+ilSH71Y6ZmYl51Y6ZmbVUKZWOsO/B2Zm/ZRa6citdMzMSi610sFVOmZm5eZWOmZmVRHjN23dSsfMrNzGb9q6SsfMrNxcpWNmVhXjVTpupWNmVm7hVjpmZhXhKh0zs4pwKx0zs2oIt9IxM6sIV+mYmVWEW+mYmVWDW+l0SdIsSV+TdKukWyQdlmf5ZmYd21ClM/w3bXMdxBz4FHBZRPyVpC2AmTmXb2bWmSjPACi5JXxJTwCOAN4EEBFrgbV5lW9m1g230unOXsAY8EVJ10o6W9JWzQtJOlnSQkkLx8bGcgzPzKwFt9LpylTgYOBzEXEQ8DBwevNCEbEgIuZFxLzR0dEcwzMza8GtdLqyBFgSEVel918j+wdgZjawXKXThYi4F1gsab/00QuAm/Mq38ysK7XxQczdSqdT7wAuSC107gLenHP5ZmadcSud7kTEImBenmWamW0OV+mYmVVFiR68csI3M5tIiap0hn8PzMz6aEOVzshIsYH0gBO+mdlEUisduUrHzKzkwjdtzcwqIcZv2jrhm5mVXN1VOmZm1eAqHTOzanArHTOzqnArHTOzaoiol6I6B5zwzcwmVg8nfDOzSqjXS1GdA074ZmYTc5WOmVk1RD1K0UIHnPDNzCZWq7lKx8ysCtxKx8ysKtxKx8ysIkrUSifXMW0l/R5YCdSA9RHh8W3NbKCVqUon14SfPC8ilhdQrplZ5+oBI+VI+OXYCzOzfqnXkMqRKvPeiwB+IOkaSSe3WkDSyZIWSlo4NjaWc3hmZo8X9fJU6eS9F4dHxMHAi4F/kHRE8wIRsSAi5kXEvNHR0ZzDMzNrUg+YUpGbtpJ2n+S2VkTEQxMtEBFL08/7JV0KHAJcOcntm5nlr14vTZXOZG7ankdWFTPRv7gAzgXOb7eApK2AKRGxMk2/CDhz8qGameWvUq10IuJ5zZ9J2iki7u2wrB2BS1N71qnAVyLisg63YWaWr3qgqiT8Nt4I/FsnK0TEXcABXZZnZlaMEt207TbhHyvpEeDyiLitlwGZmQ0St9KBVwJ3AK+QdHYP4zEzGyz1OqpKK51WIuI+4LL0MjMrr6hDSVrpdLUXkj4j6dw0/aKeRmRmNkDCvWWyFrgrTT+/R7GYmQ2eer00D151m/AfAbaVNA2Y7INZZmbDp15HU8oxxGG3rXQeAB4FPgP8onfhmJkNlsq20pE0S9IXgePTR+cD7tPezMqrqgOgRMQKSR8F5gLLgacDl/QhLjOzwVClrhVaOBG4OyK+D1zT43jMzAZKmVrpdJPwHwTeKmk/4DpgUURc29uwzMwGRFWrdAAi4iOSfgT8DjgQOAJwwjezcqrXYaSirXQknQmMAIvIru6v6HFMZmYDI+p1NK2I4b97r5sr/DMk7QgcBBwvae+IeEvvQzMzGwAVGwCllb8D/tv92ZtZ2VVqAJQ2zgH+Po1cdUFELOpdSGZmA6REY9p2+2/rFLJ/FlOBT/cuHDOzAVOiKp1u9+JOYAbwzYg4oofxmJkNlIjytNLpNuHfBPwYOFHS1Z2sKGlE0rWSvtNl2WZm+amVp7fMbuvw9wXGgAVkD2J14p3ALcATuizbzCw/rtJhf7KHrU4FTp7sSpJ2BV4CeFhEMxsKZWql0+1ezALeA5wGrO5gvU+mdepdlmtmli+30uFMshu2tzHJ5C3ppcD9ETFhh2uSTpa0UNLCsbGxLsMzM+uRqlXppButyySdBBARSyLih2n69EmWdTjwckm/By4Cni/py80LRcSCiJgXEfNGR0cnuWkzs/6oXCudiKgBNwJ7d1tQRLw3InaNiLnAa4AfR8Qbut2emVkuanVUkiqdTlrpzAROk3QksDR9FhFxbO/DMjMbEPU6lKRKp5OEf1j6eXB6AUQ3haYeNq/oZl0zszxFVHMAlD37FoWZ2aCqV/DBq4i4p5+BmJkNpKq10jEzq6qIgJFypMpy7IWZWb/U66gkdfgd74Wkl/UjEDOzgVSrlaaVTjd7cVbPozAzG1BVbaUzrhy3q80qLNau5d4PnUVtxYqiQxl49Uce6fmDV6tXreKK8z/P2tWPtpw/febWHPXWU3paJnSX8Ltqe29mg2PtPfew4uKLmbrTToxss3XR4Qy06XvtxcxnPaun27z3jtu46ac/Ytsn7sjULaZvNH/LbfrTe3y3/eGb2RCLenbdtuPpp/OEo48qOJrqqdezPidf8s7TmLPPfrmVW46KKTPrTKRObkvyQNGwqddqAEwZyfeau5uEf1/PozCzfKUrzLI0Nxw29fp4ws+3F86Oz3ZEHNmPQMwsP+NVOmVpfTJs6uvXAzBlyoAnfDMrgQ1VOk4BRRivw5+S8xO8PttmVeQqnUINUx0+kv6pYTq/W8xm1hNRS1f4JXmCdNjUa6lKJ+c6/I7+vUiaBXwC2F/SauB64ETgzb0Pzcz6xq10ClWvjVfpDHDCj4gVwJslvQS4F3gRcEkf4jKzfnKVTqEeq9IZjpu2f0nWPPNQwK12zIbMhlY6rtIpRFFVOt2e7VnAe4DTgNU9i8bM8uEqnUJtuMLPuVlmt7eIzwT2j4jbJNUns4KkGcCVwPRU7tci4gNdlm9mm2O8SifnK0zLxHizzKlDkPAjYgmwJE2fPsnV1gDPj4hVkqYBP5f0vYj4dTcxmFn33EqnWLVhevBK0mcknZumXzSZdSKzKr2dll7uedOsCDF+09ZVOkWIeg2k3G+ad1vaWuCuNP38ya4kaUTSIuB+4PKIuKrFMidLWihp4djYWJfhmdlExqsU/KRtMeq1GiMFVKd1e7YfAbZNVTO7T3aliKhFxIHArsAhkp7WYpkFETEvIuaNjo52GZ6ZTcitdApVq9UKuX/S7dl+ALgT+Azwi05XTu35rwCO7rJ8M9scbqVTqKjVcq+/hw4TvqRZkr4IHJ8+Oh+YN8l1R9OTukjaEnghcGsn5ZtZb4Rb6RSqXq8xZWr+4091/KStpI8Cc4HlwNOZ/JO2c4DzJI2Q/aO5OCK+00n5ZtYjbqVTqHqtxpQC7p908y/mRODuiPg+cM1kV4qI64GDuijPzHrNrXQKVa/Vcn/KFrpL+A8Cb029ZF4HLIqIa3sblpn1k1vpFCtL+ANepQMQER+R9CPgd8CBwBGAE77ZMHErnUJlCX8IqnQknQmMAIvIru6v6HFMZtZvrtIpVH0YWukARMQZZN0kTAGOl/T5nkdlZn21oUrHrXQKUVQdfrffKc4BngzsAHy2d+GYWS7cSqdQ9Xoxdfjdnu1TyKqDpgKf6l04ZpYLV+kUqqg6/G5LvBOYAXwzIo7oYTxmlgO30ilWfci6VrgJ+DFwoqSrexiPmeXBrXQKFbUaI8PQLDPZm6w9/oL008yGiat0ClWr1Zg6bXgS/uKI+LGkOWRdHZvZEHErnWJFrYamT8+93G6/zx0taVfgv4BP9DAeM8vDhiodX+EXoV6vMVJA52m9GMR8Tc+iMbN81LNBtPMeccky9fXrUQEPXvViEPNaLwMys/6L8St8J/xC1Ov1wW2WmYYmXCbpJMgGMY+IH6bpyQ5ibmaDou4Hr4pUVOdpkzrbEVEDbiRrnWNmw86tdApVr60f+O6RZwKnSToSWJo+i4g4tvdhmVk/bajScSudQtRr9UI6T+sk4R+Wfh6cXgDR23DMLBfjQxy6lU4hsiEOBzvh79m3KMwsV5Fa6fimbTGK6h55kwlf0u5psuXVfMP8FRHxUK8CM7M+ciudQg1yHf55ZMl+ou9+AZwLnN9uAUm7pfk7AXVgQUS4p02zImxopeMqnSLUa8U0y9xkwo+I5/WorPXAuyPit5K2Aa6RdHlE3Nyj7ZvZJEXUQXIdfkFikJtl9kJELIuI36bplcAtwC55lW9mDerh6pwC1Qqq0inkjEuaCxwEXNVi3smSFkpaODY2lntsZpVQr7tbhYJEBFGvF9K1Qu5nXNLWwNeBd7W6yRsRCyJiXkTMGx0dzTs8s0qIes1X+AUZ76l0pOxX+JKmkSX7CyLikjzLNrMGrtIpTK22HmCoRrzqmLK7Q18AbomIj+dVrpm1UK/7hm1BopY9A1H2OvzDgROA50talF7H5Fi+mSURdV/hF6ReK65KJ7d2QRHxcyZuy29meSl5lU7U69x71+2sXzN4w3WsfuRhoJgqnfwbgppZ8UreSmfJrTdx8b++t+gwJjRj5la5l+mEb1ZBZW+l8+hDfwbgqLe+k22fuGPB0WxsytRpzNln39zLdcI3q6KSV+msX7cOgF2e/FS222nngqMZHOU942bWXpS7lc76tVnd/dQttig4ksHihG9WQVEvdyud9WvXAjB1mhN+o/KecTNrr+xVOuMJ31f4j1PeM25m7ZW8lY6v8Fsr7xk3s7bKXqVTW7eWkalTS/1PrRs+GmZVVK/DlDLftF3L1C2mFx3GwHHCN6uiqCOV989//dq1jEybVnQYA6e8Z9zM2oqy37Rd5yv8Vsp7xs2svUpU6fiGbTMnfLMqimJGXMrL+rVr3EKnBSd8swoqf5XOOl/ht1DeM25m7dVqrtKpICd8swqK0rfSWeOE30J5z7iZtVfyKp3aunWuw2+hvGfczNorfSudNYz4Cn8jTvhmVVT2Vjq+adtSbglf0jmS7pd0Y15lmllrpW+l4zr8lvI84+cCR+dYnpm1U6uVfACUta7DbyG3hB8RVwIP5FWembUXUd7eMiMiu2nrK/yNDNwZl3SypIWSFo6NjRUdjlk5lbhKZ/268cFP3JdOs4E74xGxICLmRcS80dHRosMxK6d6HZW0lc5jg5+4t8xmU4sOwMzyF1GHAh68inqdq799CY+ufKhvZaxbvRrwFX4rTvhmVVQPGMk/4T+w7I/87CvnZqNRjfSvWeiMrbZmh11379v2h1VuCV/ShcBzgdmSlgAfiIgv5FW+mTWo1QrpWmH1ypUAHHfaGcw94ODcy6+63BJ+RLw2r7LMbGIRxdy0Xf3wKiC7Arf8DdxNWzPLQUGDmK9elV3hT9/aCb8ITvhmVVRQK50141f4W2+Te9nmhG9WSUW10hmv0pk+c2buZZsTvlk1FdRKZ/WqVUyfuRVTStxx2yBzwjeroqJa6Ty8ihmuvy+ME75ZBRXVSmfNw6uY7hY6hXHCN6uiggZAeXTVSjfJLJATvlkV1YsZ03bNqlVuoVMgd61gVkH9qNL58/33seaRhydc5tGVD/kKv0BO+GZVVK/3tJXOQ8vv5+xTToKITS671Xbb9axc64wTvlkFRb23rXT+tPgPEMFzXvcmttt5l7bLSVPY/an/p2flWmec8M2qqEcDoES9zsN/XsGD9y4F4ClHPJ+tt9t+s7dr/eGEb1ZFPWql86NzPsd1l38PyPqf32qWq2sGmVvpmFVRD1rpRAS3/+ZXG94/YfZoqQdGLwMnfLMK6kUrnbF77uaRP69gj6cfBLDJFjpWPCd8syqq19FmtNK554ZFfOk9pwDwnNe9CYBtdpjdi8isj1yHb1ZF9e57y6zXa1xx3ueZNn0GLzzpbey4594cd9r/5Ylz9+5xkNZrTvhmFRSbMQDKLT+7guWL7+Gl7zqd/Q57NgB7P+NZPYzO+sUJ36yKuhgAZcmtN3Hll85h2R23sdPeT2LfQw/vU3DWL7kmfElHA58CRoCzI+KjeZZvZpmImHSVTr1W4+Yrf8xPzlvAjK234aAXv4yDjnqpW+QModwSvqQR4DPAkcAS4GpJ34qIm/OKwcySDqp0rrr0Yn751QuYPnMrjn/fB9l+gidpbbApJtH3RU8Kkg4D5kfEUen9ewEi4iPt1pk3b14sXLiw47I+/epXUy+gJ0CzYSGgNgVqk6jW0fqHqU/fnrWzD4EprgXOw9rpY5x51vu7WlfSNRExr9W8PM/eLsDihvdLgI3u9Eg6GTgZYPfdd++qII3MQJre1bpmVRBAfSrEJK6L6lvMYv22+zvZl0CeZ7DVpcRGXy8iYgGwALIr/G4KeseF53ezmplZqeVZ77EE2K3h/a7A0hzLNzOrtDwT/tXAkyTtKWkL4DXAt3Is38ys0nKr0omI9ZLeDnyfrFnmORFxU17lm5lVXa53YSLiu8B38yzTzMwybrtoZlYRTvhmZhXhhG9mVhFO+GZmFZFb1wrdkDQG3NPl6rOB5T0Mpx+GIUZwnL02DHEOQ4zgOFvZIyJGW80Y6IS/OSQtbNefxKAYhhjBcfbaMMQ5DDGC4+yUq3TMzCrCCd/MrCLKnPAXFB3AJAxDjOA4e20Y4hyGGMFxdqS0dfhmZvZ4Zb7CNzOzBk74ZmYVUbqEL+loSbdJukPS6QMQz+8l3SBpkaSF6bPtJV0u6fb0c7uG5d+bYr9N0lF9jOscSfdLurHhs47jkvSMtH93SPq0ejiydZsY50v6YzqeiyQdU2SMafu7SfqJpFsk3STpnenzgTmeE8Q4UMdT0gxJv5F0XYrzX9PnA3MsNxHnQB3PjUREaV5k3S7fCewFbAFcBzyl4Jh+D8xu+uzfgNPT9OnAx9L0U1LM04E9076M9CmuI4CDgRs3Jy7gN8BhZCOafQ94cZ9jnA+c2mLZQmJM258DHJymtwF+l+IZmOM5QYwDdTzTNrdO09OAq4BDB+lYbiLOgTqeza+yXeEfAtwREXdFxFrgIuDYgmNq5VjgvDR9HnBcw+cXRcSaiLgbuINsn3ouIq4EHticuCTNAZ4QEb+K7Df3/IZ1+hVjO4XEmOJcFhG/TdMrgVvIxnAemOM5QYztFHXOIyJWpbfT0isYoGO5iTjbKez3s1HZEn6rgdIn+qXOQwA/kHSNsgHaAXaMiGWQ/SECT0yfFx1/p3HtkqabP++3t0u6PlX5jH+1H4gYJc0FDiK74hvI49kUIwzY8ZQ0ImkRcD9weUQM5LFsEycM2PFsVLaEP6mB0nN2eEQcDLwY+AdJR0yw7CDGD+3jKiLezwF7AwcCy4D/SJ8XHqOkrYGvA++KiIcmWrRNTH2PtUWMA3c8I6IWEQeSjXt9iKSnTbD4oMU5cMezUdkS/sANlB4RS9PP+4FLyapo7ktf5Ug/70+LFx1/p3EtSdPNn/dNRNyX/tDqwOd5rMqr0BglTSNLpBdExCXp44E6nq1iHNTjmWJbAVwBHM2AHct2cQ7y8YTyJfyBGihd0laSthmfBl4E3Jhi+pu02N8A30zT3wJeI2m6pD2BJ5Hd0MlLR3Glr9YrJR2aWha8sWGdvhj/o09eQXY8C40xbfcLwC0R8fGGWQNzPNvFOGjHU9KopFlpekvghcCtDNCxnCjOQTueG+nX3eCiXsAxZC0Q7gTeX3Ase5Hdmb8OuGk8HmAH4EfA7enn9g3rvD/Ffht9vFsPXEj2lXMd2VXGid3EBcwj+6W+E/hP0tPbfYzxS8ANwPVkf0Rziowxbf/ZZF/DrwcWpdcxg3Q8J4hxoI4n8HTg2hTPjcAZ3f7NFBTnQB3P5pe7VjAzq4iyVemYmVkbTvhmZhXhhG9mVhFO+GZmFeGEb2ZWEU74VgmSZkl6W8P7nSV9rU9lHSfpjDbzVqWfo5Iu60f5Zu044VtVzAI2JPyIWBoRf9Wnsk4DPjvRAhExBiyTdHifYjDbiBO+VcVHgb1TH+X/LmmuUj/7kt4k6RuSvi3pbklvl/RPkq6V9GtJ26fl9pZ0WeoI72eS9m8uRNK+wJqIWJ7e7ynpV5KulvTBpsW/Aby+r3tt1sAJ36ridODOiDgwIv65xfynAa8j6/vkLOCRiDgI+BXZ4+6QDUT9joh4BnAqra/iDwd+2/D+U8DnIuKZwL1Nyy4EntPl/ph1bGrRAZgNiJ9E1k/8Skl/Br6dPr8BeHrqZfIvgK82DEg0vcV25gBjDe8PB45P018CPtYw735g596Eb7ZpTvhmmTUN0/WG93Wyv5MpwIrIusOdyKPAtk2fteu/ZEZa3iwXrtKxqlhJNrRfVyLrO/5uSa+CrPdJSQe0WPQWYJ+G978g67UVNq6v35fHelM06zsnfKuEiPgT8AtJN0r69y4383rgREnjvZ+2Gj7zSuAgPVbv806ygW+uZuMr/+cB/9tlLGYdc2+ZZj0m6VPAtyPih5tY7krg2Ih4MJ/IrOp8hW/Wex8GZk60gKRR4ONO9pYnX+GbmVWEr/DNzCrCCd/MrCKc8M3MKsIJ38ysIpzwzcwq4v8DLBUbtTg2u/oAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"rmvs_swifter_comparison-8pl_16tp-testparticles-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"rmvs_swifter_comparison-8pl_16tp-testparticles-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time (d)' :'time'})" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'px' ()>\n",
+       "array(0.)\n",
+       "Coordinates:\n",
+       "    id       int64 105\n",
+       "    time     float64 1.09e+03
" + ], + "text/plain": [ + "\n", + "array(0.)\n", + "Coordinates:\n", + " id int64 105\n", + " time float64 1.09e+03" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftdiff['px'].sel(id=105).isel(time=109)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/rmvs_swifter_comparison/8pl_16tp_encounters/tp.in b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/tp.in new file mode 100644 index 000000000..c8cc418b0 --- /dev/null +++ b/examples/rmvs_swifter_comparison/8pl_16tp_encounters/tp.in @@ -0,0 +1,49 @@ +16 +105 +0.59427697124197276235 -0.8232523083817967491 3.7129329104855261984e-05 +0.020564990514662154913 0.010004295439859960809 -5.226292361234363611e-07 +109 +4.119750673485228276 -2.8866333472175926822 -0.080165336328135106125 +0.041127620144391897894 0.0065414198811065849687 -0.00012215100047356211078 +101 +-0.09859055695785905182 0.2975290300646933339 0.03335708456145129036 +-0.029750083068855306956 -0.0078122718370876240157 0.0023293874953380202045 +102 +-0.09863667837052235432 0.29748290865203008693 0.03335708456145129036 +-0.034957182012873608268 -0.0078122718370876240157 0.0023293874953380202045 +103 +-0.6439245854659476631 -0.32479782779646521051 0.032702713983447248558 +0.0153169432007213678765 -0.018153139924556138673 -0.0007667345025597138231 +104 +-0.6440390060468921263 -0.32491224837740956266 0.032702713983447248558 +0.002622475790030579998 -0.018153139924556138673 -0.0007667345025597138231 +106 +0.5941565154300937346 -0.82337276419367577684 3.7129329104855261984e-05 +0.0067761100461144049487 0.010004295439859960809 -5.226292361234363611e-07 +107 +-1.5926895092930311026 0.48169594448240382611 0.049163460846716633412 +-0.00044929323243133797994 -0.01219974682608557931 -0.00016910795626524249315 +108 +-1.5927535941205388514 0.48163185965489618834 0.049163460846716633412 +-0.006608251428879123937 -0.01219974682608557931 -0.00016910795626524249315 +110 +4.118428875469033912 -2.8879551452337870465 -0.080165336328135106125 +-0.032636814258902961672 0.0065414198811065849687 -0.00012215100047356211078 +111 +6.3634605491076454697 -7.64917730379279881 -0.12023019299387090186 +0.026096616095614821179 0.0035613826786502411278 -0.00022039988214595340028 +112 +6.3623595643973844815 -7.650278288503059798 -0.12023019299387090186 +-0.01812972167145235694 0.0035613826786502411278 -0.00022039988214595340028 +113 +14.814394441298382787 13.052280053388562564 -0.14347198499748289868 +0.010469662145386185101 0.0027742356008832688187 4.416821810149910185e-05 +114 +14.813914925323977911 13.051800537414157688 -0.14347198499748289868 +-0.015719864931937603536 0.0027742356008832688187 4.416821810149910185e-05 +115 +29.565157420731857485 -4.579098772788029237 -0.5871109926822926095 +0.014900134286357700347 0.003128345390031967918 -7.5036135696161668576e-05 +116 +29.564691895839423808 -4.5795642976804593616 -0.5871109926822926095 +-0.0139711373401985618214 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/.idea/.gitignore b/examples/rmvs_swifter_comparison/mars_ejecta/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in b/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in new file mode 100644 index 000000000..40cf41bad --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +0.00029591220828563 +0.004650467260962157 +0.0 +0.0 diff --git a/example/param.in b/examples/rmvs_swifter_comparison/mars_ejecta/param.swifter.in similarity index 63% rename from example/param.in rename to examples/rmvs_swifter_comparison/mars_ejecta/param.swifter.in index dd9970c9d..f4035c4c0 100644 --- a/example/param.in +++ b/examples/rmvs_swifter_comparison/mars_ejecta/param.swifter.in @@ -4,17 +4,17 @@ !NPLMAX -1 ! not used !NTPMAX -1 ! not used T0 0.0e0 -TSTOP 1.e9 ! simulation length in years -DT 1e-3 ! stepsize in years -PL_IN pl.in +TSTOP 6000.000 ! simulation length in days +DT 1e0 ! stepsize in days +ISTEP_OUT 1 ! output cadence +ISTEP_DUMP 1 ! system dump cadence +PL_IN pl.swifter.in TP_IN tp.in IN_TYPE ASCII -ISTEP_OUT 1000000 ! output cadence -BIN_OUT bin.dat -OUT_TYPE REAL4 ! double precision real output -OUT_FORM EL ! osculating element output +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 ! double precision real output +OUT_FORM XV ! osculating element output OUT_STAT NEW -ISTEP_DUMP 1000000 ! system dump cadence J2 0.0 ! no J2 term J4 0.0 ! no J4 term CHK_CLOSE yes ! check for planetary close encounters @@ -24,7 +24,7 @@ CHK_EJECT -1.0 ! ignore this check CHK_QMIN -1.0 ! ignore this check !CHK_QMIN_COORD HELIO ! commented out here !CHK_QMIN_RANGE 1.0 1000.0 ! commented out here -ENC_OUT enc.dat +ENC_OUT enc.swifter.dat EXTRA_FORCE no ! no extra user-defined forces -BIG_DISCARD no ! output all planets if anything discarded +BIG_DISCARD yes ! output all planets if anything discarded RHILL_PRESENT yes ! Hill's sphere radii in input file diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in b/examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in new file mode 100644 index 000000000..7df10c4d0 --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/param.swiftest.in @@ -0,0 +1,26 @@ +T0 0.0e0 +TSTOP 6000.000 ! simulation length in days +DT 1e0 ! stepsize in days +ISTEP_OUT 1 ! output cadence +ISTEP_DUMP 1 ! system dump cadence +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.in +IN_TYPE ASCII +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 ! double precision real output +OUT_FORM XV ! osculating element output +OUT_STAT REPLACE +CHK_CLOSE yes ! check for planetary close encounters +CHK_RMIN 0.005e0 ! check for close solar encounters +CHK_RMAX 10000.0e0 ! discard outside of +CHK_EJECT -1.0 ! ignore this check +CHK_QMIN -1.0 ! ignore this check +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no ! no extra user-defined forces +BIG_DISCARD yes ! output all planets if anything discarded +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 86400.0000 diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/pl.swifter.in b/examples/rmvs_swifter_comparison/mars_ejecta/pl.swifter.in new file mode 100644 index 000000000..ab7f6ec08 --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/pl.swifter.in @@ -0,0 +1,36 @@ + 9 ! Solar system. Taken from JPL Horizons on 10-31-2012 00:00 (JD 2456231.5) + 1 2.9591220828563E-04 + .0 .0 .0 + .0 .0 .0 + 2 4.912576812862670E-11 1.475E-03 ! Mercury / Mass (Msun) / Rhill (AU) + 1.63104E-05 ! Radius (AU) + 3.347381871776144E-01 -2.106110537919978E-01 -4.792146121659843E-02 + 9.457239437449661E-03 2.510612575783642E-02 1.183593414707043E-03 + 3 7.243495778974390E-10 6.758E-03 ! Venus + 4.04538E-05 + -4.641166544325086E-01 5.473160240817795E-01 3.428518329144122E-02 + -1.549753193570599E-02 -1.319081534035637E-02 7.136685719563098E-04 + 4 8.997065158526820E-10 1.004E-02 ! Earth + Moon + 4.2587571E-05 + 7.844742229036105E-01 6.083466458892074E-01 -1.996912082982283E-05 + -1.081828010368904E-02 1.352675083743791E-02 2.330162751015549E-07 + 5 9.549592181631700E-11 7.246E-03 ! Mars + 2.26601E-05 + 3.248808297463504E-01 -1.392041319192106E+00 -3.714224198825128E-02 + 1.415678377567019E-02 4.380992498628390E-03 -2.558013868476858E-04 + 6 2.825362796108150E-07 0.3553 ! Jupiter + 4.67326E-04 + 1.873343037544675E+00 4.683322528183729E+00 -6.137078942429344E-02 + -7.104028854569467E-03 3.164193073442964E-03 1.458211211387848E-04 + 7 8.459765747874750E-08 0.4356 ! Saturn + 3.89257E-04 + -8.251865479985982E+00 -5.225008639958182E+00 4.193935221241906E-01 + 2.677374423933877E-03 -4.723961471952217E-03 -2.458643348128228E-05 + 8 1.292032638982330E-08 0.4686 ! Uranus + 1.69534E-04 + 1.992234896320000E+01 2.342619564376139E+00 -2.493547557095487E-01 + -4.936420700174518E-04 3.724868172847281E-03 2.027439791557233E-05 + 9 1.524368011623570E-08 0.7757 ! Neptune + 1.64601E-04 + 2.647158936403647E+01 -1.409652133490650E+01 -3.196444184043846E-01 + 1.449117851099529E-03 2.791630281764020E-03 -9.063088654405710E-05 diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/pl.swiftest.in b/examples/rmvs_swifter_comparison/mars_ejecta/pl.swiftest.in new file mode 100644 index 000000000..e1931fc7f --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +2 4.91257681286267e-11 +1.63104e-05 +0.3347381871776144 -0.2106110537919978 -0.04792146121659843 +0.00945723943744966 0.02510612575783642 0.001183593414707043 +3 7.24349577897439e-10 +4.04538e-05 +-0.4641166544325086 0.5473160240817795 0.03428518329144122 +-0.01549753193570599 -0.01319081534035637 0.0007136685719563098 +4 8.99706515852682e-10 +4.2587571e-05 +0.7844742229036105 0.6083466458892074 -1.996912082982283e-05 +-0.01081828010368904 0.01352675083743791 2.330162751015549e-07 +5 9.5495921816317e-11 +2.26601e-05 +0.3248808297463504 -1.392041319192106 -0.03714224198825128 +0.01415678377567019 0.00438099249862839 -0.0002558013868476858 +6 2.82536279610815e-07 +0.000467326 +1.873343037544675 4.683322528183729 -0.06137078942429344 +-0.007104028854569467 0.003164193073442964 0.0001458211211387848 +7 8.45976574787475e-08 +0.000389257 +-8.251865479985982 -5.225008639958182 0.4193935221241906 +0.002677374423933877 -0.004723961471952217 -2.458643348128228e-05 +8 1.29203263898233e-08 +0.000169534 +19.9223489632 2.342619564376139 -0.2493547557095487 +-0.0004936420700174518 0.003724868172847281 2.027439791557233e-05 +9 1.52436801162357e-08 +0.000164601 +26.47158936403647 -14.0965213349065 -0.3196444184043846 +0.001449117851099529 0.00279163028176402 -9.06308865440571e-05 diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/swiftest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_swifter_comparison/mars_ejecta/swiftest_rmvs_vs_swifter_rmvs.ipynb new file mode 100644 index 000000000..c0ae7eec3 --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/swiftest_rmvs_vs_swifter_rmvs.ipynb @@ -0,0 +1,251 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import swiftest\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 6.000e+03\n", + "Creating Dataset\n", + "Successfully converted 6001 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swifter.in'\n", + "swiftersim = swiftest.Simulation(param_file=inparfile, codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 6.001e+03\n", + "Creating Dataset\n", + "Successfully converted 6002 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swiftest.in'\n", + "swiftestsim = swiftest.Simulation(param_file=inparfile)\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestdat - swifterdat" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (d)'})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff['rmag'] = np.sqrt(swiftdiff['px']**2 + swiftdiff['py']**2 + swiftdiff['pz']**2)\n", + "swiftdiff['vmag'] = np.sqrt(swiftdiff['vx']**2 + swiftdiff['vy']**2 + swiftdiff['vz']**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "plidx = swiftdiff.id.values[swiftdiff.id.values < 10]\n", + "tpidx = swiftdiff.id.values[swiftdiff.id.values > 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Planets only\")\n", + "fig.savefig(\"rmvs_swifter_comparison-mars_ejecta-planets-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Planets only\")\n", + "fig.savefig(\"rmvs_swifter_comparison-mars_ejecta-planets-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"rmvs_swifter_comparison-mars_ejecta-testparticles-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"rmvs_swifter_comparison-mars_ejecta-testparticles-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/rmvs_swifter_comparison/mars_ejecta/tp.in b/examples/rmvs_swifter_comparison/mars_ejecta/tp.in new file mode 100644 index 000000000..d5eb0e3f8 --- /dev/null +++ b/examples/rmvs_swifter_comparison/mars_ejecta/tp.in @@ -0,0 +1,601 @@ + 200 + 6000200 + 0.321794727714005 -1.39371227734394 -3.555372224179648E-002 + 1.263074812292130E-002 3.554726326213714E-003 5.297001107625803E-004 + 6000201 + 0.327226184487893 -1.39016803345029 -3.472777857996821E-002 + 1.531652992677778E-002 5.307306923696688E-003 9.381180638637231E-004 + 6000202 + 0.327531202012097 -1.39478453402311 -3.768059236489047E-002 + 1.546735696093592E-002 3.024509922426058E-003 -5.220083559665117E-004 + 6000203 + 0.322202594471783 -1.39306474804903 -3.456946701305916E-002 + 1.283243270995610E-002 3.874920791552106E-003 1.016400989319078E-003 + 6000204 + 0.323275102327213 -1.39231827262319 -4.063286630727199E-002 + 1.336277331700188E-002 4.244042778378470E-003 -1.981867830972686E-003 + 6000205 + 0.325545380653237 -1.39090814848439 -3.352094137611809E-002 + 1.448539519756952E-002 4.941330064430509E-003 1.534882714168952E-003 + 6000206 + 0.322100032022230 -1.38941601200018 -3.760532734717235E-002 + 1.278171696789352E-002 5.679171344404378E-003 -4.847908241938090E-004 + 6000207 + 0.325337949472342 -1.39379280734375 -3.374182250017822E-002 + 1.438282328833895E-002 3.514905332112549E-003 1.425659990227191E-003 + 6000208 + 0.326082121124172 -1.39530189188417 -3.547938702480286E-002 + 1.475080609012429E-002 2.768683467912135E-003 5.664578686714714E-004 + 6000209 + 0.327275685332658 -1.39441408865592 -3.527833381550945E-002 + 1.534100742400883E-002 3.207690138697890E-003 6.658759573365761E-004 + 6000210 + 0.327855145958387 -1.39318452150569 -3.930697139978061E-002 + 1.562754285445135E-002 3.815694439606817E-003 -1.326230758891795E-003 + 6000211 + 0.328078710851062 -1.39251497560023 -3.504731288890989E-002 + 1.573809266562045E-002 4.146775820637334E-003 7.801126762871974E-004 + 6000212 + 0.321277816542297 -1.39195915492794 -3.578170284173104E-002 + 1.237514255024041E-002 4.421621614318133E-003 4.169667921656008E-004 + 6000213 + 0.324665498950826 -1.39490683098100 -3.970778222771389E-002 + 1.405030561400833E-002 2.964035733299919E-003 -1.524426284193035E-003 + 6000214 + 0.324929781829885 -1.39405065211182 -4.042853272331495E-002 + 1.418098991790633E-002 3.387404586890700E-003 -1.880827641470143E-003 + 6000215 + 0.327555988964697 -1.39432357646482 -3.871524764041770E-002 + 1.547961377324917E-002 3.252447191181946E-003 -1.033631374975754E-003 + 6000216 + 0.321438220244275 -1.39139099683337 -3.554066697282077E-002 + 1.245446000814854E-002 4.702568096196656E-003 5.361557644332466E-004 + 6000217 + 0.327269239795964 -1.39111145972877 -3.426641502936644E-002 + 1.533782019342066E-002 4.840795408002274E-003 1.166256090318398E-003 + 6000218 + 0.323989604933645 -1.39344910147082 -4.061548100580529E-002 + 1.371608517771453E-002 3.684863230669170E-003 -1.973271034886913E-003 + 6000219 + 0.321638711062574 -1.39087780679511 -3.541758920393877E-002 + 1.255360000208438E-002 4.956333618793669E-003 5.970160540173710E-004 + 6000220 + 0.322548442178556 -1.38969900689356 -3.516409557966647E-002 + 1.300344971633673E-002 5.539234202882858E-003 7.223652175672305E-004 + 6000221 + 0.326425905823290 -1.38912149826721 -3.516059934460978E-002 + 1.492080296716386E-002 5.824804396075300E-003 7.240940584451341E-004 + 6000222 + 0.325686803560988 -1.39394570042399 -4.039235894274407E-002 + 1.455532690983334E-002 3.439301774920795E-003 -1.862940196963350E-003 + 6000223 + 0.327419177059503 -1.39257520407836 -3.429421078579946E-002 + 1.541196213929194E-002 4.116993654016758E-003 1.152511465264746E-003 + 6000224 + 0.324490052620445 -1.39553030085443 -3.872774571953116E-002 + 1.396354978011187E-002 2.655738325987235E-003 -1.039811505806850E-003 + 6000225 + 0.321731345032329 -1.39031854790183 -3.853949894445081E-002 + 1.259940624537157E-002 5.232879566177696E-003 -9.467260253928260E-004 + 6000226 + 0.325601002353804 -1.39413056037783 -3.398693779254160E-002 + 1.451289937508628E-002 3.347891031734538E-003 1.304453798319087E-003 + 6000227 + 0.325825665573909 -1.38837078808078 -3.783072474317082E-002 + 1.462399229429218E-002 6.196020414654821E-003 -5.962467834347196E-004 + 6000228 + 0.328007765778950 -1.39171771880483 -3.491579285982123E-002 + 1.570301128843478E-002 4.541008506865058E-003 8.451475491903844E-004 + 6000229 + 0.326038941297358 -1.38837178473418 -3.696108906496336E-002 + 1.472945425064948E-002 6.195527583046642E-003 -1.662237200565085E-004 + 6000230 + 0.324865697509285 -1.38818972404806 -3.707510223923227E-002 + 1.414930108941243E-002 6.285554126260012E-003 -2.226016903873118E-004 + 6000231 + 0.326890450931510 -1.39246034816528 -3.388258567264032E-002 + 1.515051423076515E-002 4.173788347277624E-003 1.356054508127195E-003 + 6000232 + 0.325593633813168 -1.38828971482136 -3.764909195799739E-002 + 1.450925573155059E-002 6.236110043272472E-003 -5.064318314410409E-004 + 6000233 + 0.326626976582762 -1.39216397200456 -3.371070451979964E-002 + 1.502022973415419E-002 4.320342344240131E-003 1.441047410021331E-003 + 6000234 + 0.327898875134393 -1.39098636673654 -3.929119504411583E-002 + 1.564916633966053E-002 4.902652198234570E-003 -1.318429564711382E-003 + 6000235 + 0.325772175388830 -1.39276944665725 -4.081849758657961E-002 + 1.459754212231259E-002 4.020943329837438E-003 -2.073659984154833E-003 + 6000236 + 0.325970862049605 -1.39573308065969 -3.729140206480187E-002 + 1.469578998479103E-002 2.555466459007209E-003 -3.295590242806717E-004 + 6000237 + 0.323334466127931 -1.38903625723277 -3.899099401712434E-002 + 1.339212791235488E-002 5.866954932989258E-003 -1.169984223183693E-003 + 6000238 + 0.321058043138336 -1.39159433514890 -3.730357920900053E-002 + 1.226646757888280E-002 4.602020053452453E-003 -3.355804571435673E-004 + 6000239 + 0.321631711087942 -1.39236740484015 -3.509861335813708E-002 + 1.255013860944605E-002 4.219747562605665E-003 7.547452891357343E-004 + 6000240 + 0.321306936119327 -1.39062854909901 -3.740848791004924E-002 + 1.238954178664758E-002 5.079588173238877E-003 -3.874563887900095E-004 + 6000241 + 0.322359878582366 -1.39481226441940 -3.804012263745659E-002 + 1.291020757217519E-002 3.010797617075125E-003 -6.997912057971096E-004 + 6000242 + 0.323817379375385 -1.38838475633633 -3.772374286905647E-002 + 1.363092197200557E-002 6.189113301486290E-003 -5.433456957891204E-004 + 6000243 + 0.327623726544369 -1.39464240098381 -3.788413992758530E-002 + 1.551310908886966E-002 3.094792785121600E-003 -6.226598686018013E-004 + 6000244 + 0.322826324940355 -1.38886200520861 -3.642775302359531E-002 + 1.314085897803487E-002 5.953120198633154E-003 9.750372819152632E-005 + 6000245 + 0.322612433934003 -1.39373086883468 -3.975745217634516E-002 + 1.303509277261627E-002 3.545533085870808E-003 -1.548987400995745E-003 + 6000246 + 0.321924589943174 -1.39047906318775 -3.905523030161998E-002 + 1.269496323622005E-002 5.153506931519558E-003 -1.201748195765625E-003 + 6000247 + 0.325483402999438 -1.39432969787986 -3.410254622383869E-002 + 1.445474808727309E-002 3.249420234359466E-003 1.247286994996116E-003 + 6000248 + 0.324075789932299 -1.39390925319708 -3.387081182165206E-002 + 1.375870249214517E-002 3.457324434934150E-003 1.361876517960287E-003 + 6000249 + 0.325555351421543 -1.39061734515993 -3.362701221631959E-002 + 1.449032560743936E-002 5.085128369354139E-003 1.482432120453008E-003 + 6000250 + 0.326533132333845 -1.39533418173792 -3.601686458585766E-002 + 1.497382502421540E-002 2.752716572605950E-003 3.006824950365570E-004 + 6000251 + 0.328077463583129 -1.39411605620772 -3.770484336908437E-002 + 1.573747590852224E-002 3.355063147389858E-003 -5.340001490527292E-004 + 6000252 + 0.321651628711733 -1.39378675143995 -3.597380335900138E-002 + 1.255998760462024E-002 3.517899894512744E-003 3.219756884387962E-004 + 6000253 + 0.324493522176533 -1.38860008548191 -3.882967355197441E-002 + 1.396526542860112E-002 6.082635955702965E-003 -1.090213438304715E-003 + 6000254 + 0.324521711140188 -1.39586389310030 -3.745606427432058E-002 + 1.397920448930016E-002 2.490781479023323E-003 -4.109822564850102E-004 + 6000255 + 0.323857759005521 -1.39310641830337 -4.070010820644245E-002 + 1.365088915215276E-002 3.854315415219456E-003 -2.015118039299293E-003 + 6000256 + 0.324036458712472 -1.39214287853430 -4.089940117322854E-002 + 1.373925373669473E-002 4.330772779566417E-003 -2.113665711887594E-003 + 6000257 + 0.322090781783657 -1.39468966511415 -3.693872754859708E-002 + 1.277714285021657E-002 3.071421312874804E-003 -1.551662531073200E-004 + 6000258 + 0.328092592928615 -1.39374096057231 -3.586344633457473E-002 + 1.574495716493310E-002 3.540542858309311E-003 3.765457421963371E-004 + 6000259 + 0.324548049062538 -1.39233312653552 -3.331554270885758E-002 + 1.399222823514643E-002 4.236697719935751E-003 1.636449572938168E-003 + 6000260 + 0.324887975354043 -1.39268402922437 -4.094045138727274E-002 + 1.416031718188453E-002 4.063181093387097E-003 -2.133964486694073E-003 + 6000261 + 0.321944774836254 -1.39352845277138 -3.514035858345473E-002 + 1.270494439243692E-002 3.645625087381753E-003 7.341028406686787E-004 + 6000262 + 0.327218902932329 -1.38903404006224 -3.771600840082730E-002 + 1.531292929618219E-002 5.868051293781019E-003 -5.395211060156568E-004 + 6000263 + 0.325421465012036 -1.39138633273825 -4.089966505983452E-002 + 1.442412059147267E-002 4.704874428056443E-003 -2.113796200239817E-003 + 6000264 + 0.324143614425125 -1.39411979216184 -3.398376362544507E-002 + 1.379224078514325E-002 3.353215768678313E-003 1.306023380953205E-003 + 6000265 + 0.324251383572956 -1.39481065425279 -3.453953133960193E-002 + 1.384553116897805E-002 3.011593822657939E-003 1.031203774355344E-003 + 6000266 + 0.323082300628443 -1.39404098553295 -3.438431714855358E-002 + 1.326743548852136E-002 3.392184579203928E-003 1.107955089402535E-003 + 6000267 + 0.325299655987546 -1.39040136408079 -4.060268324575995E-002 + 1.436388767880525E-002 5.191928087451827E-003 -1.966942715894272E-003 + 6000268 + 0.328389849750416 -1.39205995084950 -3.873156679977102E-002 + 1.589194663687427E-002 4.371779396419775E-003 -1.041700978227703E-003 + 6000269 + 0.325793463819930 -1.38928905744628 -3.967831695053032E-002 + 1.460806896313280E-002 5.741948651668003E-003 -1.509856103742432E-003 + 6000270 + 0.326601355314686 -1.39233804164542 -4.057608377821496E-002 + 1.500756036413905E-002 4.234267264663880E-003 -1.953789639491635E-003 + 6000271 + 0.321827451960849 -1.39213071131237 -3.479524070321862E-002 + 1.264692981972560E-002 4.336789306004781E-003 9.047589577125814E-004 + 6000272 + 0.321663381504649 -1.39142897193463 -3.917019157646589E-002 + 1.256579920152172E-002 4.683789923007624E-003 -1.258594988989431E-003 + 6000273 + 0.324648930551282 -1.39538104296497 -3.904801998382525E-002 + 1.404211276485815E-002 2.729544330582880E-003 -1.198182791282209E-003 + 6000274 + 0.321223963022878 -1.39253230185508 -3.603509083528145E-002 + 1.234851271435078E-002 4.138208222307412E-003 2.916698615769088E-004 + 6000275 + 0.321349228011334 -1.39221979031449 -3.561402108543606E-002 + 1.241045455438754E-002 4.292740946056133E-003 4.998831493500657E-004 + 6000276 + 0.324379742702741 -1.38833977818834 -3.620042042538130E-002 + 1.390900301999063E-002 6.211354386424082E-003 2.099166187150847E-004 + 6000277 + 0.321457479810322 -1.39117525342277 -3.868176372657838E-002 + 1.246398360268161E-002 4.809250290424065E-003 -1.017074033132608E-003 + 6000278 + 0.325405274076550 -1.39361725382059 -3.366648162894059E-002 + 1.441611439318668E-002 3.601714171383542E-003 1.462915030537829E-003 + 6000279 + 0.321794234123648 -1.39021314640619 -3.573859188553418E-002 + 1.263050404917571E-002 5.284999178073548E-003 4.382845760531595E-004 + 6000280 + 0.326444232064343 -1.39553980455841 -3.753707767299938E-002 + 1.492986504512957E-002 2.651038873102111E-003 -4.510422847790933E-004 + 6000281 + 0.322277249464589 -1.39203923743843 -3.998141216047151E-002 + 1.286934859267273E-002 4.382021897621130E-003 -1.659732579536102E-003 + 6000282 + 0.328312462659902 -1.39188336185765 -3.539912210963739E-002 + 1.585367976884838E-002 4.459100260935347E-003 6.061477820066648E-004 + 6000283 + 0.325347229643059 -1.39100999963996 -4.082441159349795E-002 + 1.438741220705580E-002 4.890966047611239E-003 -2.076584380468826E-003 + 6000284 + 0.325755425615411 -1.38888217640230 -3.916570950307285E-002 + 1.458925958623789E-002 5.943145816580859E-003 -1.256378664407702E-003 + 6000285 + 0.325383104362951 -1.39054381044671 -4.065574588764872E-002 + 1.440515177010779E-002 5.121490288988412E-003 -1.993181473557695E-003 + 6000286 + 0.325529431096013 -1.39548980174177 -3.555264887114687E-002 + 1.447750835756422E-002 2.675764588624088E-003 5.302308780096619E-004 + 6000287 + 0.321386839414644 -1.39364212905941 -3.740484666220886E-002 + 1.242905288386607E-002 3.589413702731343E-003 -3.856558410548179E-004 + 6000288 + 0.325609144161828 -1.39058365051225 -3.365164289696592E-002 + 1.451692538887061E-002 5.101789916224030E-003 1.470252582503900E-003 + 6000289 + 0.325746594379357 -1.39018221747378 -3.388130434928219E-002 + 1.458489265963108E-002 5.300293116209953E-003 1.356688105171851E-003 + 6000290 + 0.328670099790430 -1.39148012214160 -3.754968804313675E-002 + 1.603052648558429E-002 4.658496838509829E-003 -4.572779420004985E-004 + 6000291 + 0.327050766991314 -1.39494919091028 -3.584795596588932E-002 + 1.522978835080585E-002 2.943089322051995E-003 3.842055196892361E-004 + 6000292 + 0.324537148578145 -1.39587795189979 -3.718291882528427E-002 + 1.398683809326467E-002 2.483829593105807E-003 -2.759155317796403E-004 + 6000293 + 0.325510509540737 -1.38957080345959 -3.425440936567027E-002 + 1.446815190477895E-002 5.602629064425047E-003 1.172192728395570E-003 + 6000294 + 0.325364297568245 -1.39459990856101 -3.430333353770083E-002 + 1.439585206486989E-002 3.115804712620871E-003 1.148000388020130E-003 + 6000295 + 0.323644249841663 -1.39514928477911 -3.905298580505075E-002 + 1.354531176267529E-002 2.844145614251118E-003 -1.200638322614567E-003 + 6000296 + 0.322252155329533 -1.39173521301220 -3.994150826731383E-002 + 1.285693988279573E-002 4.532357858282674E-003 -1.640000644880718E-003 + 6000297 + 0.326793296706268 -1.39091455480311 -4.029063745626598E-002 + 1.510247278236859E-002 4.938162226599772E-003 -1.812640299750235E-003 + 6000298 + 0.328394129335298 -1.39145794911307 -3.861054959678920E-002 + 1.589406283363007E-002 4.669461100775097E-003 -9.818596105701817E-004 + 6000299 + 0.325717727002889 -1.39559209734865 -3.590486599481333E-002 + 1.457061813298568E-002 2.625180796653218E-003 3.560642812509859E-004 + 6000300 + 0.321281416206461 -1.39340867720813 -3.702359920936095E-002 + 1.237692253541057E-002 3.704852481010806E-003 -1.971341397410737E-004 + 6000301 + 0.326826923545244 -1.39251344124293 -4.043303848440993E-002 + 1.511910079875579E-002 4.147534539539541E-003 -1.883055679299622E-003 + 6000302 + 0.325221626988922 -1.39387263555342 -3.377034941755341E-002 + 1.432530339591360E-002 3.475431363727050E-003 1.411553815991447E-003 + 6000303 + 0.322406645286088 -1.39162516754770 -4.006538258520391E-002 + 1.293333307369588E-002 4.586773849880030E-003 -1.701254817159826E-003 + 6000304 + 0.327187048763822 -1.39463651865951 -3.547316576113219E-002 + 1.529717784133024E-002 3.097701514809212E-003 5.695341992875920E-004 + 6000305 + 0.327480662501029 -1.39487649003504 -3.693682090078323E-002 + 1.544236585728670E-002 2.979038920099771E-003 -1.542234415895329E-004 + 6000306 + 0.328551533470727 -1.39151193343580 -3.818397457052056E-002 + 1.597189704651028E-002 4.642766584423178E-003 -7.709240381764704E-004 + 6000307 + 0.322630404860865 -1.38945264563622 -3.538899387690294E-002 + 1.304397915252749E-002 5.661056507596596E-003 6.111560559036752E-004 + 6000308 + 0.328374974048021 -1.39213603553404 -3.876134862395392E-002 + 1.588459080353605E-002 4.334156550504728E-003 -1.056427686881741E-003 + 6000309 + 0.324324666115425 -1.38831319086554 -3.634772132746308E-002 + 1.388176839359332E-002 6.224501457414479E-003 1.370783178738140E-004 + 6000310 + 0.327780384205777 -1.39040540380995 -3.520423097607128E-002 + 1.559057418045742E-002 5.189930496106032E-003 7.025188076919263E-004 + 6000311 + 0.326421010606110 -1.39541002836368 -3.608433683151303E-002 + 1.491838234857564E-002 2.715211443533721E-003 2.673183834932795E-004 + 6000312 + 0.324795021294935 -1.39575370968382 -3.816709106533256E-002 + 1.411435265874821E-002 2.545265686000613E-003 -7.625753735535234E-004 + 6000313 + 0.325813555169143 -1.39541693890006 -3.874684061627268E-002 + 1.461800386317468E-002 2.711794276901274E-003 -1.049253673599004E-003 + 6000314 + 0.322857896534282 -1.38930726976145 -3.533330948140715E-002 + 1.315647070358410E-002 5.732942908509505E-003 6.386912352132688E-004 + 6000315 + 0.326219515200231 -1.39471810186507 -3.471690125726086E-002 + 1.481874559968870E-002 3.057359724732503E-003 9.434967526056666E-004 + 6000316 + 0.321329945274699 -1.39230542391461 -3.567221135978340E-002 + 1.240091950231233E-002 4.250396290733629E-003 4.711088468913174E-004 + 6000317 + 0.324943199595914 -1.39100652024179 -4.085233942880207E-002 + 1.418762482145983E-002 4.892686562876645E-003 -2.090394316735189E-003 + 6000318 + 0.326617044426315 -1.39248593326675 -4.055213917054404E-002 + 1.501531841732557E-002 4.161136861160018E-003 -1.941949355335786E-003 + 6000319 + 0.322850100717639 -1.38930020663682 -3.535283888796843E-002 + 1.315261577785102E-002 5.736435527964740E-003 6.290342082008193E-004 + 6000320 + 0.327167129230231 -1.39467550377465 -3.550717986735132E-002 + 1.528732790178609E-002 3.078423903439586E-003 5.527146844942592E-004 + 6000321 + 0.326175366886518 -1.39179718675643 -3.352228413895547E-002 + 1.479691485656030E-002 4.501712681218141E-003 1.534218736134025E-003 + 6000322 + 0.323968917553573 -1.39007740521288 -3.395618173788408E-002 + 1.370585554848606E-002 5.352121359507512E-003 1.319662250746563E-003 + 6000323 + 0.323157023880416 -1.38871984144043 -3.622802058959314E-002 + 1.330438512447146E-002 6.023418256348253E-003 1.962687113654486E-004 + 6000324 + 0.322467171269080 -1.39052754228481 -3.454951097363686E-002 + 1.296326235244168E-002 5.129534674689875E-003 1.026268980502423E-003 + 6000325 + 0.328300367708115 -1.39034678218645 -3.766648081609209E-002 + 1.584769897901974E-002 5.218918094875141E-003 -5.150303862311877E-004 + 6000326 + 0.327360300143949 -1.39032093899113 -3.953640998478093E-002 + 1.538284830205775E-002 5.231697204908905E-003 -1.439685031354920E-003 + 6000327 + 0.326573187554760 -1.39309481142322 -4.043854310486605E-002 + 1.499363178839726E-002 3.860054860233954E-003 -1.885777639553315E-003 + 6000328 + 0.325274808255286 -1.39252110692220 -3.334038631599733E-002 + 1.435160081177285E-002 4.143743964976811E-003 1.624164745722223E-003 + 6000329 + 0.322448036910301 -1.39211775354247 -4.012807498610159E-002 + 1.295380067120641E-002 4.343196747700902E-003 -1.732255360214964E-003 + 6000330 + 0.326810673793556 -1.38893153269665 -3.834409546944328E-002 + 1.511106551665390E-002 5.918739797571082E-003 -8.501016538046097E-004 + 6000331 + 0.326775470290585 -1.38869840010547 -3.741564841183009E-002 + 1.509365786127752E-002 6.034020706053717E-003 -3.909971599293355E-004 + 6000332 + 0.326271250871605 -1.39390875709412 -4.021126897748652E-002 + 1.484432818840653E-002 3.457569751128591E-003 -1.773393662065399E-003 + 6000333 + 0.321666944784208 -1.39307414833960 -3.528651321326542E-002 + 1.256756119499773E-002 3.870272475198349E-003 6.618313559388317E-004 + 6000334 + 0.325766832048710 -1.39507466523029 -3.493921370497112E-002 + 1.459489991300033E-002 2.881043970394314E-003 8.335662585066534E-004 + 6000335 + 0.321552673105825 -1.39151724509758 -3.527455850230447E-002 + 1.251105539788419E-002 4.640140039617423E-003 6.677427985786109E-004 + 6000336 + 0.326440517111881 -1.39496814513121 -3.518250039097470E-002 + 1.492802805145723E-002 2.933716716541827E-003 7.132642876744128E-004 + 6000337 + 0.328149349552533 -1.39379829625323 -3.817632697865712E-002 + 1.577302254667368E-002 3.512191140723280E-003 -7.671424075890959E-004 + 6000338 + 0.324135308775169 -1.38971487157048 -3.416375884586458E-002 + 1.378813375374246E-002 5.531389335037621E-003 1.217018182548996E-003 + 6000339 + 0.324286880142571 -1.38901868791716 -3.482913889326955E-002 + 1.386308374183996E-002 5.875642721572888E-003 8.879967618943014E-004 + 6000340 + 0.328695490885568 -1.39186332148561 -3.764840312220126E-002 + 1.604308203819967E-002 4.469009953454875E-003 -5.060912114703549E-004 + 6000341 + 0.326127505166542 -1.39330528092113 -3.372351078671609E-002 + 1.477324788433473E-002 3.755980544394189E-003 1.434714884496157E-003 + 6000342 + 0.323411133267291 -1.38892035601416 -3.885662321348482E-002 + 1.343003877428764E-002 5.924266515672206E-003 -1.103539680879768E-003 + 6000343 + 0.323443535356482 -1.38878773000395 -3.566309895402712E-002 + 1.344606116849591E-002 5.989848281256044E-003 4.756148081073266E-004 + 6000344 + 0.326161896812670 -1.39219123381745 -4.077210626406107E-002 + 1.479025408749908E-002 4.306861747038268E-003 -2.050720103554825E-003 + 6000345 + 0.327496529611136 -1.39347379619798 -3.470387250659136E-002 + 1.545021192830949E-002 3.672652022584027E-003 9.499392933331112E-004 + 6000346 + 0.326907660359911 -1.39442320185806 -3.939126722457996E-002 + 1.515902406000240E-002 3.203183783680173E-003 -1.367913902440976E-003 + 6000347 + 0.327627930876646 -1.39427354730877 -3.562233577430311E-002 + 1.551518807423184E-002 3.277185931186497E-003 4.957716483304529E-004 + 6000348 + 0.325119576127018 -1.39376660753008 -3.370627018966749E-002 + 1.427484062701359E-002 3.527860785085645E-003 1.443240126207252E-003 + 6000349 + 0.321582888441476 -1.39198483014723 -3.515228871706261E-002 + 1.252599647208718E-002 4.408925566155315E-003 7.282035511970817E-004 + 6000350 + 0.328649590429548 -1.39230144150209 -3.789609952169283E-002 + 1.602038488443426E-002 4.252365539779506E-003 -6.285737258914244E-004 + 6000351 + 0.325091488310059 -1.39588396719579 -3.697135848001232E-002 + 1.426095158198591E-002 2.480855110709554E-003 -1.713018066956808E-004 + 6000352 + 0.323629747250521 -1.38958719080047 -3.983511560394539E-002 + 1.353814042779786E-002 5.594525746332192E-003 -1.587390913967920E-003 + 6000353 + 0.321678639713746 -1.38999980605140 -3.649592552125010E-002 + 1.257334417924268E-002 5.390493093753963E-003 6.379335151967012E-005 + 6000354 + 0.321979789899611 -1.39044531600697 -3.911106486620910E-002 + 1.272225886697657E-002 5.170194455300030E-003 -1.229357631657783E-003 + 6000355 + 0.325389900698438 -1.39279507601704 -4.088553189135913E-002 + 1.440851246594727E-002 4.008269958578387E-003 -2.106807539867057E-003 + 6000356 + 0.325843612080240 -1.38834809342622 -3.662007773836583E-002 + 1.463286659858156E-002 6.207242613925633E-003 2.401761837715437E-006 + 6000357 + 0.321369009956186 -1.39207775902686 -3.555942305231640E-002 + 1.242023645816423E-002 4.362973493929667E-003 5.268811371797942E-004 + 6000358 + 0.325504520827021 -1.39403046328794 -4.038166123959698E-002 + 1.446519056696509E-002 3.397387686834489E-003 -1.857650327660951E-003 + 6000359 + 0.321990553923499 -1.38951059135313 -3.685720838148137E-002 + 1.272758153098724E-002 5.632403135476837E-003 -1.148561291719788E-004 + 6000360 + 0.324610041911226 -1.38980909225812 -3.401440587559276E-002 + 1.402288285910944E-002 5.484798481249997E-003 1.290871203314320E-003 + 6000361 + 0.328509070048447 -1.39256561942476 -3.832567067658864E-002 + 1.595089945937337E-002 4.121733135395790E-003 -8.409908433077421E-004 + 6000362 + 0.324576175323637 -1.39320821636194 -4.080080161764887E-002 + 1.400613629028089E-002 3.803977654144154E-003 -2.064909567216185E-003 + 6000363 + 0.322653205268223 -1.39479071554500 -3.866475003855334E-002 + 1.305525364512712E-002 3.021453243581057E-003 -1.008660994860108E-003 + 6000364 + 0.325278470241920 -1.39300006526267 -4.085198724804461E-002 + 1.435341161456094E-002 3.906905553258331E-003 -2.090220168121022E-003 + 6000365 + 0.327882444238280 -1.39058964691285 -3.907161492253900E-002 + 1.564104148409440E-002 5.098824777354270E-003 -1.209850168875113E-003 + 6000366 + 0.327925534924085 -1.39112239948916 -3.496856334495498E-002 + 1.566234924454749E-002 4.835385844669870E-003 8.190532590849669E-004 + 6000367 + 0.327291588883165 -1.38906313116244 -3.674455074075982E-002 + 1.534887151431583E-002 5.853666138781197E-003 -5.914845181920610E-005 + 6000368 + 0.326403910822977 -1.39105116007004 -3.374528293181369E-002 + 1.490992673743835E-002 4.870612772465192E-003 1.423948853656114E-003 + 6000369 + 0.328034117962957 -1.39191633393057 -3.935146673723238E-002 + 1.571604208647744E-002 4.442796017492191E-003 -1.348233100558018E-003 + 6000370 + 0.323887294249176 -1.39308506929055 -3.356970859695257E-002 + 1.366549393007587E-002 3.864872212877050E-003 1.510767984034018E-003 + 6000371 + 0.324195814984085 -1.39153924083899 -4.089966051523319E-002 + 1.381805325447577E-002 4.629263443433466E-003 -2.113793952996017E-003 + 6000372 + 0.323696388851772 -1.38910872113090 -3.494303980046445E-002 + 1.357109379693476E-002 5.831122516909043E-003 8.316743061108993E-004 + 6000373 + 0.328595123870093 -1.39262055299375 -3.630079724885421E-002 + 1.599345190855066E-002 4.094569229621872E-003 1.602816391441369E-004 + 6000374 + 0.326120765455020 -1.39220930951942 -3.349891101613327E-002 + 1.476991518827874E-002 4.297923557253797E-003 1.545776428773127E-003 + 6000375 + 0.325484317791356 -1.39317547361155 -4.077391072541323E-002 + 1.445520043948558E-002 3.820168500697788E-003 -2.051612385251454E-003 + 6000376 + 0.325938226310969 -1.39515654081679 -3.513803924942247E-002 + 1.467965205409683E-002 2.840557601902009E-003 7.352497199315036E-004 + 6000377 + 0.321076313569735 -1.39158800158611 -3.754184390774611E-002 + 1.227550205973084E-002 4.605151914460645E-003 -4.533991233011673E-004 + 6000378 + 0.322061849593275 -1.38999211007948 -3.550101842230587E-002 + 1.276283627396840E-002 5.394298647622158E-003 5.557614356104747E-004 + 6000379 + 0.328448014596534 -1.39176878090750 -3.857068065062026E-002 + 1.592070836541795E-002 4.515758988744939E-003 -9.621449567273610E-004 + 6000380 + 0.327573537859497 -1.39067587171533 -3.953481342703309E-002 + 1.548829146402245E-002 5.056187780465731E-003 -1.438895555174500E-003 + 6000381 + 0.325341975557433 -1.39322163371681 -4.078006057193613E-002 + 1.438481413288207E-002 3.797342953904623E-003 -2.054653401055379E-003 + 6000382 + 0.326945407039128 -1.39080439717213 -3.413440781683218E-002 + 1.517768928158405E-002 4.992633682997575E-003 1.231531868836375E-003 + 6000383 + 0.326864905896984 -1.38950094451344 -3.503286762493725E-002 + 1.513788255720786E-002 5.637173367032906E-003 7.872556636559166E-004 + 6000384 + 0.321872038730314 -1.39444412969432 -3.725713409567794E-002 + 1.266897737328358E-002 3.192835252123807E-003 -3.126139777195664E-004 + 6000385 + 0.325656830678744 -1.38929012479731 -3.972454209455978E-002 + 1.454050572555626E-002 5.741420861043140E-003 -1.532713811330532E-003 + 6000386 + 0.321381796697484 -1.39297273615133 -3.582742182750125E-002 + 1.242655932853529E-002 3.920419428636525E-003 3.943593729806181E-004 + 6000387 + 0.325031722246969 -1.38871352884892 -3.520767103604314E-002 + 1.423139807333841E-002 6.026539747343834E-003 7.008177446325606E-004 + 6000388 + 0.321818492658012 -1.39053648944325 -3.893028585473215E-002 + 1.264249956582932E-002 5.125110426032039E-003 -1.139964859192371E-003 + 6000389 + 0.328229706719982 -1.39063530392342 -3.842585640223736E-002 + 1.581275807751381E-002 5.076248004065306E-003 -8.905313275931080E-004 + 6000390 + 0.327031282654416 -1.39046595458131 -3.436136073991577E-002 + 1.522015361013151E-002 5.159988959845626E-003 1.119306722521987E-003 + 6000391 + 0.326576412217448 -1.39384168926042 -3.418873736070407E-002 + 1.499522634041712E-002 3.490733886441843E-003 1.204666645302896E-003 + 6000392 + 0.322057300552805 -1.39399573472489 -3.539654307306134E-002 + 1.276058683507447E-002 3.414560490852700E-003 6.074230806596391E-004 + 6000393 + 0.327117831128816 -1.39014808504543 -3.464203976347065E-002 + 1.526295065839501E-002 5.317171139694695E-003 9.805147472618755E-004 + 6000394 + 0.323831937101924 -1.38978966102672 -4.008662335125708E-002 + 1.363812057058993E-002 5.494406961976909E-003 -1.711758088260099E-003 + 6000395 + 0.323291350089045 -1.39111881770597 -4.052780949033966E-002 + 1.337080761514683E-002 4.837156987941165E-003 -1.929918658028077E-003 + 6000396 + 0.322050969058998 -1.39140096523577 -3.967628168503533E-002 + 1.275745599714884E-002 4.697638856237326E-003 -1.508849692523487E-003 + 6000397 + 0.322065436123730 -1.39461505964254 -3.660470991700977E-002 + 1.276460976469764E-002 3.108312708032919E-003 1.000094133619592E-005 + 6000398 + 0.325123972979440 -1.39448560316462 -4.010971214210824E-002 + 1.427701481097967E-002 3.172327182835760E-003 -1.723175182590891E-003 + 6000399 + 0.327666613656848 -1.39046306711613 -3.928421544112214E-002 + 1.553431618507078E-002 5.161416772263869E-003 -1.314978245571975E-003 diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/cb.swiftest.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/cb.swiftest.in new file mode 100644 index 000000000..d0ae0ed15 Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1pl_encounter/cb.swiftest.in differ diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/init_cond.py b/examples/symba_swifter_comparison/1pl_1pl_encounter/init_cond.py new file mode 100755 index 000000000..245f5fae0 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/init_cond.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 +""" +For testing RMVS, the code generates clones of test particles based on one that is fated to impact Mercury. +To use the script, modify the variables just after the "if __name__ == '__main__':" line +""" +import numpy as np +import swiftest +from scipy.io import FortranFile +import sys + +swifter_input = "param.swifter.in" +swifter_pl = "pl.swifter.in" +swifter_tp = "tp.swifter.in" +swifter_bin = "bin.swifter.dat" +swifter_enc = "enc.swifter.dat" + +swiftest_input = "param.swiftest.in" +swiftest_pl = "pl.swiftest.in" +swiftest_tp = "tp.swiftest.in" +swiftest_cb = "cb.swiftest.in" +swiftest_bin = "bin.swiftest.dat" +swiftest_enc = "enc.swiftest.dat" + +MU2KG = swiftest.MSun +TU2S = swiftest.YR2S +DU2M = swiftest.AU2M + +GMSun = swiftest.GMSunSI * TU2S**2 / DU2M**3 + +# Simple initial conditions of a circular planet with one smaller massive body in a close encounter state +# Simulation start, stop, and output cadence times +t_0 = 0 # simulation start time +deltaT = 0.25 * swiftest.JD2S / TU2S # simulation step size +end_sim = 0.15 +t_print = deltaT #output interval to print results + +iout = int(np.ceil(t_print / deltaT)) +rmin = swiftest.RSun / swiftest.AU2M +rmax = 1000.0 + +npl = 2 +ntp = 0 +plid1 = 2 +plid2 = 100 + +radius1 = np.double(4.25875607065041e-05) +mass1 = np.double(0.00012002693582795244940133) +mass2 = mass1 / 100.0 +radius2 = radius1 * (mass2 / mass1)**(1.0/3.0) + +apl1 = np.longdouble(1.0) +apl2 = np.longdouble(1.01) +vpl1 = np.longdouble(2 * np.pi) +vpl2 = np.longdouble(2 * np.pi / np.sqrt(apl2)) + +p_pl1 = np.array([apl1, 0.0, 0.0], dtype=np.double) +v_pl1 = np.array([0.0, vpl1, 0.0], dtype=np.double) + +p_pl2 = np.array([apl2, 0.0, 0.0], dtype=np.double) +v_pl2 = np.array([0.0, vpl2, 0.0], dtype=np.double) + +Rhill1 = np.double(apl1 * 0.0100447248332378922085) +Rhill2 = Rhill1 * (mass2 / mass1)**(1.0 / 3.0) + +#Make Swifter files +plfile = open(swifter_pl, 'w') +print(npl+1, f'! Planet input file generated using init_cond.py',file=plfile) + +print(1,GMSun,file=plfile) +print('0.0 0.0 0.0',file=plfile) +print('0.0 0.0 0.0',file=plfile) + +print(plid1,"{:.23g}".format(mass1),Rhill1, file=plfile) +print(radius1, file=plfile) +print(*p_pl1, file=plfile) +print(*v_pl1, file=plfile) + +print(plid2,"{:.23g}".format(mass2),Rhill2, file=plfile) +print(radius2, file=plfile) +print(*p_pl2, file=plfile) +print(*v_pl2, file=plfile) + +plfile.close() + +tpfile = open(swifter_tp, 'w') +print(0,file=tpfile) +tpfile.close() + +sys.stdout = open(swifter_input, "w") +print(f'! Swifter input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'PL_IN {swifter_pl}') +print(f'TP_IN {swifter_tp}') +print(f'IN_TYPE ASCII') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swifter_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT UNKNOWN') +#print(f'J2 {swiftest.J2Sun}') +#print(f'J4 {swiftest.J4Sun}') +print(f'J2 0.0') +print(f'J4 0.0') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swifter_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'RHILL_PRESENT yes') +sys.stdout = sys.__stdout__ + +#Now make Swiftest files +cbfile = FortranFile(swiftest_cb, 'w') +Msun = np.double(1.0) +cbfile.write_record(0) +cbfile.write_record(np.double(GMSun)) +cbfile.write_record(np.double(rmin)) +#cbfile.write_record(np.double(swiftest.J2Sun)) +#cbfile.write_record(np.double(swiftest.J4Sun)) +cbfile.write_record(np.double(0.0)) +cbfile.write_record(np.double(0.0)) +cbfile.close() + +plfile = FortranFile(swiftest_pl, 'w') +plfile.write_record(npl) +plfile.write_record(np.array([plid1, plid2], dtype=np.int32)) +plfile.write_record(np.vstack([p_pl1[0],p_pl2[0]])) +plfile.write_record(np.vstack([p_pl1[1],p_pl2[1]])) +plfile.write_record(np.vstack([p_pl1[2],p_pl2[2]])) +plfile.write_record(np.vstack([v_pl1[0],v_pl2[0]])) +plfile.write_record(np.vstack([v_pl1[1],v_pl2[1]])) +plfile.write_record(np.vstack([v_pl1[2],v_pl2[2]])) +plfile.write_record(np.array([mass1,mass2])) +plfile.write_record(np.array([Rhill1,Rhill2])) +plfile.write_record(np.array([radius1,radius2])) +plfile.close() +tpfile = FortranFile(swiftest_tp, 'w') +tpfile.write_record(ntp) + +tpfile.close() + +sys.stdout = open(swiftest_input, "w") +print(f'! Swiftest input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'CB_IN {swiftest_cb}') +print(f'PL_IN {swiftest_pl}') +print(f'TP_IN {swiftest_tp}') +print(f'IN_TYPE REAL8') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swiftest_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT REPLACE') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swiftest_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'DISCARD_OUT discard.swiftest.out') +print(f'ROTATION no') +print(f'ENERGY yes') +print(f'GR no') +print(f'MU2KG {MU2KG}') +print(f'DU2M {DU2M}') +print(f'TU2S {TU2S}') +print(f'RHILL_PRESENT yes') +print(f'MTINY 1e-12') + + + + diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swifter.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swifter.in new file mode 100644 index 000000000..853815639 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT UNKNOWN +J2 0.0 +J4 0.0 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swifter.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swiftest.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swiftest.in new file mode 100644 index 000000000..3050dea4a --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/param.swiftest.in @@ -0,0 +1,33 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +DISCARD_OUT discard.swiftest.out +ROTATION no +ENERGY yes +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 +RHILL_PRESENT yes +MTINY 1e-12 diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swifter.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swifter.in new file mode 100644 index 000000000..9f0548fc1 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swifter.in @@ -0,0 +1,12 @@ +3 ! Planet input file generated using init_cond.py +1 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +2 0.00012002693582795244940133 0.010044724833237892 +4.25875607065041e-05 +1.0 0.0 0.0 +0.0 6.283185307179586 0.0 +100 1.2002693582795244601319e-06 0.002164070363255244 +9.17521181499312e-06 +1.01 0.0 0.0 +0.0 6.252003053624663 0.0 diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swiftest.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swiftest.in new file mode 100644 index 000000000..1bda0535d Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1pl_encounter/pl.swiftest.in differ diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/swiftest_vs_swifter.ipynb b/examples/symba_swifter_comparison/1pl_1pl_encounter/swiftest_vs_swifter.ipynb new file mode 100644 index 000000000..3a80eebd1 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/swiftest_vs_swifter.ipynb @@ -0,0 +1,1644 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import swiftest\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.506e-01\n", + "Creating Dataset\n", + "Successfully converted 221 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.506e-01\n", + "Creating Dataset\n", + "Successfully converted 221 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestsim.ds - swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (y)'})\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "swiftdiff['vx'].plot.line(x=\"time (y)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'vx' (time (y): 221)>\n",
+       "array([0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "...\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.        , 0.        , 0.        ,\n",
+       "       0.        , 0.        , 0.02101973, 0.02102004, 0.02102057,\n",
+       "       0.0210213 , 0.02102224, 0.02102336, 0.02102465, 0.02102612,\n",
+       "       0.02102774, 0.02102951, 0.02103142, 0.02103346, 0.02103561,\n",
+       "       0.02103787, 0.02104022, 0.02104267, 0.02104519, 0.02104778,\n",
+       "       0.02105043, 0.02105312, 0.02105586, 0.02105862, 0.0210614 ,\n",
+       "       0.02106419])\n",
+       "Coordinates:\n",
+       "    id        float64 2.0\n",
+       "  * time (y)  (time (y)) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506
" + ], + "text/plain": [ + "\n", + "array([0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + "...\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0. , 0. , 0. ,\n", + " 0. , 0. , 0.02101973, 0.02102004, 0.02102057,\n", + " 0.0210213 , 0.02102224, 0.02102336, 0.02102465, 0.02102612,\n", + " 0.02102774, 0.02102951, 0.02103142, 0.02103346, 0.02103561,\n", + " 0.02103787, 0.02104022, 0.02104267, 0.02104519, 0.02104778,\n", + " 0.02105043, 0.02105312, 0.02105586, 0.02105862, 0.0210614 ,\n", + " 0.02106419])\n", + "Coordinates:\n", + " id float64 2.0\n", + " * time (y) (time (y)) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftdiff['vx'].sel(id=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'vx' (time: 221)>\n",
+       "array([ 0.        , -0.02730963, -0.05461883, -0.08192718, -0.10923426,\n",
+       "       -0.13653965, -0.16384292, -0.19114364, -0.21844141, -0.24573578,\n",
+       "       -0.27302634, -0.30031266, -0.32759433, -0.35487091, -0.38214199,\n",
+       "       -0.40940715, -0.43666596, -0.463918  , -0.49116285, -0.51840009,\n",
+       "       -0.5456293 , -0.57285005, -0.60006193, -0.62726452, -0.6544574 ,\n",
+       "       -0.68164014, -0.70881234, -0.73597358, -0.76312342, -0.79026147,\n",
+       "       -0.8173873 , -0.8445005 , -0.87160064, -0.89868733, -0.92576014,\n",
+       "       -0.95281866, -0.97986247, -1.00689117, -1.03390434, -1.06090158,\n",
+       "       -1.08788246, -1.11484659, -1.14179356, -1.16872296, -1.19563437,\n",
+       "       -1.22252741, -1.24940165, -1.27625671, -1.30309216, -1.32990762,\n",
+       "       -1.35670269, -1.38347696, -1.41023003, -1.43696151, -1.463671  ,\n",
+       "       -1.4903581 , -1.51702243, -1.54366359, -1.57028119, -1.59687484,\n",
+       "       -1.62344416, -1.64998874, -1.67650822, -1.70300221, -1.72947032,\n",
+       "       -1.75591217, -1.78232739, -1.8087156 , -1.83507643, -1.8614095 ,\n",
+       "       -1.88771444, -1.91399088, -1.94023846, -1.96645681, -1.99264557,\n",
+       "       -2.01880437, -2.04493287, -2.0710307 , -2.09709752, -2.12313297,\n",
+       "       -2.1491367 , -2.17510838, -2.20104766, -2.2269542 , -2.25282767,\n",
+       "       -2.27866774, -2.30447407, -2.33024634, -2.35598424, -2.38168744,\n",
+       "       -2.40735563, -2.43298851, -2.45858576, -2.48414708, -2.50967219,\n",
+       "       -2.53516079, -2.56061259, -2.58602731, -2.61140468, -2.63674443,\n",
+       "...\n",
+       "       -3.28166908, -3.30592115, -3.33013189, -3.3543014 , -3.37842979,\n",
+       "       -3.40251722, -3.42656386, -3.45056991, -3.47453562, -3.49846126,\n",
+       "       -3.52234715, -3.54619364, -3.57000113, -3.59377005, -3.61750092,\n",
+       "       -3.64119426, -3.66485068, -3.68847086, -3.71205553, -3.73560548,\n",
+       "       -3.75912161, -3.78260489, -3.80605637, -3.82947723, -3.85286873,\n",
+       "       -3.87623226, -3.89956936, -3.92288168, -3.94617105, -3.96943947,\n",
+       "       -3.99268912, -4.01592242, -4.03914199, -4.06235073, -4.08555183,\n",
+       "       -4.10874879, -4.13194551, -4.15514625, -4.17835577, -4.20157933,\n",
+       "       -4.2248228 , -4.24809272, -4.2713964 , -4.29474206, -4.31813893,\n",
+       "       -4.34159746, -4.36512951, -4.38874856, -4.41247007, -4.43631182,\n",
+       "       -4.46029439, -4.48444172, -4.50878191, -4.53334814, -4.55817998,\n",
+       "       -4.58332498, -4.60884098, -4.63479915, -4.66128825, -4.68842081,\n",
+       "       -4.71634199, -4.7452432 , -4.77538326, -4.80712299, -4.84098468,\n",
+       "       -4.87776098, -4.91873117, -4.96614064, -5.02443531, -5.10428159,\n",
+       "       -5.24263186, -5.9750488 ,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan])\n",
+       "Coordinates:\n",
+       "    id       float64 100.0\n",
+       "  * time     (time) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506
" + ], + "text/plain": [ + "\n", + "array([ 0. , -0.02730963, -0.05461883, -0.08192718, -0.10923426,\n", + " -0.13653965, -0.16384292, -0.19114364, -0.21844141, -0.24573578,\n", + " -0.27302634, -0.30031266, -0.32759433, -0.35487091, -0.38214199,\n", + " -0.40940715, -0.43666596, -0.463918 , -0.49116285, -0.51840009,\n", + " -0.5456293 , -0.57285005, -0.60006193, -0.62726452, -0.6544574 ,\n", + " -0.68164014, -0.70881234, -0.73597358, -0.76312342, -0.79026147,\n", + " -0.8173873 , -0.8445005 , -0.87160064, -0.89868733, -0.92576014,\n", + " -0.95281866, -0.97986247, -1.00689117, -1.03390434, -1.06090158,\n", + " -1.08788246, -1.11484659, -1.14179356, -1.16872296, -1.19563437,\n", + " -1.22252741, -1.24940165, -1.27625671, -1.30309216, -1.32990762,\n", + " -1.35670269, -1.38347696, -1.41023003, -1.43696151, -1.463671 ,\n", + " -1.4903581 , -1.51702243, -1.54366359, -1.57028119, -1.59687484,\n", + " -1.62344416, -1.64998874, -1.67650822, -1.70300221, -1.72947032,\n", + " -1.75591217, -1.78232739, -1.8087156 , -1.83507643, -1.8614095 ,\n", + " -1.88771444, -1.91399088, -1.94023846, -1.96645681, -1.99264557,\n", + " -2.01880437, -2.04493287, -2.0710307 , -2.09709752, -2.12313297,\n", + " -2.1491367 , -2.17510838, -2.20104766, -2.2269542 , -2.25282767,\n", + " -2.27866774, -2.30447407, -2.33024634, -2.35598424, -2.38168744,\n", + " -2.40735563, -2.43298851, -2.45858576, -2.48414708, -2.50967219,\n", + " -2.53516079, -2.56061259, -2.58602731, -2.61140468, -2.63674443,\n", + "...\n", + " -3.28166908, -3.30592115, -3.33013189, -3.3543014 , -3.37842979,\n", + " -3.40251722, -3.42656386, -3.45056991, -3.47453562, -3.49846126,\n", + " -3.52234715, -3.54619364, -3.57000113, -3.59377005, -3.61750092,\n", + " -3.64119426, -3.66485068, -3.68847086, -3.71205553, -3.73560548,\n", + " -3.75912161, -3.78260489, -3.80605637, -3.82947723, -3.85286873,\n", + " -3.87623226, -3.89956936, -3.92288168, -3.94617105, -3.96943947,\n", + " -3.99268912, -4.01592242, -4.03914199, -4.06235073, -4.08555183,\n", + " -4.10874879, -4.13194551, -4.15514625, -4.17835577, -4.20157933,\n", + " -4.2248228 , -4.24809272, -4.2713964 , -4.29474206, -4.31813893,\n", + " -4.34159746, -4.36512951, -4.38874856, -4.41247007, -4.43631182,\n", + " -4.46029439, -4.48444172, -4.50878191, -4.53334814, -4.55817998,\n", + " -4.58332498, -4.60884098, -4.63479915, -4.66128825, -4.68842081,\n", + " -4.71634199, -4.7452432 , -4.77538326, -4.80712299, -4.84098468,\n", + " -4.87776098, -4.91873117, -4.96614064, -5.02443531, -5.10428159,\n", + " -5.24263186, -5.9750488 , nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan])\n", + "Coordinates:\n", + " id float64 100.0\n", + " * time (time) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftestsim.ds.sel(id=100)['vx']" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'vx' (time: 221)>\n",
+       "array([ 0.        , -0.02730963, -0.05461883, -0.08192718, -0.10923426,\n",
+       "       -0.13653965, -0.16384292, -0.19114364, -0.21844141, -0.24573578,\n",
+       "       -0.27302634, -0.30031266, -0.32759433, -0.35487091, -0.38214199,\n",
+       "       -0.40940715, -0.43666596, -0.463918  , -0.49116285, -0.51840009,\n",
+       "       -0.5456293 , -0.57285005, -0.60006193, -0.62726452, -0.6544574 ,\n",
+       "       -0.68164014, -0.70881234, -0.73597358, -0.76312342, -0.79026147,\n",
+       "       -0.8173873 , -0.8445005 , -0.87160064, -0.89868733, -0.92576014,\n",
+       "       -0.95281866, -0.97986247, -1.00689117, -1.03390434, -1.06090158,\n",
+       "       -1.08788246, -1.11484659, -1.14179356, -1.16872296, -1.19563437,\n",
+       "       -1.22252741, -1.24940165, -1.27625671, -1.30309216, -1.32990762,\n",
+       "       -1.35670269, -1.38347696, -1.41023003, -1.43696151, -1.463671  ,\n",
+       "       -1.4903581 , -1.51702243, -1.54366359, -1.57028119, -1.59687484,\n",
+       "       -1.62344416, -1.64998874, -1.67650822, -1.70300221, -1.72947032,\n",
+       "       -1.75591217, -1.78232739, -1.8087156 , -1.83507643, -1.8614095 ,\n",
+       "       -1.88771444, -1.91399088, -1.94023846, -1.96645681, -1.99264557,\n",
+       "       -2.01880437, -2.04493287, -2.0710307 , -2.09709752, -2.12313297,\n",
+       "       -2.1491367 , -2.17510838, -2.20104766, -2.2269542 , -2.25282767,\n",
+       "       -2.27866774, -2.30447407, -2.33024634, -2.35598424, -2.38168744,\n",
+       "       -2.40735563, -2.43298851, -2.45858576, -2.48414708, -2.50967219,\n",
+       "       -2.53516079, -2.56061259, -2.58602731, -2.61140468, -2.63674443,\n",
+       "...\n",
+       "       -3.28166908, -3.30592115, -3.33013189, -3.3543014 , -3.37842979,\n",
+       "       -3.40251722, -3.42656386, -3.45056991, -3.47453562, -3.49846126,\n",
+       "       -3.52234715, -3.54619364, -3.57000113, -3.59377005, -3.61750092,\n",
+       "       -3.64119426, -3.66485068, -3.68847086, -3.71205553, -3.73560548,\n",
+       "       -3.75912161, -3.78260489, -3.80605637, -3.82947723, -3.85286873,\n",
+       "       -3.87623226, -3.89956936, -3.92288168, -3.94617105, -3.96943947,\n",
+       "       -3.99268912, -4.01592242, -4.03914199, -4.06235073, -4.08555183,\n",
+       "       -4.10874879, -4.13194551, -4.15514625, -4.17835577, -4.20157933,\n",
+       "       -4.2248228 , -4.24809272, -4.2713964 , -4.29474206, -4.31813893,\n",
+       "       -4.34159746, -4.36512951, -4.38874856, -4.41247007, -4.43631182,\n",
+       "       -4.46029439, -4.48444172, -4.50878191, -4.53334814, -4.55817998,\n",
+       "       -4.58332498, -4.60884098, -4.63479915, -4.66128825, -4.68842081,\n",
+       "       -4.71634199, -4.7452432 , -4.77538326, -4.80712299, -4.84098468,\n",
+       "       -4.87776098, -4.91873117, -4.96614064, -5.02443531, -5.10428159,\n",
+       "       -5.24263186, -5.9750488 ,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan,         nan,         nan,         nan,         nan,\n",
+       "               nan])\n",
+       "Coordinates:\n",
+       "    id       int64 100\n",
+       "  * time     (time) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506
" + ], + "text/plain": [ + "\n", + "array([ 0. , -0.02730963, -0.05461883, -0.08192718, -0.10923426,\n", + " -0.13653965, -0.16384292, -0.19114364, -0.21844141, -0.24573578,\n", + " -0.27302634, -0.30031266, -0.32759433, -0.35487091, -0.38214199,\n", + " -0.40940715, -0.43666596, -0.463918 , -0.49116285, -0.51840009,\n", + " -0.5456293 , -0.57285005, -0.60006193, -0.62726452, -0.6544574 ,\n", + " -0.68164014, -0.70881234, -0.73597358, -0.76312342, -0.79026147,\n", + " -0.8173873 , -0.8445005 , -0.87160064, -0.89868733, -0.92576014,\n", + " -0.95281866, -0.97986247, -1.00689117, -1.03390434, -1.06090158,\n", + " -1.08788246, -1.11484659, -1.14179356, -1.16872296, -1.19563437,\n", + " -1.22252741, -1.24940165, -1.27625671, -1.30309216, -1.32990762,\n", + " -1.35670269, -1.38347696, -1.41023003, -1.43696151, -1.463671 ,\n", + " -1.4903581 , -1.51702243, -1.54366359, -1.57028119, -1.59687484,\n", + " -1.62344416, -1.64998874, -1.67650822, -1.70300221, -1.72947032,\n", + " -1.75591217, -1.78232739, -1.8087156 , -1.83507643, -1.8614095 ,\n", + " -1.88771444, -1.91399088, -1.94023846, -1.96645681, -1.99264557,\n", + " -2.01880437, -2.04493287, -2.0710307 , -2.09709752, -2.12313297,\n", + " -2.1491367 , -2.17510838, -2.20104766, -2.2269542 , -2.25282767,\n", + " -2.27866774, -2.30447407, -2.33024634, -2.35598424, -2.38168744,\n", + " -2.40735563, -2.43298851, -2.45858576, -2.48414708, -2.50967219,\n", + " -2.53516079, -2.56061259, -2.58602731, -2.61140468, -2.63674443,\n", + "...\n", + " -3.28166908, -3.30592115, -3.33013189, -3.3543014 , -3.37842979,\n", + " -3.40251722, -3.42656386, -3.45056991, -3.47453562, -3.49846126,\n", + " -3.52234715, -3.54619364, -3.57000113, -3.59377005, -3.61750092,\n", + " -3.64119426, -3.66485068, -3.68847086, -3.71205553, -3.73560548,\n", + " -3.75912161, -3.78260489, -3.80605637, -3.82947723, -3.85286873,\n", + " -3.87623226, -3.89956936, -3.92288168, -3.94617105, -3.96943947,\n", + " -3.99268912, -4.01592242, -4.03914199, -4.06235073, -4.08555183,\n", + " -4.10874879, -4.13194551, -4.15514625, -4.17835577, -4.20157933,\n", + " -4.2248228 , -4.24809272, -4.2713964 , -4.29474206, -4.31813893,\n", + " -4.34159746, -4.36512951, -4.38874856, -4.41247007, -4.43631182,\n", + " -4.46029439, -4.48444172, -4.50878191, -4.53334814, -4.55817998,\n", + " -4.58332498, -4.60884098, -4.63479915, -4.66128825, -4.68842081,\n", + " -4.71634199, -4.7452432 , -4.77538326, -4.80712299, -4.84098468,\n", + " -4.87776098, -4.91873117, -4.96614064, -5.02443531, -5.10428159,\n", + " -5.24263186, -5.9750488 , nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan, nan, nan, nan, nan,\n", + " nan])\n", + "Coordinates:\n", + " id int64 100\n", + " * time (time) float64 0.0 0.0006845 0.001369 ... 0.1492 0.1499 0.1506" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftersim.ds.sel(id=100)['vx']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swifter.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swifter.in new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swifter.in @@ -0,0 +1 @@ +0 diff --git a/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swiftest.in b/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swiftest.in new file mode 100644 index 000000000..64bf92f74 Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1pl_encounter/tp.swiftest.in differ diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore b/examples/symba_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in new file mode 100644 index 000000000..d0ae0ed15 Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1tp_encounter/cb.swiftest.in differ diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/init_cond.py b/examples/symba_swifter_comparison/1pl_1tp_encounter/init_cond.py new file mode 100755 index 000000000..338b5d5a8 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/init_cond.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python3 +""" +For testing RMVS, the code generates clones of test particles based on one that is fated to impact Mercury. +To use the script, modify the variables just after the "if __name__ == '__main__':" line +""" +import numpy as np +import swiftest +from scipy.io import FortranFile +import sys + +swifter_input = "param.swifter.in" +swifter_pl = "pl.swifter.in" +swifter_tp = "tp.swifter.in" +swifter_bin = "bin.swifter.dat" +swifter_enc = "enc.swifter.dat" + +swiftest_input = "param.swiftest.in" +swiftest_pl = "pl.swiftest.in" +swiftest_tp = "tp.swiftest.in" +swiftest_cb = "cb.swiftest.in" +swiftest_bin = "bin.swiftest.dat" +swiftest_enc = "enc.swiftest.dat" + +MU2KG = swiftest.MSun +TU2S = swiftest.YR2S +DU2M = swiftest.AU2M + +J2 = 0.0 #swiftest.J2Sun +J4 = 0.0 #swiftest.J4Sun + +GMSun = swiftest.GMSunSI * TU2S**2 / DU2M**3 + +# Simple initial conditions of a circular planet with one test particle in a close encounter state +# Simulation start, stop, and output cadence times +t_0 = 0 # simulation start time +deltaT = 0.25 * swiftest.JD2S / TU2S # simulation step size +end_sim = 0.15 +t_print = deltaT #output interval to print results + +iout = int(np.ceil(t_print / deltaT)) +rmin = swiftest.RSun / swiftest.AU2M +rmax = 1000.0 + +npl = 1 +plid = 2 +tpid = 100 + +radius = np.double(4.25875607065041e-05) +mass = np.double(0.00012002693582795244940133) +apl = np.longdouble(1.0) +atp = np.longdouble(1.01) +vpl = np.longdouble(2 * np.pi) +vtp = np.longdouble(2 * np.pi / np.sqrt(atp)) + +p_pl = np.array([apl, 0.0, 0.0], dtype=np.double) +v_pl = np.array([0.0, vpl, 0.0], dtype=np.double) + +p_tp = np.array([atp, 0.0, 0.0], dtype=np.double) +v_tp = np.array([0.0, vtp, 0.0], dtype=np.double) + +Rhill = np.double(apl * 0.0100447248332378922085) + +#Make Swifter files +plfile = open(swifter_pl, 'w') +print(npl+1, f'! Planet input file generated using init_cond.py',file=plfile) +print(1,GMSun,file=plfile) +print('0.0 0.0 0.0',file=plfile) +print('0.0 0.0 0.0',file=plfile) +print(plid,"{:.23g}".format(mass),Rhill, file=plfile) +print(radius, file=plfile) +print(*p_pl, file=plfile) +print(*v_pl, file=plfile) +plfile.close() + +tpfile = open(swifter_tp, 'w') +print(1,file=tpfile) +print(tpid, file=tpfile) +print(*p_tp, file=tpfile) +print(*v_tp, file=tpfile) +tpfile.close() + +sys.stdout = open(swifter_input, "w") +print(f'! Swifter input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'PL_IN {swifter_pl}') +print(f'TP_IN {swifter_tp}') +print(f'IN_TYPE ASCII') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swifter_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT UNKNOWN') +print(f'J2 {J2}') +print(f'J4 {J4}') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swifter_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'RHILL_PRESENT yes') +sys.stdout = sys.__stdout__ + +#Now make Swiftest files +cbfile = FortranFile(swiftest_cb, 'w') +Msun = np.double(1.0) +cbfile.write_record(0) +cbfile.write_record(np.double(GMSun)) +cbfile.write_record(np.double(rmin)) +cbfile.write_record(np.double(J2)) +cbfile.write_record(np.double(J4)) +cbfile.close() + +plfile = FortranFile(swiftest_pl, 'w') +plfile.write_record(npl) + +plfile.write_record(plid) +plfile.write_record(p_pl[0]) +plfile.write_record(p_pl[1]) +plfile.write_record(p_pl[2]) +plfile.write_record(v_pl[0]) +plfile.write_record(v_pl[1]) +plfile.write_record(v_pl[2]) +plfile.write_record(mass) +plfile.write_record(Rhill) +plfile.write_record(radius) +plfile.close() +tpfile = FortranFile(swiftest_tp, 'w') +ntp = 1 +tpfile.write_record(ntp) +tpfile.write_record(tpid) +tpfile.write_record(p_tp[0]) +tpfile.write_record(p_tp[1]) +tpfile.write_record(p_tp[2]) +tpfile.write_record(v_tp[0]) +tpfile.write_record(v_tp[1]) +tpfile.write_record(v_tp[2]) + +tpfile.close() + +sys.stdout = open(swiftest_input, "w") +print(f'! Swiftest input file generated using init_cond.py') +print(f'T0 {t_0} ') +print(f'TSTOP {end_sim}') +print(f'DT {deltaT}') +print(f'CB_IN {swiftest_cb}') +print(f'PL_IN {swiftest_pl}') +print(f'TP_IN {swiftest_tp}') +print(f'IN_TYPE REAL8') +print(f'ISTEP_OUT {iout:d}') +print(f'ISTEP_DUMP {iout:d}') +print(f'BIN_OUT {swiftest_bin}') +print(f'OUT_TYPE REAL8') +print(f'OUT_FORM XV') +print(f'OUT_STAT REPLACE') +print(f'CHK_CLOSE yes') +print(f'CHK_RMIN {rmin}') +print(f'CHK_RMAX {rmax}') +print(f'CHK_EJECT {rmax}') +print(f'CHK_QMIN {rmin}') +print(f'CHK_QMIN_COORD HELIO') +print(f'CHK_QMIN_RANGE {rmin} {rmax}') +print(f'ENC_OUT {swiftest_enc}') +print(f'EXTRA_FORCE no') +print(f'BIG_DISCARD no') +print(f'ROTATION no') +print(f'GR no') +print(f'MU2KG {MU2KG}') +print(f'DU2M {DU2M}') +print(f'TU2S {TU2S}') +print(f'RHILL_PRESENT yes') +print(f'MTINY 1e-12') + + + + diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swifter.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swifter.in new file mode 100644 index 000000000..853815639 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT UNKNOWN +J2 0.0 +J4 0.0 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swifter.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swiftest.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swiftest.in new file mode 100644 index 000000000..a7f91ba33 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/param.swiftest.in @@ -0,0 +1,31 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 +RHILL_PRESENT yes +MTINY 1e-12 diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swifter.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swifter.in new file mode 100644 index 000000000..17d461561 --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swifter.in @@ -0,0 +1,8 @@ +2 ! Planet input file generated using init_cond.py +1 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +2 0.00012002693582795244940133 0.010044724833237892 +4.25875607065041e-05 +1.0 0.0 0.0 +0.0 6.283185307179586 0.0 diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in new file mode 100644 index 000000000..c94c6ae61 Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1tp_encounter/pl.swiftest.in differ diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb b/examples/symba_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb new file mode 100644 index 000000000..02d6b0bef --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb @@ -0,0 +1,593 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import swiftest\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.355e-01\n", + "Creating Dataset\n", + "Successfully converted 199 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.506e-01\n", + "Creating Dataset\n", + "Successfully converted 221 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestsim.ds - swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (y)'})\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "swiftdiff['vx'].plot.line(x=\"time (y)\")" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'vx' (time (y): 199)>\n",
+       "array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,\n",
+       "        0.,  0.,  0., nan])\n",
+       "Coordinates:\n",
+       "    id        float64 100.0\n",
+       "  * time (y)  (time (y)) float64 0.0 0.0006845 0.001369 ... 0.1342 0.1348 0.1355
" + ], + "text/plain": [ + "\n", + "array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., nan])\n", + "Coordinates:\n", + " id float64 100.0\n", + " * time (y) (time (y)) float64 0.0 0.0006845 0.001369 ... 0.1342 0.1348 0.1355" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftdiff['vx'].sel(id=100)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swifter.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swifter.in new file mode 100644 index 000000000..9c026369e --- /dev/null +++ b/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swifter.in @@ -0,0 +1,4 @@ +1 +100 +1.01 0.0 0.0 +0.0 6.252003053624663 0.0 diff --git a/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in b/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in new file mode 100644 index 000000000..e1506974a Binary files /dev/null and b/examples/symba_swifter_comparison/1pl_1tp_encounter/tp.swiftest.in differ diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore b/examples/symba_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.in new file mode 100644 index 000000000..81c636655 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.in @@ -0,0 +1,5 @@ +0 +0.00029591220819207774 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in new file mode 100644 index 000000000..2e8d49f62 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +0.00029591220819207774 +0.004650467260962157 +0.0 +0.0 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/init_cond.py b/examples/symba_swifter_comparison/8pl_16tp_encounters/init_cond.py new file mode 100755 index 000000000..18ef4ce48 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/init_cond.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python3 +import numpy as np +import swiftest +import swiftest.io as swio +import astropy.constants as const +import sys +import xarray as xr + +# Both codes use the same tp input file +tpin = "tp.in" + +swifter_input = "param.swifter.in" +swifter_pl = "pl.swifter.in" +swifter_bin = "bin.swifter.dat" +swifter_enc = "enc.swifter.dat" + +swiftest_input = "param.swiftest.in" +swiftest_pl = "pl.swiftest.in" +swiftest_cb = "cb.swiftest.in" +swiftest_bin = "bin.swiftest.dat" +swiftest_enc = "enc.swiftest.dat" + +sim = swiftest.Simulation() + +sim.param['T0'] = 0.0 +sim.param['DT'] = 1.0 +sim.param['TSTOP'] = 365.25e1 +sim.param['ISTEP_OUT'] = 11 +sim.param['ISTEP_DUMP'] = 1 +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['OUT_FORM'] = "XV" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'NO' +sim.param['CHK_CLOSE'] = 'YES' +sim.param['RHILL_PRESENT'] = 'YES' +sim.param['MTINY'] = 1.0e-12 + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.JD2S +sim.param['DU2M'] = swiftest.AU2M + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +ds = sim.ds +cb = ds.sel(id=0) +pl = ds.where(ds.id > 0, drop=True) +npl = pl.id.size + +ntp = 16 +dims = ['time', 'id', 'vec'] +tp = [] +t = np.array([0.0]) +clab, plab, tlab = swio.make_swiftest_labels(sim.param) + +# For each planet, we will initialize a pair of test particles. One on its way in, and one on its way out. We will also initialize two additional particles that don't encounter anything +tpnames = np.arange(101, 101 + ntp) +tpxv1 = np.empty((6)) +tpxv2 = np.empty((6)) + +p1 = [] +p2 = [] +p3 = [] +p4 = [] +p5 = [] +p6 = [] + +for i in pl.id: + pli = pl.sel(id=i) + rstart = 2 * np.double(pli['Radius']) # Start the test particles at a multiple of the planet radius away + vstart = 1.5 * np.sqrt(2 * np.double(pli['Mass']) / rstart) # Start the test particle velocities at a multiple of the escape speed + xvstart = np.array([rstart / np.sqrt(2.0), rstart / np.sqrt(2.0), 0.0, vstart, 0.0, 0.0]) + # The positions and velocities of each pair of test particles will be in reference to a planet + plvec = np.array([np.double(pli['px']), + np.double(pli['py']), + np.double(pli['pz']), + np.double(pli['vx']), + np.double(pli['vy']), + np.double(pli['vz'])]) + tpxv1 = plvec + xvstart + tpxv2 = plvec - xvstart + p1.append(tpxv1[0]) + p1.append(tpxv2[0]) + p2.append(tpxv1[1]) + p2.append(tpxv2[1]) + p3.append(tpxv1[2]) + p3.append(tpxv2[2]) + p4.append(tpxv1[3]) + p4.append(tpxv2[3]) + p5.append(tpxv1[4]) + p5.append(tpxv2[4]) + p6.append(tpxv1[5]) + p6.append(tpxv2[5]) + +tvec = np.vstack([p1, p2, p3, p4, p5, p6]) +tpframe = np.expand_dims(tvec.T, axis=0) +tpxr = xr.DataArray(tpframe, dims = dims, coords = {'time' : t, 'id' : tpnames, 'vec' : tlab}) + +tp = [tpxr] +tpda = xr.concat(tp,dim='time') +tpds = tpda.to_dataset(dim = 'vec') + +sim.ds = xr.combine_by_coords([sim.ds, tpds]) +swio.swiftest_xr2infile(sim.ds, sim.param) + +sim.param['PL_IN'] = swiftest_pl +sim.param['TP_IN'] = tpin +sim.param['CB_IN'] = swiftest_cb +sim.param['BIN_OUT'] = swiftest_bin +sim.param['ENC_OUT'] = swiftest_enc +sim.save(swiftest_input) + +sim.param['PL_IN'] = swifter_pl +sim.param['TP_IN'] = tpin +sim.param['BIN_OUT'] = swifter_bin +sim.param['ENC_OUT'] = swifter_enc +sim.save(swifter_input, codename="Swifter") diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swifter.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swifter.in new file mode 100644 index 000000000..f9305cfa2 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swifter.in @@ -0,0 +1,26 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 3652.5 +DT 1.0 +ISTEP_OUT 11 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +J2 0.0 +J4 0.0 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swiftest.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swiftest.in new file mode 100644 index 000000000..e9ed6376c --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/param.swiftest.in @@ -0,0 +1,36 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 3652.5 +DT 1.0 +ISTEP_OUT 11 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 86400 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR NO +YARKOVSKY NO +YORP NO +MTINY 1e-12 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.in new file mode 100644 index 000000000..86a616119 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.in @@ -0,0 +1,33 @@ +8 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swifter.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swifter.in new file mode 100644 index 000000000..595cdc169 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 0.00029591220819207775568 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in new file mode 100644 index 000000000..86a616119 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 4.9125474498983623693e-11 0.0014751239400086721089 +1.6306381826061645943e-05 +-0.09861361766419070307 0.29750596935836171042 0.03335708456145129036 +-0.032353632540864457612 -0.0078122718370876240157 0.0023293874953380202045 +2 7.243452483873646905e-10 0.0067590794275223005208 +4.0453784346544178454e-05 +-0.6439817957564198947 -0.3248550380869373866 0.032702713983447248558 +0.008969709495375973937 -0.018153139924556138673 -0.0007667345025597138231 +3 8.9970113821660187435e-10 0.010044873080337524463 +4.25875607065040958e-05 +0.59421674333603324847 -0.82331253628773626296 3.7129329104855261984e-05 +0.013670550280388280365 0.010004295439859960809 -5.226292361234363611e-07 +4 9.549535102761465607e-11 0.0072467054748629370034 +2.265740805092889601e-05 +-1.592721551706784977 0.48166390206865000723 0.049163460846716633412 +-0.0035287723306552309585 -0.01219974682608557931 -0.00016910795626524249315 +5 2.825345908631354893e-07 0.35527074967975702942 +0.00046732617030490929307 +4.119089774477131094 -2.8872942462256898644 -0.080165336328135106125 +0.004245402942744468111 0.0065414198811065849687 -0.00012215100047356211078 +6 8.459715183006415395e-08 0.4376562090257202473 +0.00038925687730393611812 +6.3629100567525149756 -7.649727796147929304 -0.12023019299387090186 +0.0039834472120812329868 0.0035613826786502411278 -0.00022039988214595340028 +7 1.2920249163736673626e-08 0.4695793205674148502 +0.00016953449859497231466 +14.814154683311180349 13.052040295401360126 -0.14347198499748289868 +-0.002625101393275708784 0.0027742356008832688187 4.416821810149910185e-05 +8 1.5243589003230834323e-08 0.7813388398513013378 +0.000164587904124493665 +29.564924658285640646 -4.579331535234244299 -0.5871109926822926095 +0.00046449847307956888343 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/swiftest_symba_vs_swifter_symba.ipynb b/examples/symba_swifter_comparison/8pl_16tp_encounters/swiftest_symba_vs_swifter_symba.ipynb new file mode 100644 index 000000000..c3c42dd4f --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/swiftest_symba_vs_swifter_symba.ipynb @@ -0,0 +1,643 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import swiftest\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 3.652e+03\n", + "Creating Dataset\n", + "Successfully converted 333 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swifter.in'\n", + "swiftersim = swiftest.Simulation(param_file=inparfile, codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 3.652e+03\n", + "Creating Dataset\n", + "Successfully converted 333 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "inparfile = 'param.swiftest.in'\n", + "swiftestsim = swiftest.Simulation(param_file=inparfile)\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestdat - swifterdat" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (d)'})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff['rmag'] = np.sqrt(swiftdiff['px']**2 + swiftdiff['py']**2 + swiftdiff['pz']**2)\n", + "swiftdiff['vmag'] = np.sqrt(swiftdiff['vx']**2 + swiftdiff['vy']**2 + swiftdiff['vz']**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "plidx = swiftdiff.id.values[swiftdiff.id.values < 10]\n", + "tpidx = swiftdiff.id.values[swiftdiff.id.values > 10]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Planets only\")\n", + "fig.savefig(\"symba_swifter_comparison-8pl-16tp-planets-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=plidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Planets only\")\n", + "fig.savefig(\"symba_swifter_comparison-8pl-16tp-planets-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['rmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{r}_{swiftest} - \\mathbf{r}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric position differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"symba_swifter_comparison-8pl-16tp-testparticles-rmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "No handles with labels found to put in legend.\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "swiftdiff['vmag'].sel(id=tpidx).plot.line(ax=ax, x=\"time (d)\")\n", + "ax.set_ylabel(\"$|\\mathbf{v}_{swiftest} - \\mathbf{v}_{swifter}|$\")\n", + "ax.set_title(\"Heliocentric velocity differences \\n Test Particles only\")\n", + "legend = ax.legend()\n", + "legend.remove()\n", + "fig.savefig(\"symba_swifter_comparison-8pl-16tp-testparticles-vmag.png\", facecolor='white', transparent=False, dpi=300)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time (d)' : 'time'})" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.DataArray 'px' (id: 16)>\n",
+       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n",
+       "Coordinates:\n",
+       "  * id       (id) int64 101 102 103 104 105 106 107 ... 111 112 113 114 115 116\n",
+       "    time     float64 110.0
" + ], + "text/plain": [ + "\n", + "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n", + "Coordinates:\n", + " * id (id) int64 101 102 103 104 105 106 107 ... 111 112 113 114 115 116\n", + " time float64 110.0" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "swiftdiff['px'].sel(id=tpidx).isel(time=10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/symba_swifter_comparison/8pl_16tp_encounters/tp.in b/examples/symba_swifter_comparison/8pl_16tp_encounters/tp.in new file mode 100644 index 000000000..ae7796698 --- /dev/null +++ b/examples/symba_swifter_comparison/8pl_16tp_encounters/tp.in @@ -0,0 +1,49 @@ +16 +101 +-0.09859055695785905182 0.2975290300646933339 0.03335708456145129036 +-0.029750083068855306956 -0.0078122718370876240157 0.0023293874953380202045 +102 +-0.09863667837052235432 0.29748290865203008693 0.03335708456145129036 +-0.034957182012873608268 -0.0078122718370876240157 0.0023293874953380202045 +103 +-0.6439245854659476631 -0.32479782779646521051 0.032702713983447248558 +0.0153169432007213678765 -0.018153139924556138673 -0.0007667345025597138231 +104 +-0.6440390060468921263 -0.32491224837740956266 0.032702713983447248558 +0.002622475790030579998 -0.018153139924556138673 -0.0007667345025597138231 +105 +0.59427697124197276235 -0.8232523083817967491 3.7129329104855261984e-05 +0.020564990514662154913 0.010004295439859960809 -5.226292361234363611e-07 +106 +0.5941565154300937346 -0.82337276419367577684 3.7129329104855261984e-05 +0.0067761100461144049487 0.010004295439859960809 -5.226292361234363611e-07 +107 +-1.5926895092930311026 0.48169594448240382611 0.049163460846716633412 +-0.00044929323243133797994 -0.01219974682608557931 -0.00016910795626524249315 +108 +-1.5927535941205388514 0.48163185965489618834 0.049163460846716633412 +-0.006608251428879123937 -0.01219974682608557931 -0.00016910795626524249315 +109 +4.119750673485228276 -2.8866333472175926822 -0.080165336328135106125 +0.041127620144391897894 0.0065414198811065849687 -0.00012215100047356211078 +110 +4.118428875469033912 -2.8879551452337870465 -0.080165336328135106125 +-0.032636814258902961672 0.0065414198811065849687 -0.00012215100047356211078 +111 +6.3634605491076454697 -7.64917730379279881 -0.12023019299387090186 +0.026096616095614821179 0.0035613826786502411278 -0.00022039988214595340028 +112 +6.3623595643973844815 -7.650278288503059798 -0.12023019299387090186 +-0.01812972167145235694 0.0035613826786502411278 -0.00022039988214595340028 +113 +14.814394441298382787 13.052280053388562564 -0.14347198499748289868 +0.010469662145386185101 0.0027742356008832688187 4.416821810149910185e-05 +114 +14.813914925323977911 13.051800537414157688 -0.14347198499748289868 +-0.015719864931937603536 0.0027742356008832688187 4.416821810149910185e-05 +115 +29.565157420731857485 -4.579098772788029237 -0.5871109926822926095 +0.014900134286357700347 0.003128345390031967918 -7.5036135696161668576e-05 +116 +29.564691895839423808 -4.5795642976804593616 -0.5871109926822926095 +-0.0139711373401985618214 0.003128345390031967918 -7.5036135696161668576e-05 diff --git a/examples/whm_gr_test/cb.swiftest.in b/examples/whm_gr_test/cb.swiftest.in new file mode 100644 index 000000000..e4a010b1e --- /dev/null +++ b/examples/whm_gr_test/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +39.476926408897626 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/whm_gr_test/init_cond.py b/examples/whm_gr_test/init_cond.py new file mode 100755 index 000000000..8d197c6f4 --- /dev/null +++ b/examples/whm_gr_test/init_cond.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +import swiftest + +sim = swiftest.Simulation() +sim.param['PL_IN'] = "pl.swiftest.in" +sim.param['TP_IN'] = "tp.swiftest.in" +sim.param['CB_IN'] = "cb.swiftest.in" +sim.param['BIN_OUT'] = "bin.swiftest.dat" +sim.param['ENC_OUT'] = "enc.swiftest.dat" + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.YR2S +sim.param['DU2M'] = swiftest.AU2M +sim.param['T0'] = 0.0 +sim.param['DT'] = 0.25 * swiftest.JD2S / swiftest.YR2S +sim.param['TSTOP'] = 1000.0 +sim.param['ISTEP_OUT'] = 1461 +sim.param['ISTEP_DUMP'] = 1461 +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['OUT_FORM'] = "EL" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'YES' + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +sim.save("param.swiftest.in") +sim.param['PL_IN'] = "pl.swifter.in" +sim.param['TP_IN'] = "tp.swifter.in" +sim.param['BIN_OUT'] = "bin.swifter.dat" +sim.param['ENC_OUT'] = "enc.swifter.dat" +sim.save("param.swifter.in", codename="Swifter") + + diff --git a/examples/whm_gr_test/param.swifter.in b/examples/whm_gr_test/param.swifter.in new file mode 100644 index 000000000..789250f41 --- /dev/null +++ b/examples/whm_gr_test/param.swifter.in @@ -0,0 +1,27 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 1000.0 +DT 0.0006844626967830253 +ISTEP_OUT 1461 +ISTEP_DUMP 1461 +OUT_FORM EL +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.swifter.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +C 63241.07708426628 +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +RHILL_PRESENT YES diff --git a/examples/whm_gr_test/param.swiftest.in b/examples/whm_gr_test/param.swiftest.in new file mode 100644 index 000000000..ace6f3cad --- /dev/null +++ b/examples/whm_gr_test/param.swiftest.in @@ -0,0 +1,35 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 1000.0 +DT 0.0006844626967830253 +ISTEP_OUT 1461 +ISTEP_DUMP 1461 +OUT_FORM EL +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 31557600.0 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR YES +YARKOVSKY NO +YORP NO +MTINY 0.0 diff --git a/examples/whm_gr_test/pl.swifter.in b/examples/whm_gr_test/pl.swifter.in new file mode 100644 index 000000000..782e57140 --- /dev/null +++ b/examples/whm_gr_test/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 6.5537098095653139645e-06 0.0014751234419554511911 +1.6306381826061645943e-05 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 +2 9.663313399581537916e-05 0.00675908960945781479 +4.0453784346544178454e-05 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 +3 0.000120026935827952453094 0.010044837538502923644 +4.25875607065040958e-05 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 +4 1.2739802010675941456e-05 0.0072467236860282326973 +2.265740805092889601e-05 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 +5 0.037692251088985676735 0.35527094075555771578 +0.00046732617030490929307 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 +6 0.011285899820091272997 0.43765464106459166412 +0.00038925687730393611812 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 +7 0.0017236589478267730203 0.46956055286931676728 +0.00016953449859497231466 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 +8 0.0020336100526728302319 0.7813163071687303693 +0.000164587904124493665 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/whm_gr_test/pl.swiftest.in b/examples/whm_gr_test/pl.swiftest.in new file mode 100644 index 000000000..10d425453 --- /dev/null +++ b/examples/whm_gr_test/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 6.5537098095653139645e-06 +1.6306381826061645943e-05 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 +2 9.663313399581537916e-05 +4.0453784346544178454e-05 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 +3 0.000120026935827952453094 +4.25875607065040958e-05 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 +4 1.2739802010675941456e-05 +2.265740805092889601e-05 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 +5 0.037692251088985676735 +0.00046732617030490929307 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 +6 0.011285899820091272997 +0.00038925687730393611812 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 +7 0.0017236589478267730203 +0.00016953449859497231466 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 +8 0.0020336100526728302319 +0.000164587904124493665 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/whm_gr_test/swiftest_relativity.ipynb b/examples/whm_gr_test/swiftest_relativity.ipynb new file mode 100644 index 000000000..69bacdf51 --- /dev/null +++ b/examples/whm_gr_test/swiftest_relativity.ipynb @@ -0,0 +1,192 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import swiftest\n", + "from astroquery.jplhorizons import Horizons" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.000e+03\n", + "Creating Dataset\n", + "Successfully converted 1001 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()\n", + "swifterdat = swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.000e+03\n", + "Creating Dataset\n", + "Successfully converted 1001 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()\n", + "swiftestdat = swiftestsim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swifterdat['varpi'] = swifterdat['omega'] + swifterdat['capom']\n", + "swiftestdat['varpi'] = swiftestdat['omega'] + swiftestdat['capom']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "obj = Horizons(id='1', id_type='majorbody',location='@sun',\n", + " epochs={'start':'2021-01-28', 'stop':'3021-02-05',\n", + " 'step':'1y'})\n", + "el = obj.elements()\n", + "t = (el['datetime_jd']-el['datetime_jd'][0]) / 365.25\n", + "varpi_obs = el['w'] + el['Omega']" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "varpiswiftest = swiftestdat['varpi'].sel(id=1) * 180.0 / np.pi\n", + "varpiswifter = swifterdat['varpi'].sel(id=1) * 180.0 / np.pi\n", + "tsim = swiftestdat['time']" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "dvarpi_swiftest = np.diff(varpiswiftest) * 3600 * 100 \n", + "dvarpi_swifter = np.diff(varpiswifter) * 3600 * 100 \n", + "dvarpi_obs = np.diff(varpi_obs) / np.diff(t) * 3600 * 100 " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Mean precession rate for Mercury long. peri. (arcsec/100 y)\n", + "JPL Horizons : 571.3210506300043\n", + "Swifter GR : 571.6183105524942\n", + "Swiftest GR : 571.61831053222\n", + "Obs - Swifter : -0.2972599224899675\n", + "Obs - Swiftest : -0.29725990221562437\n", + "Swiftest - Swifter: -2.0274342205084395e-08\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "ax.plot(t, varpi_obs, label=\"JPL Horizons\")\n", + "ax.plot(tsim, varpiswifter, label=\"Swifter GR\")\n", + "ax.plot(tsim, varpiswiftest, label=\"Swiftest GR\")\n", + "ax.set_xlabel('Time (y)')\n", + "ax.set_ylabel('Mercury $\\\\varpi$ (deg)')\n", + "ax.legend()\n", + "print('Mean precession rate for Mercury long. peri. (arcsec/100 y)')\n", + "print(f'JPL Horizons : {np.mean(dvarpi_obs)}')\n", + "print(f'Swifter GR : {np.mean(dvarpi_swifter)}')\n", + "print(f'Swiftest GR : {np.mean(dvarpi_swiftest)}')\n", + "print(f'Obs - Swifter : {np.mean(dvarpi_obs - dvarpi_swifter)}')\n", + "print(f'Obs - Swiftest : {np.mean(dvarpi_obs - dvarpi_swiftest)}')\n", + "print(f'Swiftest - Swifter: {np.mean(dvarpi_swiftest - dvarpi_swifter)}')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/whm_gr_test/tp.swifter.in b/examples/whm_gr_test/tp.swifter.in new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/examples/whm_gr_test/tp.swifter.in @@ -0,0 +1 @@ +0 diff --git a/examples/whm_gr_test/tp.swiftest.in b/examples/whm_gr_test/tp.swiftest.in new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/examples/whm_gr_test/tp.swiftest.in @@ -0,0 +1 @@ +0 diff --git a/examples/whm_swifter_comparison/cb.swiftest.in b/examples/whm_swifter_comparison/cb.swiftest.in new file mode 100644 index 000000000..e4a010b1e --- /dev/null +++ b/examples/whm_swifter_comparison/cb.swiftest.in @@ -0,0 +1,5 @@ +0 +39.476926408897626 +0.004650467260962157 +4.7535806948127355e-12 +-2.2473967953572827e-18 diff --git a/examples/whm_swifter_comparison/init_cond.py b/examples/whm_swifter_comparison/init_cond.py new file mode 100755 index 000000000..cc86e7635 --- /dev/null +++ b/examples/whm_swifter_comparison/init_cond.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +import swiftest + +sim = swiftest.Simulation() + +sim.param['MU2KG'] = swiftest.MSun +sim.param['TU2S'] = swiftest.YR2S +sim.param['DU2M'] = swiftest.AU2M +sim.param['T0'] = 0.0 +sim.param['TSTOP'] = 1.0 +sim.param['DT'] = 0.25 * swiftest.JD2S / swiftest.YR2S +sim.param['CHK_QMIN_COORD'] = "HELIO" +sim.param['CHK_QMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_QMIN_RANGE'] = f"{swiftest.RSun / swiftest.AU2M} 1000.0" +sim.param['CHK_RMIN'] = swiftest.RSun / swiftest.AU2M +sim.param['CHK_RMAX'] = 1000.0 +sim.param['CHK_EJECT'] = 1000.0 +sim.param['ISTEP_OUT'] = 1 +sim.param['ISTEP_DUMP'] = 1 +sim.param['OUT_FORM'] = "XV" +sim.param['OUT_STAT'] = "UNKNOWN" +sim.param['GR'] = 'NO' + +bodyid = { + "Sun": 0, + "Mercury": 1, + "Venus": 2, + "Earth": 3, + "Mars": 4, + "Jupiter": 5, + "Saturn": 6, + "Uranus": 7, + "Neptune": 8, + "Ceres": 101, + "Pallas": 102, + "Juno": 103, + "Vesta": 104 +} + +for name, id in bodyid.items(): + sim.add(name, idval=id) + +sim.param['PL_IN'] = "pl.swiftest.in" +sim.param['TP_IN'] = "tp.swiftest.in" +sim.param['CB_IN'] = "cb.swiftest.in" +sim.param['BIN_OUT'] = "bin.swiftest.dat" +sim.param['ENC_OUT'] = "enc.swiftest.dat" +sim.save("param.swiftest.in") +sim.param['PL_IN'] = "pl.swifter.in" +sim.param['TP_IN'] = "tp.swifter.in" +sim.param['BIN_OUT'] = "bin.swifter.dat" +sim.param['ENC_OUT'] = "enc.swifter.dat" +sim.save("param.swifter.in", codename="Swifter") + diff --git a/examples/whm_swifter_comparison/param.swifter.in b/examples/whm_swifter_comparison/param.swifter.in new file mode 100644 index 000000000..417c3ab04 --- /dev/null +++ b/examples/whm_swifter_comparison/param.swifter.in @@ -0,0 +1,26 @@ +! VERSION Swifter parameter file converted from Swiftest +T0 0.0 +TSTOP 1.0 +DT 0.0006844626967830253 +ISTEP_OUT 1 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swifter.in +TP_IN tp.swifter.in +BIN_OUT bin.swifter.dat +ENC_OUT enc.swifter.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 diff --git a/examples/whm_swifter_comparison/param.swiftest.in b/examples/whm_swifter_comparison/param.swiftest.in new file mode 100644 index 000000000..13fdad2ec --- /dev/null +++ b/examples/whm_swifter_comparison/param.swiftest.in @@ -0,0 +1,36 @@ +! VERSION Swiftest parameter input +T0 0.0 +TSTOP 1.0 +DT 0.0006844626967830253 +ISTEP_OUT 1 +ISTEP_DUMP 1 +OUT_FORM XV +OUT_TYPE REAL8 +OUT_STAT UNKNOWN +IN_TYPE ASCII +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +CB_IN cb.swiftest.in +BIN_OUT bin.swiftest.dat +ENC_OUT enc.swiftest.dat +CHK_QMIN 0.004650467260962157 +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +MU2KG 1.988409870698051e+30 +TU2S 31557600.0 +DU2M 149597870700.0 +EXTRA_FORCE NO +BIG_DISCARD NO +CHK_CLOSE YES +RHILL_PRESENT YES +FRAGMENTATION NO +ROTATION NO +TIDES NO +ENERGY NO +GR NO +YARKOVSKY NO +YORP NO +MTINY 0.0 diff --git a/examples/whm_swifter_comparison/pl.swifter.in b/examples/whm_swifter_comparison/pl.swifter.in new file mode 100644 index 000000000..946ff123b --- /dev/null +++ b/examples/whm_swifter_comparison/pl.swifter.in @@ -0,0 +1,36 @@ +9 +0 39.476926408897625196 +0.0 0.0 0.0 +0.0 0.0 0.0 +1 6.5537098095653139645e-06 0.0014751242768086609319 +1.6306381826061645943e-05 +-0.21794225400065470044 0.24570059548519398995 0.040069659678364698274 +-9.768342370075118952 -6.4098488749322373205 0.37225116289830816995 +2 9.663313399581537916e-05 0.0067590742435367571566 +4.0453784346544178454e-05 +-0.60413504586259936247 -0.39527613440541492507 0.029436881824798030033 +3.992938767473374092 -6.2169034295501688922 -0.3157349287333398891 +3 0.000120026935827952453094 0.010044891628501106769 +4.25875607065040958e-05 +0.6475137988388671717 -0.78146344078682306034 3.4954277703126252982e-05 +4.7364737841481480227 3.9858178826605781494 -0.000206181980282845843 +4 1.2739802010675941456e-05 0.0072466933032545104062 +2.265740805092889601e-05 +-1.6060166552595489531 0.43262604649099911658 0.048461907252935247647 +-1.1388942318608360441 -4.4988235352611598648 -0.066344559364066134143 +5 0.037692251088985676735 0.3552707368190505097 +0.00046732617030490929307 +4.1359946230316175786 -2.8610749953481979801 -0.08065244615734604161 +1.536603427793050461 2.399023353553466048 -0.044342472584791124157 +6 0.011285899820091272997 0.4376572328164372643 +0.00038925687730393611812 +6.3788284394924916754 -7.635463758938534795 -0.121111501730720202974 +1.4521392831727842248 1.3041738917825064364 -0.08044788317293871613 +7 0.0017236589478267730203 0.46959013246222981483 +0.00016953449859497231466 +14.803649648126269156 13.063133279359290029 -0.14329526741228329478 +-0.9596636872292902537 1.0125665712568530355 0.016140607193432704789 +8 0.0020336100526728302319 0.78135207839715916734 +0.000164587904124493665 +29.566779964594630314 -4.5668176855665958414 -0.58741108465859714904 +0.16916723445783939828 1.142713652049310879 -0.027397346380668001207 diff --git a/examples/whm_swifter_comparison/pl.swiftest.in b/examples/whm_swifter_comparison/pl.swiftest.in new file mode 100644 index 000000000..c13f0640d --- /dev/null +++ b/examples/whm_swifter_comparison/pl.swiftest.in @@ -0,0 +1,33 @@ +8 +1 6.5537098095653139645e-06 0.0014751242768086609319 +1.6306381826061645943e-05 +-0.21794225400065470044 0.24570059548519398995 0.040069659678364698274 +-9.768342370075118952 -6.4098488749322373205 0.37225116289830816995 +2 9.663313399581537916e-05 0.0067590742435367571566 +4.0453784346544178454e-05 +-0.60413504586259936247 -0.39527613440541492507 0.029436881824798030033 +3.992938767473374092 -6.2169034295501688922 -0.3157349287333398891 +3 0.000120026935827952453094 0.010044891628501106769 +4.25875607065040958e-05 +0.6475137988388671717 -0.78146344078682306034 3.4954277703126252982e-05 +4.7364737841481480227 3.9858178826605781494 -0.000206181980282845843 +4 1.2739802010675941456e-05 0.0072466933032545104062 +2.265740805092889601e-05 +-1.6060166552595489531 0.43262604649099911658 0.048461907252935247647 +-1.1388942318608360441 -4.4988235352611598648 -0.066344559364066134143 +5 0.037692251088985676735 0.3552707368190505097 +0.00046732617030490929307 +4.1359946230316175786 -2.8610749953481979801 -0.08065244615734604161 +1.536603427793050461 2.399023353553466048 -0.044342472584791124157 +6 0.011285899820091272997 0.4376572328164372643 +0.00038925687730393611812 +6.3788284394924916754 -7.635463758938534795 -0.121111501730720202974 +1.4521392831727842248 1.3041738917825064364 -0.08044788317293871613 +7 0.0017236589478267730203 0.46959013246222981483 +0.00016953449859497231466 +14.803649648126269156 13.063133279359290029 -0.14329526741228329478 +-0.9596636872292902537 1.0125665712568530355 0.016140607193432704789 +8 0.0020336100526728302319 0.78135207839715916734 +0.000164587904124493665 +29.566779964594630314 -4.5668176855665958414 -0.58741108465859714904 +0.16916723445783939828 1.142713652049310879 -0.027397346380668001207 diff --git a/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb b/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb new file mode 100644 index 000000000..ef0a664c8 --- /dev/null +++ b/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb @@ -0,0 +1,245 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import swiftest" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swifter file param.swifter.in\n", + "Reading in time 1.000e+00\n", + "Creating Dataset\n", + "Successfully converted 1462 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftersim = swiftest.Simulation(param_file=\"param.swifter.in\", codename=\"Swifter\")\n", + "swiftersim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.000e+00\n", + "Creating Dataset\n", + "Successfully converted 1462 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], + "source": [ + "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", + "swiftestsim.bin2xr()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftestsim.ds - swiftersim.ds" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff = swiftdiff.rename({'time' : 'time (y)'})" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "swiftdiff['dr'] = np.sqrt(swiftdiff['px']**2 + swiftdiff['py']**2 + swiftdiff['pz']**2)\n", + "swiftdiff['dv'] = np.sqrt(swiftdiff['vx']**2 + swiftdiff['vy']**2 + swiftdiff['vz']**2)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "pldiff = swiftdiff.where(np.invert(np.isnan(swiftdiff['Mass'])), drop=True)\n", + "tpdiff = swiftdiff.where(np.isnan(swiftdiff['Mass']), drop=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "pldiff['dr'].plot.line(x=\"time (y)\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "tpdiff['dr'].plot.line(x=\"time (y)\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "pldiff['dv'].plot.line(x=\"time (y)\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "tpdiff['dv'].plot.line(x=\"time (y)\")\n", + "print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "swiftestOOF", + "language": "python", + "name": "swiftestoof" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/whm_swifter_comparison/tp.swifter.in b/examples/whm_swifter_comparison/tp.swifter.in new file mode 100644 index 000000000..22ca5a6ca --- /dev/null +++ b/examples/whm_swifter_comparison/tp.swifter.in @@ -0,0 +1,13 @@ +4 +101 +2.1437140623725170485 1.8307543455088179929 -0.33710883085786358393 +-2.5169991736250634084 2.6269266483088493027 0.54674712095669365287 +102 +3.0507953356624089025 -0.9309107058567914761 0.38209550228666327998 +0.45214249601424874418 2.5995875558304815747 -1.8388641770977671949 +103 +-0.30288545144121659103 -3.139125526168093927 0.7252151132548391166 +3.0919425994019995516 0.13633790246363267858 -0.15665049243950410883 +104 +-1.9314729940131600827 -1.0389307897540689396 0.26607157142831372454 +2.2775049779995786108 -3.7157836040053666307 -0.16601542341215017115 diff --git a/examples/whm_swifter_comparison/tp.swiftest.in b/examples/whm_swifter_comparison/tp.swiftest.in new file mode 100644 index 000000000..22ca5a6ca --- /dev/null +++ b/examples/whm_swifter_comparison/tp.swiftest.in @@ -0,0 +1,13 @@ +4 +101 +2.1437140623725170485 1.8307543455088179929 -0.33710883085786358393 +-2.5169991736250634084 2.6269266483088493027 0.54674712095669365287 +102 +3.0507953356624089025 -0.9309107058567914761 0.38209550228666327998 +0.45214249601424874418 2.5995875558304815747 -1.8388641770977671949 +103 +-0.30288545144121659103 -3.139125526168093927 0.7252151132548391166 +3.0919425994019995516 0.13633790246363267858 -0.15665049243950410883 +104 +-1.9314729940131600827 -1.0389307897540689396 0.26607157142831372454 +2.2775049779995786108 -3.7157836040053666307 -0.16601542341215017115 diff --git a/fxdr/Defines.aix b/fxdr/Defines.aix deleted file mode 100644 index 8ef714c13..000000000 --- a/fxdr/Defines.aix +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -DIFSTYLE=2 -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib diff --git a/fxdr/Defines.hpux b/fxdr/Defines.hpux deleted file mode 100644 index 9da3a811a..000000000 --- a/fxdr/Defines.hpux +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = fort77 -F77OPTS = +U77 +O3 -K +e +es -CCCMD = c89 -CCOPTS = -DIFSTYLE=2 -AR = ar -CPP = /lib/cpp -64_BIT_REALS = -r8 diff --git a/fxdr/Defines.irix b/fxdr/Defines.irix deleted file mode 100644 index 50c237050..000000000 --- a/fxdr/Defines.irix +++ /dev/null @@ -1,8 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc - -RANLIB = echo -AR = ar - -CPP = /lib/cpp diff --git a/fxdr/Defines.linux b/fxdr/Defines.linux deleted file mode 100644 index b7f207d78..000000000 --- a/fxdr/Defines.linux +++ /dev/null @@ -1,5 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = diff --git a/fxdr/Defines.osf1 b/fxdr/Defines.osf1 deleted file mode 100644 index b7f207d78..000000000 --- a/fxdr/Defines.osf1 +++ /dev/null @@ -1,5 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = diff --git a/fxdr/Defines.sun b/fxdr/Defines.sun deleted file mode 100644 index 0414beb19..000000000 --- a/fxdr/Defines.sun +++ /dev/null @@ -1,8 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib -EXTRA_LIBS = -lnsl diff --git a/fxdr/Defines.ultrix b/fxdr/Defines.ultrix deleted file mode 100644 index 173c9dac5..000000000 --- a/fxdr/Defines.ultrix +++ /dev/null @@ -1,4 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -RANLIB = ranlib diff --git a/fxdr/Defines.unicos b/fxdr/Defines.unicos deleted file mode 100644 index d64efca91..000000000 --- a/fxdr/Defines.unicos +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = f90 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray_twobytecptrs -Dcray -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp diff --git a/fxdr/Defines.unicos.old b/fxdr/Defines.unicos.old deleted file mode 100644 index 42291de05..000000000 --- a/fxdr/Defines.unicos.old +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = cf77 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp diff --git a/fxdr/Defines.unicos_t3e b/fxdr/Defines.unicos_t3e deleted file mode 100644 index 213d7c293..000000000 --- a/fxdr/Defines.unicos_t3e +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = f90 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray_twobytecptrs -Dcray -h nomessage=230 -RANLIB = echo -AR = ar -CPP = /usr/lib/gpp diff --git a/fxdr/Defines.unsupported b/fxdr/Defines.unsupported deleted file mode 100644 index 901fdc677..000000000 --- a/fxdr/Defines.unsupported +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib diff --git a/fxdr/Makefile.bak b/fxdr/Makefile.bak deleted file mode 100644 index 78d0cc573..000000000 --- a/fxdr/Makefile.bak +++ /dev/null @@ -1,46 +0,0 @@ -F77CMD = cf77 -CCCMD = c89 -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp -OBJS = cxdrinit.o xdrint.o initxdr.o cxdrint.o xdrclose.o \ - cxdrclose.o xdrreal.o cxdrreal.o cxdrdouble.o \ - xdrdouble.o xdrrmat.o cxdrrmat.o xdrdmat.o cxdrdmat.o \ - xdrimat.o cxdrimat.o xdrstring.o cxdrstring.o \ - xdrreal64.o cxdrreal64.o xdrrmat64.o cxdrrmat64.o - -SRCS = cxdrinit.c xdrint.F initxdr.F cxdrint.c xdrclose.F \ - cxdrclose.c xdrreal.F cxdrreal.c cxdrdouble.c \ - xdrdouble.F xdrrmat.F cxdrrmat.c xdrdmat.F cxdrdmat.c \ - xdrimat.F cxdrimat.c xdrstring.F cxdrstring.c \ - xdrreal64.F cxdrreal64.c - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - cp libfxdr.a $(HOME)/lib - -test: $(OBJS) test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr - ./test - -clean: - -rm *.o test Makefile - -tar: - @echo "Remember to make clean before making tar!" - cd .. ; tar cvf fxdr_0.9.tar fxdr_0.9 diff --git a/fxdr/Makefile.fxdr b/fxdr/Makefile.fxdr deleted file mode 100644 index 549eb76c1..000000000 --- a/fxdr/Makefile.fxdr +++ /dev/null @@ -1,105 +0,0 @@ -#****************************************************************************** -# -# Unit Name : Makefile.fxdr -# Unit Type : makefile -# Project : SWIFTER -# Package : N/A -# Language : GNU makefile syntax -# -# Description : Controls the build of the FXDR library -# -# Input -# Arguments : Zero or more of the following targets: -# (1) libfxdr.a : builds the FXDR library -# (2) test : runs tests on FXDR library -# (3) install : installs library and FXDR include file -# (4) clean : removes object modules and test program -# Terminal : none -# File : Makefile.Defines -# -# Output -# Arguments : none -# Terminal : status messages -# File : none -# -# Invocation : make [libfxdr.a|test|install|clean] -# -# Notes : -# -#****************************************************************************** - -include Makefile.Defines - -OBJS = cxdrinit.o ixdrint.o initxdr.o cxdrint.o ixdrclose.o \ - cxdrclose.o ixdrreal.o cxdrreal.o cxdrdouble.o \ - ixdrdouble.o ixdrrmat.o cxdrrmat.o ixdrdmat.o cxdrdmat.o \ - ixdrimat.o cxdrimat.o ixdrstring.o cxdrstring.o \ - ixdrreal64.o cxdrreal64.o ixdrrmat64.o cxdrrmat64.o \ - ixdrrewind.o cxdrrewind.o ixdrshort.o cxdrshort.o - -SRCS = cxdrinit.c ixdrint.F initxdr.F cxdrint.c ixdrclose.F \ - cxdrclose.c ixdrreal.F cxdrreal.c cxdrdouble.c \ - ixdrdouble.F ixdrrmat.F cxdrrmat.c ixdrdmat.F cxdrdmat.c \ - ixdrimat.F cxdrimat.c ixdrstring.F cxdrstring.c \ - ixdrreal64.F cxdrreal64.c ixdrrewind.F cxdrrewind.c \ - ixdrshort.F cxdrshort.F - -PLACE_FOR_LIBRARY = $(SWIFTER_HOME)/lib - -PLACE_FOR_HEADER = $(SWIFTER_HOME)/include - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - @echo "Now do 'make test' to check the library" - -test: libfxdr.a test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr $(EXTRA_LIBS) - touch test_no_read.xdr - chmod -r test_no_read.xdr - ./test - rm test_no_read.xdr - -clean: - -rm *.o test - -install: - $(INSTALL_DATA) libfxdr.a $(PLACE_FOR_LIBRARY) - $(INSTALL_DATA) fxdr.inc $(PLACE_FOR_HEADER) - -#****************************************************************************** -# -# Author(s) : David W. Pierce -# -# Revision Control System (RCS) Information -# -# Source File : $RCSfile: Makefile.fxdr,v $ -# Full Path : $Source: /d1/kaufmann/development/RCS/Makefile.fxdr,v $ -# Revision : $Revision: 0.1 $ -# Date : $Date: 2003/04/15 23:10:41 $ -# Programmer : $Author: kaufmann $ -# Locked By : $Locker: $ -# State : $State: Exp $ -# -# Modification History: -# -# $Log: Makefile.fxdr,v $ -# Revision 0.1 2003/04/15 23:10:41 kaufmann -# Initial implementation -# -# -#****************************************************************************** diff --git a/fxdr/Makefile.tmpl b/fxdr/Makefile.tmpl deleted file mode 100644 index 5f6e728a4..000000000 --- a/fxdr/Makefile.tmpl +++ /dev/null @@ -1,55 +0,0 @@ -OBJS = cxdrinit.o ixdrint.o initxdr.o cxdrint.o ixdrclose.o \ - cxdrclose.o ixdrreal.o cxdrreal.o cxdrdouble.o \ - ixdrdouble.o ixdrrmat.o cxdrrmat.o ixdrdmat.o cxdrdmat.o \ - ixdrimat.o cxdrimat.o ixdrstring.o cxdrstring.o \ - ixdrreal64.o cxdrreal64.o ixdrrmat64.o cxdrrmat64.o \ - ixdrrewind.o cxdrrewind.o ixdrshort.o cxdrshort.o - -SRCS = cxdrinit.c ixdrint.F initxdr.F cxdrint.c ixdrclose.F \ - cxdrclose.c ixdrreal.F cxdrreal.c cxdrdouble.c \ - ixdrdouble.F ixdrrmat.F cxdrrmat.c ixdrdmat.F cxdrdmat.c \ - ixdrimat.F cxdrimat.c ixdrstring.F cxdrstring.c \ - ixdrreal64.F cxdrreal64.c ixdrrewind.F cxdrrewind.c \ - ixdrshort.F cxdrshort.F - -PLACE_FOR_LIBRARY = /usr/local/lib - -PLACE_FOR_HEADER = /usr/local/include - -PLACE_FOR_MANPAGE = /usr/man/local - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - @echo "Now do 'make test' to check the library" - -test: libfxdr.a test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr $(EXTRA_LIBS) - touch test_no_read.xdr - chmod -r test_no_read.xdr - ./test - rm test_no_read.xdr - -clean: - -rm *.o test Makefile - -install: - cp libfxdr.a $(PLACE_FOR_LIBRARY)/libfxdr.a - cp fxdr.inc $(PLACE_FOR_HEADER)/fxdr.inc - cp fxdr.3f $(PLACE_FOR_MANPAGE)/fxdr.3f - - diff --git a/fxdr/README b/fxdr/README deleted file mode 100644 index 3fec6a9f4..000000000 --- a/fxdr/README +++ /dev/null @@ -1,33 +0,0 @@ -Copyright (c) 1995, 1999 The Regents of the University of California. All -rights reserved. - -Redistribution and use in source and binary forms are permitted provided -that (1) source distrubutions retain this entire copyright notice and -comment, and (2) distributions including binaries display the following -acknowledgement: ``This product includes software developed by the -University of California, San Diego and its contributors'' in the -documentation or other materials provided with the distribution and in -all advertising materials mentioning features or use of this software. -Neither the name of the University nor the names of its contributors may -be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -============================================================================= - -Make sure to read one of these if it applies to your platform: - -README.HPUX -README.sun_and_IDL -README.Linux - -============================================================================= - -The main information resides at: - -http://meteora.ucsd.edu:80/~pierce/fxdr_home_page.html - -Please consult the information there. diff --git a/fxdr/README.HPUX b/fxdr/README.HPUX deleted file mode 100644 index a8cb05535..000000000 --- a/fxdr/README.HPUX +++ /dev/null @@ -1,27 +0,0 @@ -I don't have access to a modern HP system, so I can't -check this configuration myself. However, fxdr apparently -doesn't compile out of the box on newer HP systems. I -received the following message: - -================================================================== - -Date: Thu, 11 Sep 1997 16:05:20 +0200 -Message-Id: <199709111405.AA273236720@utmfu3.math.utwente.nl> -From: ijzerman -To: dpierce@ucsd.edu -Status: RO -X-Status: - -Dear David Pierce, - -I downloaded the fxdr-package. To install it on HP-unix 9.0 or 10.0 I -had to change the c89 in the default makefile to cc. Otherwise all -kind of error occured with respect to the rpc.h files. - -Sincerely yours, - -Wilbert IJzerman - -================================================================== - -So, if this is the platform you are using, give this a try. diff --git a/fxdr/README.Linux b/fxdr/README.Linux deleted file mode 100644 index ce2e70b38..000000000 --- a/fxdr/README.Linux +++ /dev/null @@ -1,59 +0,0 @@ -The package works on a Linux system I tried that uses the gnu compilers. -However, the following message may be of interest to people running Linux -with Nag Fortran90: - -=================================================================== - -Date: Tue, 09 Sep 1997 19:13:22 +0200 -From: Axel vom Endt -Organization: MPI f. Aeronomie -X-Mailer: Mozilla 3.01Gold (X11; I; Linux 2.0.25 i586) -Mime-Version: 1.0 -To: dpierce@ucsd.edu -Subject: fxdr -Content-Type: multipart/mixed; boundary="------------1EE0A5BF2F6227C5175DD76D" -Status: RO -X-Status: - -This is a multi-part message in MIME format. - ---------------1EE0A5BF2F6227C5175DD76D -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit - -Dera Mr. Pierce, - -Today I found your fxdr package and adopted it to my system, running -Linux 2.0.25 and Nag Fortran90. - -If you are interested in the changes I made to your package, You will -find the files attached. - -I had to move all *.F to *.f files since NAGf90 doesn't like any -extension but .f or .f90 and I also had to delete all # preprocessor -pragmas in test.f. Not very diffucult, though. - -Thank you very much for providing this package, you saved me a lot of -time... - -All the best from Germany - --- -Axel vom Endt Office: A2_95 -Max-Planck-Institut f. Aeronomie Phone: +49-(0)5556-979-481 -Postfach 20 Fax: +49-(0)5556-979-240 -D-37191 Katlenburg-Lindau Email: Axel.vom.Endt@linmpi.mpg.de - -=============================================================== - -filename="Defines.linux" - -F77CMD = f90 -64_BIT_REALS = -r8 -CCCMD = gcc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib - - diff --git a/fxdr/README.sun_and_IDL b/fxdr/README.sun_and_IDL deleted file mode 100644 index f0a843612..000000000 --- a/fxdr/README.sun_and_IDL +++ /dev/null @@ -1,107 +0,0 @@ -The following e-mail might be helpful to people using the FXDR -library on the Sun platform, or using it in conjunction with IDL. -The alterations and routines mentioned below have been included -with the release. - ----------------------------------------------------------------- - -From wilms@rocinante.Colorado.EDU Tue Aug 13 09:11:26 1996 -Date: Tue, 13 Aug 1996 09:42:24 -0600 -From: Joern Wilms -To: dpierce@ucsd.edu - -Dear Dr. Pierce, - -first I'd like to thank you for the development of the -fxdr library, which is a great help for all of us who are -stuck with FORTRAN... - -I recently compiled fxdr on a Sun machine (uname -a is) - - SunOS dulcinea 5.5.1 Generic sun4u sparc SUNW,Ultra-1 - -using the standard Sun compilers. On this machine, in order -to get the library to work, it is also necessary to link the binaries -with the nsl library (i.e. -L/usr/local/lib -lfxdr -lnsl) because the -xdr routines are not in the system-library. Apart from that, the -Defines.unsupported just worked fine. - -Secondly when interfacing the library with IDL, a visualization language -often used in astronomy, satellite imagery, and in medical applications, I -found it necessary to add some subroutines that write shorts in xdr format -(IDL writes its integers as shorts and prepends strings with their length -in short format; in addition, IDL DOES NOT use the xdr_array function to -write its arrays, but just uses a loop to write all array elements, here, -the array is NOT prepended with its length; I really wonder why they didn't -use the standard xdr constructs in both cases...). I've attached the -necessary subroutines, feel free to include them with the next release of -fxdr (only if you want....) - -Thanks again, - -Joern - - - -**** -xdrshort.F -**** - -c -c Write/Read an integer as a short (may cause wrap-around!) -c J. Wilms, wilms@astro.uni-tuebingen.de or wilms@colorado.edu -c - subroutine xdrshort (ixdrs, num) - integer ixdrs,ixdrsm1,num - - ixdrsm1=ixdrs - 1 - - call cxdrshort( ixdrsm1, num) - - return - end - -***** -cxdrshort.c -***** - -/* Write/Read a short */ -/* J. Wilms, wilms@astro.uni-tuebingen.de or wilms@colorado.edu */ - -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#ifdef cray - CXDRSHORT( int *ixdrid, int *i ) - -#elif defined( hpux ) - cxdrshort( ixdrid, i ) - int *ixdrid; - int *i; - -#else - cxdrshort_( int *ixdrid, int *i ) -#endif -{ - XDR *xdrs; - short ii; - - xdrs = xdrfile[*ixdrid].xdrs; - - if (xdrs->x_op == XDR_ENCODE) ii=(short) *i; - - if( ! xdr_short( xdrs, &ii ) ) { - fprintf( stderr, "FXDR library error! Call to read short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - - if (xdrs->x_op == XDR_DECODE) i=(int) ii; -} - diff --git a/fxdr/README.unicos b/fxdr/README.unicos deleted file mode 100644 index 6ccb120bf..000000000 --- a/fxdr/README.unicos +++ /dev/null @@ -1,27 +0,0 @@ -At some point Cray stopped defining the compiler symbol -'cray' in the c89 command; I've added a "-Dcray" to the -c89 command line to fix that. Also, newer crays do not -include support for the cf77 compiler; I've switched it -to the f90 compiler. I've not experienced any problems -with this change. In case you need it for old installations, -there is a "Defines.unicos.old" that has the old values -for the unicos system; copy that to Defines.unicos if -you need to. - ---David Pierce -13 November 1998 - -Note added 31 Aug 1999: -At some point Cray decided to switch Fortran character -strings from one word pointers to TWO word pointers! -Needless to say, this messed up the routines that -transfer character strings from Fortran to C. The -code has been changed to use the new style TWO word pointers. -This is controlled by adding "-Dcray_twobytecptrs" to the -CC command in the Defines.unicos* files. If you have an -old Cray installation that predates this change, you will -probably have to get rid of the -Dcray_twobytecptrs entry -in your Defines.unicos file, make clean, configure, then -make and make test. - - diff --git a/fxdr/cfxdr.h b/fxdr/cfxdr.h deleted file mode 100644 index 2ab4a4dea..000000000 --- a/fxdr/cfxdr.h +++ /dev/null @@ -1,15 +0,0 @@ - -#define MAX_N_XDR_FILES 32 - -typedef struct { - char *filename; - int return_on_error; /* 0=FALSE, 1=TRUE */ - XDR *xdrs; -} XDR_element; - -#define FXDRERR_WRNEGNELS -10 -#define FXDRERR_WRITEERR -11 -#define FXDRERR_READERR -12 -#define FXDRERR_READWRONGNELS -13 -#define FXDRERR_REWIND -14 - diff --git a/fxdr/configure b/fxdr/configure deleted file mode 100755 index 3da5a31a0..000000000 --- a/fxdr/configure +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh - -if test $# -eq 0; then - un=`uname -a` - un1=`echo $un | awk ' { print substr($1,1,4) }'` - un5=`echo $un | awk ' { print $5 }'` - un6=`echo $un | awk ' { print $6 }'` - if test $un1 = "HP-U"; then - sys=hpux - elif test $un1 = "Linu"; then - sys=linux - elif test $un1 = "IRIX"; then - sys=irix - elif test $un1 = "ULTR"; then - sys=ultrix - elif test $un1 = "AIX"; then - sys=aix - elif test $un1 = "OSF1"; then - sys=osf1 - elif test $un1 = "SunO"; then - sys=sun - echo "Note: on a Sun, you must link your application programs" - echo "with the system nsl library in addition to the fxdr" - echo "library. So, for example, you would add the following" - echo "to the end of your compile command:" - echo " -L/usr/local/lib -lfxdr -lnsl" - echo " " - elif test $un5 = "CRAY"; then - if test $un6 = "T3E"; then - sys=unicos_t3e - else - sys=unicos - fi - else - echo "I can't figure out what kind of system this is," - echo "or I just may not be set up to handle it." - echo "Try invoking configure with one of the following" - echo "arguments, if appropriate:" - echo " hpux irix ultrix osf1 unicos aix linux" - exit - fi -else - sys=$1 -fi - -if test ! -r Defines.$sys; then - echo "I don't know how to handle system $sys" - echo "Please see the README file for configuring for an unsupported" - echo "system. Or, you can just try 'make unsupported' and hope it" - echo "works!" - exit -fi - -cat Defines.$sys Makefile.tmpl > Makefile -echo "Configured a Makefile for $sys" -echo "Now type \"make\"" diff --git a/fxdr/cxdrclose.c b/fxdr/cxdrclose.c deleted file mode 100644 index d667d4458..000000000 --- a/fxdr/cxdrclose.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void - -#if (IFSTYLE==1) - CXDRCLOSE( int *ixdrid, int *retval ) - -#elif (IFSTYLE==2) - cxdrclose( ixdrid, retval ) - int *ixdrid; - int *retval; - -#else - cxdrclose_( int *ixdrid, int *retval ) -#endif -{ - XDR *xdrs; - FILE *f; - - *retval = 0; /* No errors */ - - xdrs = xdrfile[*ixdrid].xdrs; - - /* Get the file pointer, which was saved in the user's - * data area, so we can close the file after destroying - * the XDR handle. - */ - f = (FILE *)xdrs->x_public; - - xdr_destroy( xdrs ); - - fclose( f ); - - xdrfile[*ixdrid].filename = NULL; -} - diff --git a/fxdr/cxdrdmat.c b/fxdr/cxdrdmat.c deleted file mode 100644 index d92aee020..000000000 --- a/fxdr/cxdrdmat.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRDMAT( int *ixdrid, int *nels, double *d, int *retval ) - -#elif (IFSTYLE==2) - cxdrdmat( ixdrid, nels, d, retval ) - int *ixdrid; - int *nels; - double *d; - int *retval; - -#else - cxdrdmat_( int *ixdrid, int *nels, double *d, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write double precision array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&d, &ne, *nels, sizeof(double), xdr_double ) ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to " ); - fprintf( stderr, "write double precision array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - if( ! xdr_array( xdrs, (char **)&d, &actual_nels, *nels, sizeof(double), xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to " ); - fprintf( stderr, "read double precision array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "error reading the file\n" ); - exit( -1 ); - } - } - - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d double precision elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr/cxdrdouble.c b/fxdr/cxdrdouble.c deleted file mode 100644 index 6dcaf07dd..000000000 --- a/fxdr/cxdrdouble.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRDOUBLE( int *ixdrid, double *d, int *retval ) - -#elif (IFSTYLE==2) - cxdrdouble( ixdrid, d, retval ) - int *ixdrid; - double *d; - int *retval; - -#else - cxdrdouble_( int *ixdrid, double *d, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_double( xdrs, d )) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to write " ); - fprintf( stderr, "a double precision number from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to read " ); - fprintf( stderr, "a double precision number to file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr/cxdrimat.c b/fxdr/cxdrimat.c deleted file mode 100644 index 876d7250e..000000000 --- a/fxdr/cxdrimat.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRIMAT( int *ixdrid, int *nels, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrimat( ixdrid, nels, i, retval ) - int *ixdrid; - int *nels; - int *i; - int *retval; - -#else - cxdrimat_( int *ixdrid, int *nels, int *i, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write integer array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&i, &ne, *nels, sizeof(int), xdr_int )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write integer array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - if( ! xdr_array( xdrs, (char **)&i, &actual_nels, *nels, sizeof(int), xdr_int )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read integer array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d integer elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured while reading file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr/cxdrinit.c b/fxdr/cxdrinit.c deleted file mode 100644 index 87128ef05..000000000 --- a/fxdr/cxdrinit.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include "cfxdr.h" - -XDR_element xdrfile[MAX_N_XDR_FILES] = { - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL }; - - long -#if defined(cray_twobytecptrs) - CXDRINIT( int *fname_len, char *filename, int *dummy, int *mode, int *return_on_err ) - -#elif (IFSTYLE==1) - CXDRINIT( int *fname_len, char *filename, int *mode, int *return_on_err ) - -#elif (IFSTYLE==2) - cxdrinit( fname_len, filename, mode, return_on_err ) - int *fname_len; - char *filename; - int *mode; - int *return_on_err; - -#else - cxdrinit_( int *fname_len, char *filename, int *mode, int *return_on_err ) -#endif -{ - FILE *f; - int xdr_mode, new_xdr_id; - XDR *xdrs; - char local_filename[2048]; - - strncpy( local_filename, filename, *fname_len ); - local_filename[*fname_len] = '\0'; - - /* Get the new XDR ID to use when accessing this file */ - if( (new_xdr_id = cxdrgetid()) == -1 ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "Error while trying to open file %s\n", - local_filename ); - exit( -1 ); - } - } - - /* Save the file name of this XDR file, so that we - * can print it out in case of errors. - */ - xdrfile[new_xdr_id].filename = (char *) - malloc(sizeof(char)*(*fname_len + 1)); - strcpy( xdrfile[new_xdr_id].filename, local_filename ); - - xdrs = (XDR *)malloc( sizeof( XDR ) ); - if( xdrs == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "Error on xdr stream create\n" ); - fprintf( stderr, "filename=%s\n", local_filename ); - exit( -1 ); - } - } - - if( *mode == 1 ) { - xdr_mode = XDR_DECODE; - if( (f = fopen( local_filename, "r" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for reading\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else if( *mode == 2 ) { - xdr_mode = XDR_ENCODE; - if( (f = fopen( local_filename, "w" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for writing\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else if( *mode == 3 ) { - xdr_mode = XDR_ENCODE; - if( (f = fopen( local_filename, "a" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for appending\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else /* Wrong mode specified */ - { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "error: cxdrinit.c called with mode=%ld\n", *mode ); - exit( -1 ); - } - } - - xdrstdio_create( xdrs, f, xdr_mode ); - - xdrfile[new_xdr_id].return_on_error = *return_on_err; - xdrfile[new_xdr_id].xdrs = xdrs; - - /* Add the file pointer to the user's data area so - * that we can close the file when the destroy routine - * is called! - */ - xdrs->x_public = (caddr_t)f; - - return( new_xdr_id ); -} - - int -cxdrgetid() -{ - int i; - - i = 0; - while( xdrfile[i].filename != NULL ) { - i++; - if( i >= MAX_N_XDR_FILES ) { - fprintf( stderr, "FXDR library error: too many "); - fprintf( stderr, "XDR files open! Max is %d\n", - MAX_N_XDR_FILES ); - return( -1 ); - } - } - return( i ); -} diff --git a/fxdr/cxdrint.c b/fxdr/cxdrint.c deleted file mode 100644 index 0096db0b9..000000000 --- a/fxdr/cxdrint.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRINT( int *ixdrid, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrint( ixdrid, i, retval ) - int *ixdrid; - int *i; - int *retval; - -#else - cxdrint_( int *ixdrid, int *i, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_int( xdrs, i ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write integer "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read integer "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr/cxdrreal.c b/fxdr/cxdrreal.c deleted file mode 100644 index 6a6ed3bf8..000000000 --- a/fxdr/cxdrreal.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREAL( int *ixdrid, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrreal( ixdrid, r, retval ) - int *ixdrid; - float *r; - int *retval; - -#else - cxdrreal_( int *ixdrid, float *r, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_float( xdrs, r ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write real "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read real "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr/cxdrreal64 b/fxdr/cxdrreal64 deleted file mode 100644 index 3f01074b7..000000000 Binary files a/fxdr/cxdrreal64 and /dev/null differ diff --git a/fxdr/cxdrreal64.c b/fxdr/cxdrreal64.c deleted file mode 100644 index 5b0a38e33..000000000 --- a/fxdr/cxdrreal64.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREAL64( int *ixdrid, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrreal64( ixdrid, r, retval ) - int *ixdrid; - float *r; - int *retval; - -#else - cxdrreal64_( int *ixdrid, float *r, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_double( xdrs, (double *)r ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write double "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read double "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr/cxdrrewind.c b/fxdr/cxdrrewind.c deleted file mode 100644 index 94ef67827..000000000 --- a/fxdr/cxdrrewind.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREWIND( int *ixdrid, int *retval ) - -#elif (IFSTYLE==2) - cxdrrewind( ixdrid, retval ) - int *ixdrid; - int *retval; - -#else - cxdrrewind_( int *ixdrid, int *retval ) -#endif -{ - XDR *xdrs; - u_int position; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - position = 0; - - if( ! xdr_setpos( xdrs, position ) ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_REWIND; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to rewind "); - fprintf( stderr, "file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } -} diff --git a/fxdr/cxdrrmat.c b/fxdr/cxdrrmat.c deleted file mode 100644 index 462ade04d..000000000 --- a/fxdr/cxdrrmat.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRRMAT( int *ixdrid, int *nels, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrrmat( ixdrid, nels, r, retval ) - int *ixdrid; - int *nels; - float *r; - int *retval; - -#else - cxdrrmat_( int *ixdrid, int *nels, float *r, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &ne, ne, sizeof(float), xdr_float )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &actual_nels, ne, sizeof(float), xdr_float)) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read real array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d real elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr/cxdrrmat64.c b/fxdr/cxdrrmat64.c deleted file mode 100644 index 10f5be62a..000000000 --- a/fxdr/cxdrrmat64.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRRMAT64( int *ixdrid, int *nels, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrrmat64( ixdrid, nels, r, retval ) - int *ixdrid; - int *nels; - float *r; - int *retval; - -#else - cxdrrmat64_( int *ixdrid, int *nels, float *r, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real64 array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &ne, ne, 8, xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real (64 bit) array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &actual_nels, ne, 8, xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read real (64 bit) array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d real64 elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr/cxdrshort.c b/fxdr/cxdrshort.c deleted file mode 100644 index e67addd14..000000000 --- a/fxdr/cxdrshort.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Write/Read a short */ - -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRSHORT( int *ixdrid, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrshort( ixdrid, i, retval ) - int *ixdrid; - int *i; - int *retval; - -#else - cxdrshort_( int *ixdrid, int *i, int *retval ) -#endif -{ - XDR *xdrs; - short ii; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if (xdrs->x_op == XDR_ENCODE) ii=(short) *i; - - if( ! xdr_short( xdrs, &ii ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } - - if (xdrs->x_op == XDR_DECODE) *i=(int)ii; -} - diff --git a/fxdr/cxdrstring.c b/fxdr/cxdrstring.c deleted file mode 100644 index d69e27247..000000000 --- a/fxdr/cxdrstring.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if defined(cray_twobytecptrs) - CXDRSTRING( int *ixdrid, u_int *len, char *s, int *dummy, int *retval ) - -#elif (IFSTYLE==1) - CXDRSTRING( int *ixdrid, u_int *len, char *s, int *retval ) - -#elif (IFSTYLE==2) - cxdrstring( ixdrid, len, s, retval ) - int *ixdrid; - u_int *len; - char *s; - int *retval; - -#else - cxdrstring_( int *ixdrid, u_int *len, char *s, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_bytes( xdrs, &s, len, *len ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to write a"); - fprintf( stderr, "string from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to read a"); - fprintf( stderr, "string from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr/fxdr.3f b/fxdr/fxdr.3f deleted file mode 100644 index e00b6d042..000000000 --- a/fxdr/fxdr.3f +++ /dev/null @@ -1,342 +0,0 @@ -.TH FXDR 3F local - -fxdr: a library to interface the XDR routines to FORTRAN. -.PP -The FXDR library is a set of FORTRAN routines which provide an interface -to the XDR routines which already exist (almost certainly) on your workstation -or mainframe. I.e., it provides an easy and convenient way to -use the XDR ability of your computer from FORTRAN. -.PP -If you use the FXDR routines in your FORTRAN codes -to write out your binary data files, then you can move those data files -around to any of the different machines you use, and the data will be -read in correctly within the precision limits of XDR and your machine -(generally, about 1 part in 10**7 for 32-bit single precision numbers and -1 part in 10**15 for 64-bit double precision numbers). -.PP -.SH ROUTINES: -.PP -.I integer function INITXDR( filename, mode, return_on_error ) -.EX - character*(*) filename (an input) - character*1 mode (an input; 'r', 'w', or 'a') - logical return_on_error (an input) -.EE -initializes an XDR file -for reading (if mode='r'), writing (if mode='w'), or appending (if mode='a'). -Returns the XDR file ID ('ixdrs'), which is greater than or -equal to zero; or, if an error is encountered -and return_on_error is .TRUE., returns an error code that -is less than zero. -If logical argument return_on_error is .FALSE., then any fxdr -routines (including this one!) that encounter errors accessing this file -(for example, trying to read past an end of file, or reading in -a different number of array elements than was originally -written to the file) will print out an error message and stop. -This is similar to what Fortran does, so for the most -Fortran-like behavior set return_on_error to .FALSE.. -If logical argument return_on_error is .TRUE., then -any fxdr routines (including this one!) that encounter errors will -NOT stop, but instead return a value -that is less than 0 to the calling routine. -.PP -.I INTEGER FUNCTION IXDRINT( ixdrs, ival ): -Read or write a FORTRAN integer. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREAL( ixdrs, sval ): -Read or write a FORTRAN 'real' using 32 bits in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRDOUBLE( ixdrs, dval ): -Read or write a FORTRAN 'double precision' using 64 bits in -the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREAL64( ixdrs, fval ): -Read or write a FORTRAN 'real' using 64 bits in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRSTRING( ixdrs, string ): -Read or write a FORTRAN "character*(*)". -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the string. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRIMAT( ixdrs, nels, iarray ): -Read or write an array of FORTRAN integers. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRRMAT( ixdrs, nels, sarray ): -Read or write an array of FORTRAN 'real' using 32 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRDMAT( ixdrs, nels, darray ): -Read or write an array of FORTRAN 'double precision' using 64 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRRMAT64( ixdrs, nels, sarray ): -Read or write an array of FORTRAN 'real' using 64 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREWIND( ixdrs ): -Rewind an XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when rewinding. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRCLOSE( ixdrs ): -Close an XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when closing the file. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.SH USEAGE: -You just replace your FORTRAN unformatted binary write statements with -calls to the appropriate FXDR library routine. -For most Fortran-like behavior, set the return_on_error argument -to INITXDR (the third argument) to .FALSE. -- this will make the -routines print out an error message and halt if an error is -encountered. -If you want to handle error messages yourself, then set -the return_on_error argument -to INITXDR (the third argument) to .TRUE., and check the -returned values from the XDR routines; they will be less than -zero if an error is encountered. -A list of error codes is in 'fxdr.inc', which you also need -to include in your source code if you are using 'implicit none'. -.PP -Example to write data: -.EX - Replace - parameter (nx=80,ny=100) - real coeffs(nx,ny) - open(ilun, file='test_data', form='unformatted') - write(ilun) coeffs - - With - parameter (nx=80,ny=100) - real coeffs(nx,ny) - ixdrs = initxdr('test_data.xdr', 'w', .FALSE.) - ierr = ixdrrmat( ixdrs, nx*ny, coeffs ) -.EE -.PP -Pretty easy, eh? To read in that same data: -.EX - Replace - open(ilun, file='test_data', form='unformatted') - read(ilun) coeffs - - With - ixdrs = initxdr('test_data.xdr', 'r', .FALSE.) - ierr = ixdrrmat( ixdrs, nx*ny, coeffs ) -.EE -Note that the call to the FXDR routine is EXACTLY THE SAME whether you -are reading or writing; whether you actually read or write is determined -by whether you called the 'initxdr' routine with a 'r' or 'w' as the -second argument. This is opposite FORTRAN, where the call to open the -file is exactly the same whether you are reading or writing, but you -call different routines ('read' or 'write') to accomplish the one you want. -.PP -.I More detail on using the FXDR library -To use the FXDR library you first open the XDR-format file using the 'initxdr' -routine. This routine returns an integer which is the ID number which all -the XDR routines will use to indicate which XDR file you want to work with. -The first argument to 'initxdr' is the name of the file, the second -argument is either 'r', 'w', or 'a' for reading, writing, or appending, and the third -is a logical that you set to .TRUE. if you want to do your own error -handling (by testing if the return value of functions is less than 0), -and .FALSE. if you want the Fortran-like behavior of printing an -error message and halting if an error is encountered: -.EX - character*(*) filename - character*1 mode - integer id - id = initxdr( filename, mode, .FALSE. ) -.EE -Then you replace both your 'read' and 'write' calls with a call to one of -the following integer functions: -.EX -Name Bits FORTRAN type of argument ---------- ---- -------------------------------------------------------- -ixdrdouble 64 double precision floating point number -ixdrdmat 64 array of double precision floating point numbers -ixdrint 32 integer -ixdrimat 32 array of integers -ixdrreal 32 single precision floating point number -ixdrrmat 32 array of single precision floating point numbers -ixdrreal64 64 single precision floating point number -ixdrrmat64 64 array of single precision floating point numbers -ixdrstring n/a character*(*) -.EE -The 'Bits' column shows how many significant bits are saved in the XDR file. -.PP -The scaler (i.e., single value, not array) functions all take exactly two -parameters: -.EX - 1) the xdr file ID, which was the integer returned by the - 'initxdr' call. - - 2) the variable to either read or write. -.EE -The array functions all take exactly three parameters: -.EX - 1) the xdr file ID, which was the integer returned by the - 'initxdr' call. - - 2) The TOTAL number of elements in the array. - - 3) the array to either read or write. -.EE -If initxdr was called with the third argument (return_on_error) to -be .FALSE., then these functions print out an error message and halt -if they encounter an error. -If initxdr was called with the third argument (return_on_error) to -be .TRUE., then these routines return an error code that is less than -zero if they encounter an error. -A list of error codes is in 'fxdr.inc'. -.PP -.SH PRECISION -It is IMPORTANT to understand that the precision referred to above (for -example, the 'single' precision of routine 'xdrreal' or the 'double' -precision of routine 'xdrdouble') is SET BY YOUR COMPILER, not -by the FXDR library. This matters, because different compilers -have different default precisions (as in, number of bits) associated -with the names 'single', 'double', etc. At the time of writing this, -this makes the biggest difference when moving XDR files between Crays and -workstations such as Suns, HPs, or DECs, because by defalt the Cray FORTRAN -compiler uses a 'single' precision of 64 bits and a 'double' precision -of 128 bits, while the Sun, HP, and DEC use a 'single' precision of 32 -bits and a 'double' precision of 64 bits. (You might get a similar effect -on a workstation if you compile with a flag such as '-r8' which instructs -the compiler to make all 'single precision' variables default to 8 bytes -[64 bits] of precision). -.PP -The upshot is that if you use a Cray to write a FORTRAN single precision -floating point number into an XDR file using routine "ixdrreal", only 32 -bits of the original 64 bits will be written. But, you can't use routine -"ixdrdouble" to write all 64 bits correctly, because that routine expects -to be passed a FORTRAN double precision floating point variable, not a -single precision variable. -.PP -To get around this, there is a set of special routines which take 'single -precision' variables as defined by the FORTRAN compiler and write them -out with 64 bits (these are the 'ixdrreal64' and 'ixdrrmat64' routines). To -read these in on a workstation where a real is only 32 bits, you should -use the 'ixdrdouble' or 'ixdrdmat' routines and supply a *double* precision -floating point variable to receive the 64 bits of valid data. (To read -these in on a Cray, you just use the same routine which wrote the data out -in the first place--'ixdrreal64' or 'ixdrrmat64'). -.PP -.I To sum up: -.PP - Write SINGLE PRECISION values on a Cray (or workstation with - 64 bit FORTRAN reals) with 'ixdrreal64' or 'ixdrrmat64', then - read them into DOUBLE PRECISION values on a regular workstation - with a call to 'ixdrdouble' or 'ixdrdmat'. -.PP - Write DOUBLE PRECISION values on a workstation with 'ixdrdouble' - or 'ixdrdmat', then read them into SINGLE PRECISION values on - a Cray (or workstation with 64 bit FORTRAN reals) with a call - to 'ixdrreal64' or 'ixdrrmat64'. -.PP -Note that even workstations which are 64-bit machines, such as the -DEC Alpha and the SGI Power machines, generally do NOT have a FORTRAN -"real" be 64 bits by default -- they stick to 32 bits. -.PP -.I PRECISION PART II. -Unfortunately, that's not all you should know about precision. There is -also the problem that Crays (at the moment--new Crays might change this) -use a completely different scheme for representing numbers internally than -do workstations. Crays use "Cray floating point format" (duh) while -workstations use "IEEE floating point format". Well, the underlying XDR -libraries which FXDR calls *always* use IEEE floating point format, so if -you always work on a workstation then everything is fine and please ignore -this paragraph despite the fact that you've already read a lot of it. If -you work on Crays, though, you need to be aware that putting data into an -XDR file and then immediately reading it back in WILL NOT leave you with -exactly the same floating point number which you started with. It will -likely be different in the last bit position or so. This is a tiny difference, -and to put it into perspective, the Cray compiler will itself do things -to your code (and warn you that it is doing them) which can change your -results this much, for the sake of making the code run faster. However -if you just can't live with losing a bit of precision in your numbers then -please erase this library and for God's sake start drinking decaffinated -coffee. -.PP -.SH Linking with the FXDR library -OK, you've written your FORTRAN program with calls to the FXDR library--now -how do you get it to compile correctly? -.PP -Well, here would be a typical command line: -.EX - f77 niftyprogram.F -I/usr/local/include -L/usr/local/lib -lfxdr -.EE -the "-lfxdr" tells the compiler to link with the library named "libfxdr.a"; -the "-L/usr/local/lib" tells the compiler to look for "libfxdr.a" in -directory "/usr/local/lib". This is the default place to install the -library. If you put the library somewhere else instead, then you will -have to substitute the place where you put "libfxdr.a" in for "/usr/local/lib" -in the typical command line given above. -The "-I/usr/local/include" tells the compiler to look for file "fxdr.inc" -in directory "/usr/local/include". This is only needed if you want -to use the FXDR error codes by name, or if you usually use 'implicit none' -if your Fortran code and want to have all the xdr routines defined -properly. - -.SH Author -David Pierce, Scripps Institution of Oceanography, Climate Research -Division. E-mail "dpierce@ucsd.edu". - diff --git a/fxdr/fxdr.inc b/fxdr/fxdr.inc deleted file mode 100644 index 8bb331713..000000000 --- a/fxdr/fxdr.inc +++ /dev/null @@ -1,21 +0,0 @@ - integer initxdr - integer ixdrclose - integer ixdrdmat - integer ixdrdouble - integer ixdrimat - integer ixdrint - integer ixdrreal - integer ixdrreal64 - integer ixdrrewind - integer ixdrrmat - integer ixdrrmat64 - integer ixdrshort - integer ixdrstring - - integer FXDRERR_WRNEGNELS, FXDRERR_WRITEERR - integer FXDRERR_READERR, FXDRERR_READWRONGNELS - integer FXDRERR_REWIND - parameter(FXDRERR_WRNEGNELS=-10, FXDRERR_WRITEERR=-11) - parameter(FXDRERR_READERR=-12, FXDRERR_READWRONGNELS=-13) - parameter(FXDRERR_REWIND=-14) - diff --git a/fxdr/gmon.out b/fxdr/gmon.out deleted file mode 100644 index 370b730d2..000000000 Binary files a/fxdr/gmon.out and /dev/null differ diff --git a/fxdr/include b/fxdr/include deleted file mode 100644 index 8bb331713..000000000 --- a/fxdr/include +++ /dev/null @@ -1,21 +0,0 @@ - integer initxdr - integer ixdrclose - integer ixdrdmat - integer ixdrdouble - integer ixdrimat - integer ixdrint - integer ixdrreal - integer ixdrreal64 - integer ixdrrewind - integer ixdrrmat - integer ixdrrmat64 - integer ixdrshort - integer ixdrstring - - integer FXDRERR_WRNEGNELS, FXDRERR_WRITEERR - integer FXDRERR_READERR, FXDRERR_READWRONGNELS - integer FXDRERR_REWIND - parameter(FXDRERR_WRNEGNELS=-10, FXDRERR_WRITEERR=-11) - parameter(FXDRERR_READERR=-12, FXDRERR_READWRONGNELS=-13) - parameter(FXDRERR_REWIND=-14) - diff --git a/fxdr/initxdr.F b/fxdr/initxdr.F deleted file mode 100644 index 9e33ef470..000000000 --- a/fxdr/initxdr.F +++ /dev/null @@ -1,93 +0,0 @@ -c ------------------------------------------------- -c Returns < 0 on error, otherwise the xdrid used to -c access the xdr file -c -c Args: -c filename: character*(*): name of file to -c access -c mode: character*1: either 'r', 'w', or 'a' -c (for read, write, and append) -c returnonerror: logical: if .TRUE., then -c routines return even if there is -c an I/O error. If .FALSE., then -c routines halt on I/O error, -c printing out a useful message -c (this is like what fortran does, -c so set to .FALSE. for most fortran- -c like behavior) -c ------------------------------------------------- - integer function initxdr( filename, mode, returnonerror ) - - implicit none - - character*(*) filename - character*1 mode - logical returnonerror - - integer iretval, cxdrinit, iroe, imode, lenf, istrlen - integer ifxdrstrlen - - if( (mode .eq. 'r').or.(mode .eq. 'R') ) then - imode = 1 - else if( (mode .eq. 'w').or.(mode .eq. 'W') ) then - imode = 2 - else if( (mode .eq. 'a').or.(mode .eq. 'A') ) then - imode = 3 - else - write(0,*) 'Error: fxdr library, initxdr called ' - write(0,*) 'with unknown mode (should be r, w, or a):', - & mode - stop 'fxdr library: initxdr routine, bad mode' - endif - - lenf = len(filename) - istrlen = ifxdrstrlen( filename ) - if( istrlen .lt. lenf ) then - lenf = istrlen - endif - - if( returnonerror ) then - iroe = 1 - else - iroe = 0 - endif - - iretval = cxdrinit( lenf, filename, imode, iroe ) - if( iretval .lt. 0 ) then - initxdr = iretval - return - endif - -c ----------------------------------------------------------- -c Add one to the returned value because the C library returns -c starting with zero, which is awkward considering that -c unitialized variables often start with zero in Fortran. -c ----------------------------------------------------------- - initxdr = iretval + 1 - - return - end - -c======================================================================== - - integer function ifxdrstrlen( s ) - - character*(*) s - - i = 1 -100 continue - if( s(i:i) .eq. ' ' ) then - goto 200 - endif - i = i + 1 - if( i .gt. len(s) ) then - goto 200 - endif - goto 100 - -200 continue - ifxdrstrlen = i-1 - - return - end - diff --git a/fxdr/ixdrclose.F b/fxdr/ixdrclose.F deleted file mode 100644 index 3b60257d9..000000000 --- a/fxdr/ixdrclose.F +++ /dev/null @@ -1,16 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrclose( ixdr ) - - implicit none - - integer ixdr, ixdrm1, ierr - - ixdrm1 = ixdr - 1 - call cxdrclose( ixdrm1, ierr ) - - ixdrclose = ierr - - return - end diff --git a/fxdr/ixdrdmat.F b/fxdr/ixdrdmat.F deleted file mode 100644 index 225256972..000000000 --- a/fxdr/ixdrdmat.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrdmat( ixdrs, nels, dval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - double precision dval(nels) - - ixdrsm1 = ixdrs - 1 - call cxdrdmat( ixdrsm1, nels, dval, ierr ) - - ixdrdmat = ierr - - return - end - - diff --git a/fxdr/ixdrdouble.F b/fxdr/ixdrdouble.F deleted file mode 100644 index bc4fbeef8..000000000 --- a/fxdr/ixdrdouble.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrdouble( ixdrs, dval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - double precision dval - - ixdrsm1 = ixdrs - 1 - - call cxdrdouble( ixdrsm1, dval, ierr ) - - ixdrdouble = ierr - - return - end - - diff --git a/fxdr/ixdrimat.F b/fxdr/ixdrimat.F deleted file mode 100644 index 5df236b04..000000000 --- a/fxdr/ixdrimat.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrimat( ixdrs, nels, ival ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - integer ival(nels) - - ixdrsm1 = ixdrs - 1 - call cxdrimat( ixdrsm1, nels, ival, ierr ) - - ixdrimat = ierr - - return - end - - diff --git a/fxdr/ixdrint.F b/fxdr/ixdrint.F deleted file mode 100644 index 8ca920078..000000000 --- a/fxdr/ixdrint.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrint( ixdrs, ival ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - integer ival - - ixdrsm1 = ixdrs - 1 - call cxdrint( ixdrsm1, ival, ierr ) - - ixdrint = ierr - - return - end - - diff --git a/fxdr/ixdrreal.F b/fxdr/ixdrreal.F deleted file mode 100644 index 588fbf56b..000000000 --- a/fxdr/ixdrreal.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrreal( ixdrs, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - real rval - - ixdrsm1 = ixdrs - 1 - - call cxdrreal( ixdrsm1, rval, ierr ) - - ixdrreal = ierr - - return - end - - diff --git a/fxdr/ixdrreal64.F b/fxdr/ixdrreal64.F deleted file mode 100644 index d4640ab58..000000000 --- a/fxdr/ixdrreal64.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrreal64( ixdrs, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - real rval - - ixdrsm1 = ixdrs - 1 - - call cxdrreal64( ixdrsm1, rval, ierr ) - - ixdrreal64 = ierr - - return - end - - diff --git a/fxdr/ixdrrewind.F b/fxdr/ixdrrewind.F deleted file mode 100644 index 9357b3037..000000000 --- a/fxdr/ixdrrewind.F +++ /dev/null @@ -1,17 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrewind( ixdrs ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - - ixdrsm1 = ixdrs - 1 - - call cxdrrewind( ixdrsm1, ierr ) - - ixdrrewind = ierr - - return - end diff --git a/fxdr/ixdrrmat.F b/fxdr/ixdrrmat.F deleted file mode 100644 index e047b7d31..000000000 --- a/fxdr/ixdrrmat.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrmat( ixdrs, nels, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - real rval(nels) - - ixdrsm1 = ixdrs - 1 - - call cxdrrmat( ixdrsm1, nels, rval, ierr ) - - ixdrrmat = ierr - - return - end - - diff --git a/fxdr/ixdrrmat64.F b/fxdr/ixdrrmat64.F deleted file mode 100644 index 5044644d4..000000000 --- a/fxdr/ixdrrmat64.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrmat64( ixdrs, nels, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - real rval(nels) - - ixdrsm1 = ixdrs - 1 - - call cxdrrmat64( ixdrsm1, nels, rval, ierr ) - - ixdrrmat64 = ierr - - return - end - - diff --git a/fxdr/ixdrshort.F b/fxdr/ixdrshort.F deleted file mode 100644 index cfe1f6325..000000000 --- a/fxdr/ixdrshort.F +++ /dev/null @@ -1,18 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrshort (ixdrs, num) - - implicit none - - integer ixdrs,ixdrsm1,num, ierr - - ixdrsm1=ixdrs - 1 - - call cxdrshort( ixdrsm1, num, ierr ) - - ixdrshort = ierr - - return - end - diff --git a/fxdr/ixdrstring.F b/fxdr/ixdrstring.F deleted file mode 100644 index 6c8ea7cc0..000000000 --- a/fxdr/ixdrstring.F +++ /dev/null @@ -1,21 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrstring( ixdrs, string ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, ilen - character*(*) string - - ixdrsm1 = ixdrs - 1 - - ilen = len(string) - call cxdrstring( ixdrsm1, ilen, string, ierr ) - - ixdrstring = ierr - - return - end - - diff --git a/fxdr/lib b/fxdr/lib deleted file mode 100644 index c419ead13..000000000 Binary files a/fxdr/lib and /dev/null differ diff --git a/fxdr/libfxdr.a b/fxdr/libfxdr.a deleted file mode 100644 index c419ead13..000000000 Binary files a/fxdr/libfxdr.a and /dev/null differ diff --git a/fxdr/penmp b/fxdr/penmp deleted file mode 100644 index 07967ed3e..000000000 Binary files a/fxdr/penmp and /dev/null differ diff --git a/fxdr/test.F b/fxdr/test.F deleted file mode 100644 index 8391e9ea0..000000000 --- a/fxdr/test.F +++ /dev/null @@ -1,487 +0,0 @@ - program testfxdr - -c =========================================================== -c Test the FXDR library by exercising the calls, and -c comparing the results to the known good .xdr file. -c -c David Pierce Scripps Inst. Oceanography / Climate Research -c Aug 10, 1999 -c =========================================================== - - implicit none - - include 'fxdr.inc' - - integer ien, jen - parameter(ien=3,jen=2) - - integer iwrite, ierr, isign, j, i2, imatwrite, ixdrs, iread - real*4 rwrite, rsign, rxpon, fmatwrite, rread -#ifdef cray - real dwrite -#else - double precision dwrite -#endif - - dimension imatwrite(ien) - dimension fmatwrite(ien,jen) -#ifdef cray - real dmatwrite(ien,jen), dsign, dxpon -#else - double precision dmatwrite(ien,jen), dsign, dxpon -#endif - character*26 stringwrite - - common /cb1/ iwrite, imatwrite - common /cb2/ rwrite, fmatwrite - common /cb3/ dwrite, dmatwrite - common /cb4/ stringwrite - -c ----------------------------------------------- -c Initialize our variables to recognizable values -c ----------------------------------------------- - iwrite = 987654 - rwrite = 3.1415926535e0 -#ifdef cray - dwrite = 1.234567890123456789e0 -#else - dwrite = 1.234567890123456789d0 -#endif - stringwrite = 'this is a FXDR test string' - -c ------------------------------------------------- -c Fill in the integer, single precision, and double -c precision arrays with useful values. -c ------------------------------------------------- - dsign = 1.0d0 - rsign = 1.0 - isign = 1 - rxpon = -20.0 - dxpon = -20.0d0 - do j=1, jen - do i2=1, ien - imatwrite(i2) = isign*i2 - fmatwrite(i2,j) = rsign*(float(i2) + - & float(j)/100.0)*10.0**rxpon -#ifdef cray - dmatwrite(i2,j) = dsign*(float(i2) + - & float(j)/10000000000.0)*10.0**dxpon -#else - dmatwrite(i2,j) = dsign*(dble(i2) + - & dble(j)/10000000000.0)*10.0**dxpon -#endif - dsign = -1.0d0*dsign - rsign = -1.0*rsign - isign = -isign - rxpon = rxpon + 7.0 - dxpon = dxpon + 7.0d0 - enddo - enddo - - print *, 'here are the check values:' - print *, fmatwrite - print *, dmatwrite - -c ------------------------------------------------- -c Open the test XDR file. Set it to halt on errors -c (.FALSE.), so don't bother checking error codes -c below. -c ------------------------------------------------- - print *, 'generating test XDR file test.xdr...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - -c ------------------------------------------------------ -c Put the scalar values: integer, real, double precision -c ------------------------------------------------------ - ierr = ixdrint ( ixdrs, iwrite ) - ierr = ixdrreal ( ixdrs, rwrite ) -#ifdef cray - ierr = ixdrreal64( ixdrs, dwrite ) -#else - ierr = ixdrdouble( ixdrs, dwrite ) -#endif - -c ----------------------------------------------------- -c Put the array values: integer, real, double precision -c ----------------------------------------------------- - ierr = ixdrimat ( ixdrs, ien, imatwrite ) - ierr = ixdrrmat ( ixdrs, ien*jen, fmatwrite ) -#ifdef cray - ierr = ixdrrmat64( ixdrs, ien*jen, dmatwrite ) -#else - ierr = ixdrdmat ( ixdrs, ien*jen, dmatwrite ) -#endif - - ierr = ixdrstring( ixdrs, stringwrite ) - - ierr = ixdrclose( ixdrs ) - print *, 'successfully wrote the test file test.xdr' - - call compareto( 'test.xdr' ) - call compareto( 'test.orig.xdr' ) - - print * - print *, 'Testing the rewind function...' - ixdrs = initxdr( 'test.xdr', 'r', .FALSE. ) - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) - ierr = ixdrrewind( ixdrs ) - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) - ierr = ixdrclose ( ixdrs ) - -c ------------------------------------------ -c Now check the error handling functionality -c ------------------------------------------ - print * - print *, '---------------------------------------------' - print *, 'Testing the error handling functionality ... ' - print *, 'these routine should NOT STOP!' - print *, '---------------------------------------------' - print * - -c ---------------------------------------- -c Try to open a read-only file for writing -c ---------------------------------------- - print *, 'opening a read-only file for writing...' - ixdrs = initxdr( 'test_read_only.xdr', 'w', .TRUE. ) - if( ixdrs .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to open a read only file for writing!!' - print *, 'Make SURE file test_read_only.xdr does NOT' - print *, 'have write permissions!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ---------------------------------------- -c Try to open a no-access file for reading -c ---------------------------------------- - print *, 'opening a no-access file for reading...' - ixdrs = initxdr( 'test_no_read.xdr', 'r', .TRUE. ) - if( ixdrs .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to open a no-access file for reading!!' - print *, 'Make SURE file test_no_read.xdr does NOT' - print *, 'have read permissions!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ------------------------------------------------------------- -c Write a single integer, rewind, then try to read TWO integers -c ------------------------------------------------------------- - print *, 'trying to read integer past EOF...' - ixdrs = initxdr( 'test.xdr', 'w', .TRUE. ) - ierr = ixdrint( ixdrs, iwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrint( ixdrs, iread ) - if( ierr .lt. 0 ) then - print *, 'TEST FAILED! Anomalous error returned when' - print *, 'trying to read a test integer from file' - print *, 'test.xdr!' - print *, '--------- TEST FAILED ----------' - stop - endif - ierr = ixdrint( ixdrs, iread ) - if( ierr .ne. FXDRERR_READERR ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read a test integer past the end of file!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ------------------------------------------------------- -c Write a single real, rewind, then try to read TWO reals -c ------------------------------------------------------- - print *, 'trying to read real past EOF...' - ixdrs = initxdr( 'test.xdr', 'w', .TRUE. ) - ierr = ixdrreal( ixdrs, rwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrreal( ixdrs, rread ) - if( ierr .lt. 0 ) then - print *, 'TEST FAILED! Anomalous error returned when' - print *, 'trying to read a test real from file' - print *, 'test.xdr!' - print *, '--------- TEST FAILED ----------' - stop - endif - ierr = ixdrint( ixdrs, iread ) - if( ierr .ne. FXDRERR_READERR ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read a test real past the end of file!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ----------------------------------------------------- -c Try to read wrong # of elements from an integer array -c ----------------------------------------------------- - print *,'try to read wrong # of elements from integer array...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrimat ( ixdrs, ien, imatwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrimat ( ixdrs, 2*ien, imatwrite ) - if( ierr .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read incorrect # integer elements from' - print *, 'an array!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ----------------------------------------------------- -c Try to read wrong # of elements from an real array -c ----------------------------------------------------- - print *, 'try to read wrong # of elements from a real array...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrrmat ( ixdrs, ien*jen, fmatwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrrmat ( ixdrs, ien, fmatwrite ) - if( ierr .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read incorrect # real elements from an' - print *, 'array!' - print *, 'ierr=', ierr - print *, '--------- TEST FAILED ----------' - stop - endif - -c -------------------- -c Test append function -c -------------------- - print * - print *, '--------------------------' - print *, 'Testing append function...' - print *, '--------------------------' - print * -c ... make test file with single integer ... - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrint( ixdrs, iwrite ) - ierr = ixdrclose( ixdrs ) -c ... read back same integer ... - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrint( ixdrs, iread ) - if( ierr .lt. 0 ) then - print *, 'ERROR reading first int from test file!!' - print *, '-------- TEST FAILED -------' - stop - endif - call checki( iwrite, iread ) -c ... read back ANOTHER real, should fail ... - ierr = ixdrreal( ixdrs, rread ) - if( ierr .ge. 0 ) then - print *, 'ERROR: no error value returned when reading' - print *, 'past end of file!!' - print *, '-------- TEST FAILED -------' - stop - endif - ierr = ixdrclose( ixdrs ) -c ... now try to append real to this file ... - ixdrs = initxdr( 'test.xdr', 'a', .TRUE. ) - ierr = ixdrreal( ixdrs, rwrite ) - if( ierr .lt. 0 ) then - print *, 'ERROR trying to append real to test file!' - print *, '-------- TEST FAILED -------' - stop - endif - ierr = ixdrclose( ixdrs ) -c ... check to make sure appendation (?) went OK ... - ixdrs = initxdr( 'test.xdr', 'r', .FALSE. ) - ierr = ixdrint( ixdrs, iread ) - call checki( iwrite, iread ) - ierr = ixdrreal( ixdrs, rread ) - call checkr( rwrite, rread ) - ierr = ixdrclose( ixdrs ) - - print * - print *, '---------------------------------------------------' - print *, 'All tests passed successfully: precision loss was' - print *, 'never more than 1 part in 10**-10 for double' - print *, 'precision nor more than 1 part in 10**-5 for single' - print *, 'precision.' - print *, '---------------------------------------------------' - - end - -c===================================================================== - - subroutine compareto( filename ) - - character*(*) filename - - parameter(ien=3,jen=2) - - integer iread, iwrite - real*4 rread, rwrite, fmatwrite, fmatread -#ifdef cray - real dread, dwrite -#else - double precision dread, dwrite -#endif - - common /cb1/ iwrite, imatwrite - common /cb2/ rwrite, fmatwrite - common /cb3/ dwrite, dmatwrite - common /cb4/ stringwrite - - dimension imatwrite(ien), imatread(ien) - dimension fmatwrite(ien,jen), fmatread(ien,jen) -#ifdef cray - real dmatwrite(ien,jen), dmatread(ien,jen) -#else - double precision dmatwrite(ien,jen), dmatread(ien,jen) -#endif - character*26 stringwrite, stringread - - print * - print *, '--------------------------------------------' - print *, 'checking file ', filename, ' for correctness.' - print *, '--------------------------------------------' - -c ----------------------------------------- -c Open the file and try to read it back in. -c ----------------------------------------- - ixdrs = initxdr( filename, 'r', .FALSE. ) - -c ------------------------------------------------------- -c Read the scalar values: integer, real, double precision -c ------------------------------------------------------- - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) -#ifdef cray - ierr = ixdrreal64( ixdrs, dread ) -#else - ierr = ixdrdouble( ixdrs, dread ) -#endif - call checkd ( dwrite, dread ) - -c ------------------------------------------------------ -c Read the array values: integer, real, double precision -c ------------------------------------------------------ - ierr = ixdrimat ( ixdrs, ien, imatread ) - do i=1, ien - call checki( imatwrite(i), imatread(i) ) - enddo - ierr = ixdrrmat ( ixdrs, ien*jen, fmatread ) - do j=1, jen - do i=1, ien - call checkr( fmatwrite(i,j), fmatread(i,j) ) - enddo - enddo -#ifdef cray - ierr = ixdrrmat64( ixdrs, ien*jen, dmatread ) -#else - ierr = ixdrdmat ( ixdrs, ien*jen, dmatread ) -#endif - do j=1, jen - do i=1, ien - call checkd( dmatwrite(i,j), dmatread(i,j) ) - enddo - enddo - - ierr = ixdrstring( ixdrs, stringread ) - do i=1, len(stringread) - if( stringread(i:i) .ne. stringwrite(i:i) ) then - print *, 'Error on string read! I expected: ', - & stringwrite(i:i) - print *, 'but got: ', stringread(i:i) - endif - enddo - - ierr = ixdrclose( ixdrs ) - - return - end - -c==================================================================== - - subroutine checkr( expected, got ) - - real*4 expected, got - - if( got .ne. expected ) then - diffnorm = abs((got-expected)/(.5*(got+expected))) - if( diffnorm .gt. 1.0e-5 ) then - print *, 'Fatal error! On single precision read, I got ', - & got - print *, 'but expected ', expected - print *, 'The library failed its tests--please do not use it!' - stop - else - print *, 'checking single precision...' - print *, '===> precision loss of 1 part in 10**', - & nint(log10(1.0/diffnorm)) - endif - else - print *, 'checking single precision...OK' - endif - - return - end - -c==================================================================== - - subroutine checkd( expected, got ) - -#ifdef cray - real expected, got, diffnorm -#else - double precision expected, got, diffnorm -#endif - - if( got .ne. expected ) then -#ifdef cray - diffnorm = abs((got-expected)/(.5d0*(got+expected))) -#else - diffnorm = dabs((got-expected)/(.5d0*(got+expected))) -#endif - if( diffnorm .gt. 1.0d-10 ) then - print *, 'Fatal error! On double precision read, I got ', - & got - print *, 'but expected ', expected - print *, 'The library failed its tests--please do not use it!' - stop - else - print *, 'checking double precision...' -#ifdef cray - iprecis = nint(log10(1.0/diffnorm)) -#else - iprecis = nint(dlog10(1.0/diffnorm)) -#endif - print *, '===> precision loss of 1 part in 10**', iprecis - endif - else - print *, 'checking double precision...OK' - endif - - return - end - -c==================================================================== - - subroutine checki( expected, got ) - - integer expected, got - - if( got .ne. expected ) then - print *, 'Fatal error! On integer read, I got ', got - print *, 'but expected ', expected - print *, 'The library failed its tests--' - print *, 'please do not use it!' - stop - endif - print *, 'checking integer...OK' - - return - end diff --git a/fxdr/test.orig.xdr b/fxdr/test.orig.xdr deleted file mode 100644 index 6f8e4f73b..000000000 Binary files a/fxdr/test.orig.xdr and /dev/null differ diff --git a/fxdr/test.xdr b/fxdr/test.xdr deleted file mode 100644 index fece55ba2..000000000 Binary files a/fxdr/test.xdr and /dev/null differ diff --git a/fxdr/test_read_only.xdr b/fxdr/test_read_only.xdr deleted file mode 100644 index 6f8e4f73b..000000000 Binary files a/fxdr/test_read_only.xdr and /dev/null differ diff --git a/fxdr/testprog.F b/fxdr/testprog.F deleted file mode 100644 index 9f6dc036d..000000000 --- a/fxdr/testprog.F +++ /dev/null @@ -1,31 +0,0 @@ - program testprog - -#ifdef cray - real x1, x2 -#else - double precision x1, x2 -#endif - - common /cb1/ x1, x2 - - x1 = 3.0 - x2 = 4.0 - call sub( x1, x2) - - end - -c======================================================== - - subroutine sub( x1, x2 ) - -#ifdef cray - real x1, x2 -#else - double precision x1, x2 -#endif - - print *, x1, x2 - - return - end - diff --git a/fxdr_2.1c/Defines.aix b/fxdr_2.1c/Defines.aix deleted file mode 100644 index 8ef714c13..000000000 --- a/fxdr_2.1c/Defines.aix +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -DIFSTYLE=2 -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib diff --git a/fxdr_2.1c/Defines.hpux b/fxdr_2.1c/Defines.hpux deleted file mode 100644 index 9da3a811a..000000000 --- a/fxdr_2.1c/Defines.hpux +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = fort77 -F77OPTS = +U77 +O3 -K +e +es -CCCMD = c89 -CCOPTS = -DIFSTYLE=2 -AR = ar -CPP = /lib/cpp -64_BIT_REALS = -r8 diff --git a/fxdr_2.1c/Defines.irix b/fxdr_2.1c/Defines.irix deleted file mode 100644 index 50c237050..000000000 --- a/fxdr_2.1c/Defines.irix +++ /dev/null @@ -1,8 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc - -RANLIB = echo -AR = ar - -CPP = /lib/cpp diff --git a/fxdr_2.1c/Defines.linux b/fxdr_2.1c/Defines.linux deleted file mode 100644 index b7f207d78..000000000 --- a/fxdr_2.1c/Defines.linux +++ /dev/null @@ -1,5 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = diff --git a/fxdr_2.1c/Defines.osf1 b/fxdr_2.1c/Defines.osf1 deleted file mode 100644 index b7f207d78..000000000 --- a/fxdr_2.1c/Defines.osf1 +++ /dev/null @@ -1,5 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = diff --git a/fxdr_2.1c/Defines.sun b/fxdr_2.1c/Defines.sun deleted file mode 100644 index 0414beb19..000000000 --- a/fxdr_2.1c/Defines.sun +++ /dev/null @@ -1,8 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib -EXTRA_LIBS = -lnsl diff --git a/fxdr_2.1c/Defines.ultrix b/fxdr_2.1c/Defines.ultrix deleted file mode 100644 index 173c9dac5..000000000 --- a/fxdr_2.1c/Defines.ultrix +++ /dev/null @@ -1,4 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -RANLIB = ranlib diff --git a/fxdr_2.1c/Defines.unicos b/fxdr_2.1c/Defines.unicos deleted file mode 100644 index d64efca91..000000000 --- a/fxdr_2.1c/Defines.unicos +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = f90 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray_twobytecptrs -Dcray -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp diff --git a/fxdr_2.1c/Defines.unicos.old b/fxdr_2.1c/Defines.unicos.old deleted file mode 100644 index 42291de05..000000000 --- a/fxdr_2.1c/Defines.unicos.old +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = cf77 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp diff --git a/fxdr_2.1c/Defines.unicos_t3e b/fxdr_2.1c/Defines.unicos_t3e deleted file mode 100644 index 213d7c293..000000000 --- a/fxdr_2.1c/Defines.unicos_t3e +++ /dev/null @@ -1,6 +0,0 @@ -F77CMD = f90 -Dcray -64_BIT_REALS = -CCCMD = c89 -DIFSTYLE=1 -Dcray_twobytecptrs -Dcray -h nomessage=230 -RANLIB = echo -AR = ar -CPP = /usr/lib/gpp diff --git a/fxdr_2.1c/Defines.unsupported b/fxdr_2.1c/Defines.unsupported deleted file mode 100644 index 901fdc677..000000000 --- a/fxdr_2.1c/Defines.unsupported +++ /dev/null @@ -1,7 +0,0 @@ -F77CMD = f77 -64_BIT_REALS = -r8 -CCCMD = cc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib diff --git a/fxdr_2.1c/Makefile.Defines b/fxdr_2.1c/Makefile.Defines deleted file mode 100644 index 0b1c13407..000000000 --- a/fxdr_2.1c/Makefile.Defines +++ /dev/null @@ -1,89 +0,0 @@ -#****************************************************************************** -# -# Unit Name : Makefile.Defines -# Unit Type : makefile -# Project : SWIFTER -# Package : N/A -# Language : GNU makefile syntax -# -# Description : Contains user-modifiable macro definitions used in the build -# process for the Swifter library, drivers and tools, as well as -# the FXDR library -# -# Input -# Arguments : none -# Terminal : none -# File : none -# -# Output -# Arguments : none -# Terminal : none -# File : none -# -# Invocation : include Makefile.Defines (from within another makefile) -# -# Notes : -# -#****************************************************************************** - -# System utilities - -SHELL = /bin/sh -AR = ar -RANLIB = ranlib -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -m 755 -INSTALL_DATA = $(INSTALL) -m 644 - -# Swifter definitions - -SWIFTER_HOME = /home/kaufmann/swifter -USER_MODULES = - -# Compiler definitions - -# DO NOT include in FFLAGS the "-c" option to compile object only -# this is done explicitly as needed in the Makefile - -#FORTRAN = ifort -#FFLAGS = -O -w -pc 64 -FORTRAN = g95 -FFLAGS = -O -i4 - -# DO NOT include in CFLAGS the "-c" option to compile object only -# this is done explicitly as needed in the Makefile - -CC = cc -CFLAGS = -O - -64_BIT_REALS = -r8 - -# FXDR Makefile compatibility - DO NOT ALTER - -F77CMD = $(FORTRAN) -F77OPTS = $(FFLAGS) -CCCMD = $(CC) -CCOPTS = $(CFLAGS) - -#****************************************************************************** -# -# Author(s) : David E. Kaufmann -# -# Revision Control System (RCS) Information -# -# Source File : $RCSfile: Makefile.Defines,v $ -# Full Path : $Source: /d1/kaufmann/development/RCS/Makefile.Defines,v $ -# Revision : $Revision: 0.1 $ -# Date : $Date: 2003/04/15 22:56:57 $ -# Programmer : $Author: kaufmann $ -# Locked By : $Locker: $ -# State : $State: Exp $ -# -# Modification History: -# -# $Log: Makefile.Defines,v $ -# Revision 0.1 2003/04/15 22:56:57 kaufmann -# Initial implementation -# -# -#****************************************************************************** diff --git a/fxdr_2.1c/Makefile.bak b/fxdr_2.1c/Makefile.bak deleted file mode 100644 index 78d0cc573..000000000 --- a/fxdr_2.1c/Makefile.bak +++ /dev/null @@ -1,46 +0,0 @@ -F77CMD = cf77 -CCCMD = c89 -RANLIB = echo -AR = bld -CPP = /usr/lib/gpp -OBJS = cxdrinit.o xdrint.o initxdr.o cxdrint.o xdrclose.o \ - cxdrclose.o xdrreal.o cxdrreal.o cxdrdouble.o \ - xdrdouble.o xdrrmat.o cxdrrmat.o xdrdmat.o cxdrdmat.o \ - xdrimat.o cxdrimat.o xdrstring.o cxdrstring.o \ - xdrreal64.o cxdrreal64.o xdrrmat64.o cxdrrmat64.o - -SRCS = cxdrinit.c xdrint.F initxdr.F cxdrint.c xdrclose.F \ - cxdrclose.c xdrreal.F cxdrreal.c cxdrdouble.c \ - xdrdouble.F xdrrmat.F cxdrrmat.c xdrdmat.F cxdrdmat.c \ - xdrimat.F cxdrimat.c xdrstring.F cxdrstring.c \ - xdrreal64.F cxdrreal64.c - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - cp libfxdr.a $(HOME)/lib - -test: $(OBJS) test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr - ./test - -clean: - -rm *.o test Makefile - -tar: - @echo "Remember to make clean before making tar!" - cd .. ; tar cvf fxdr_0.9.tar fxdr_0.9 diff --git a/fxdr_2.1c/Makefile.fxdr b/fxdr_2.1c/Makefile.fxdr deleted file mode 100644 index 549eb76c1..000000000 --- a/fxdr_2.1c/Makefile.fxdr +++ /dev/null @@ -1,105 +0,0 @@ -#****************************************************************************** -# -# Unit Name : Makefile.fxdr -# Unit Type : makefile -# Project : SWIFTER -# Package : N/A -# Language : GNU makefile syntax -# -# Description : Controls the build of the FXDR library -# -# Input -# Arguments : Zero or more of the following targets: -# (1) libfxdr.a : builds the FXDR library -# (2) test : runs tests on FXDR library -# (3) install : installs library and FXDR include file -# (4) clean : removes object modules and test program -# Terminal : none -# File : Makefile.Defines -# -# Output -# Arguments : none -# Terminal : status messages -# File : none -# -# Invocation : make [libfxdr.a|test|install|clean] -# -# Notes : -# -#****************************************************************************** - -include Makefile.Defines - -OBJS = cxdrinit.o ixdrint.o initxdr.o cxdrint.o ixdrclose.o \ - cxdrclose.o ixdrreal.o cxdrreal.o cxdrdouble.o \ - ixdrdouble.o ixdrrmat.o cxdrrmat.o ixdrdmat.o cxdrdmat.o \ - ixdrimat.o cxdrimat.o ixdrstring.o cxdrstring.o \ - ixdrreal64.o cxdrreal64.o ixdrrmat64.o cxdrrmat64.o \ - ixdrrewind.o cxdrrewind.o ixdrshort.o cxdrshort.o - -SRCS = cxdrinit.c ixdrint.F initxdr.F cxdrint.c ixdrclose.F \ - cxdrclose.c ixdrreal.F cxdrreal.c cxdrdouble.c \ - ixdrdouble.F ixdrrmat.F cxdrrmat.c ixdrdmat.F cxdrdmat.c \ - ixdrimat.F cxdrimat.c ixdrstring.F cxdrstring.c \ - ixdrreal64.F cxdrreal64.c ixdrrewind.F cxdrrewind.c \ - ixdrshort.F cxdrshort.F - -PLACE_FOR_LIBRARY = $(SWIFTER_HOME)/lib - -PLACE_FOR_HEADER = $(SWIFTER_HOME)/include - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - @echo "Now do 'make test' to check the library" - -test: libfxdr.a test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr $(EXTRA_LIBS) - touch test_no_read.xdr - chmod -r test_no_read.xdr - ./test - rm test_no_read.xdr - -clean: - -rm *.o test - -install: - $(INSTALL_DATA) libfxdr.a $(PLACE_FOR_LIBRARY) - $(INSTALL_DATA) fxdr.inc $(PLACE_FOR_HEADER) - -#****************************************************************************** -# -# Author(s) : David W. Pierce -# -# Revision Control System (RCS) Information -# -# Source File : $RCSfile: Makefile.fxdr,v $ -# Full Path : $Source: /d1/kaufmann/development/RCS/Makefile.fxdr,v $ -# Revision : $Revision: 0.1 $ -# Date : $Date: 2003/04/15 23:10:41 $ -# Programmer : $Author: kaufmann $ -# Locked By : $Locker: $ -# State : $State: Exp $ -# -# Modification History: -# -# $Log: Makefile.fxdr,v $ -# Revision 0.1 2003/04/15 23:10:41 kaufmann -# Initial implementation -# -# -#****************************************************************************** diff --git a/fxdr_2.1c/Makefile.tmpl b/fxdr_2.1c/Makefile.tmpl deleted file mode 100644 index 5f6e728a4..000000000 --- a/fxdr_2.1c/Makefile.tmpl +++ /dev/null @@ -1,55 +0,0 @@ -OBJS = cxdrinit.o ixdrint.o initxdr.o cxdrint.o ixdrclose.o \ - cxdrclose.o ixdrreal.o cxdrreal.o cxdrdouble.o \ - ixdrdouble.o ixdrrmat.o cxdrrmat.o ixdrdmat.o cxdrdmat.o \ - ixdrimat.o cxdrimat.o ixdrstring.o cxdrstring.o \ - ixdrreal64.o cxdrreal64.o ixdrrmat64.o cxdrrmat64.o \ - ixdrrewind.o cxdrrewind.o ixdrshort.o cxdrshort.o - -SRCS = cxdrinit.c ixdrint.F initxdr.F cxdrint.c ixdrclose.F \ - cxdrclose.c ixdrreal.F cxdrreal.c cxdrdouble.c \ - ixdrdouble.F ixdrrmat.F cxdrrmat.c ixdrdmat.F cxdrdmat.c \ - ixdrimat.F cxdrimat.c ixdrstring.F cxdrstring.c \ - ixdrreal64.F cxdrreal64.c ixdrrewind.F cxdrrewind.c \ - ixdrshort.F cxdrshort.F - -PLACE_FOR_LIBRARY = /usr/local/lib - -PLACE_FOR_HEADER = /usr/local/include - -PLACE_FOR_MANPAGE = /usr/man/local - -.SUFFIXES: -.SUFFIXES: .c .o .F - -########################################################################### - -.c.o: - $(CCCMD) $(CCOPTS) -c $< - -.F.o: - $(F77CMD) $(F77OPTS) -c $< - -########################################################################### - -libfxdr.a: $(OBJS) - -rm libfxdr.a - $(AR) q libfxdr.a $(OBJS) - -$(RANLIB) libfxdr.a - @echo "Now do 'make test' to check the library" - -test: libfxdr.a test.F - $(F77CMD) $(F77OPTS) -o test test.F -L. -lfxdr $(EXTRA_LIBS) - touch test_no_read.xdr - chmod -r test_no_read.xdr - ./test - rm test_no_read.xdr - -clean: - -rm *.o test Makefile - -install: - cp libfxdr.a $(PLACE_FOR_LIBRARY)/libfxdr.a - cp fxdr.inc $(PLACE_FOR_HEADER)/fxdr.inc - cp fxdr.3f $(PLACE_FOR_MANPAGE)/fxdr.3f - - diff --git a/fxdr_2.1c/README b/fxdr_2.1c/README deleted file mode 100644 index 3fec6a9f4..000000000 --- a/fxdr_2.1c/README +++ /dev/null @@ -1,33 +0,0 @@ -Copyright (c) 1995, 1999 The Regents of the University of California. All -rights reserved. - -Redistribution and use in source and binary forms are permitted provided -that (1) source distrubutions retain this entire copyright notice and -comment, and (2) distributions including binaries display the following -acknowledgement: ``This product includes software developed by the -University of California, San Diego and its contributors'' in the -documentation or other materials provided with the distribution and in -all advertising materials mentioning features or use of this software. -Neither the name of the University nor the names of its contributors may -be used to endorse or promote products derived from this software -without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -============================================================================= - -Make sure to read one of these if it applies to your platform: - -README.HPUX -README.sun_and_IDL -README.Linux - -============================================================================= - -The main information resides at: - -http://meteora.ucsd.edu:80/~pierce/fxdr_home_page.html - -Please consult the information there. diff --git a/fxdr_2.1c/README.HPUX b/fxdr_2.1c/README.HPUX deleted file mode 100644 index a8cb05535..000000000 --- a/fxdr_2.1c/README.HPUX +++ /dev/null @@ -1,27 +0,0 @@ -I don't have access to a modern HP system, so I can't -check this configuration myself. However, fxdr apparently -doesn't compile out of the box on newer HP systems. I -received the following message: - -================================================================== - -Date: Thu, 11 Sep 1997 16:05:20 +0200 -Message-Id: <199709111405.AA273236720@utmfu3.math.utwente.nl> -From: ijzerman -To: dpierce@ucsd.edu -Status: RO -X-Status: - -Dear David Pierce, - -I downloaded the fxdr-package. To install it on HP-unix 9.0 or 10.0 I -had to change the c89 in the default makefile to cc. Otherwise all -kind of error occured with respect to the rpc.h files. - -Sincerely yours, - -Wilbert IJzerman - -================================================================== - -So, if this is the platform you are using, give this a try. diff --git a/fxdr_2.1c/README.Linux b/fxdr_2.1c/README.Linux deleted file mode 100644 index ce2e70b38..000000000 --- a/fxdr_2.1c/README.Linux +++ /dev/null @@ -1,59 +0,0 @@ -The package works on a Linux system I tried that uses the gnu compilers. -However, the following message may be of interest to people running Linux -with Nag Fortran90: - -=================================================================== - -Date: Tue, 09 Sep 1997 19:13:22 +0200 -From: Axel vom Endt -Organization: MPI f. Aeronomie -X-Mailer: Mozilla 3.01Gold (X11; I; Linux 2.0.25 i586) -Mime-Version: 1.0 -To: dpierce@ucsd.edu -Subject: fxdr -Content-Type: multipart/mixed; boundary="------------1EE0A5BF2F6227C5175DD76D" -Status: RO -X-Status: - -This is a multi-part message in MIME format. - ---------------1EE0A5BF2F6227C5175DD76D -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit - -Dera Mr. Pierce, - -Today I found your fxdr package and adopted it to my system, running -Linux 2.0.25 and Nag Fortran90. - -If you are interested in the changes I made to your package, You will -find the files attached. - -I had to move all *.F to *.f files since NAGf90 doesn't like any -extension but .f or .f90 and I also had to delete all # preprocessor -pragmas in test.f. Not very diffucult, though. - -Thank you very much for providing this package, you saved me a lot of -time... - -All the best from Germany - --- -Axel vom Endt Office: A2_95 -Max-Planck-Institut f. Aeronomie Phone: +49-(0)5556-979-481 -Postfach 20 Fax: +49-(0)5556-979-240 -D-37191 Katlenburg-Lindau Email: Axel.vom.Endt@linmpi.mpg.de - -=============================================================== - -filename="Defines.linux" - -F77CMD = f90 -64_BIT_REALS = -r8 -CCCMD = gcc -F77OPTS = -CCOPTS = -AR = ar -RANLIB = ranlib - - diff --git a/fxdr_2.1c/README.sun_and_IDL b/fxdr_2.1c/README.sun_and_IDL deleted file mode 100644 index f0a843612..000000000 --- a/fxdr_2.1c/README.sun_and_IDL +++ /dev/null @@ -1,107 +0,0 @@ -The following e-mail might be helpful to people using the FXDR -library on the Sun platform, or using it in conjunction with IDL. -The alterations and routines mentioned below have been included -with the release. - ----------------------------------------------------------------- - -From wilms@rocinante.Colorado.EDU Tue Aug 13 09:11:26 1996 -Date: Tue, 13 Aug 1996 09:42:24 -0600 -From: Joern Wilms -To: dpierce@ucsd.edu - -Dear Dr. Pierce, - -first I'd like to thank you for the development of the -fxdr library, which is a great help for all of us who are -stuck with FORTRAN... - -I recently compiled fxdr on a Sun machine (uname -a is) - - SunOS dulcinea 5.5.1 Generic sun4u sparc SUNW,Ultra-1 - -using the standard Sun compilers. On this machine, in order -to get the library to work, it is also necessary to link the binaries -with the nsl library (i.e. -L/usr/local/lib -lfxdr -lnsl) because the -xdr routines are not in the system-library. Apart from that, the -Defines.unsupported just worked fine. - -Secondly when interfacing the library with IDL, a visualization language -often used in astronomy, satellite imagery, and in medical applications, I -found it necessary to add some subroutines that write shorts in xdr format -(IDL writes its integers as shorts and prepends strings with their length -in short format; in addition, IDL DOES NOT use the xdr_array function to -write its arrays, but just uses a loop to write all array elements, here, -the array is NOT prepended with its length; I really wonder why they didn't -use the standard xdr constructs in both cases...). I've attached the -necessary subroutines, feel free to include them with the next release of -fxdr (only if you want....) - -Thanks again, - -Joern - - - -**** -xdrshort.F -**** - -c -c Write/Read an integer as a short (may cause wrap-around!) -c J. Wilms, wilms@astro.uni-tuebingen.de or wilms@colorado.edu -c - subroutine xdrshort (ixdrs, num) - integer ixdrs,ixdrsm1,num - - ixdrsm1=ixdrs - 1 - - call cxdrshort( ixdrsm1, num) - - return - end - -***** -cxdrshort.c -***** - -/* Write/Read a short */ -/* J. Wilms, wilms@astro.uni-tuebingen.de or wilms@colorado.edu */ - -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#ifdef cray - CXDRSHORT( int *ixdrid, int *i ) - -#elif defined( hpux ) - cxdrshort( ixdrid, i ) - int *ixdrid; - int *i; - -#else - cxdrshort_( int *ixdrid, int *i ) -#endif -{ - XDR *xdrs; - short ii; - - xdrs = xdrfile[*ixdrid].xdrs; - - if (xdrs->x_op == XDR_ENCODE) ii=(short) *i; - - if( ! xdr_short( xdrs, &ii ) ) { - fprintf( stderr, "FXDR library error! Call to read short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - - if (xdrs->x_op == XDR_DECODE) i=(int) ii; -} - diff --git a/fxdr_2.1c/README.unicos b/fxdr_2.1c/README.unicos deleted file mode 100644 index 6ccb120bf..000000000 --- a/fxdr_2.1c/README.unicos +++ /dev/null @@ -1,27 +0,0 @@ -At some point Cray stopped defining the compiler symbol -'cray' in the c89 command; I've added a "-Dcray" to the -c89 command line to fix that. Also, newer crays do not -include support for the cf77 compiler; I've switched it -to the f90 compiler. I've not experienced any problems -with this change. In case you need it for old installations, -there is a "Defines.unicos.old" that has the old values -for the unicos system; copy that to Defines.unicos if -you need to. - ---David Pierce -13 November 1998 - -Note added 31 Aug 1999: -At some point Cray decided to switch Fortran character -strings from one word pointers to TWO word pointers! -Needless to say, this messed up the routines that -transfer character strings from Fortran to C. The -code has been changed to use the new style TWO word pointers. -This is controlled by adding "-Dcray_twobytecptrs" to the -CC command in the Defines.unicos* files. If you have an -old Cray installation that predates this change, you will -probably have to get rid of the -Dcray_twobytecptrs entry -in your Defines.unicos file, make clean, configure, then -make and make test. - - diff --git a/fxdr_2.1c/cfxdr.h b/fxdr_2.1c/cfxdr.h deleted file mode 100644 index 2ab4a4dea..000000000 --- a/fxdr_2.1c/cfxdr.h +++ /dev/null @@ -1,15 +0,0 @@ - -#define MAX_N_XDR_FILES 32 - -typedef struct { - char *filename; - int return_on_error; /* 0=FALSE, 1=TRUE */ - XDR *xdrs; -} XDR_element; - -#define FXDRERR_WRNEGNELS -10 -#define FXDRERR_WRITEERR -11 -#define FXDRERR_READERR -12 -#define FXDRERR_READWRONGNELS -13 -#define FXDRERR_REWIND -14 - diff --git a/fxdr_2.1c/configure b/fxdr_2.1c/configure deleted file mode 100755 index 3da5a31a0..000000000 --- a/fxdr_2.1c/configure +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh - -if test $# -eq 0; then - un=`uname -a` - un1=`echo $un | awk ' { print substr($1,1,4) }'` - un5=`echo $un | awk ' { print $5 }'` - un6=`echo $un | awk ' { print $6 }'` - if test $un1 = "HP-U"; then - sys=hpux - elif test $un1 = "Linu"; then - sys=linux - elif test $un1 = "IRIX"; then - sys=irix - elif test $un1 = "ULTR"; then - sys=ultrix - elif test $un1 = "AIX"; then - sys=aix - elif test $un1 = "OSF1"; then - sys=osf1 - elif test $un1 = "SunO"; then - sys=sun - echo "Note: on a Sun, you must link your application programs" - echo "with the system nsl library in addition to the fxdr" - echo "library. So, for example, you would add the following" - echo "to the end of your compile command:" - echo " -L/usr/local/lib -lfxdr -lnsl" - echo " " - elif test $un5 = "CRAY"; then - if test $un6 = "T3E"; then - sys=unicos_t3e - else - sys=unicos - fi - else - echo "I can't figure out what kind of system this is," - echo "or I just may not be set up to handle it." - echo "Try invoking configure with one of the following" - echo "arguments, if appropriate:" - echo " hpux irix ultrix osf1 unicos aix linux" - exit - fi -else - sys=$1 -fi - -if test ! -r Defines.$sys; then - echo "I don't know how to handle system $sys" - echo "Please see the README file for configuring for an unsupported" - echo "system. Or, you can just try 'make unsupported' and hope it" - echo "works!" - exit -fi - -cat Defines.$sys Makefile.tmpl > Makefile -echo "Configured a Makefile for $sys" -echo "Now type \"make\"" diff --git a/fxdr_2.1c/cxdrclose.c b/fxdr_2.1c/cxdrclose.c deleted file mode 100644 index d667d4458..000000000 --- a/fxdr_2.1c/cxdrclose.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void - -#if (IFSTYLE==1) - CXDRCLOSE( int *ixdrid, int *retval ) - -#elif (IFSTYLE==2) - cxdrclose( ixdrid, retval ) - int *ixdrid; - int *retval; - -#else - cxdrclose_( int *ixdrid, int *retval ) -#endif -{ - XDR *xdrs; - FILE *f; - - *retval = 0; /* No errors */ - - xdrs = xdrfile[*ixdrid].xdrs; - - /* Get the file pointer, which was saved in the user's - * data area, so we can close the file after destroying - * the XDR handle. - */ - f = (FILE *)xdrs->x_public; - - xdr_destroy( xdrs ); - - fclose( f ); - - xdrfile[*ixdrid].filename = NULL; -} - diff --git a/fxdr_2.1c/cxdrdmat.c b/fxdr_2.1c/cxdrdmat.c deleted file mode 100644 index d92aee020..000000000 --- a/fxdr_2.1c/cxdrdmat.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRDMAT( int *ixdrid, int *nels, double *d, int *retval ) - -#elif (IFSTYLE==2) - cxdrdmat( ixdrid, nels, d, retval ) - int *ixdrid; - int *nels; - double *d; - int *retval; - -#else - cxdrdmat_( int *ixdrid, int *nels, double *d, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write double precision array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&d, &ne, *nels, sizeof(double), xdr_double ) ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to " ); - fprintf( stderr, "write double precision array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - if( ! xdr_array( xdrs, (char **)&d, &actual_nels, *nels, sizeof(double), xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to " ); - fprintf( stderr, "read double precision array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "error reading the file\n" ); - exit( -1 ); - } - } - - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d double precision elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr_2.1c/cxdrdouble.c b/fxdr_2.1c/cxdrdouble.c deleted file mode 100644 index 6dcaf07dd..000000000 --- a/fxdr_2.1c/cxdrdouble.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRDOUBLE( int *ixdrid, double *d, int *retval ) - -#elif (IFSTYLE==2) - cxdrdouble( ixdrid, d, retval ) - int *ixdrid; - double *d; - int *retval; - -#else - cxdrdouble_( int *ixdrid, double *d, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_double( xdrs, d )) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to write " ); - fprintf( stderr, "a double precision number from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to read " ); - fprintf( stderr, "a double precision number to file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr_2.1c/cxdrimat.c b/fxdr_2.1c/cxdrimat.c deleted file mode 100644 index 876d7250e..000000000 --- a/fxdr_2.1c/cxdrimat.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRIMAT( int *ixdrid, int *nels, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrimat( ixdrid, nels, i, retval ) - int *ixdrid; - int *nels; - int *i; - int *retval; - -#else - cxdrimat_( int *ixdrid, int *nels, int *i, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write integer array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&i, &ne, *nels, sizeof(int), xdr_int )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write integer array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - if( ! xdr_array( xdrs, (char **)&i, &actual_nels, *nels, sizeof(int), xdr_int )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read integer array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d integer elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured while reading file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr_2.1c/cxdrinit.c b/fxdr_2.1c/cxdrinit.c deleted file mode 100644 index 87128ef05..000000000 --- a/fxdr_2.1c/cxdrinit.c +++ /dev/null @@ -1,167 +0,0 @@ -#include -#include -#include "cfxdr.h" - -XDR_element xdrfile[MAX_N_XDR_FILES] = { - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, - NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, NULL }; - - long -#if defined(cray_twobytecptrs) - CXDRINIT( int *fname_len, char *filename, int *dummy, int *mode, int *return_on_err ) - -#elif (IFSTYLE==1) - CXDRINIT( int *fname_len, char *filename, int *mode, int *return_on_err ) - -#elif (IFSTYLE==2) - cxdrinit( fname_len, filename, mode, return_on_err ) - int *fname_len; - char *filename; - int *mode; - int *return_on_err; - -#else - cxdrinit_( int *fname_len, char *filename, int *mode, int *return_on_err ) -#endif -{ - FILE *f; - int xdr_mode, new_xdr_id; - XDR *xdrs; - char local_filename[2048]; - - strncpy( local_filename, filename, *fname_len ); - local_filename[*fname_len] = '\0'; - - /* Get the new XDR ID to use when accessing this file */ - if( (new_xdr_id = cxdrgetid()) == -1 ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "Error while trying to open file %s\n", - local_filename ); - exit( -1 ); - } - } - - /* Save the file name of this XDR file, so that we - * can print it out in case of errors. - */ - xdrfile[new_xdr_id].filename = (char *) - malloc(sizeof(char)*(*fname_len + 1)); - strcpy( xdrfile[new_xdr_id].filename, local_filename ); - - xdrs = (XDR *)malloc( sizeof( XDR ) ); - if( xdrs == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "Error on xdr stream create\n" ); - fprintf( stderr, "filename=%s\n", local_filename ); - exit( -1 ); - } - } - - if( *mode == 1 ) { - xdr_mode = XDR_DECODE; - if( (f = fopen( local_filename, "r" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for reading\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else if( *mode == 2 ) { - xdr_mode = XDR_ENCODE; - if( (f = fopen( local_filename, "w" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for writing\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else if( *mode == 3 ) { - xdr_mode = XDR_ENCODE; - if( (f = fopen( local_filename, "a" )) == NULL ) { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, - "Error opening XDR file \"%s\" for appending\n", - local_filename ); - perror( "Reason" ); - exit( -1 ); - } - } - } - - else /* Wrong mode specified */ - { - if( *return_on_err ) { - return( -1 ); - } - else - { - fprintf( stderr, "error: cxdrinit.c called with mode=%ld\n", *mode ); - exit( -1 ); - } - } - - xdrstdio_create( xdrs, f, xdr_mode ); - - xdrfile[new_xdr_id].return_on_error = *return_on_err; - xdrfile[new_xdr_id].xdrs = xdrs; - - /* Add the file pointer to the user's data area so - * that we can close the file when the destroy routine - * is called! - */ - xdrs->x_public = (caddr_t)f; - - return( new_xdr_id ); -} - - int -cxdrgetid() -{ - int i; - - i = 0; - while( xdrfile[i].filename != NULL ) { - i++; - if( i >= MAX_N_XDR_FILES ) { - fprintf( stderr, "FXDR library error: too many "); - fprintf( stderr, "XDR files open! Max is %d\n", - MAX_N_XDR_FILES ); - return( -1 ); - } - } - return( i ); -} diff --git a/fxdr_2.1c/cxdrint.c b/fxdr_2.1c/cxdrint.c deleted file mode 100644 index 0096db0b9..000000000 --- a/fxdr_2.1c/cxdrint.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRINT( int *ixdrid, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrint( ixdrid, i, retval ) - int *ixdrid; - int *i; - int *retval; - -#else - cxdrint_( int *ixdrid, int *i, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_int( xdrs, i ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write integer "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read integer "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr_2.1c/cxdrreal.c b/fxdr_2.1c/cxdrreal.c deleted file mode 100644 index 6a6ed3bf8..000000000 --- a/fxdr_2.1c/cxdrreal.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREAL( int *ixdrid, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrreal( ixdrid, r, retval ) - int *ixdrid; - float *r; - int *retval; - -#else - cxdrreal_( int *ixdrid, float *r, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_float( xdrs, r ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write real "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read real "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr_2.1c/cxdrreal64 b/fxdr_2.1c/cxdrreal64 deleted file mode 100644 index 3f01074b7..000000000 Binary files a/fxdr_2.1c/cxdrreal64 and /dev/null differ diff --git a/fxdr_2.1c/cxdrreal64.c b/fxdr_2.1c/cxdrreal64.c deleted file mode 100644 index 5b0a38e33..000000000 --- a/fxdr_2.1c/cxdrreal64.c +++ /dev/null @@ -1,59 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREAL64( int *ixdrid, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrreal64( ixdrid, r, retval ) - int *ixdrid; - float *r; - int *retval; - -#else - cxdrreal64_( int *ixdrid, float *r, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_double( xdrs, (double *)r ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write double "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read double "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr_2.1c/cxdrrewind.c b/fxdr_2.1c/cxdrrewind.c deleted file mode 100644 index 94ef67827..000000000 --- a/fxdr_2.1c/cxdrrewind.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRREWIND( int *ixdrid, int *retval ) - -#elif (IFSTYLE==2) - cxdrrewind( ixdrid, retval ) - int *ixdrid; - int *retval; - -#else - cxdrrewind_( int *ixdrid, int *retval ) -#endif -{ - XDR *xdrs; - u_int position; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - position = 0; - - if( ! xdr_setpos( xdrs, position ) ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_REWIND; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to rewind "); - fprintf( stderr, "file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } -} diff --git a/fxdr_2.1c/cxdrrmat.c b/fxdr_2.1c/cxdrrmat.c deleted file mode 100644 index 462ade04d..000000000 --- a/fxdr_2.1c/cxdrrmat.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRRMAT( int *ixdrid, int *nels, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrrmat( ixdrid, nels, r, retval ) - int *ixdrid; - int *nels; - float *r; - int *retval; - -#else - cxdrrmat_( int *ixdrid, int *nels, float *r, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &ne, ne, sizeof(float), xdr_float )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &actual_nels, ne, sizeof(float), xdr_float)) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read real array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d real elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr_2.1c/cxdrrmat64.c b/fxdr_2.1c/cxdrrmat64.c deleted file mode 100644 index 10f5be62a..000000000 --- a/fxdr_2.1c/cxdrrmat64.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRRMAT64( int *ixdrid, int *nels, float *r, int *retval ) - -#elif (IFSTYLE==2) - cxdrrmat64( ixdrid, nels, r, retval ) - int *ixdrid; - int *nels; - float *r; - int *retval; - -#else - cxdrrmat64_( int *ixdrid, int *nels, float *r, int *retval ) -#endif -{ - XDR *xdrs; - u_int actual_nels, ne; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( xdrs->x_op == XDR_ENCODE ) { - if( *nels < 0 ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRNEGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real64 array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "negative number of elements specified!\n" ); - exit( -1 ); - } - } - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &ne, ne, 8, xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "write real (64 bit) array to file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "write error (disk full?)\n" ); - exit( -1 ); - } - } - } - else - { - ne = *nels; - if( ! xdr_array( xdrs, (char **)&r, &actual_nels, ne, 8, xdr_double )) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error in call to "); - fprintf( stderr, "read real (64 bit) array from file %s:\n", - xdrfile[*ixdrid].filename ); - fprintf( stderr, "read error (end of file?)\n" ); - exit( -1 ); - } - } - if( actual_nels != *nels ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READWRONGNELS; - return; - } - else - { - fprintf( stderr, "FXDR library error! Asked for " ); - fprintf( stderr, "%d real64 elements, but actually read %d!\n", - *nels, actual_nels ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} diff --git a/fxdr_2.1c/cxdrshort.c b/fxdr_2.1c/cxdrshort.c deleted file mode 100644 index e67addd14..000000000 --- a/fxdr_2.1c/cxdrshort.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Write/Read a short */ - -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if (IFSTYLE==1) - CXDRSHORT( int *ixdrid, int *i, int *retval ) - -#elif (IFSTYLE==2) - cxdrshort( ixdrid, i, retval ) - int *ixdrid; - int *i; - int *retval; - -#else - cxdrshort_( int *ixdrid, int *i, int *retval ) -#endif -{ - XDR *xdrs; - short ii; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if (xdrs->x_op == XDR_ENCODE) ii=(short) *i; - - if( ! xdr_short( xdrs, &ii ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to write short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error! Call to read short "); - fprintf( stderr, "did not complete successfully!\n" ); - fprintf( stderr, "Error occured in file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } - - if (xdrs->x_op == XDR_DECODE) *i=(int)ii; -} - diff --git a/fxdr_2.1c/cxdrstring.c b/fxdr_2.1c/cxdrstring.c deleted file mode 100644 index d69e27247..000000000 --- a/fxdr_2.1c/cxdrstring.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include "cfxdr.h" - -extern XDR_element xdrfile[MAX_N_XDR_FILES]; - - void -#if defined(cray_twobytecptrs) - CXDRSTRING( int *ixdrid, u_int *len, char *s, int *dummy, int *retval ) - -#elif (IFSTYLE==1) - CXDRSTRING( int *ixdrid, u_int *len, char *s, int *retval ) - -#elif (IFSTYLE==2) - cxdrstring( ixdrid, len, s, retval ) - int *ixdrid; - u_int *len; - char *s; - int *retval; - -#else - cxdrstring_( int *ixdrid, u_int *len, char *s, int *retval ) -#endif -{ - XDR *xdrs; - - *retval = 0; /* No error */ - - xdrs = xdrfile[*ixdrid].xdrs; - - if( ! xdr_bytes( xdrs, &s, len, *len ) ) { - if( xdrs->x_op == XDR_ENCODE ) { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_WRITEERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to write a"); - fprintf( stderr, "string from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - else - { - if( xdrfile[*ixdrid].return_on_error ) { - *retval = FXDRERR_READERR; - return; - } - else - { - fprintf( stderr, "FXDR library error while trying to read a"); - fprintf( stderr, "string from file %s\n", - xdrfile[*ixdrid].filename ); - exit( -1 ); - } - } - } -} - diff --git a/fxdr_2.1c/fxdr.3f b/fxdr_2.1c/fxdr.3f deleted file mode 100644 index e00b6d042..000000000 --- a/fxdr_2.1c/fxdr.3f +++ /dev/null @@ -1,342 +0,0 @@ -.TH FXDR 3F local - -fxdr: a library to interface the XDR routines to FORTRAN. -.PP -The FXDR library is a set of FORTRAN routines which provide an interface -to the XDR routines which already exist (almost certainly) on your workstation -or mainframe. I.e., it provides an easy and convenient way to -use the XDR ability of your computer from FORTRAN. -.PP -If you use the FXDR routines in your FORTRAN codes -to write out your binary data files, then you can move those data files -around to any of the different machines you use, and the data will be -read in correctly within the precision limits of XDR and your machine -(generally, about 1 part in 10**7 for 32-bit single precision numbers and -1 part in 10**15 for 64-bit double precision numbers). -.PP -.SH ROUTINES: -.PP -.I integer function INITXDR( filename, mode, return_on_error ) -.EX - character*(*) filename (an input) - character*1 mode (an input; 'r', 'w', or 'a') - logical return_on_error (an input) -.EE -initializes an XDR file -for reading (if mode='r'), writing (if mode='w'), or appending (if mode='a'). -Returns the XDR file ID ('ixdrs'), which is greater than or -equal to zero; or, if an error is encountered -and return_on_error is .TRUE., returns an error code that -is less than zero. -If logical argument return_on_error is .FALSE., then any fxdr -routines (including this one!) that encounter errors accessing this file -(for example, trying to read past an end of file, or reading in -a different number of array elements than was originally -written to the file) will print out an error message and stop. -This is similar to what Fortran does, so for the most -Fortran-like behavior set return_on_error to .FALSE.. -If logical argument return_on_error is .TRUE., then -any fxdr routines (including this one!) that encounter errors will -NOT stop, but instead return a value -that is less than 0 to the calling routine. -.PP -.I INTEGER FUNCTION IXDRINT( ixdrs, ival ): -Read or write a FORTRAN integer. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREAL( ixdrs, sval ): -Read or write a FORTRAN 'real' using 32 bits in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRDOUBLE( ixdrs, dval ): -Read or write a FORTRAN 'double precision' using 64 bits in -the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREAL64( ixdrs, fval ): -Read or write a FORTRAN 'real' using 64 bits in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the value. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRSTRING( ixdrs, string ): -Read or write a FORTRAN "character*(*)". -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the string. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRIMAT( ixdrs, nels, iarray ): -Read or write an array of FORTRAN integers. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRRMAT( ixdrs, nels, sarray ): -Read or write an array of FORTRAN 'real' using 32 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRDMAT( ixdrs, nels, darray ): -Read or write an array of FORTRAN 'double precision' using 64 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRRMAT64( ixdrs, nels, sarray ): -Read or write an array of FORTRAN 'real' using 64 bits for -each element in the XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when reading or writing the array. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRREWIND( ixdrs ): -Rewind an XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when rewinding. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.I INTEGER FUNCTION IXDRCLOSE( ixdrs ): -Close an XDR file. -If INITXDR was called with return_on_error=.TRUE., then -a return value less than 0 indicates an error was encountered -when closing the file. -If INITXDR was called with return_on_error=.FALSE., then -this routine will print and error message and stop if -an error is encountered. -.PP -.SH USEAGE: -You just replace your FORTRAN unformatted binary write statements with -calls to the appropriate FXDR library routine. -For most Fortran-like behavior, set the return_on_error argument -to INITXDR (the third argument) to .FALSE. -- this will make the -routines print out an error message and halt if an error is -encountered. -If you want to handle error messages yourself, then set -the return_on_error argument -to INITXDR (the third argument) to .TRUE., and check the -returned values from the XDR routines; they will be less than -zero if an error is encountered. -A list of error codes is in 'fxdr.inc', which you also need -to include in your source code if you are using 'implicit none'. -.PP -Example to write data: -.EX - Replace - parameter (nx=80,ny=100) - real coeffs(nx,ny) - open(ilun, file='test_data', form='unformatted') - write(ilun) coeffs - - With - parameter (nx=80,ny=100) - real coeffs(nx,ny) - ixdrs = initxdr('test_data.xdr', 'w', .FALSE.) - ierr = ixdrrmat( ixdrs, nx*ny, coeffs ) -.EE -.PP -Pretty easy, eh? To read in that same data: -.EX - Replace - open(ilun, file='test_data', form='unformatted') - read(ilun) coeffs - - With - ixdrs = initxdr('test_data.xdr', 'r', .FALSE.) - ierr = ixdrrmat( ixdrs, nx*ny, coeffs ) -.EE -Note that the call to the FXDR routine is EXACTLY THE SAME whether you -are reading or writing; whether you actually read or write is determined -by whether you called the 'initxdr' routine with a 'r' or 'w' as the -second argument. This is opposite FORTRAN, where the call to open the -file is exactly the same whether you are reading or writing, but you -call different routines ('read' or 'write') to accomplish the one you want. -.PP -.I More detail on using the FXDR library -To use the FXDR library you first open the XDR-format file using the 'initxdr' -routine. This routine returns an integer which is the ID number which all -the XDR routines will use to indicate which XDR file you want to work with. -The first argument to 'initxdr' is the name of the file, the second -argument is either 'r', 'w', or 'a' for reading, writing, or appending, and the third -is a logical that you set to .TRUE. if you want to do your own error -handling (by testing if the return value of functions is less than 0), -and .FALSE. if you want the Fortran-like behavior of printing an -error message and halting if an error is encountered: -.EX - character*(*) filename - character*1 mode - integer id - id = initxdr( filename, mode, .FALSE. ) -.EE -Then you replace both your 'read' and 'write' calls with a call to one of -the following integer functions: -.EX -Name Bits FORTRAN type of argument ---------- ---- -------------------------------------------------------- -ixdrdouble 64 double precision floating point number -ixdrdmat 64 array of double precision floating point numbers -ixdrint 32 integer -ixdrimat 32 array of integers -ixdrreal 32 single precision floating point number -ixdrrmat 32 array of single precision floating point numbers -ixdrreal64 64 single precision floating point number -ixdrrmat64 64 array of single precision floating point numbers -ixdrstring n/a character*(*) -.EE -The 'Bits' column shows how many significant bits are saved in the XDR file. -.PP -The scaler (i.e., single value, not array) functions all take exactly two -parameters: -.EX - 1) the xdr file ID, which was the integer returned by the - 'initxdr' call. - - 2) the variable to either read or write. -.EE -The array functions all take exactly three parameters: -.EX - 1) the xdr file ID, which was the integer returned by the - 'initxdr' call. - - 2) The TOTAL number of elements in the array. - - 3) the array to either read or write. -.EE -If initxdr was called with the third argument (return_on_error) to -be .FALSE., then these functions print out an error message and halt -if they encounter an error. -If initxdr was called with the third argument (return_on_error) to -be .TRUE., then these routines return an error code that is less than -zero if they encounter an error. -A list of error codes is in 'fxdr.inc'. -.PP -.SH PRECISION -It is IMPORTANT to understand that the precision referred to above (for -example, the 'single' precision of routine 'xdrreal' or the 'double' -precision of routine 'xdrdouble') is SET BY YOUR COMPILER, not -by the FXDR library. This matters, because different compilers -have different default precisions (as in, number of bits) associated -with the names 'single', 'double', etc. At the time of writing this, -this makes the biggest difference when moving XDR files between Crays and -workstations such as Suns, HPs, or DECs, because by defalt the Cray FORTRAN -compiler uses a 'single' precision of 64 bits and a 'double' precision -of 128 bits, while the Sun, HP, and DEC use a 'single' precision of 32 -bits and a 'double' precision of 64 bits. (You might get a similar effect -on a workstation if you compile with a flag such as '-r8' which instructs -the compiler to make all 'single precision' variables default to 8 bytes -[64 bits] of precision). -.PP -The upshot is that if you use a Cray to write a FORTRAN single precision -floating point number into an XDR file using routine "ixdrreal", only 32 -bits of the original 64 bits will be written. But, you can't use routine -"ixdrdouble" to write all 64 bits correctly, because that routine expects -to be passed a FORTRAN double precision floating point variable, not a -single precision variable. -.PP -To get around this, there is a set of special routines which take 'single -precision' variables as defined by the FORTRAN compiler and write them -out with 64 bits (these are the 'ixdrreal64' and 'ixdrrmat64' routines). To -read these in on a workstation where a real is only 32 bits, you should -use the 'ixdrdouble' or 'ixdrdmat' routines and supply a *double* precision -floating point variable to receive the 64 bits of valid data. (To read -these in on a Cray, you just use the same routine which wrote the data out -in the first place--'ixdrreal64' or 'ixdrrmat64'). -.PP -.I To sum up: -.PP - Write SINGLE PRECISION values on a Cray (or workstation with - 64 bit FORTRAN reals) with 'ixdrreal64' or 'ixdrrmat64', then - read them into DOUBLE PRECISION values on a regular workstation - with a call to 'ixdrdouble' or 'ixdrdmat'. -.PP - Write DOUBLE PRECISION values on a workstation with 'ixdrdouble' - or 'ixdrdmat', then read them into SINGLE PRECISION values on - a Cray (or workstation with 64 bit FORTRAN reals) with a call - to 'ixdrreal64' or 'ixdrrmat64'. -.PP -Note that even workstations which are 64-bit machines, such as the -DEC Alpha and the SGI Power machines, generally do NOT have a FORTRAN -"real" be 64 bits by default -- they stick to 32 bits. -.PP -.I PRECISION PART II. -Unfortunately, that's not all you should know about precision. There is -also the problem that Crays (at the moment--new Crays might change this) -use a completely different scheme for representing numbers internally than -do workstations. Crays use "Cray floating point format" (duh) while -workstations use "IEEE floating point format". Well, the underlying XDR -libraries which FXDR calls *always* use IEEE floating point format, so if -you always work on a workstation then everything is fine and please ignore -this paragraph despite the fact that you've already read a lot of it. If -you work on Crays, though, you need to be aware that putting data into an -XDR file and then immediately reading it back in WILL NOT leave you with -exactly the same floating point number which you started with. It will -likely be different in the last bit position or so. This is a tiny difference, -and to put it into perspective, the Cray compiler will itself do things -to your code (and warn you that it is doing them) which can change your -results this much, for the sake of making the code run faster. However -if you just can't live with losing a bit of precision in your numbers then -please erase this library and for God's sake start drinking decaffinated -coffee. -.PP -.SH Linking with the FXDR library -OK, you've written your FORTRAN program with calls to the FXDR library--now -how do you get it to compile correctly? -.PP -Well, here would be a typical command line: -.EX - f77 niftyprogram.F -I/usr/local/include -L/usr/local/lib -lfxdr -.EE -the "-lfxdr" tells the compiler to link with the library named "libfxdr.a"; -the "-L/usr/local/lib" tells the compiler to look for "libfxdr.a" in -directory "/usr/local/lib". This is the default place to install the -library. If you put the library somewhere else instead, then you will -have to substitute the place where you put "libfxdr.a" in for "/usr/local/lib" -in the typical command line given above. -The "-I/usr/local/include" tells the compiler to look for file "fxdr.inc" -in directory "/usr/local/include". This is only needed if you want -to use the FXDR error codes by name, or if you usually use 'implicit none' -if your Fortran code and want to have all the xdr routines defined -properly. - -.SH Author -David Pierce, Scripps Institution of Oceanography, Climate Research -Division. E-mail "dpierce@ucsd.edu". - diff --git a/fxdr_2.1c/fxdr.inc b/fxdr_2.1c/fxdr.inc deleted file mode 100644 index 8bb331713..000000000 --- a/fxdr_2.1c/fxdr.inc +++ /dev/null @@ -1,21 +0,0 @@ - integer initxdr - integer ixdrclose - integer ixdrdmat - integer ixdrdouble - integer ixdrimat - integer ixdrint - integer ixdrreal - integer ixdrreal64 - integer ixdrrewind - integer ixdrrmat - integer ixdrrmat64 - integer ixdrshort - integer ixdrstring - - integer FXDRERR_WRNEGNELS, FXDRERR_WRITEERR - integer FXDRERR_READERR, FXDRERR_READWRONGNELS - integer FXDRERR_REWIND - parameter(FXDRERR_WRNEGNELS=-10, FXDRERR_WRITEERR=-11) - parameter(FXDRERR_READERR=-12, FXDRERR_READWRONGNELS=-13) - parameter(FXDRERR_REWIND=-14) - diff --git a/fxdr_2.1c/initxdr.F b/fxdr_2.1c/initxdr.F deleted file mode 100644 index 9e33ef470..000000000 --- a/fxdr_2.1c/initxdr.F +++ /dev/null @@ -1,93 +0,0 @@ -c ------------------------------------------------- -c Returns < 0 on error, otherwise the xdrid used to -c access the xdr file -c -c Args: -c filename: character*(*): name of file to -c access -c mode: character*1: either 'r', 'w', or 'a' -c (for read, write, and append) -c returnonerror: logical: if .TRUE., then -c routines return even if there is -c an I/O error. If .FALSE., then -c routines halt on I/O error, -c printing out a useful message -c (this is like what fortran does, -c so set to .FALSE. for most fortran- -c like behavior) -c ------------------------------------------------- - integer function initxdr( filename, mode, returnonerror ) - - implicit none - - character*(*) filename - character*1 mode - logical returnonerror - - integer iretval, cxdrinit, iroe, imode, lenf, istrlen - integer ifxdrstrlen - - if( (mode .eq. 'r').or.(mode .eq. 'R') ) then - imode = 1 - else if( (mode .eq. 'w').or.(mode .eq. 'W') ) then - imode = 2 - else if( (mode .eq. 'a').or.(mode .eq. 'A') ) then - imode = 3 - else - write(0,*) 'Error: fxdr library, initxdr called ' - write(0,*) 'with unknown mode (should be r, w, or a):', - & mode - stop 'fxdr library: initxdr routine, bad mode' - endif - - lenf = len(filename) - istrlen = ifxdrstrlen( filename ) - if( istrlen .lt. lenf ) then - lenf = istrlen - endif - - if( returnonerror ) then - iroe = 1 - else - iroe = 0 - endif - - iretval = cxdrinit( lenf, filename, imode, iroe ) - if( iretval .lt. 0 ) then - initxdr = iretval - return - endif - -c ----------------------------------------------------------- -c Add one to the returned value because the C library returns -c starting with zero, which is awkward considering that -c unitialized variables often start with zero in Fortran. -c ----------------------------------------------------------- - initxdr = iretval + 1 - - return - end - -c======================================================================== - - integer function ifxdrstrlen( s ) - - character*(*) s - - i = 1 -100 continue - if( s(i:i) .eq. ' ' ) then - goto 200 - endif - i = i + 1 - if( i .gt. len(s) ) then - goto 200 - endif - goto 100 - -200 continue - ifxdrstrlen = i-1 - - return - end - diff --git a/fxdr_2.1c/ixdrclose.F b/fxdr_2.1c/ixdrclose.F deleted file mode 100644 index 3b60257d9..000000000 --- a/fxdr_2.1c/ixdrclose.F +++ /dev/null @@ -1,16 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrclose( ixdr ) - - implicit none - - integer ixdr, ixdrm1, ierr - - ixdrm1 = ixdr - 1 - call cxdrclose( ixdrm1, ierr ) - - ixdrclose = ierr - - return - end diff --git a/fxdr_2.1c/ixdrdmat.F b/fxdr_2.1c/ixdrdmat.F deleted file mode 100644 index 225256972..000000000 --- a/fxdr_2.1c/ixdrdmat.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrdmat( ixdrs, nels, dval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - double precision dval(nels) - - ixdrsm1 = ixdrs - 1 - call cxdrdmat( ixdrsm1, nels, dval, ierr ) - - ixdrdmat = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrdouble.F b/fxdr_2.1c/ixdrdouble.F deleted file mode 100644 index bc4fbeef8..000000000 --- a/fxdr_2.1c/ixdrdouble.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrdouble( ixdrs, dval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - double precision dval - - ixdrsm1 = ixdrs - 1 - - call cxdrdouble( ixdrsm1, dval, ierr ) - - ixdrdouble = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrimat.F b/fxdr_2.1c/ixdrimat.F deleted file mode 100644 index 5df236b04..000000000 --- a/fxdr_2.1c/ixdrimat.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrimat( ixdrs, nels, ival ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - integer ival(nels) - - ixdrsm1 = ixdrs - 1 - call cxdrimat( ixdrsm1, nels, ival, ierr ) - - ixdrimat = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrint.F b/fxdr_2.1c/ixdrint.F deleted file mode 100644 index 8ca920078..000000000 --- a/fxdr_2.1c/ixdrint.F +++ /dev/null @@ -1,19 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrint( ixdrs, ival ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - integer ival - - ixdrsm1 = ixdrs - 1 - call cxdrint( ixdrsm1, ival, ierr ) - - ixdrint = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrreal.F b/fxdr_2.1c/ixdrreal.F deleted file mode 100644 index 588fbf56b..000000000 --- a/fxdr_2.1c/ixdrreal.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrreal( ixdrs, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - real rval - - ixdrsm1 = ixdrs - 1 - - call cxdrreal( ixdrsm1, rval, ierr ) - - ixdrreal = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrreal64.F b/fxdr_2.1c/ixdrreal64.F deleted file mode 100644 index d4640ab58..000000000 --- a/fxdr_2.1c/ixdrreal64.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrreal64( ixdrs, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - real rval - - ixdrsm1 = ixdrs - 1 - - call cxdrreal64( ixdrsm1, rval, ierr ) - - ixdrreal64 = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrrewind.F b/fxdr_2.1c/ixdrrewind.F deleted file mode 100644 index 9357b3037..000000000 --- a/fxdr_2.1c/ixdrrewind.F +++ /dev/null @@ -1,17 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrewind( ixdrs ) - - implicit none - - integer ixdrs, ixdrsm1, ierr - - ixdrsm1 = ixdrs - 1 - - call cxdrrewind( ixdrsm1, ierr ) - - ixdrrewind = ierr - - return - end diff --git a/fxdr_2.1c/ixdrrmat.F b/fxdr_2.1c/ixdrrmat.F deleted file mode 100644 index e047b7d31..000000000 --- a/fxdr_2.1c/ixdrrmat.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrmat( ixdrs, nels, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - real rval(nels) - - ixdrsm1 = ixdrs - 1 - - call cxdrrmat( ixdrsm1, nels, rval, ierr ) - - ixdrrmat = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrrmat64.F b/fxdr_2.1c/ixdrrmat64.F deleted file mode 100644 index 5044644d4..000000000 --- a/fxdr_2.1c/ixdrrmat64.F +++ /dev/null @@ -1,20 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrrmat64( ixdrs, nels, rval ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, nels - real rval(nels) - - ixdrsm1 = ixdrs - 1 - - call cxdrrmat64( ixdrsm1, nels, rval, ierr ) - - ixdrrmat64 = ierr - - return - end - - diff --git a/fxdr_2.1c/ixdrshort.F b/fxdr_2.1c/ixdrshort.F deleted file mode 100644 index cfe1f6325..000000000 --- a/fxdr_2.1c/ixdrshort.F +++ /dev/null @@ -1,18 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrshort (ixdrs, num) - - implicit none - - integer ixdrs,ixdrsm1,num, ierr - - ixdrsm1=ixdrs - 1 - - call cxdrshort( ixdrsm1, num, ierr ) - - ixdrshort = ierr - - return - end - diff --git a/fxdr_2.1c/ixdrstring.F b/fxdr_2.1c/ixdrstring.F deleted file mode 100644 index 6c8ea7cc0..000000000 --- a/fxdr_2.1c/ixdrstring.F +++ /dev/null @@ -1,21 +0,0 @@ -c ----------------------------- -c Returns < 0 if error, 0 if OK -c ----------------------------- - integer function ixdrstring( ixdrs, string ) - - implicit none - - integer ixdrs, ixdrsm1, ierr, ilen - character*(*) string - - ixdrsm1 = ixdrs - 1 - - ilen = len(string) - call cxdrstring( ixdrsm1, ilen, string, ierr ) - - ixdrstring = ierr - - return - end - - diff --git a/fxdr_2.1c/libfxdr.a b/fxdr_2.1c/libfxdr.a deleted file mode 100644 index 18d3d5e08..000000000 Binary files a/fxdr_2.1c/libfxdr.a and /dev/null differ diff --git a/fxdr_2.1c/test.F b/fxdr_2.1c/test.F deleted file mode 100644 index 8391e9ea0..000000000 --- a/fxdr_2.1c/test.F +++ /dev/null @@ -1,487 +0,0 @@ - program testfxdr - -c =========================================================== -c Test the FXDR library by exercising the calls, and -c comparing the results to the known good .xdr file. -c -c David Pierce Scripps Inst. Oceanography / Climate Research -c Aug 10, 1999 -c =========================================================== - - implicit none - - include 'fxdr.inc' - - integer ien, jen - parameter(ien=3,jen=2) - - integer iwrite, ierr, isign, j, i2, imatwrite, ixdrs, iread - real*4 rwrite, rsign, rxpon, fmatwrite, rread -#ifdef cray - real dwrite -#else - double precision dwrite -#endif - - dimension imatwrite(ien) - dimension fmatwrite(ien,jen) -#ifdef cray - real dmatwrite(ien,jen), dsign, dxpon -#else - double precision dmatwrite(ien,jen), dsign, dxpon -#endif - character*26 stringwrite - - common /cb1/ iwrite, imatwrite - common /cb2/ rwrite, fmatwrite - common /cb3/ dwrite, dmatwrite - common /cb4/ stringwrite - -c ----------------------------------------------- -c Initialize our variables to recognizable values -c ----------------------------------------------- - iwrite = 987654 - rwrite = 3.1415926535e0 -#ifdef cray - dwrite = 1.234567890123456789e0 -#else - dwrite = 1.234567890123456789d0 -#endif - stringwrite = 'this is a FXDR test string' - -c ------------------------------------------------- -c Fill in the integer, single precision, and double -c precision arrays with useful values. -c ------------------------------------------------- - dsign = 1.0d0 - rsign = 1.0 - isign = 1 - rxpon = -20.0 - dxpon = -20.0d0 - do j=1, jen - do i2=1, ien - imatwrite(i2) = isign*i2 - fmatwrite(i2,j) = rsign*(float(i2) + - & float(j)/100.0)*10.0**rxpon -#ifdef cray - dmatwrite(i2,j) = dsign*(float(i2) + - & float(j)/10000000000.0)*10.0**dxpon -#else - dmatwrite(i2,j) = dsign*(dble(i2) + - & dble(j)/10000000000.0)*10.0**dxpon -#endif - dsign = -1.0d0*dsign - rsign = -1.0*rsign - isign = -isign - rxpon = rxpon + 7.0 - dxpon = dxpon + 7.0d0 - enddo - enddo - - print *, 'here are the check values:' - print *, fmatwrite - print *, dmatwrite - -c ------------------------------------------------- -c Open the test XDR file. Set it to halt on errors -c (.FALSE.), so don't bother checking error codes -c below. -c ------------------------------------------------- - print *, 'generating test XDR file test.xdr...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - -c ------------------------------------------------------ -c Put the scalar values: integer, real, double precision -c ------------------------------------------------------ - ierr = ixdrint ( ixdrs, iwrite ) - ierr = ixdrreal ( ixdrs, rwrite ) -#ifdef cray - ierr = ixdrreal64( ixdrs, dwrite ) -#else - ierr = ixdrdouble( ixdrs, dwrite ) -#endif - -c ----------------------------------------------------- -c Put the array values: integer, real, double precision -c ----------------------------------------------------- - ierr = ixdrimat ( ixdrs, ien, imatwrite ) - ierr = ixdrrmat ( ixdrs, ien*jen, fmatwrite ) -#ifdef cray - ierr = ixdrrmat64( ixdrs, ien*jen, dmatwrite ) -#else - ierr = ixdrdmat ( ixdrs, ien*jen, dmatwrite ) -#endif - - ierr = ixdrstring( ixdrs, stringwrite ) - - ierr = ixdrclose( ixdrs ) - print *, 'successfully wrote the test file test.xdr' - - call compareto( 'test.xdr' ) - call compareto( 'test.orig.xdr' ) - - print * - print *, 'Testing the rewind function...' - ixdrs = initxdr( 'test.xdr', 'r', .FALSE. ) - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) - ierr = ixdrrewind( ixdrs ) - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) - ierr = ixdrclose ( ixdrs ) - -c ------------------------------------------ -c Now check the error handling functionality -c ------------------------------------------ - print * - print *, '---------------------------------------------' - print *, 'Testing the error handling functionality ... ' - print *, 'these routine should NOT STOP!' - print *, '---------------------------------------------' - print * - -c ---------------------------------------- -c Try to open a read-only file for writing -c ---------------------------------------- - print *, 'opening a read-only file for writing...' - ixdrs = initxdr( 'test_read_only.xdr', 'w', .TRUE. ) - if( ixdrs .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to open a read only file for writing!!' - print *, 'Make SURE file test_read_only.xdr does NOT' - print *, 'have write permissions!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ---------------------------------------- -c Try to open a no-access file for reading -c ---------------------------------------- - print *, 'opening a no-access file for reading...' - ixdrs = initxdr( 'test_no_read.xdr', 'r', .TRUE. ) - if( ixdrs .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to open a no-access file for reading!!' - print *, 'Make SURE file test_no_read.xdr does NOT' - print *, 'have read permissions!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ------------------------------------------------------------- -c Write a single integer, rewind, then try to read TWO integers -c ------------------------------------------------------------- - print *, 'trying to read integer past EOF...' - ixdrs = initxdr( 'test.xdr', 'w', .TRUE. ) - ierr = ixdrint( ixdrs, iwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrint( ixdrs, iread ) - if( ierr .lt. 0 ) then - print *, 'TEST FAILED! Anomalous error returned when' - print *, 'trying to read a test integer from file' - print *, 'test.xdr!' - print *, '--------- TEST FAILED ----------' - stop - endif - ierr = ixdrint( ixdrs, iread ) - if( ierr .ne. FXDRERR_READERR ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read a test integer past the end of file!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ------------------------------------------------------- -c Write a single real, rewind, then try to read TWO reals -c ------------------------------------------------------- - print *, 'trying to read real past EOF...' - ixdrs = initxdr( 'test.xdr', 'w', .TRUE. ) - ierr = ixdrreal( ixdrs, rwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrreal( ixdrs, rread ) - if( ierr .lt. 0 ) then - print *, 'TEST FAILED! Anomalous error returned when' - print *, 'trying to read a test real from file' - print *, 'test.xdr!' - print *, '--------- TEST FAILED ----------' - stop - endif - ierr = ixdrint( ixdrs, iread ) - if( ierr .ne. FXDRERR_READERR ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read a test real past the end of file!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ----------------------------------------------------- -c Try to read wrong # of elements from an integer array -c ----------------------------------------------------- - print *,'try to read wrong # of elements from integer array...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrimat ( ixdrs, ien, imatwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrimat ( ixdrs, 2*ien, imatwrite ) - if( ierr .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read incorrect # integer elements from' - print *, 'an array!' - print *, '--------- TEST FAILED ----------' - stop - endif - -c ----------------------------------------------------- -c Try to read wrong # of elements from an real array -c ----------------------------------------------------- - print *, 'try to read wrong # of elements from a real array...' - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrrmat ( ixdrs, ien*jen, fmatwrite ) - ierr = ixdrclose( ixdrs ) - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrrmat ( ixdrs, ien, fmatwrite ) - if( ierr .ge. 0 ) then - print *, 'TEST FAILED! No error returned when trying' - print *, 'to read incorrect # real elements from an' - print *, 'array!' - print *, 'ierr=', ierr - print *, '--------- TEST FAILED ----------' - stop - endif - -c -------------------- -c Test append function -c -------------------- - print * - print *, '--------------------------' - print *, 'Testing append function...' - print *, '--------------------------' - print * -c ... make test file with single integer ... - ixdrs = initxdr( 'test.xdr', 'w', .FALSE. ) - ierr = ixdrint( ixdrs, iwrite ) - ierr = ixdrclose( ixdrs ) -c ... read back same integer ... - ixdrs = initxdr( 'test.xdr', 'r', .TRUE. ) - ierr = ixdrint( ixdrs, iread ) - if( ierr .lt. 0 ) then - print *, 'ERROR reading first int from test file!!' - print *, '-------- TEST FAILED -------' - stop - endif - call checki( iwrite, iread ) -c ... read back ANOTHER real, should fail ... - ierr = ixdrreal( ixdrs, rread ) - if( ierr .ge. 0 ) then - print *, 'ERROR: no error value returned when reading' - print *, 'past end of file!!' - print *, '-------- TEST FAILED -------' - stop - endif - ierr = ixdrclose( ixdrs ) -c ... now try to append real to this file ... - ixdrs = initxdr( 'test.xdr', 'a', .TRUE. ) - ierr = ixdrreal( ixdrs, rwrite ) - if( ierr .lt. 0 ) then - print *, 'ERROR trying to append real to test file!' - print *, '-------- TEST FAILED -------' - stop - endif - ierr = ixdrclose( ixdrs ) -c ... check to make sure appendation (?) went OK ... - ixdrs = initxdr( 'test.xdr', 'r', .FALSE. ) - ierr = ixdrint( ixdrs, iread ) - call checki( iwrite, iread ) - ierr = ixdrreal( ixdrs, rread ) - call checkr( rwrite, rread ) - ierr = ixdrclose( ixdrs ) - - print * - print *, '---------------------------------------------------' - print *, 'All tests passed successfully: precision loss was' - print *, 'never more than 1 part in 10**-10 for double' - print *, 'precision nor more than 1 part in 10**-5 for single' - print *, 'precision.' - print *, '---------------------------------------------------' - - end - -c===================================================================== - - subroutine compareto( filename ) - - character*(*) filename - - parameter(ien=3,jen=2) - - integer iread, iwrite - real*4 rread, rwrite, fmatwrite, fmatread -#ifdef cray - real dread, dwrite -#else - double precision dread, dwrite -#endif - - common /cb1/ iwrite, imatwrite - common /cb2/ rwrite, fmatwrite - common /cb3/ dwrite, dmatwrite - common /cb4/ stringwrite - - dimension imatwrite(ien), imatread(ien) - dimension fmatwrite(ien,jen), fmatread(ien,jen) -#ifdef cray - real dmatwrite(ien,jen), dmatread(ien,jen) -#else - double precision dmatwrite(ien,jen), dmatread(ien,jen) -#endif - character*26 stringwrite, stringread - - print * - print *, '--------------------------------------------' - print *, 'checking file ', filename, ' for correctness.' - print *, '--------------------------------------------' - -c ----------------------------------------- -c Open the file and try to read it back in. -c ----------------------------------------- - ixdrs = initxdr( filename, 'r', .FALSE. ) - -c ------------------------------------------------------- -c Read the scalar values: integer, real, double precision -c ------------------------------------------------------- - ierr = ixdrint ( ixdrs, iread ) - call checki ( iwrite, iread ) - ierr = ixdrreal ( ixdrs, rread ) - call checkr ( rwrite, rread ) -#ifdef cray - ierr = ixdrreal64( ixdrs, dread ) -#else - ierr = ixdrdouble( ixdrs, dread ) -#endif - call checkd ( dwrite, dread ) - -c ------------------------------------------------------ -c Read the array values: integer, real, double precision -c ------------------------------------------------------ - ierr = ixdrimat ( ixdrs, ien, imatread ) - do i=1, ien - call checki( imatwrite(i), imatread(i) ) - enddo - ierr = ixdrrmat ( ixdrs, ien*jen, fmatread ) - do j=1, jen - do i=1, ien - call checkr( fmatwrite(i,j), fmatread(i,j) ) - enddo - enddo -#ifdef cray - ierr = ixdrrmat64( ixdrs, ien*jen, dmatread ) -#else - ierr = ixdrdmat ( ixdrs, ien*jen, dmatread ) -#endif - do j=1, jen - do i=1, ien - call checkd( dmatwrite(i,j), dmatread(i,j) ) - enddo - enddo - - ierr = ixdrstring( ixdrs, stringread ) - do i=1, len(stringread) - if( stringread(i:i) .ne. stringwrite(i:i) ) then - print *, 'Error on string read! I expected: ', - & stringwrite(i:i) - print *, 'but got: ', stringread(i:i) - endif - enddo - - ierr = ixdrclose( ixdrs ) - - return - end - -c==================================================================== - - subroutine checkr( expected, got ) - - real*4 expected, got - - if( got .ne. expected ) then - diffnorm = abs((got-expected)/(.5*(got+expected))) - if( diffnorm .gt. 1.0e-5 ) then - print *, 'Fatal error! On single precision read, I got ', - & got - print *, 'but expected ', expected - print *, 'The library failed its tests--please do not use it!' - stop - else - print *, 'checking single precision...' - print *, '===> precision loss of 1 part in 10**', - & nint(log10(1.0/diffnorm)) - endif - else - print *, 'checking single precision...OK' - endif - - return - end - -c==================================================================== - - subroutine checkd( expected, got ) - -#ifdef cray - real expected, got, diffnorm -#else - double precision expected, got, diffnorm -#endif - - if( got .ne. expected ) then -#ifdef cray - diffnorm = abs((got-expected)/(.5d0*(got+expected))) -#else - diffnorm = dabs((got-expected)/(.5d0*(got+expected))) -#endif - if( diffnorm .gt. 1.0d-10 ) then - print *, 'Fatal error! On double precision read, I got ', - & got - print *, 'but expected ', expected - print *, 'The library failed its tests--please do not use it!' - stop - else - print *, 'checking double precision...' -#ifdef cray - iprecis = nint(log10(1.0/diffnorm)) -#else - iprecis = nint(dlog10(1.0/diffnorm)) -#endif - print *, '===> precision loss of 1 part in 10**', iprecis - endif - else - print *, 'checking double precision...OK' - endif - - return - end - -c==================================================================== - - subroutine checki( expected, got ) - - integer expected, got - - if( got .ne. expected ) then - print *, 'Fatal error! On integer read, I got ', got - print *, 'but expected ', expected - print *, 'The library failed its tests--' - print *, 'please do not use it!' - stop - endif - print *, 'checking integer...OK' - - return - end diff --git a/fxdr_2.1c/test.orig.xdr b/fxdr_2.1c/test.orig.xdr deleted file mode 100644 index 6f8e4f73b..000000000 Binary files a/fxdr_2.1c/test.orig.xdr and /dev/null differ diff --git a/fxdr_2.1c/test.xdr b/fxdr_2.1c/test.xdr deleted file mode 100644 index fece55ba2..000000000 Binary files a/fxdr_2.1c/test.xdr and /dev/null differ diff --git a/fxdr_2.1c/test_read_only.xdr b/fxdr_2.1c/test_read_only.xdr deleted file mode 100644 index 6f8e4f73b..000000000 Binary files a/fxdr_2.1c/test_read_only.xdr and /dev/null differ diff --git a/fxdr_2.1c/testprog.F b/fxdr_2.1c/testprog.F deleted file mode 100644 index 9f6dc036d..000000000 --- a/fxdr_2.1c/testprog.F +++ /dev/null @@ -1,31 +0,0 @@ - program testprog - -#ifdef cray - real x1, x2 -#else - double precision x1, x2 -#endif - - common /cb1/ x1, x2 - - x1 = 3.0 - x2 = 4.0 - call sub( x1, x2) - - end - -c======================================================== - - subroutine sub( x1, x2 ) - -#ifdef cray - real x1, x2 -#else - double precision x1, x2 -#endif - - print *, x1, x2 - - return - end - diff --git a/helio/helio_discard.f90 b/helio/helio_discard.f90 deleted file mode 100644 index ea189c2df..000000000 --- a/helio/helio_discard.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_discard -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! helio_tpd1P : pointer to head of discard helio test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! helio_tpd1P : pointer to head of discard helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_discard(t, npl, ntp, nsp, helio_pl1P, helio_tp1P, helio_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE helio_discard(t, npl, ntp, nsp, helio_pl1P, helio_tp1P, helio_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(helio_tp), POINTER :: helio_tpP, helio_tpspP - -! Executable code - swifter_pl1P => helio_pl1P%swifter - swifter_tp1P => helio_tp1P%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - helio_tpP => helio_tp1P - DO i = 1, ntp - helio_tpspP => helio_tpP - helio_tpP => helio_tpP%nextP - swifter_tpspP => helio_tpspP%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL helio_discard_spill(ntp, nsp, helio_tp1P, helio_tpd1P, helio_tpspP) - END DO - - RETURN - -END SUBROUTINE helio_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_discard_spill.f90 b/helio/helio_discard_spill.f90 deleted file mode 100644 index 0ca9cb9b0..000000000 --- a/helio/helio_discard_spill.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) helio test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! helio_tpd1P : pointer to head of discard helio test particle structure linked-list -! helio_tpspP : pointer to helio test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! helio_tpd1P : pointer to head of discard helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_discard_spill(ntp, nsp, helio_tp1P, helio_tpd1P, helio_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE helio_discard_spill(ntp, nsp, helio_tp1P, helio_tpd1P, helio_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpd1P, helio_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - swifter_tpspP => helio_tpspP%swifter - IF (nsp == 0) THEN - helio_tpd1P => helio_tpspP - ELSE - helio_tpP => helio_tpd1P - DO i = 1, nsp - 1 - helio_tpP => helio_tpP%nextP - END DO - helio_tpP%nextP => helio_tpspP - helio_tpP%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(helio_tpspP%prevP)) THEN - helio_tpspP%prevP%nextP => helio_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - helio_tp1P => helio_tpspP%nextP - END IF - IF (ASSOCIATED(helio_tpspP%nextP)) THEN - helio_tpspP%nextP%prevP => helio_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(helio_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - helio_tpspP%prevP => helio_tpP - swifter_tpspP%prevP => helio_tpP%swifter - END IF - NULLIFY(helio_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE helio_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_drift.f90 b/helio/helio_drift.f90 deleted file mode 100644 index 8f0862998..000000000 --- a/helio/helio_drift.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_drift -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Loop through planets and call Danby drift routine -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL helio_drift(npl, swifter_pl1P, dt) -! -! Notes : Adapted from Hal Levison's Swift routine drift.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_drift(npl, swifter_pl1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => helio_drift - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i, iflag - REAL(DP) :: mu - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - mu = swifter_pl1P%mass - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - CALL drift_one(mu, swifter_plP%xh(:), swifter_plP%vb(:), dt, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", swifter_plP%id, " is lost!!!!!!!!!!" - WRITE(*, *) mu, dt - WRITE(*, *) swifter_plP%xh(:) - WRITE(*, *) swifter_plP%vb(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - END DO - - RETURN - -END SUBROUTINE helio_drift -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_drift_tp.f90 b/helio/helio_drift_tp.f90 deleted file mode 100644 index 7f39e2fd7..000000000 --- a/helio/helio_drift_tp.f90 +++ /dev/null @@ -1,77 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_drift_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Loop through test particles and call Danby drift routine -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL helio_drift_tp(ntp, swifter_tp1P, mu, dt) -! -! Notes : Adapted from Hal Levison's Swift routine drift_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_drift_tp(ntp, swifter_tp1P, mu, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => helio_drift_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i, iflag - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - CALL drift_one(mu, swifter_tpP%xh(:), swifter_tpP%vb(:), dt, iflag) - IF (iflag /= 0) THEN - swifter_tpP%status = DISCARDED_DRIFTERR - WRITE(*, *) "Particle ", swifter_tpP%id, " lost due to error in Danby drift" - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE helio_drift_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_getacch.f90 b/helio/helio_getacch.f90 deleted file mode 100644 index f484058a9..000000000 --- a/helio/helio_getacch.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of planets -! -! Input -! Arguments : lflag : logical flag indicating whether to recompute direct cross term accelerations -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_getacch(lflag, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine helio_getacch.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_getacch(lflag, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_getacch - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(helio_pl), POINTER :: helio_plP - -! Executable code - IF (lflag) THEN - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ahi(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - CALL helio_getacch_int(npl, helio_pl1P) - END IF - IF (j2rp2 /= 0.0_DP) THEN - swifter_pl1P => helio_pl1P%swifter - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xh(:, i) = swifter_plP%xh(:) - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ah(:) = helio_plP%ahi(:) + aobl(:, i) - aobl(:, 1) - END DO - ELSE - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ah(:) = helio_plP%ahi(:) - END DO - END IF - IF (lextra_force) CALL helio_user_getacch(t, npl, helio_pl1P) - - RETURN - -END SUBROUTINE helio_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_getacch_int.f90 b/helio/helio_getacch_int.f90 deleted file mode 100644 index 654825b11..000000000 --- a/helio/helio_getacch_int.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_getacch_int -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Compute direct cross term heliocentric accelerations of planets -! -! Input -! Arguments : npl : number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_getacch_int(npl, helio_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah3.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_getacch_int(npl, helio_pl1P) - -! Modules - USE module_parameters - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_getacch_int - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, faci, facj - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(helio_pl), POINTER :: helio_pliP, helio_pljP - -! Executable code - helio_pliP => helio_pl1P - DO i = 2, npl - 1 - helio_pliP => helio_pliP%nextP - helio_pljP => helio_pliP - DO j = i + 1, npl - helio_pljP => helio_pljP%nextP - dx(:) = helio_pljP%swifter%xh(:) - helio_pliP%swifter%xh(:) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - faci = helio_pliP%swifter%mass*irij3 - facj = helio_pljP%swifter%mass*irij3 - helio_pliP%ahi(:) = helio_pliP%ahi(:) + facj*dx(:) - helio_pljP%ahi(:) = helio_pljP%ahi(:) - faci*dx(:) - END DO - END DO - - RETURN - -END SUBROUTINE helio_getacch_int -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_getacch_int_tp.f90 b/helio/helio_getacch_int_tp.f90 deleted file mode 100644 index eae4181f5..000000000 --- a/helio/helio_getacch_int_tp.f90 +++ /dev/null @@ -1,90 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_getacch_int_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Compute direct cross term heliocentric accelerations of test particles -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! xh : heliocentric planet positions -! Terminal : none -! File : none -! -! Output -! Arguments : helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_getacch_int_tp(npl, ntp, swifter_pl1P, helio_tp1P, xh) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah3_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_getacch_int_tp(npl, ntp, swifter_pl1P, helio_tp1P, xh) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_getacch_int_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: r2, fac - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - helio_tpP => helio_tp1P - DO i = 1, ntp - swifter_tpP => helio_tpP%swifter - IF (swifter_tpP%status == ACTIVE) THEN - swifter_plP => swifter_pl1P - DO j = 2, npl - swifter_plP => swifter_plP%nextP - dx(:) = swifter_tpP%xh(:) - swifter_plP%xh(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = swifter_plP%mass/(r2*SQRT(r2)) - helio_tpP%ahi(:) = helio_tpP%ahi(:) - fac*dx(:) - END DO - END IF - helio_tpP => helio_tpP%nextP - END DO - - RETURN - -END SUBROUTINE helio_getacch_int_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_getacch_tp.f90 b/helio/helio_getacch_tp.f90 deleted file mode 100644 index 83e6244fe..000000000 --- a/helio/helio_getacch_tp.f90 +++ /dev/null @@ -1,127 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of test particles -! -! Input -! Arguments : lflag : logical flag indicating whether to recompute direct cross term accelerations -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! xh : heliocentric positions of planets at time t -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_getacch_tp(lflag, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, xh, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine helio_getacch_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_getacch_tp(lflag, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, xh, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_getacch_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh, irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: aobl, xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - swifter_pl1P => helio_pl1P%swifter - IF (lflag) THEN - helio_tpP => helio_tp1P - DO i = 1, ntp - helio_tpP%ahi(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - helio_tpP => helio_tpP%nextP - END DO - CALL helio_getacch_int_tp(npl, ntp, swifter_pl1P, helio_tp1P, xh) - END IF - IF (j2rp2 /= 0.0_DP) THEN - IF (lmalloc) THEN - ALLOCATE(aobl(NDIM, nplmax), irh(nplmax), xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - DO i = 2, npl - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - mu = swifter_pl1P%mass - swifter_tpP => helio_tp1P%swifter - DO i = 1, ntp - xht(:, i) = swifter_tpP%xh(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - swifter_tpP => swifter_tpP%nextP - END DO - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - helio_tpP => helio_tp1P - DO i = 1, ntp - helio_tpP%ah(:) = helio_tpP%ahi(:) + aoblt(:, i) - aobl(:, 1) - helio_tpP => helio_tpP%nextP - END DO - ELSE - helio_tpP => helio_tp1P - DO i = 1, ntp - helio_tpP%ah(:) = helio_tpP%ahi(:) - helio_tpP => helio_tpP%nextP - END DO - END IF - IF (lextra_force) CALL helio_user_getacch_tp(t, ntp, helio_tp1P) - - RETURN - -END SUBROUTINE helio_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_kickvb.f90 b/helio/helio_kickvb.f90 deleted file mode 100644 index 874452358..000000000 --- a/helio/helio_kickvb.f90 +++ /dev/null @@ -1,86 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_kickvb -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Kick barycentric velocities of planets -! -! Input -! Arguments : npl : number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_kickvb(npl, helio_pl1P, dt) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine kickvh.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_kickvb(npl, helio_pl1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_kickvb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(helio_pl), POINTER :: helio_plP - -! Executable code - !Removed by D. Minton - !helio_plP => helio_pl1P - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,helio_plP,swifter_plP) & - !$OMP SHARED(npl,helio_pl1P,dt) - DO i = 2, npl - !Removed by D. Minton - !helio_plP => helio_plP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - helio_plP => helio_pl1P%helio_plPA(i)%thisP - swifter_plP => helio_plP%swifter - swifter_plP%vb(:) = swifter_plP%vb(:) + helio_plP%ah(:)*dt - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE helio_kickvb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_kickvb_tp.f90 b/helio/helio_kickvb_tp.f90 deleted file mode 100644 index 878a8bb9e..000000000 --- a/helio/helio_kickvb_tp.f90 +++ /dev/null @@ -1,75 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_kickvb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Kick barycentric velocities of active test particles -! -! Input -! Arguments : ntp : number of active test particles -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_kickvb_tp(ntp, helio_tp1P, dt) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine kickvh_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_kickvb_tp(ntp, helio_tp1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_kickvb_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - helio_tpP => helio_tp1P - DO i = 1, ntp - swifter_tpP => helio_tpP%swifter - IF (swifter_tpP%status == ACTIVE) swifter_tpP%vb(:) = swifter_tpP%vb(:) + helio_tpP%ah(:)*dt - helio_tpP => helio_tpP%nextP - END DO - - RETURN - -END SUBROUTINE helio_kickvb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_lindrift.f90 b/helio/helio_lindrift.f90 deleted file mode 100644 index b49004489..000000000 --- a/helio/helio_lindrift.f90 +++ /dev/null @@ -1,120 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_lindrift -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Perform linear drift of planets due to barycentric momentum of Sun -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! pt : negative barycentric velocity of the Sun -! Terminal : none -! File : none -! -! Invocation : CALL helio_lindrift(npl, swifter_pl1P, dt, pt) -! -! Notes : Adapted from Hal Levison's Swift routine helio_lindrift.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_lindrift(npl, swifter_pl1P, dt, pt) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => helio_lindrift - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: pt - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - -! Added by D. Minton - REAL(DP) :: ptx,pty,ptz - REAL(DP),DIMENSION(NDIM) :: pttmp !INTENT(OUT) variables don't play nicely - !with OpenMP's reduction for some reason - -! Executable code - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - pttmp(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P) & - !$OMP REDUCTION(+:pttmp) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !pt(:) = pt(:) + swifter_plP%mass*swifter_plP%vb(:) - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - pttmp(:) = pttmp(:) + swifter_plP%mass*swifter_plP%vb(:) - !^^^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - !Removed by D. Minton - !pt(:) = pt(:)/swifter_pl1P%mass - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - pttmp(:) = pttmp(:)/swifter_pl1P%mass - !^^^^^^^^^^^^^^^^^^ - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P,pttmp,dt) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !swifter_plP%xh(:) = swifter_plP%xh(:) + pt(:)*dt - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - swifter_plP%xh(:) = swifter_plP%xh(:) + pttmp(:)*dt - !^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - - !Added by D. Minton - pt(:)=pttmp(:) - !^^^^^^^^^^^^^^^^^^ - - RETURN - -END SUBROUTINE helio_lindrift -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_lindrift_tp.f90 b/helio/helio_lindrift_tp.f90 deleted file mode 100644 index ff5e97542..000000000 --- a/helio/helio_lindrift_tp.f90 +++ /dev/null @@ -1,74 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_lindrift_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Perform linear drift of test particles due to barycentric momentum of Sun -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! dt : time step -! pt : negative barycentric velocity of the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_lindrift_tp(ntp, swifter_tp1P, dt, pt) -! -! Notes : Adapted from Hal Levison's Swift routine helio_lindrift_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_lindrift_tp(ntp, swifter_tp1P, dt, pt) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => helio_lindrift_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: pt - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) swifter_tpP%xh(:) = swifter_tpP%xh(:) + pt(:)*dt - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE helio_lindrift_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_setup.f90 b/helio/helio_setup.f90 deleted file mode 100644 index 9b528cfba..000000000 --- a/helio/helio_setup.f90 +++ /dev/null @@ -1,133 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_setup -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Set up pointers within helio and Swifter planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! helio_plA : helio planet structure array -! helio_tpA : helio test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : helio_plA : helio planet structure array -! helio_tpA : helio test particle structure array -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_setup(npl, ntp, helio_plA, helio_tpA, helio_pl1P, helio_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE helio_setup(npl, ntp, helio_plA, helio_tpA, helio_pl1P, helio_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(helio_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: helio_plA - TYPE(helio_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: helio_tpA - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_pl), POINTER :: helio_plP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - helio_pl1P => helio_plA(1) - swifter_pl1P => helio_plA(1)%swifter - NULLIFY(helio_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(helio_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - helio_pl1P%nextP => helio_plA(2) - swifter_pl1P%nextP => helio_plA(2)%swifter - DO i = 2, npl - 1 - helio_plA(i)%prevP => helio_plA(i-1) - helio_plA(i)%nextP => helio_plA(i+1) - swifter_plP => helio_plA(i)%swifter - swifter_plP%prevP => helio_plA(i-1)%swifter - swifter_plP%nextP => helio_plA(i+1)%swifter - END DO - helio_plA(npl)%prevP => helio_plA(npl-1) - helio_plP => helio_plA(npl) - NULLIFY(helio_plP%nextP) - swifter_plP => helio_plA(npl)%swifter - swifter_plP%prevP => helio_plA(npl-1)%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(helio_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - helio_tp1P => helio_tpA(1) - swifter_tp1P => helio_tpA(1)%swifter - NULLIFY(helio_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(helio_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - helio_tp1P%nextP => helio_tpA(2) - swifter_tp1P%nextP => helio_tpA(2)%swifter - DO i = 2, ntp - 1 - helio_tpA(i)%prevP => helio_tpA(i-1) - helio_tpA(i)%nextP => helio_tpA(i+1) - swifter_tpP => helio_tpA(i)%swifter - swifter_tpP%prevP => helio_tpA(i-1)%swifter - swifter_tpP%nextP => helio_tpA(i+1)%swifter - END DO - helio_tpA(ntp)%prevP => helio_tpA(ntp-1) - helio_tpP => helio_tpA(ntp) - NULLIFY(helio_tpP%nextP) - swifter_tpP => helio_tpA(ntp)%swifter - swifter_tpP%prevP => helio_tpA(ntp-1)%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE helio_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_step.f90 b/helio/helio_step.f90 deleted file mode 100644 index 84e17cece..000000000 --- a/helio/helio_step.f90 +++ /dev/null @@ -1,91 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_step -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! helio_pl1P : pointer to head of WHM planet structure linked-list -! helio_tp1P : pointer to head of active WHM test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! helio_pl1P : pointer to head of WHM planet structure linked-list -! helio_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine helio_step.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - REAL(DP), DIMENSION(NDIM) :: ptb, pte - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, xend - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - lfirsttp = lfirst - CALL helio_step_pl(lfirst, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) - IF (ntp > 0) CALL helio_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, & - dt, xbeg, xend, ptb, pte) - - RETURN - -END SUBROUTINE helio_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_step_pl.f90 b/helio/helio_step_pl.f90 deleted file mode 100644 index 971ff8db5..000000000 --- a/helio/helio_step_pl.f90 +++ /dev/null @@ -1,111 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_step_pl -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Step planets ahead Democratic Heliocentric method -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! helio_pl1P : pointer to head of helio planet structure linked-list -! xbeg : heliocentric planet positions at beginning of time step -! xend : heliocentric planet positions at end of time step -! ptb : negative barycentric velocity of the Sun at beginning of time step -! pte : negative barycentric velocity of the Sun at end of time step -! Terminal : none -! File : none -! -! Invocation : CALL helio_step_pl(lfirst, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) -! -! Notes : Adapted from Hal Levison's Swift routine helio_step_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_step_pl(lfirst, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_step_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: ptb, pte - REAL(DP), DIMENSION(NDIM, npl), INTENT(OUT) :: xbeg, xend - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - LOGICAL(LGT) :: lflag - INTEGER(I4B) :: i - REAL(DP) :: dth, msys - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - -! Executable code - dth = 0.5_DP*dt - lflag = lfirst - swifter_pl1P => helio_pl1P%swifter - IF (lfirst) THEN - CALL coord_vh2vb(npl, swifter_pl1P, msys) - lfirst = .FALSE. - END IF - CALL helio_lindrift(npl, swifter_pl1P, dth, ptb) - CALL helio_getacch(lflag, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4) - lflag = .TRUE. - CALL helio_kickvb(npl, helio_pl1P, dth) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xbeg(:, i) = swifter_plP%xh(:) - END DO - CALL helio_drift(npl, swifter_pl1P, dt) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xend(:, i) = swifter_plP%xh(:) - END DO - CALL helio_getacch(lflag, lextra_force, t+dt, npl, nplmax, helio_pl1P, j2rp2, j4rp4) - CALL helio_kickvb(npl, helio_pl1P, dth) - CALL helio_lindrift(npl, swifter_pl1P, dth, pte) - CALL coord_vb2vh(npl, swifter_pl1P) - - RETURN - -END SUBROUTINE helio_step_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_step_tp.f90 b/helio/helio_step_tp.f90 deleted file mode 100644 index 20dc2ef40..000000000 --- a/helio/helio_step_tp.f90 +++ /dev/null @@ -1,107 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_step_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Step active test particles ahead using Democratic Heliocentric method -! -! Input -! Arguments : lfirsttp : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! xbeg : heliocentric planet positions at beginning of time step -! xend : heliocentric planet positions at end of time step -! ptb : negative barycentric velocity of the Sun at beginning of time step -! pte : negative barycentric velocity of the Sun at end of time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirsttp : logical flag indicating whether current invocation is the first -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL helio_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt, -! xbeg, xend, ptb, pte) -! -! Notes : Adapted from Hal Levison's Swift routine helio_step_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE helio_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt, xbeg, & - xend, ptb, pte) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_step_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirsttp - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: ptb, pte - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xbeg, xend - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - LOGICAL(LGT) :: lflag - REAL(DP) :: dth, mu - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Executable code - dth = 0.5_DP*dt - lflag = lfirsttp - mu = helio_pl1P%swifter%mass - swifter_tp1P => helio_tp1P%swifter - IF (lfirsttp) THEN - CALL coord_vh2vb_tp(ntp, swifter_tp1P, -ptb) - lfirsttp = .FALSE. - END IF - CALL helio_lindrift_tp(ntp, swifter_tp1P, dth, ptb) - CALL helio_getacch_tp(lflag, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, xbeg, j2rp2, j4rp4) - lflag = .TRUE. - CALL helio_kickvb_tp(ntp, helio_tp1P, dth) - CALL helio_drift_tp(ntp, swifter_tp1P, mu, dt) - CALL helio_getacch_tp(lflag, lextra_force, t+dt, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, xend, j2rp2, j4rp4) - CALL helio_kickvb_tp(ntp, helio_tp1P, dth) - CALL helio_lindrift_tp(ntp, swifter_tp1P, dth, pte) - CALL coord_vb2vh_tp(ntp, swifter_tp1P, -pte) - - RETURN - -END SUBROUTINE helio_step_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_user_getacch.f90 b/helio/helio_user_getacch.f90 deleted file mode 100644 index 10e9f3bce..000000000 --- a/helio/helio_user_getacch.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_user_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL helio_user_getacch(t, npl, helio_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE helio_user_getacch(t, npl, helio_pl1P) - -! Modules - USE module_parameters - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_user_getacch - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE helio_user_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/helio/helio_user_getacch_tp.f90 b/helio/helio_user_getacch_tp.f90 deleted file mode 100644 index c8e1de762..000000000 --- a/helio/helio_user_getacch_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : helio_user_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : helio -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : helio_tp1P : pointer to head of active helio test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL helio_user_getacch_tp(t, ntp, helio_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE helio_user_getacch_tp(t, ntp, helio_tp1P) - -! Modules - USE module_parameters - USE module_helio - USE module_interfaces, EXCEPT_THIS_ONE => helio_user_getacch_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE helio_user_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_discard_write.f90 b/io/io_discard_write.f90 deleted file mode 100644 index 094d6baf3..000000000 --- a/io/io_discard_write.f90 +++ /dev/null @@ -1,109 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_discard_write -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write out information about discarded test particles -! -! Input -! Arguments : t : time -! npl : number of planets -! nsp : number of spilled test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tpd1P : pointer to head of discard Swifter test particle structure linked-list -! fname : name of file to write -! lbig_discard : logical flag indicating whether to dump planet data with discards -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : discard data to discard file -! -! Invocation : CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, fname, lbig_discard) -! -! Notes : Adapted from Hal Levison's Swift routine io_discard_write.f -! -!********************************************************************************************************************************** -SUBROUTINE io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, fname, lbig_discard) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => io_discard_write - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lbig_discard - INTEGER(I4B), INTENT(IN) :: npl, nsp - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: fname - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tpd1P - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 40 - INTEGER(I4B) :: i, ierr - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - CALL io_open(LUN, fname, "APPEND", "FORMATTED", ierr) - IF (ierr /= 0) THEN - CALL io_open(LUN, fname, "NEW", "FORMATTED", ierr) - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open discard output file, ", fname - CALL util_exit(FAILURE) - END IF - END IF - WRITE(LUN, 100) t, nsp, lbig_discard - 100 FORMAT(E23.16, 1X, I8, 1X, L1) - swifter_tpP => swifter_tpd1P - DO i = 1, nsp - WRITE(LUN, 200) SUB, swifter_tpP%id, swifter_tpP%status - 200 FORMAT(A, 2(1X, I8)) - WRITE(LUN, 300) swifter_tpP%xh(:) - 300 FORMAT(3(E23.16, 1X)) - WRITE(LUN, 300) swifter_tpP%vh(:) - swifter_tpP => swifter_tpP%nextP - END DO - IF (lbig_discard) THEN - WRITE(LUN, 400) npl - 400 FORMAT(I8) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - WRITE(LUN, 500) swifter_plP%id, swifter_plP%mass, swifter_plP%radius - 500 FORMAT(I8, 2(1X, E23.16)) - WRITE(LUN, 300) swifter_plP%xh(:) - WRITE(LUN, 300) swifter_plP%vh(:) - END DO - END IF - CLOSE(LUN) - - RETURN - -END SUBROUTINE io_discard_write -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_discard_write_symba.f90 b/io/io_discard_write_symba.f90 deleted file mode 100644 index 1659166f9..000000000 --- a/io/io_discard_write_symba.f90 +++ /dev/null @@ -1,155 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_discard_write_symba -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write out information about discarded and merged planets and test particles in SyMBA -! -! Input -! Arguments : t : time -! mtiny : smallest self-gravitating mass -! npl : number of planets -! nsppl : number of spilled planets -! nsptp : number of spilled test particles -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! symba_tpd1P : pointer to head of discard SyMBA test particle structure linked-list -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! fname : name of file to write -! lbig_discard : logical flag indicating whether to dump planet data with discards -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : discard data to discard file -! -! Invocation : CALL io_discard_write_symba(t, mtiny, npl, nsppl, nsptp, nmergeadd, nmergesub, symba_pl1P, symba_pld1P, -! symba_tpd1P, mergeadd_list, mergesub_list, fname, lbig_discard) -! -! Notes : Adapted from Hal Levison's Swift routine io_discard_mass.f and io_discard_merge.f -! -!********************************************************************************************************************************** -SUBROUTINE io_discard_write_symba(t, mtiny, npl, nsppl, nsptp, nmergeadd, nmergesub, symba_pl1P, symba_pld1P, symba_tpd1P, & - mergeadd_list, mergesub_list, fname, lbig_discard) - -! Modules - USE module_parameters - USE module_swifter - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => io_discard_write_symba - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lbig_discard - INTEGER(I4B), INTENT(IN) :: npl, nsppl, nsptp, nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, mtiny - CHARACTER(*), INTENT(IN) :: fname - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - TYPE(symba_tp), POINTER :: symba_tpd1P - TYPE(symba_merger), DIMENSION(:), INTENT(IN) :: mergeadd_list, mergesub_list - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 40 - INTEGER(I4B) :: i, index, j, ncomp, ierr, nplm - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(symba_pl), POINTER :: symba_plP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - CALL io_open(LUN, fname, "APPEND", "FORMATTED", ierr) - IF (ierr /= 0) THEN - CALL io_open(LUN, fname, "NEW", "FORMATTED", ierr) - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open discard output file, ", fname - CALL util_exit(FAILURE) - END IF - END IF - WRITE(LUN, 100) t, nsppl + 2*nmergeadd + nsptp, lbig_discard - 100 FORMAT(E23.16, 1X, I8, 1X, L1) - index = 0 - DO i = 1, nmergeadd - WRITE(LUN, 200) ADD, mergeadd_list(i)%id, mergeadd_list(i)%status - 200 FORMAT(A, 2(1X, I8)) - WRITE(LUN, 300) mergeadd_list(i)%xh(:) - 300 FORMAT(3(E23.16, 1X)) - WRITE(LUN, 300) mergeadd_list(i)%vh(:) - ncomp = mergeadd_list(i)%ncomp - DO j = 1, ncomp - index = index + 1 - WRITE(LUN, 200) SUB, mergesub_list(index)%id, mergesub_list(index)%status - WRITE(LUN, 300) mergesub_list(index)%xh(:) - WRITE(LUN, 300) mergesub_list(index)%vh(:) - END DO - END DO - symba_plP => symba_pld1P - DO i = 1, nsppl - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status /= MERGED) THEN - WRITE(LUN, 200) SUB, swifter_plP%id, swifter_plP%status - WRITE(LUN, 300) swifter_plP%xh(:) - WRITE(LUN, 300) swifter_plP%vh(:) - END IF - symba_plP => symba_plP%nextP - END DO - symba_tpP => symba_tpd1P - DO i = 1, nsptp - swifter_tpP => symba_tpP%helio%swifter - WRITE(LUN, 200) SUB, swifter_tpP%id, swifter_tpP%status - WRITE(LUN, 300) swifter_tpP%xh(:) - WRITE(LUN, 300) swifter_tpP%vh(:) - symba_tpP => symba_tpP%nextP - END DO - IF (lbig_discard) THEN - nplm = 0 - swifter_plP => symba_pl1P%helio%swifter - DO i = 1, npl - IF (swifter_plP%mass < mtiny) EXIT - nplm = nplm + 1 - swifter_plP => swifter_plP%nextP - END DO - IF (nplm > 1) THEN - WRITE(LUN, 400) nplm - 400 FORMAT(I8) - swifter_plP => symba_pl1P%helio%swifter - DO i = 2, nplm - swifter_plP => swifter_plP%nextP - WRITE(LUN, 500) swifter_plP%id, swifter_plP%mass, swifter_plP%radius - 500 FORMAT(I8, 2(1X, E23.16)) - WRITE(LUN, 300) swifter_plP%xh(:) - WRITE(LUN, 300) swifter_plP%vh(:) - END DO - END IF - END IF - CLOSE(LUN) - - RETURN - -END SUBROUTINE io_discard_write_symba -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_dump_param.f90 b/io/io_dump_param.f90 deleted file mode 100644 index 14353cc2e..000000000 --- a/io/io_dump_param.f90 +++ /dev/null @@ -1,205 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_dump_param -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Dump integration parameters to file -! -! Input -! Arguments : nplmax : maximum allowed number of planets -! ntpmax : maximum allowed number of test particles -! ntp : number of active test particles -! t : time -! tstop : integration stop time -! dt : time step -! in_type : format of input data files -! istep_out : number of time steps between binary outputs -! outfile : name of output binary file -! out_type : binary format of output file -! out_form : data to write to output file -! istep_dump : number of time steps between dumps -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! lclose : logical flag indicating whether to check for planet-test particle encounters -! rmin : minimum heliocentric radius for test particle -! rmax : maximum heliocentric radius for test particle -! rmaxu : maximum unbound heliocentric radius for test particle -! qmin : minimum pericenter distance for test particle -! qmin_coord : coordinate frame to use for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! encounter_file : name of output file for encounters -! lextra_force : logical flag indicating whether to use user-supplied accelerations -! lbig_discard : logical flag indicating whether to dump planet data with discards -! lrhill_present : logical flag indicating whether Hill's sphere radii are present in planet data -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : none -! File : (same quantities listed above as input from argument are dumped to file, with the following exceptions) -! ntp : number of active test particles (NOT WRITTEN) -! inplfile : name of corresponding planet data dump file (WRITTEN) -! intpfile : name of corresponding test particle data dump file (WRITTEN) -! out_stat : open status for output binary file (WRITTEN) -! -! Invocation : CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, -! istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, -! encounter_file, lextra_force, lbig_discard, lrhill_present) -! -! Notes : Adapted from Martin Duncan's Swift routine io_dump_param.f -! -!********************************************************************************************************************************** -SUBROUTINE io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => io_dump_param - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lextra_force, lbig_discard, lrhill_present - INTEGER(I4B), INTENT(IN) :: nplmax, ntpmax, ntp, istep_out, istep_dump - REAL(DP), INTENT(IN) :: t, tstop, dt, j2rp2, j4rp4, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord, encounter_file, in_type, outfile, out_type, out_form - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 7 - INTEGER(I4B) :: ierr - INTEGER(I4B), SAVE :: idx = 1 - -! Executable code - - CALL io_open(LUN, DUMP_PARAM_FILE(idx), "REPLACE", "FORMATTED", ierr) - 100 FORMAT(A20) - WRITE(LUN, 100, ADVANCE = "NO") "NPLMAX " - WRITE(LUN, *) nplmax - WRITE(LUN, 100, ADVANCE = "NO") "NTPMAX " - WRITE(LUN, *) ntpmax - WRITE(LUN, 100, ADVANCE = "NO") "T0 " - WRITE(LUN, *) t - WRITE(LUN, 100, ADVANCE = "NO") "TSTOP " - WRITE(LUN, *) tstop - WRITE(LUN, 100, ADVANCE = "NO") "DT " - WRITE(LUN, *) dt - WRITE(LUN, 100, ADVANCE = "NO") "PL_IN " - WRITE(LUN, *) TRIM(DUMP_PL_FILE(idx)) - IF (ntp > 0) THEN - WRITE(LUN, 100, ADVANCE = "NO") "TP_IN " - WRITE(LUN, *) TRIM(DUMP_TP_FILE(idx)) - ELSE - WRITE(LUN, 100) "!TP_IN " - END IF - WRITE(LUN, 100, ADVANCE = "NO") "IN_TYPE " - WRITE(LUN, *) XDR8_TYPE - IF (istep_out > 0) THEN - WRITE(LUN, 100, ADVANCE = "NO") "ISTEP_OUT " - WRITE(LUN, *) istep_out - WRITE(LUN, 100, ADVANCE = "NO") "BIN_OUT " - WRITE(LUN, *) TRIM(outfile) - WRITE(LUN, 100, ADVANCE = "NO") "OUT_TYPE " - WRITE(LUN, *) TRIM(out_type) - WRITE(LUN, 100, ADVANCE = "NO") "OUT_FORM " - WRITE(LUN, *) TRIM(out_form) - WRITE(LUN, 100, ADVANCE = "NO") "OUT_STAT " - WRITE(LUN, *) "APPEND" - ELSE - WRITE(LUN, 100) "!ISTEP_OUT " - WRITE(LUN, 100) "!BIN_OUT " - WRITE(LUN, 100) "!OUT_TYPE " - WRITE(LUN, 100) "!OUT_FORM " - WRITE(LUN, 100) "!OUT_STAT " - END IF - IF (istep_dump > 0) THEN - WRITE(LUN, 100, ADVANCE = "NO") "ISTEP_DUMP " - WRITE(LUN, *) istep_dump - ELSE - WRITE(LUN, 100) "!ISTEP_DUMP " - END IF - IF (j2rp2 /= 0.0_DP) THEN - WRITE(LUN, 100, ADVANCE = "NO") "J2 " - WRITE(LUN, *) j2rp2 - IF (j4rp4 /= 0.0_DP) THEN - WRITE(LUN, 100, ADVANCE= "NO") "J4 " - WRITE(LUN, *) j4rp4 - ELSE - WRITE(LUN, 100) "!J4 " - END IF - ELSE - WRITE(LUN, 100) "!J2 " - WRITE(LUN, 100) "!J4 " - END IF - WRITE(LUN, 100, ADVANCE = "NO") "CHK_CLOSE " - IF (lclose) THEN - WRITE(LUN, *) "YES" - ELSE - WRITE(LUN, *) "NO" - END IF - WRITE(LUN, 100, ADVANCE = "NO") "CHK_RMIN " - WRITE(LUN, *) rmin - WRITE(LUN, 100, ADVANCE = "NO") "CHK_RMAX " - WRITE(LUN, *) rmax - WRITE(LUN, 100, ADVANCE = "NO") "CHK_EJECT " - WRITE(LUN, *) rmaxu - WRITE(LUN, 100, ADVANCE = "NO") "CHK_QMIN " - WRITE(LUN, *) qmin - IF (qmin >= 0.0_DP) THEN - WRITE(LUN, 100, ADVANCE = "NO") "CHK_QMIN_COORD " - WRITE(LUN, *) TRIM(qmin_coord) - WRITE(LUN, 100, ADVANCE = "NO") "CHK_QMIN_RANGE " - WRITE(LUN, *) qmin_alo, qmin_ahi - ELSE - WRITE(LUN, 100) "!CHK_QMIN_COORD " - WRITE(LUN, 100) "!CHK_QMIN_RANGE " - END IF - WRITE(LUN, 100, ADVANCE = "NO") "ENC_OUT " - WRITE(LUN, *) TRIM(encounter_file) - WRITE(LUN, 100, ADVANCE = "NO") "EXTRA_FORCE " - IF (lextra_force) THEN - WRITE(LUN, *) "YES" - ELSE - WRITE(LUN, *) "NO" - END IF - WRITE(LUN, 100, ADVANCE = "NO") "BIG_DISCARD " - IF (lbig_discard) THEN - WRITE(LUN, *) "YES" - ELSE - WRITE(LUN, *) "NO" - END IF - WRITE(LUN, 100, ADVANCE = "NO") "RHILL_PRESENT " - IF (lrhill_present) THEN - WRITE(LUN, *) "YES" - ELSE - WRITE(LUN, *) "NO" - END IF - CLOSE(UNIT = LUN) - idx = idx + 1 - IF (idx > 2) idx = 1 - - RETURN - -END SUBROUTINE io_dump_param -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_dump_pl.f90 b/io/io_dump_pl.f90 deleted file mode 100644 index 9f1e8e911..000000000 --- a/io/io_dump_pl.f90 +++ /dev/null @@ -1,101 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_dump_pl -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Dump planet data to file -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! lclose : logical flag indicating whether to check for planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill's sphere radii are present in planet data -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : to dump file -! npl : number of planets -! id : planet identifier (from planet structure, for each planet) -! mass : mass (from planet structure, for each planet) -! rhill : Hill's sphere radius (from planet structure, for each planet except the Sun, if lrhill_present) -! radius : planet radius (from planet structure, for each planet except the Sun, if lclose) -! xh : heliocentric position (from planet structure, for each planet) -! vh : heliocentric velocity (from planet structure, for each planet) -! -! Invocation : CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) -! -! Notes : Adapted from Martin Duncan's Swift routine io_dump_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_dump_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i, iu, ierr - INTEGER(I4B), SAVE :: idx = 1 - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - CALL io_open_fxdr(DUMP_PL_FILE(idx), "W", .TRUE., iu, ierr) - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary dump file ", TRIM(DUMP_PL_FILE(idx)) - CALL util_exit(FAILURE) - END IF - ierr = ixdrint(iu, npl) - ierr = ixdrint(iu, swifter_pl1P%id) - ierr = ixdrdouble(iu, swifter_pl1P%mass) - ierr = ixdrdmat(iu, NDIM, swifter_pl1P%xh) - ierr = ixdrdmat(iu, NDIM, swifter_pl1P%vh) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - ierr = ixdrint(iu, swifter_plP%id) - ierr = ixdrdouble(iu, swifter_plP%mass) - IF (lrhill_present) ierr = ixdrdouble(iu, swifter_plP%rhill) - IF (lclose) ierr = ixdrdouble(iu, swifter_plP%radius) - ierr = ixdrdmat(iu, NDIM, swifter_plP%xh) - ierr = ixdrdmat(iu, NDIM, swifter_plP%vh) - END DO - ierr = ixdrclose(iu) - idx = idx + 1 - IF (idx > 2) idx = 1 - - RETURN - -END SUBROUTINE io_dump_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_dump_tp.f90 b/io/io_dump_tp.f90 deleted file mode 100644 index 289c7af10..000000000 --- a/io/io_dump_tp.f90 +++ /dev/null @@ -1,88 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_dump_tp -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Dump test particle data to file -! -! Input -! Arguments : ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : to dump file -! ntp : number of active test particles -! id : test particle identifier (from test particle structure, for each test particle) -! xh : heliocentric position (from test particle structure, for each test particle) -! vh : heliocentric velocity (from test particle structure, for each test particle) -! -! Invocation : CALL io_dump_tp(ntp, swifter_tp1P) -! -! Notes : Adapted from Martin Duncan's Swift routine io_dump_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE io_dump_tp(ntp, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_dump_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i, iu, ierr - INTEGER(I4B), SAVE :: idx = 1 - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - CALL io_open_fxdr(DUMP_TP_FILE(idx), "W", .TRUE., iu, ierr) - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary dump file ", TRIM(DUMP_TP_FILE(idx)) - CALL util_exit(FAILURE) - END IF - ierr = ixdrint(iu, ntp) - swifter_tpP => swifter_tp1P - DO i = 1, ntp - ierr = ixdrint(iu, swifter_tpP%id) - ierr = ixdrdmat(iu, NDIM, swifter_tpP%xh) - ierr = ixdrdmat(iu, NDIM, swifter_tpP%vh) - swifter_tpP => swifter_tpP%nextP - END DO - ierr = ixdrclose(iu) - idx = idx + 1 - IF (idx > 2) idx = 1 - - RETURN - -END SUBROUTINE io_dump_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_get_token.f90 b/io/io_get_token.f90 deleted file mode 100644 index 7dabb00aa..000000000 --- a/io/io_get_token.f90 +++ /dev/null @@ -1,89 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_get_token -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Return the next token from a character buffer -! -! Input -! Arguments : buffer : input character buffer -! ilength : buffer length -! ifirst : index in character buffer to begin token search -! Terminal : none -! File : none -! -! Output -! Arguments : ifirst : index in character buffer to begin token search (returned as index of first character of found token) -! ilast : index in character buffer of last character of token -! ierr : error status (0 = OK, -1 = NO TOKEN FOUND) -! Terminal : none -! File : none -! -! Invocation : CALL io_get_token(buffer, ilength, ifirst, ilast, ierr) -! -! Notes : Here a token is defined as any set of contiguous non-blank characters not beginning with or containing "!" -! If "!" is present, any remaining part of the buffer including the "!" is ignored -! -!********************************************************************************************************************************** -SUBROUTINE io_get_token(buffer, ilength, ifirst, ilast, ierr) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => io_get_token - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ilength - INTEGER(I4B), INTENT(INOUT) :: ifirst - INTEGER(I4B), INTENT(OUT) :: ilast, ierr - CHARACTER(*), INTENT(IN) :: buffer - -! Internals - INTEGER(I4B) :: i - -! Executable code - IF (ifirst > ilength) THEN - ilast = ifirst - ierr = -1 - RETURN - END IF - DO i = ifirst, ilength - IF (buffer(i:i) /= " ") EXIT - END DO - IF ((i > ilength) .OR. (buffer(i:i) == "!")) THEN - ifirst = i - ilast = i - ierr = -1 - RETURN - END IF - ifirst = i - DO i = ifirst, ilength - IF ((buffer(i:i) == " ") .OR. (buffer(i:i) == "!")) EXIT - END DO - ilast = i - 1 - ierr = 0 - - RETURN - -END SUBROUTINE io_get_token -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_getn.f90 b/io/io_getn.f90 deleted file mode 100644 index 0bd93d4ac..000000000 --- a/io/io_getn.f90 +++ /dev/null @@ -1,119 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_getn -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read the number of planets and test particles from respective input files -! -! Input -! Arguments : inplfile : name of input file for planets -! intpfile : name of input file for test particles -! in_type : format of input data files -! nplmax : maximum allowed number of planets -! ntpmax : maximum allowed number of test particles -! Terminal : none -! File : npl : number of planets -! ntp : number of active test particles -! -! Output -! Arguments : npl : number of planets -! ntp : number of active test particles -! nplmax : maximum allowed number of planets -! ntpmax : maximum allowed number of test particles -! Terminal : error, warning messages -! File : none -! -! Invocation : CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) -! -! Notes : nplmax (ntpmax) is reset to npl (ntp) if the latter exceeds the former -! -!********************************************************************************************************************************** -SUBROUTINE io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_getn - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: nplmax, ntpmax - INTEGER(I4B), INTENT(OUT) :: npl, ntp - CHARACTER(*), INTENT(IN) :: inplfile, intpfile, in_type - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 7 - INTEGER(I4B) :: iu, ierr - -! Executable code - npl = 0 - IF (in_type == "ASCII") THEN - CALL io_open(LUN, inplfile, "OLD", "FORMATTED", ierr) - READ(LUN, *) npl - CLOSE(UNIT = LUN) - ELSE - CALL io_open_fxdr(inplfile, "R", .TRUE., iu, ierr) - ierr = ixdrint(iu, npl) - ierr = ixdrclose(iu) - END IF - IF (npl < 1) THEN - WRITE(*, *) "Error: the number of planets, ", npl, "," - WRITE(*, *) " must be at least 1" - CALL util_exit(FAILURE) - ELSE IF ((npl > nplmax) .AND. .NOT. (nplmax < 0)) THEN - WRITE(*, *) "Warning: the number of planets, ", npl, "," - WRITE(*, *) " exceeds the specified maximum number of planets, ", nplmax - WRITE(*, *) " ...resetting nplmax to ", npl - nplmax = npl - ELSE IF (nplmax < 0) THEN - nplmax = npl - END IF - ntp = 0 - IF (intpfile /= "") THEN - IF (in_type == "ASCII") THEN - CALL io_open(LUN, intpfile, "OLD", "FORMATTED", ierr) - READ(LUN, *) ntp - CLOSE(UNIT = LUN) - ELSE - CALL io_open_fxdr(intpfile, "R", .TRUE., iu, ierr) - ierr = ixdrint(iu, ntp) - ierr = ixdrclose(iu) - END IF - IF (ntp < 0) THEN - WRITE(*, *) "Error: the number of test particles, ", ntp, "," - WRITE(*, *) " must be at least 0" - CALL util_exit(FAILURE) - ELSE IF ((ntp > ntpmax) .AND. .NOT. (ntpmax < 0)) THEN - WRITE(*, *) "Warning: the number of test particles, ", ntp, "," - WRITE(*, *) " exceeds the specified maximum number of test particles, ", ntpmax - WRITE(*, *) " ...resetting ntpmax to ", ntp - ntpmax = ntp - ELSE IF (ntpmax < 0) THEN - ntpmax = ntp - END IF - END IF - - RETURN - -END SUBROUTINE io_getn -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_init_param.f90 b/io/io_init_param.f90 deleted file mode 100644 index b5b28a138..000000000 --- a/io/io_init_param.f90 +++ /dev/null @@ -1,406 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_init_param -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read in parameters for the integration -! -! Input -! Arguments : inparfile -! Terminal : none -! File : nplmax : maximum allowed number of planets -! ntpmax : maximum allowed number of test particles -! t0 : integration start time -! tstop : integration stop time -! dt : time step -! inplfile : name of input file for planets -! intpfile : name of input file for test particles -! in_type : format of input data files -! istep_out : number of time steps between binary outputs -! outfile : name of output binary file -! out_type : binary format of output file -! out_form : data to write to output file -! out_stat : open status for output binary file -! istep_dump : number of time steps between dumps -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! lclose : logical flag indicating whether to check for planet-test particle encounters -! rmin : minimum heliocentric radius for test particle -! rmax : maximum heliocentric radius for test particle -! rmaxu : maximum unbound heliocentric radius for test particle -! qmin : minimum pericenter distance for test particle -! qmin_coord : coordinate frame to use for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! encounter_file : name of output file for encounters -! lextra_force : logical flag indicating whether to use user-supplied accelerations -! lbig_discard : logical flag indicating whether to dump planet data with discards -! lrhill_present : logical flag indicating whether Hill's sphere radii are present in planet data -! -! Output -! Arguments : (same quantities listed above as input from file are passed back to the calling routine as output arguments) -! Terminal : status, error messages -! File : none -! -! Invocation : CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, -! out_type, out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, -! qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, lrhill_present) -! -! Notes : Adapted from Martin Duncan's Swift routine io_init_param.f -! -!********************************************************************************************************************************** -SUBROUTINE io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => io_init_param -! OPENMP code added by D. Minton - !$ use omp_lib - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(OUT) :: lclose, lextra_force, lbig_discard, lrhill_present - INTEGER(I4B), INTENT(OUT) :: nplmax, ntpmax, istep_out, istep_dump - REAL(DP), INTENT(OUT) :: t0, tstop, dt, j2rp2, j4rp4, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: inparfile - CHARACTER(*), INTENT(OUT) :: qmin_coord, encounter_file, inplfile, intpfile, in_type, outfile, out_type, out_form, out_stat - -! Internals - LOGICAL(LGT) :: t0_set, tstop_set, dt_set - INTEGER(I4B), PARAMETER :: LUN = 7 - INTEGER(I4B) :: ierr, ilength, ifirst, ilast - CHARACTER(STRMAX) :: line, token - -! Executable code - nplmax = -1 - ntpmax = -1 - t0_set = .FALSE. - tstop_set = .FALSE. - dt_set = .FALSE. - t0 = 0.0_DP - tstop = 0.0_DP - dt = 0.0_DP - inplfile = "" - intpfile = "" - in_type = "ASCII" - istep_out = -1 - outfile = "" - out_type = XDR4_TYPE - out_form = "XV" - out_stat = "NEW" - istep_dump = -1 - j2rp2 = 0.0_DP - j4rp4 = 0.0_DP - lclose = .FALSE. - rmin = -1.0_DP - rmax = -1.0_DP - rmaxu = -1.0_DP - qmin = -1.0_DP - qmin_coord = "HELIO" - qmin_alo = -1.0_DP - qmin_ahi = -1.0_DP - encounter_file = "" - lextra_force = .FALSE. - lbig_discard = .FALSE. - lrhill_present = .FALSE. - WRITE(*, 100, ADVANCE = "NO") "Parameter data file is " - WRITE(*, 100) inparfile - WRITE(*, *) " " - 100 FORMAT(A) - CALL io_open(LUN, inparfile, "OLD", "FORMATTED", ierr) - IF (ierr /= 0) THEN - WRITE(*, 100, ADVANCE = "NO") "Unable to open file " - WRITE(*, 100) inparfile - CALL util_exit(FAILURE) - END IF - DO - READ(LUN, 100, IOSTAT = ierr, END = 1) line - line = ADJUSTL(line) - ilength = LEN_TRIM(line) - IF ((ilength /= 0) .AND. (line(1:1) /= "!")) THEN - ifirst = 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - SELECT CASE (token) - CASE ("NPLMAX") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) nplmax - CASE ("NTPMAX") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) ntpmax - CASE ("T0") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) t0 - t0_set = .TRUE. - CASE ("TSTOP") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) tstop - tstop_set = .TRUE. - CASE ("DT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) dt - dt_set = .TRUE. - CASE ("PL_IN") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - inplfile = token - CASE ("TP_IN") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - intpfile = token - CASE ("IN_TYPE") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - in_type = token - CASE ("ISTEP_OUT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) istep_out - CASE ("BIN_OUT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - outfile = token - CASE ("OUT_TYPE") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - out_type = token - CASE ("OUT_FORM") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - out_form = token - CASE ("OUT_STAT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - out_stat = token - CASE ("ISTEP_DUMP") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) istep_dump - CASE ("J2") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) j2rp2 - CASE ("J4") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) j4rp4 - CASE ("CHK_CLOSE") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - IF (token == "YES") lclose = .TRUE. - CASE ("CHK_RMIN") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) rmin - CASE ("CHK_RMAX") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) rmax - CASE ("CHK_EJECT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) rmaxu - CASE ("CHK_QMIN") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) qmin - CASE ("CHK_QMIN_COORD") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - qmin_coord = token - CASE ("CHK_QMIN_RANGE") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) qmin_alo - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - READ(token, *) qmin_ahi - CASE ("ENC_OUT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - encounter_file = token - CASE ("EXTRA_FORCE") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - IF (token == "YES") lextra_force = .TRUE. - CASE ("BIG_DISCARD") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - IF (token == "YES") lbig_discard = .TRUE. - CASE ("RHILL_PRESENT") - ifirst = ilast + 1 - CALL io_get_token(line, ilength, ifirst, ilast, ierr) - token = line(ifirst:ilast) - CALL util_toupper(token) - IF (token == "YES") lrhill_present = .TRUE. - CASE DEFAULT - WRITE(*, 100, ADVANCE = "NO") "Unknown parameter -> " - WRITE(*, *) token - CALL util_exit(FAILURE) - END SELECT - END IF - END DO - 1 CLOSE(UNIT = LUN) - WRITE(*, 100, ADVANCE = "NO") "NPLMAX = " - WRITE(*, *) nplmax - WRITE(*, 100, ADVANCE = "NO") "NTPMAX = " - WRITE(*, *) ntpmax - WRITE(*, 100, ADVANCE = "NO") "T0 = " - WRITE(*, *) t0 - WRITE(*, 100, ADVANCE = "NO") "TSTOP = " - WRITE(*, *) tstop - WRITE(*, 100, ADVANCE = "NO") "DT = " - WRITE(*, *) dt - WRITE(*, 100, ADVANCE = "NO") "PL_IN = " - ilength = LEN_TRIM(inplfile) - WRITE(*, *) inplfile(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "TP_IN = " - ilength = LEN_TRIM(intpfile) - WRITE(*, *) intpfile(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "IN_TYPE = " - ilength = LEN_TRIM(in_type) - WRITE(*, *) in_type(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "ISTEP_OUT = " - WRITE(*, *) istep_out - WRITE(*, 100, ADVANCE = "NO") "BIN_OUT = " - ilength = LEN_TRIM(outfile) - WRITE(*, *) outfile(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "OUT_TYPE = " - ilength = LEN_TRIM(out_type) - WRITE(*, *) out_type(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "OUT_FORM = " - ilength = LEN_TRIM(out_form) - WRITE(*, *) out_form(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "OUT_STAT = " - ilength = LEN_TRIM(out_stat) - WRITE(*, *) out_stat(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "ISTEP_DUMP = " - WRITE(*, *) istep_dump - WRITE(*, 100, ADVANCE = "NO") "J2 = " - WRITE(*, *) j2rp2 - WRITE(*, 100, ADVANCE = "NO") "J4 = " - WRITE(*, *) j4rp4 - WRITE(*, 100, ADVANCE = "NO") "CHK_CLOSE = " - WRITE(*, *) lclose - WRITE(*, 100, ADVANCE = "NO") "CHK_RMIN = " - WRITE(*, *) rmin - WRITE(*, 100, ADVANCE = "NO") "CHK_RMAX = " - WRITE(*, *) rmax - WRITE(*, 100, ADVANCE = "NO") "CHK_EJECT = " - WRITE(*, *) rmaxu - WRITE(*, 100, ADVANCE = "NO") "CHK_QMIN = " - WRITE(*, *) qmin - WRITE(*, 100, ADVANCE = "NO") "CHK_QMIN_COORD = " - ilength = LEN_TRIM(qmin_coord) - WRITE(*, *) qmin_coord(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "CHK_QMIN_RANGE = " - WRITE(*, *) qmin_alo, qmin_ahi - WRITE(*, 100, ADVANCE = "NO") "ENC_OUT = " - ilength = LEN_TRIM(encounter_file) - WRITE(*, *) encounter_file(1:ilength) - WRITE(*, 100, ADVANCE = "NO") "EXTRA_FORCE = " - WRITE(*, *) lextra_force - WRITE(*, 100, ADVANCE = "NO") "BIG_DISCARD = " - WRITE(*, *) lbig_discard - WRITE(*, 100, ADVANCE = "NO") "RHILL_PRESENT = " - WRITE(*, *) lrhill_present - WRITE(*, *) " " - ierr = 0 - IF ((.NOT. t0_set) .OR. (.NOT. tstop_set) .OR. (.NOT. dt_set)) ierr = -1 - IF (dt <= 0.0_DP) ierr = -1 - IF (inplfile == "") ierr = -1 - IF ((in_type /= XDR8_TYPE) .AND. (in_type /= "ASCII")) ierr = -1 - IF ((istep_out <= 0) .AND. (istep_dump <= 0)) ierr = -1 - IF ((istep_out > 0) .AND. (outfile == "")) ierr = -1 - IF (outfile /= "") THEN - IF ((out_type /= REAL4_TYPE) .AND. (out_type /= REAL8_TYPE) .AND. & - (out_type /= XDR4_TYPE) .AND. (out_type /= XDR8_TYPE)) ierr = -1 - IF ((out_form /= "EL") .AND. (out_form /= "XV") .AND. (out_form /= "FILT")) ierr = -1 - IF ((out_stat /= "NEW") .AND. (out_stat /= "UNKNOWN") .AND. (out_stat /= "APPEND")) ierr = -1 - END IF - IF ((j2rp2 == 0.0_DP) .AND. (j4rp4 /= 0.0_DP)) ierr = -1 - IF (qmin > 0.0_DP) THEN - IF ((qmin_coord /= "HELIO") .AND. (qmin_coord /= "BARY")) ierr = -1 - IF ((qmin_alo <= 0.0_DP) .OR. (qmin_ahi <= 0.0_DP)) ierr = -1 - END IF - IF (ierr < 0) THEN - WRITE(*, 100) "Input parameter(s) failed check" - CALL util_exit(FAILURE) - END IF - - ! OPENMP code added by D. Minton - - ! Define the maximum number of threads - nthreads = 1 ! In the *serial* case - !$ nthreads = omp_get_max_threads() ! In the *parallel* case - !$ write(*,'(a)') ' OpenMP parameters:' - !$ write(*,'(a)') ' ------------------' - !$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads - - RETURN - -END SUBROUTINE io_init_param -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_init_pl.f90 b/io/io_init_pl.f90 deleted file mode 100644 index 813186d3f..000000000 --- a/io/io_init_pl.f90 +++ /dev/null @@ -1,156 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_init_pl -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read in planet data -! -! Input -! Arguments : inplfile : name of input file for planets -! in_type : format of input data file -! lclose : logical flag indicating whether planets' physical radii are present in input file -! lrhill_present : logical flag indicating whether planets' Hill's sphere radii are present in input file -! npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : none -! File : id : planet identifier (all planets) -! mass : mass (all planets) -! rhill : Hill's sphere radius (optional) (if present, all planets except the Sun) -! radius : physical radius (optional) (if present, all planets except the Sun) -! xh : heliocentric position (all planets) -! vh : heliocentric velocity (all planets) -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) -! -! Notes : Adapted from Martin Duncan's Swift routine io_init_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_init_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - CHARACTER(*), INTENT(IN) :: inplfile, in_type - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 7 - INTEGER(I4B) :: i, iu, ierr, inpl - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - swifter_plP => swifter_pl1P - IF (in_type == "ASCII") THEN - CALL io_open(LUN, inplfile, "OLD", "FORMATTED", ierr) - READ(LUN, *) inpl - READ(LUN, *) swifter_plP%id, swifter_plP%mass - swifter_plP%rhill = 0.0_DP - swifter_plP%radius = 0.0_DP - READ(LUN, *) swifter_plP%xh(:) - READ(LUN, *) swifter_plP%vh(:) - DO i = 1, NDIM - IF ((swifter_plP%xh(i) /= 0.0_DP) .OR. (swifter_plP%vh(i) /= 0.0_DP)) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Input MUST be in heliocentric coordinates." - WRITE(*, *) " Position/velocity components of Body 1 are" - WRITE(*, *) swifter_plP%xh(:) - WRITE(*, *) swifter_plP%vh(:) - CALL util_exit(FAILURE) - END IF - END DO - swifter_plP%status = ACTIVE - DO i = 2, npl - swifter_plP => swifter_plP%nextP - IF (lrhill_present) THEN - READ(LUN, *) swifter_plP%id, swifter_plP%mass, swifter_plP%rhill - ELSE - READ(LUN, *) swifter_plP%id, swifter_plP%mass - swifter_plP%rhill = 0.0_DP - END IF - IF (lclose) THEN - READ(LUN, *) swifter_plP%radius - ELSE - swifter_plP%radius = 0.0_DP - END IF - READ(LUN, *) swifter_plP%xh(:) - READ(LUN, *) swifter_plP%vh(:) - swifter_plP%status = ACTIVE - END DO - CLOSE(UNIT = LUN) - ELSE - CALL io_open_fxdr(inplfile, "R", .TRUE., iu, ierr) - ierr = ixdrint(iu, inpl) - ierr = ixdrint(iu, swifter_plP%id) - ierr = ixdrdouble(iu, swifter_plP%mass) - swifter_plP%rhill = 0.0_DP - swifter_plP%radius = 0.0_DP - ierr = ixdrdmat(iu, NDIM, swifter_plP%xh) - ierr = ixdrdmat(iu, NDIM, swifter_plP%vh) - DO i = 1, NDIM - IF ((swifter_plP%xh(i) /= 0.0_DP) .OR. (swifter_plP%vh(i) /= 0.0_DP)) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Input MUST be in heliocentric coordinates." - WRITE(*, *) " Position/velocity components of Body 1 are" - WRITE(*, *) swifter_plP%xh(:) - WRITE(*, *) swifter_plP%vh(:) - CALL util_exit(FAILURE) - END IF - END DO - swifter_plP%status = ACTIVE - DO i = 2, npl - swifter_plP => swifter_plP%nextP - ierr = ixdrint(iu, swifter_plP%id) - ierr = ixdrdouble(iu, swifter_plP%mass) - IF (lrhill_present) THEN - ierr = ixdrdouble(iu, swifter_plP%rhill) - ELSE - swifter_plP%rhill = 0.0_DP - END IF - IF (lclose) THEN - ierr = ixdrdouble(iu, swifter_plP%radius) - ELSE - swifter_plP%radius = 0.0_DP - END IF - ierr = ixdrdmat(iu, NDIM, swifter_plP%xh) - ierr = ixdrdmat(iu, NDIM, swifter_plP%vh) - swifter_plP%status = ACTIVE - END DO - ierr = ixdrclose(iu) - END IF - - RETURN - -END SUBROUTINE io_init_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_init_tp.f90 b/io/io_init_tp.f90 deleted file mode 100644 index 84657636a..000000000 --- a/io/io_init_tp.f90 +++ /dev/null @@ -1,97 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_init_tp -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read in test particle data -! -! Input -! Arguments : intpfile : name of input file for test particles -! in_type : format of input data file -! ntp : number of active test particles -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : id : test particle identifier (all test particles) -! xh : heliocentric position (all test particles) -! vh : heliocentric velocity (all test particles) -! -! Output -! Arguments : swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) -! -! Notes : Adapted from Martin Duncan's Swift routine io_init_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_init_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - CHARACTER(*), INTENT(IN) :: intpfile, in_type - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B), PARAMETER :: LUN = 7 - INTEGER(I4B) :: i, iu, ierr, intp - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - IF (ntp == 0) RETURN - swifter_tpP => swifter_tp1P - IF (in_type == "ASCII") THEN - CALL io_open(LUN, intpfile, "OLD", "FORMATTED", ierr) - READ(LUN, *) intp - DO i = 1, ntp - READ(LUN, *) swifter_tpP%id - READ(LUN, *) swifter_tpP%xh(:) - READ(LUN, *) swifter_tpP%vh(:) - swifter_tpP%status = ACTIVE - swifter_tpP => swifter_tpP%nextP - END DO - CLOSE(UNIT = LUN) - ELSE - CALL io_open_fxdr(intpfile, "R", .TRUE., iu, ierr) - ierr = ixdrint(iu, intp) - DO i = 1, ntp - ierr = ixdrint(iu, swifter_tpP%id) - ierr = ixdrdmat(iu, NDIM, swifter_tpP%xh) - ierr = ixdrdmat(iu, NDIM, swifter_tpP%vh) - swifter_tpP%status = ACTIVE - swifter_tpP => swifter_tpP%nextP - END DO - ierr = ixdrclose(iu) - END IF - - RETURN - -END SUBROUTINE io_init_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_open.f90 b/io/io_open.f90 deleted file mode 100644 index 454978d31..000000000 --- a/io/io_open.f90 +++ /dev/null @@ -1,73 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_open -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Open a file -! -! Input -! Arguments : iu : unit number with which to open file -! fname : name of file to open -! fopenstat : status with which to open file -! fmt : format string -! Terminal : none -! File : none -! -! Output -! Arguments : ierr : open error status (0 = OK, nonzero = ERROR) -! Terminal : none -! File : none -! -! Invocation : CALL io_open(iu, fname, fopenstat, fmt, ierr) -! -! Notes : Adapted from Hal Levison's Swift routine io_open.F -! -!********************************************************************************************************************************** -SUBROUTINE io_open(iu, fname, fopenstat, fmt, ierr) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => io_open - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: ierr - CHARACTER(*), INTENT(IN) :: fname, fopenstat, fmt - -! Internals - CHARACTER(STRMAX) :: fostat - -! Executable code - fostat = TRIM(ADJUSTL(fopenstat)) - CALL util_toupper(fostat) - IF (fostat == "APPEND") THEN - OPEN(UNIT = iu, FILE = fname, STATUS = "OLD", POSITION = fostat, FORM = fmt, IOSTAT = ierr) - ELSE - OPEN(UNIT = iu, FILE = fname, STATUS = fostat, FORM = fmt, IOSTAT = ierr) - END IF - - RETURN - -END SUBROUTINE io_open -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_open_fxdr.f90 b/io/io_open_fxdr.f90 deleted file mode 100644 index b8d3e6794..000000000 --- a/io/io_open_fxdr.f90 +++ /dev/null @@ -1,71 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_open_fxdr -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Open an XDR formatted file using FXDR routines -! -! Input -! Arguments : fname : name of file to open -! fopenstat : status with which to open file -! lflag : logical flag indicating behavior to exhibit on error (.TRUE. = return, .FALSE. = stop) -! Terminal : none -! File : none -! -! Output -! Arguments : iu : unit number of open file -! ierr : open error status (0 = OK, nonzero = ERROR) -! Terminal : none -! File : none -! -! Invocation : CALL io_open_fxdr(fname, fopenstat, lflag, iu, ierr) -! -! Notes : Adapted from Hal Levison's Swift routine io_open_fxdr.F -! -!********************************************************************************************************************************** -SUBROUTINE io_open_fxdr(fname, fopenstat, lflag, iu, ierr) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_open_fxdr - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lflag - INTEGER(I4B), INTENT(OUT) :: iu, ierr - CHARACTER(*), INTENT(IN) :: fname - CHARACTER(1), INTENT(IN) :: fopenstat - -! Executable code - iu = initxdr(fname, fopenstat, lflag) - IF (iu >= 0) THEN - ierr = 0 - ELSE - ierr = iu - END IF - - RETURN - -END SUBROUTINE io_open_fxdr -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_read_encounter.f90 b/io/io_read_encounter.f90 deleted file mode 100644 index 8fc43fda7..000000000 --- a/io/io_read_encounter.f90 +++ /dev/null @@ -1,134 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_read_encounter -! Unit Type : function -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read close encounter data from input binary file -! -! Input -! Arguments : encounter_file : name of input binary file for encounters -! out_type : format of input binary file -! Terminal : none -! File : t : time -! -! Output -! Arguments : t : time -! id1 : identifier of first planet / particle -! id2 : identifier of second planet / particle -! mass1 : mass of first planet / particle -! mass2 : mass of second planet / particle -! xh1 : heliocentric position of first planet / particle -! xh2 : heliocentric position of second planet / particle -! vh1 : heliocentric velocity of first planet / particle -! vh2 : heliocentric velocity of second planet / particle -! Terminal : error message -! File : none -! -! Invocation : istat = io_read_encounter(t, id1, id2, mass1, mass2, xh1, xh2, vh1, vh2, encounter_file, out_type) -! -! Notes : Other than time t, there is no direct file input from this function -! -! Function returns read error status (0 = OK, nonzero = ERROR) -! -!********************************************************************************************************************************** -FUNCTION io_read_encounter(t, id1, id2, mass1, mass2, xh1, xh2, vh1, vh2, encounter_file, out_type) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_read_encounter - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: io_read_encounter - INTEGER(I4B), INTENT(OUT) :: id1, id2 - REAL(DP), INTENT(OUT) :: t, mass1, mass2 - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: xh1, xh2, vh1, vh2 - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - -! Internals - LOGICAL(LGT) :: lxdr - LOGICAL(LGT), SAVE :: lfirst = .TRUE. - INTEGER(I4B), PARAMETER :: LUN = 30 - INTEGER(I4B) :: ierr - INTEGER(I4B), SAVE :: iu = LUN - -! Executable code - lxdr = ((out_type == XDR4_TYPE) .OR. (out_type == XDR8_TYPE)) - IF (lfirst) THEN - IF (lxdr) THEN - CALL io_open_fxdr(encounter_file, "R", .TRUE., iu, ierr) - ELSE - CALL io_open(iu, encounter_file, "OLD", "UNFORMATTED", ierr) - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary encounter file" - CALL util_exit(FAILURE) - END IF - lfirst = .FALSE. - END IF - IF (lxdr) THEN - ierr = ixdrdouble(iu, t) - io_read_encounter = ierr - IF (ierr /= 0) THEN - ierr = ixdrclose(iu) - RETURN - END IF - ierr = io_read_line(iu, id1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), vh1(3), XDR8_TYPE, MASS = mass1) - io_read_encounter = ierr - IF (ierr /= 0) THEN - ierr = ixdrclose(iu) - RETURN - END IF - ierr = io_read_line(iu, id2, xh2(1), xh2(2), xh2(3), vh2(1), vh2(2), vh2(3), XDR8_TYPE, MASS = mass2) - io_read_encounter = ierr - IF (ierr /= 0) THEN - ierr = ixdrclose(iu) - RETURN - END IF - ELSE - READ(iu, IOSTAT = ierr) t - io_read_encounter = ierr - IF (ierr /= 0) THEN - CLOSE(UNIT = iu, IOSTAT = ierr) - RETURN - END IF - ierr = io_read_line(iu, id1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), vh1(3), REAL8_TYPE, MASS = mass1) - io_read_encounter = ierr - IF (ierr /= 0) THEN - CLOSE(UNIT = iu, IOSTAT = ierr) - RETURN - END IF - ierr = io_read_line(iu, id2, xh2(1), xh2(2), xh2(3), vh2(1), vh2(2), vh2(3), REAL8_TYPE, MASS = mass2) - io_read_encounter = ierr - IF (ierr /= 0) THEN - CLOSE(UNIT = iu, IOSTAT = ierr) - RETURN - END IF - END IF - - RETURN - -END FUNCTION io_read_encounter -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_read_hdr.f90 b/io/io_read_hdr.f90 deleted file mode 100644 index c1cb89eb5..000000000 --- a/io/io_read_hdr.f90 +++ /dev/null @@ -1,108 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_read_hdr -! Unit Type : function -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read frame header from input binary file -! -! Input -! Arguments : iu : unit number associated with input binary file -! out_type : format of input binary file -! Terminal : none -! File : t (or ttmp) : time -! npl : number of planets -! ntp : number of active test particles -! iout_form : specifier of data contained in input file (elements / heliocentric coordinates / filtered elements) -! -! Output -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! iout_form : specifier of data contained in input file (elements / heliocentric coordinates / filtered elements) -! Terminal : none -! File : none -! -! Invocation : istat = io_read_hdr(iu, t, npl, ntp, iout_form, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine io_read_hdr.F -! -! Function returns read error status (0 = OK, nonzero = ERROR) -! -!********************************************************************************************************************************** -FUNCTION io_read_hdr(iu, t, npl, ntp, iout_form, out_type) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_read_hdr - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: io_read_hdr - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: npl, ntp, iout_form - REAL(DP), INTENT(OUT) :: t - CHARACTER(*), INTENT(IN) :: out_type - -! Internals - INTEGER(I4B) :: ierr - INTEGER(I4B), DIMENSION(3) :: nn - REAL(SP) :: ttmp - -! Executable code - SELECT CASE (out_type) - CASE (REAL4_TYPE) - READ(iu, IOSTAT = ierr) ttmp, npl, ntp, iout_form - io_read_hdr = ierr - IF (ierr /= 0) RETURN - t = ttmp - CASE (REAL8_TYPE) - READ(iu, IOSTAT = ierr) t, npl, ntp, iout_form - io_read_hdr = ierr - CASE (XDR4_TYPE) - ierr = ixdrreal(iu, ttmp) - io_read_hdr = ierr - IF (ierr /= 0) RETURN - t = ttmp - ierr = ixdrimat(iu, 3, nn) - io_read_hdr = ierr - IF (ierr /= 0) RETURN - npl = nn(1) - ntp = nn(2) - iout_form = nn(3) - CASE (XDR8_TYPE) - ierr = ixdrdouble(iu, t) - io_read_hdr = ierr - IF (ierr /= 0) RETURN - ierr = ixdrimat(iu, 3, nn) - io_read_hdr = ierr - IF (ierr /= 0) RETURN - npl = nn(1) - ntp = nn(2) - iout_form = nn(3) - END SELECT - - RETURN - -END FUNCTION io_read_hdr -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_read_line.f90 b/io/io_read_line.f90 deleted file mode 100644 index 6245f2574..000000000 --- a/io/io_read_line.f90 +++ /dev/null @@ -1,149 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_read_line -! Unit Type : function -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Read a line (record) from input binary file -! -! Input -! Arguments : iu : unit number associated with input binary file -! out_type : format of input binary file -! Terminal : none -! File : id : planet or test particle identifier -! smass (or MASS) : optional mass (omitted for massless test particle) -! sradius (or RADIUS) : optional radius (omitted for massless test particle) -! svec (or dvec) : 6-vector of orbital elements or position and velocity components -! -! Output -! Arguments : id : planet or test particle identifier -! d1 : first quantity (semimajor axis (pericentric distance for a parabola) or heliocentric x ) -! d2 : second quantity (eccentricity or heliocentric y ) -! d3 : third quantity (inclination or heliocentric z ) -! d4 : fourth quantity (longitude of the ascending node or heliocentric vx) -! d5 : fifth quantity (argument of pericenter or heliocentric vy) -! d6 : sixth quantity (mean anomaly or heliocentric vz) -! MASS : optional mass (omitted for massless test particle) -! RADIUS : optional radius (omitted for massless test particle) -! Terminal : none -! File : none -! -! Invocation : istat = io_read_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) -! -! Notes : Adapted from Hal Levison's Swift function io_read_line -! -! Function returns read error status (0 = OK, nonzero = ERROR) -! -!********************************************************************************************************************************** -FUNCTION io_read_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_read_line - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: io_read_line - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: id - REAL(DP), INTENT(OUT) :: d1, d2, d3, d4, d5, d6 - REAL(DP), OPTIONAL, INTENT(OUT) :: MASS, RADIUS - CHARACTER(*), INTENT(IN) :: out_type - -! Internals - LOGICAL(LGT) :: lmass, lradius - INTEGER(I4B) :: ierr - REAL(SP) :: smass, sradius - REAL(SP), DIMENSION(6) :: svec - REAL(DP), DIMENSION(6) :: dvec - -! Executable code - lmass = PRESENT(MASS) - IF (lmass) THEN - lradius = PRESENT(RADIUS) - IF (.NOT. lradius) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Subroutine io_read_line called with optional MASS but without optional RADIUS" - CALL util_exit(FAILURE) - END IF - END IF - SELECT CASE (out_type) - CASE (REAL4_TYPE) - IF (lmass) THEN - READ(iu, IOSTAT = ierr) id, smass, sradius, svec - ELSE - READ(iu, IOSTAT = ierr) id, svec - END IF - io_read_line = ierr - IF (ierr /= 0) RETURN - IF (lmass) MASS = smass - d1 = svec(1); d2 = svec(2); d3 = svec(3); d4 = svec(4); d5 = svec(5); d6 = svec(6) - CASE (REAL8_TYPE) - IF (lmass) THEN - READ(iu, IOSTAT = ierr) id, MASS, RADIUS, dvec - ELSE - READ(iu, IOSTAT = ierr) id, dvec - END IF - io_read_line = ierr - IF (ierr /= 0) RETURN - d1 = dvec(1); d2 = dvec(2); d3 = dvec(3); d4 = dvec(4); d5 = dvec(5); d6 = dvec(6) - CASE (XDR4_TYPE) - ierr = ixdrint(iu, id) - io_read_line = ierr - IF (ierr /= 0) RETURN - IF (lmass) THEN - ierr = ixdrreal(iu, smass) - io_read_line = ierr - IF (ierr /= 0) RETURN - MASS = smass - ierr = ixdrreal(iu, sradius) - io_read_line = ierr - IF (ierr /= 0) RETURN - RADIUS = sradius - END IF - ierr = ixdrrmat(iu, 6, svec) - io_read_line = ierr - IF (ierr /= 0) RETURN - d1 = svec(1); d2 = svec(2); d3 = svec(3); d4 = svec(4); d5 = svec(5); d6 = svec(6) - CASE (XDR8_TYPE) - ierr = ixdrint(iu, id) - io_read_line = ierr - IF (ierr /= 0) RETURN - IF (lmass) THEN - ierr = ixdrdouble(iu, MASS) - io_read_line = ierr - IF (ierr /= 0) RETURN - ierr = ixdrdouble(iu, RADIUS) - io_read_line = ierr - IF (ierr /= 0) RETURN - END IF - ierr = ixdrdmat(iu, 6, dvec) - io_read_line = ierr - IF (ierr /= 0) RETURN - d1 = dvec(1); d2 = dvec(2); d3 = dvec(3); d4 = dvec(4); d5 = dvec(5); d6 = dvec(6) - END SELECT - - RETURN - -END FUNCTION io_read_line -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_write_encounter.f90 b/io/io_write_encounter.f90 deleted file mode 100644 index 14f7336fb..000000000 --- a/io/io_write_encounter.f90 +++ /dev/null @@ -1,128 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_write_encounter -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write close encounter data to output binary file -! -! Input -! Arguments : t : time -! id1 : identifier of first planet / particle -! id2 : identifier of second planet / particle -! mass1 : mass of first planet / particle -! mass2 : mass of second planet / particle -! radius1 : radius of first planet / particle -! radius2 : radius of second planet / particle -! xh1 : heliocentric position of first planet / particle -! xh2 : heliocentric position of second planet / particle -! vh1 : heliocentric velocity of first planet / particle -! vh2 : heliocentric velocity of second planet / particle -! encounter_file : name of output binary file for encounters -! out_type : format of output binary file -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : none -! -! Invocation : CALL io_write_encounter(t, id1, id2, mass1, mass2, radius1, radius2, xh1, xh2, vh1, vh2, encounter_file, out_type) -! -! Notes : There is no direct file output from this subroutine -! -!********************************************************************************************************************************** -SUBROUTINE io_write_encounter(t, id1, id2, mass1, mass2, radius1, radius2, xh1, xh2, vh1, vh2, encounter_file, out_type) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_write_encounter - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: id1, id2 - REAL(DP), INTENT(IN) :: t, mass1, mass2, radius1, radius2 - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: xh1, xh2, vh1, vh2 - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - -! Internals - LOGICAL(LGT) :: lxdr - LOGICAL(LGT), SAVE :: lfirst = .TRUE. - INTEGER(I4B), PARAMETER :: LUN = 30 - INTEGER(I4B) :: ierr - INTEGER(I4B), SAVE :: iu = LUN - -! Executable code - lxdr = ((out_type == XDR4_TYPE) .OR. (out_type == XDR8_TYPE)) - IF (lxdr) THEN - CALL io_open_fxdr(encounter_file, "A", .TRUE., iu, ierr) - IF ((ierr /= 0) .AND. lfirst) THEN - CALL io_open_fxdr(encounter_file, "W", .TRUE., iu, ierr) - lfirst = .FALSE. - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary encounter file" - CALL util_exit(FAILURE) - END IF - ierr = ixdrdouble(iu, t) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - CALL io_write_line(iu, id1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), vh1(3), XDR8_TYPE, MASS = mass1, RADIUS = radius1) - CALL io_write_line(iu, id2, xh2(1), xh2(2), xh2(3), vh2(1), vh2(2), vh2(3), XDR8_TYPE, MASS = mass2, RADIUS = radius2) - ierr = ixdrclose(iu) - ELSE - CALL io_open(iu, encounter_file, "APPEND", "UNFORMATTED", ierr) - IF ((ierr /= 0) .AND. lfirst) THEN - CALL io_open(iu, encounter_file, "NEW", "UNFORMATTED", ierr) - lfirst = .FALSE. - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary encounter file" - CALL util_exit(FAILURE) - END IF - WRITE(iu, IOSTAT = ierr) t - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - CALL io_write_line(iu, id1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), vh1(3), REAL8_TYPE, MASS = mass1, RADIUS = radius1) - CALL io_write_line(iu, id2, xh2(1), xh2(2), xh2(3), vh2(1), vh2(2), vh2(3), REAL8_TYPE, MASS = mass2, RADIUS = radius2) - CLOSE(UNIT = iu, IOSTAT = ierr) - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to close binary encounter file" - CALL util_exit(FAILURE) - END IF - - RETURN - -END SUBROUTINE io_write_encounter -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_write_frame.f90 b/io/io_write_frame.f90 deleted file mode 100644 index 7a1d50322..000000000 --- a/io/io_write_frame.f90 +++ /dev/null @@ -1,194 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_write_frame -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write a frame (header plus records for each planet and active test particle) to output binary file -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! outfile : name of output binary file -! out_type : binary format of output file -! out_form : data to write to output file (elements / heliocentric coordinates / filtered elements) -! out_stat : open status for output binary file -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : none -! -! Invocation : CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) -! -! Notes : Adapted from Hal Levison's Swift routine io_write_frame.F -! -! There is no direct file output from this subroutine -! -!********************************************************************************************************************************** -SUBROUTINE io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - -! Modules - USE module_parameters - USE module_swifter - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_write_frame - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: outfile, out_type, out_form, out_stat - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - LOGICAL(LGT) :: lxdr - LOGICAL(LGT), SAVE :: lfirst = .TRUE. - INTEGER(I4B), PARAMETER :: LUN = 20 - INTEGER(I4B) :: i, j, ierr - INTEGER(I4B), SAVE :: iu = LUN, iout_form = XV - REAL(DP) :: a, e, inc, capom, omega, capm, mu - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - lxdr = ((out_type == XDR4_TYPE) .OR. (out_type == XDR8_TYPE)) - IF (lfirst) THEN - IF (out_stat == "APPEND") THEN - IF (lxdr) THEN - CALL io_open_fxdr(outfile, "A", .TRUE., iu, ierr) - ELSE - CALL io_open(iu, outfile, out_stat, "UNFORMATTED", ierr) - END IF - ELSE IF (out_stat == "NEW") THEN - IF (lxdr) THEN - CALL io_open_fxdr(outfile, "R", .TRUE., iu, ierr) - IF (ierr == 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Binary output file already exists" - CALL util_exit(FAILURE) - END IF - CALL io_open_fxdr(outfile, "W", .TRUE., iu, ierr) - ELSE - CALL io_open(iu, outfile, out_stat, "UNFORMATTED", ierr) - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Binary output file already exists" - CALL util_exit(FAILURE) - END IF - END IF - ELSE - IF (lxdr) THEN - CALL io_open_fxdr(outfile, "W", .TRUE., iu, ierr) - ELSE - CALL io_open(iu, outfile, "REPLACE", "UNFORMATTED", ierr) - END IF - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary output file" - CALL util_exit(FAILURE) - END IF - SELECT CASE (out_form) - CASE ("EL") - iout_form = EL - CASE ("XV") - iout_form = XV - CASE ("FILT") - iout_form = FILT - END SELECT - lfirst = .FALSE. - ELSE - IF (lxdr) THEN - CALL io_open_fxdr(outfile, "A", .TRUE., iu, ierr) - ELSE - CALL io_open(iu, outfile, "APPEND", "UNFORMATTED", ierr) - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to open binary output file for append" - CALL util_exit(FAILURE) - END IF - END IF - CALL io_write_hdr(iu, t, npl, ntp, iout_form, out_type) - SELECT CASE (iout_form) - CASE (EL) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - mu = swifter_pl1P%mass + swifter_plP%mass - j = swifter_plP%id - CALL orbel_xv2el(swifter_plP%xh(:), swifter_plP%vh(:), mu, a, e, inc, capom, omega, capm) - CALL io_write_line(iu, j, a, e, inc, capom, omega, capm, out_type, MASS = swifter_plP%mass, & - RADIUS = swifter_plP%radius) - END DO - mu = swifter_pl1P%mass - swifter_tpP => swifter_tp1P - DO i = 1, ntp - j = swifter_tpP%id - CALL orbel_xv2el(swifter_tpP%xh(:), swifter_tpP%vh(:), mu, a, e, inc, capom, omega, capm) - CALL io_write_line(iu, j, a, e, inc, capom, omega, capm, out_type) - swifter_tpP => swifter_tpP%nextP - END DO - CASE (XV) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xtmp(:) = swifter_plP%xh(:) - vtmp(:) = swifter_plP%vh(:) - j = swifter_plP%id - CALL io_write_line(iu, j, xtmp(1), xtmp(2), xtmp(3), vtmp(1), vtmp(2), vtmp(3), out_type, & - MASS = swifter_plP%mass, RADIUS = swifter_plP%radius) - END DO - swifter_tpP => swifter_tp1P - DO i = 1, ntp - xtmp(:) = swifter_tpP%xh(:) - vtmp(:) = swifter_tpP%vh(:) - j = swifter_tpP%id - CALL io_write_line(iu, j, xtmp(1), xtmp(2), xtmp(3), vtmp(1), vtmp(2), vtmp(3), out_type) - swifter_tpP => swifter_tpP%nextP - END DO - CASE (FILT) -! DEK - add code here to handle the case for an OUT_FORM = FILT - END SELECT - IF (lxdr) THEN - ierr = ixdrclose(iu) - ELSE - CLOSE(UNIT = iu, IOSTAT = ierr) - END IF - IF (ierr /= 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to close binary output file" - CALL util_exit(FAILURE) - END IF - - RETURN - -END SUBROUTINE io_write_frame -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_write_hdr.f90 b/io/io_write_hdr.f90 deleted file mode 100644 index aa98f9290..000000000 --- a/io/io_write_hdr.f90 +++ /dev/null @@ -1,120 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_write_hdr -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write frame header to output binary file -! -! Input -! Arguments : iu : unit number associated with output binary file -! t : time -! npl : number of planets -! ntp : number of active test particles -! iout_form : specifier of data to write to output file (elements / heliocentric coordinates / filtered elements) -! out_type : format of output binary file -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : t (or ttmp) : time -! npl : number of planets -! ntp : number of active test particles -! iout_form : specifier of data to write to output file (elements / heliocentric coordinates / filtered elements) -! -! Invocation : CALL io_write_hdr(iu, t, npl, ntp, iout_form, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine io_write_hdr.F -! -!********************************************************************************************************************************** -SUBROUTINE io_write_hdr(iu, t, npl, ntp, iout_form, out_type) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_write_hdr - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: iu, npl, ntp, iout_form - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: out_type - -! Internals - INTEGER(I4B) :: ierr - INTEGER(I4B), DIMENSION(3) :: nn - REAL(SP) :: ttmp - -! Executable code - ttmp = t - nn(1) = npl - nn(2) = ntp - nn(3) = iout_form - SELECT CASE (out_type) - CASE (REAL4_TYPE) - WRITE(iu, IOSTAT = ierr) ttmp, npl, ntp, iout_form - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - CASE (REAL8_TYPE) - WRITE(iu, IOSTAT = ierr) t, npl, ntp, iout_form - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - CASE (XDR4_TYPE) - ierr = ixdrreal(iu, ttmp) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - ierr = ixdrimat(iu, 3, nn) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - CASE (XDR8_TYPE) - ierr = ixdrdouble(iu, t) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - ierr = ixdrimat(iu, 3, nn) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file header" - CALL util_exit(FAILURE) - END IF - END SELECT - - RETURN - -END SUBROUTINE io_write_hdr -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/io/io_write_line.f90 b/io/io_write_line.f90 deleted file mode 100644 index 0fd8d5615..000000000 --- a/io/io_write_line.f90 +++ /dev/null @@ -1,173 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : io_write_line -! Unit Type : subroutine -! Project : Swifter -! Package : io -! Language : Fortran 90/95 -! -! Description : Write a line (record) to output binary file -! -! Input -! Arguments : iu : unit number associated with output binary file -! id : planet or test particle identifier -! d1 : first quantity to write (semimajor axis (pericentric distance for a parabola) or heliocentric x ) -! d2 : second quantity to write (eccentricity or heliocentric y ) -! d3 : third quantity to write (inclination or heliocentric z ) -! d4 : fourth quantity to write (longitude of the ascending node or heliocentric vx) -! d5 : fifth quantity to write (argument of pericenter or heliocentric vy) -! d6 : sixth quantity to write (mean anomaly or heliocentric vz) -! out_type : format of output binary file -! MASS : optional mass (omitted for massless test particle) -! RADIUS : optional radius (omitted for massless test particle; must be present if optional MASS is present) -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : id : planet or test particle identifier -! smass (or dmass) : optional mass (omitted for massless test particle) -! sradius (or dradius) : optional radius (omitted for massless test particle) -! svec (or dvec) : 6-vector of orbital elements or position and velocity components -! -! Invocation : CALL io_write_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) -! -! Notes : Adapted from Hal Levison's Swift routine io_write_line.F -! -!********************************************************************************************************************************** -SUBROUTINE io_write_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) - -! Modules - USE module_parameters - USE module_fxdr - USE module_interfaces, EXCEPT_THIS_ONE => io_write_line - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: iu, id - REAL(DP), INTENT(IN) :: d1, d2, d3, d4, d5, d6 - REAL(DP), OPTIONAL, INTENT(IN) :: MASS, RADIUS - CHARACTER(*), INTENT(IN) :: out_type - -! Internals - INTEGER(I4B) :: ierr - REAL(DP), DIMENSION(6) :: dvec - REAL(SP), DIMENSION(6) :: svec - REAL(SP) :: smass, sradius - LOGICAL(LGT) :: lmass, lradius - -! Executable code - dvec(1) = d1; dvec(2) = d2; dvec(3) = d3; dvec(4) = d4; dvec(5) = d5; dvec(6) = d6 - svec(1) = d1; svec(2) = d2; svec(3) = d3; svec(4) = d4; svec(5) = d5; svec(6) = d6 - lmass = PRESENT(MASS) - IF (lmass) THEN - lradius = PRESENT(RADIUS) - IF (.NOT. lradius) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Subroutine io_write_line called with optional MASS but without optional RADIUS" - CALL util_exit(FAILURE) - END IF - smass = MASS - sradius = RADIUS - END IF - SELECT CASE (out_type) - CASE (REAL4_TYPE) - IF (lmass) THEN - WRITE(iu, IOSTAT = ierr) id, smass, sradius, svec - ELSE - WRITE(iu, IOSTAT = ierr) id, svec - END IF - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - CASE (REAL8_TYPE) - IF (lmass) THEN - WRITE(iu, IOSTAT = ierr) id, MASS, RADIUS, dvec - ELSE - WRITE(iu, IOSTAT = ierr) id, dvec - END IF - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - CASE (XDR4_TYPE) - ierr = ixdrint(iu, id) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - IF (lmass) THEN - ierr = ixdrreal(iu, smass) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - ierr = ixdrreal(iu, sradius) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - END IF - ierr = ixdrrmat(iu, 6, svec) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - CASE (XDR8_TYPE) - ierr = ixdrint(iu, id) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - IF (lmass) THEN - ierr = ixdrdouble(iu, MASS) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - ierr = ixdrdouble(iu, RADIUS) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - END IF - ierr = ixdrdmat(iu, 6, dvec) - IF (ierr < 0) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Unable to write binary file record" - CALL util_exit(FAILURE) - END IF - END SELECT - - RETURN - -END SUBROUTINE io_write_line -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_bs.f90 b/main/swifter_bs.f90 deleted file mode 100644 index db860e314..000000000 --- a/main/swifter_bs.f90 +++ /dev/null @@ -1,184 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_bs -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the Bulirsch-Stoer integrator -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : status messages -! File : none -! -! Invocation : % swifter_bs -! -! Notes : References: Stoer, J. & Bulirsch, R. 1980. Introduction to Numerical Analysis, (New York: Springer-Verlag), -! Sec. 7.2.14. -! Press, W. H., Teukolsky, S. A., Vetterling, W. T. & Flannery B. P. 1992. Numerical Recipes in -! Fortran 77, The Art of Scientific Computing, 2nd Edition, Vol. 1 of Fortran Numerical Recipes, -! (Cambridge University Press), Sec. 16.4, 718 - 725. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_bs.f -! -!********************************************************************************************************************************** -PROGRAM swifter_bs - -! Modules - USE module_parameters - USE module_swifter - USE module_bs - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(bs_pl), DIMENSION(:), ALLOCATABLE, TARGET :: bs_plA - TYPE(bs_tp), DIMENSION(:), ALLOCATABLE, TARGET :: bs_tpA - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P, bs_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(bs_plA(nplmax)) - CALL set_point(bs_plA) - IF (ntpmax > 0) THEN - ALLOCATE(bs_tpA(ntpmax)) - CALL set_point(bs_tpA) - END IF - CALL bs_setup(npl, ntp, bs_plA, bs_tpA, bs_pl1P, bs_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(bs_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL bs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4, dt) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL bs_discard(t, npl, ntp, nsp, bs_pl1P, bs_tp1P, bs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => bs_tp1P%swifter - swifter_tpd1P => bs_tpd1P%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(bs_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(bs_plA)) DEALLOCATE(bs_plA) - IF (ALLOCATED(bs_tpA)) DEALLOCATE(bs_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_bs -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_helio.f90 b/main/swifter_helio.f90 deleted file mode 100644 index 8bd12bad9..000000000 --- a/main/swifter_helio.f90 +++ /dev/null @@ -1,180 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_helio -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for Democratic Heliocentric Method -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : status messages -! File : none -! -! Invocation : % swifter_helio -! -! Notes : Reference: Duncan, M. J., Levison, H. F. & Lee, M. H. 1998. Astron. J., 116, 2067. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_helio.f -! -!********************************************************************************************************************************** -PROGRAM swifter_helio - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(helio_pl), DIMENSION(:), ALLOCATABLE, TARGET :: helio_plA - TYPE(helio_tp), DIMENSION(:), ALLOCATABLE, TARGET :: helio_tpA - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(helio_plA(nplmax)) - CALL set_point(helio_plA) - IF (ntp > 0) THEN - ALLOCATE(helio_tpA(ntpmax)) - CALL set_point(helio_tpA) - END IF - CALL helio_setup(npl, ntp, helio_plA, helio_tpA, helio_pl1P, helio_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(helio_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL helio_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL helio_discard(t, npl, ntp, nsp, helio_pl1P, helio_tp1P, helio_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => helio_tp1P%swifter - swifter_tpd1P => helio_tpd1P%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(helio_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(helio_plA)) DEALLOCATE(helio_plA) - IF (ALLOCATED(helio_tpA)) DEALLOCATE(helio_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_helio -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_ra15.f90 b/main/swifter_ra15.f90 deleted file mode 100644 index 35cf159b4..000000000 --- a/main/swifter_ra15.f90 +++ /dev/null @@ -1,179 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_ra15 -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the 15th-order RADAU integrator -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : status messages -! File : none -! -! Invocation : % swifter_ra15 -! -! Notes : Reference: Everhart, E. 1985. Dynamics of Comets: Their Origin and Evolution, A. Carusi & B. Valsecchi (eds.), -! (D. Reidel Publishing Company), 185 - 202. -! -!********************************************************************************************************************************** -PROGRAM swifter_ra15 - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(ra15_pl), DIMENSION(:), ALLOCATABLE, TARGET :: ra15_plA - TYPE(ra15_tp), DIMENSION(:), ALLOCATABLE, TARGET :: ra15_tpA - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P, ra15_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(ra15_plA(nplmax)) - CALL set_point(ra15_plA) - IF (ntp > 0) THEN - ALLOCATE(ra15_tpA(ntpmax)) - CALL set_point(ra15_tpA) - END IF - CALL ra15_setup(npl, ntp, ra15_plA, ra15_tpA, ra15_pl1P, ra15_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(ra15_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL ra15_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4, dt) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL ra15_discard(t, npl, ntp, nsp, ra15_pl1P, ra15_tp1P, ra15_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => ra15_tp1P%swifter - swifter_tpd1P => ra15_tpd1P%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(ra15_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ",I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(ra15_plA)) DEALLOCATE(ra15_plA) - IF (ALLOCATED(ra15_tpA)) DEALLOCATE(ra15_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_ra15 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_rmvs.f90 b/main/swifter_rmvs.f90 deleted file mode 100644 index a1f0dc702..000000000 --- a/main/swifter_rmvs.f90 +++ /dev/null @@ -1,187 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_rmvs -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the Regularized Mixed Variable Symplectic algorithm -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! status messages -! File : none -! -! Invocation : % swifter_rmvs -! -! Notes : Reference: Levison, H. F. & Duncan, M. J. 1994. Icarus, 108, 18. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_rmvs3.f -! -!********************************************************************************************************************************** -PROGRAM swifter_rmvs - -! Modules - USE module_parameters - USE module_swifter - USE module_rmvs - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(rmvs_pl), DIMENSION(:), ALLOCATABLE, TARGET :: rmvs_plA - TYPE(rmvs_tp), DIMENSION(:), ALLOCATABLE, TARGET :: rmvs_tpA - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P, rmvs_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - IF (.NOT. lrhill_present) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Integrator RMVS requires planet Hill sphere radii on input" - CALL util_exit(FAILURE) - END IF - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(rmvs_plA(nplmax)) - CALL set_point(rmvs_plA) - IF (ntp > 0) THEN - ALLOCATE(rmvs_tpA(ntpmax)) - CALL set_point(rmvs_tpA) - END IF - CALL rmvs_setup(npl, ntp, rmvs_plA, rmvs_tpA, rmvs_pl1P, rmvs_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(rmvs_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL rmvs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL rmvs_discard(t, npl, ntp, nsp, rmvs_pl1P, rmvs_tp1P, rmvs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => rmvs_tp1P%whm%swifter - swifter_tpd1P => rmvs_tpd1P%whm%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(rmvs_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(rmvs_plA)) DEALLOCATE(rmvs_plA) - IF (ALLOCATED(rmvs_tpA)) DEALLOCATE(rmvs_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_rmvs -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_symba_omp.f90 b/main/swifter_symba_omp.f90 deleted file mode 100644 index f347d98f6..000000000 --- a/main/swifter_symba_omp.f90 +++ /dev/null @@ -1,220 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_symba_omp -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the Symplectic Massive Body Algorithm with -! OpenMP parallelization -! -! Input -! Arguments : none -! Terminal : parameter file name -! mtiny : smallest self-gravitating mass -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! status messages -! File : none -! -! Invocation : % swifter_symba -! -! Notes : Reference: Duncan, M. J., Levison, H. F. & Lee, M. H. 1998. Astron. J., 116, 2067. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_symba5.f -! OpenMP parallelization by David Minton -! -!********************************************************************************************************************************** -PROGRAM swifter_symba_omp - -! Modules - USE module_parameters - USE module_swifter - USE module_symba - USE module_random_access - USE module_interfaces - !Added by D. Minton - !$ USE omp_lib - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsppl, nsptp, iout, idump, iloop - INTEGER(I4B) :: nplplenc, npltpenc, nmergeadd, nmergesub - REAL(DP) :: t, tfrac, tbase, mtiny, ke, pe, te, eoffset - REAL(DP), DIMENSION(NDIM) :: htot - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(symba_pl), DIMENSION(:), ALLOCATABLE, TARGET :: symba_plA - TYPE(symba_tp), DIMENSION(:), ALLOCATABLE, TARGET :: symba_tpA - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - TYPE(symba_tp), POINTER :: symba_tp1P, symba_tpd1P - TYPE(symba_plplenc), DIMENSION(NENMAX) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(NENMAX) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), ALLOCATABLE :: mergeadd_list, mergesub_list - -! Executable code - CALL util_version - ! OpenMP code added by D. Minton - ! Define the maximum number of threads - nthreads = 1 ! In the *serial* case - !$ write(*,*) 'Dynamic thread allocation: ',OMP_get_dynamic() - !$ nthreads = OMP_get_max_threads() ! In the *parallel* case - !$ write(*,'(a)') ' OpenMP parameters:' - !$ write(*,'(a)') ' ------------------' - !$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - IF (.NOT. lrhill_present) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Integrator SyMBA requires planet Hill sphere radii on input" - CALL util_exit(FAILURE) - END IF - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(symba_plA(nplmax), mergeadd_list(nplmax), mergesub_list(nplmax)) - CALL set_point(symba_plA) - IF (ntp > 0) THEN - ALLOCATE(symba_tpA(ntpmax)) - CALL set_point(symba_tpA) - END IF - CALL symba_setup(npl, ntp, symba_plA, symba_tpA, symba_pl1P, symba_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - WRITE(*, 100, ADVANCE = "NO") "Enter the smallest mass to self-gravitate: " - READ(*, *) mtiny - CALL symba_reorder_pl(npl, symba_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nmergeadd = 0 - nmergesub = 0 - nsppl = 0 - nsptp = 0 - eoffset = 0.0_DP - NULLIFY(symba_pld1P, symba_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL symba_step(lfirst, lextra_force, lclose, t, npl, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, dt, & - nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, & - mtiny, encounter_file, out_type) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL symba_discard_merge_pl(t, npl, nsppl, symba_pl1P, symba_pld1P, nplplenc, plplenc_list) - CALL symba_discard_pl(t, npl, nplmax, nsppl, symba_pl1P, symba_pld1P, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, j2rp2, j4rp4, eoffset) - CALL symba_discard_tp(t, npl, ntp, nsptp, symba_pl1P, symba_tp1P, symba_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - IF ((nsppl > 0) .OR. (nsptp > 0)) THEN - swifter_tp1P => symba_tp1P%helio%swifter - CALL io_discard_write_symba(t, mtiny, npl, nsppl, nsptp, nmergeadd, nmergesub, symba_pl1P, symba_pld1P, & - symba_tpd1P, mergeadd_list, mergesub_list, DISCARD_FILE, lbig_discard) - nmergeadd = 0 - nmergesub = 0 - nsppl = 0 - nsptp = 0 - NULLIFY(symba_pld1P, symba_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(symba_plA)) DEALLOCATE(symba_plA) - IF (ALLOCATED(mergeadd_list)) DEALLOCATE(mergeadd_list) - IF (ALLOCATED(mergesub_list)) DEALLOCATE(mergesub_list) - IF (ALLOCATED(symba_tpA)) DEALLOCATE(symba_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_symba_omp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_tu4.f90 b/main/swifter_tu4.f90 deleted file mode 100644 index a839fe137..000000000 --- a/main/swifter_tu4.f90 +++ /dev/null @@ -1,183 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_tu4 -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the 4th-order T + V integrator -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : status messages -! File : none -! -! Invocation : % swifter_tu4 -! -! Notes : References: Gladman, B. & Duncan, M. 1990. Astron. J., 100, 1669. -! Candy, J. & Rozmus, W. 1991. J. Comp. Phys., 92, 230. -! Forest, E. & Ruth, R. 1990. Physica D, 43, 105. -! Gladman, B., Duncan, M. & Candy, J. 1991, Cel. Mech. & Dyn. Astron., 52, 221. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_tu4.f -! -!********************************************************************************************************************************** -PROGRAM swifter_tu4 - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(tu4_pl), DIMENSION(:), ALLOCATABLE, TARGET :: tu4_plA - TYPE(tu4_tp), DIMENSION(:), ALLOCATABLE, TARGET :: tu4_tpA - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P, tu4_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(tu4_plA(nplmax)) - CALL set_point(tu4_plA) - IF (ntp > 0) THEN - ALLOCATE(tu4_tpA(ntpmax)) - CALL set_point(tu4_tpA) - END IF - CALL tu4_setup(npl, ntp, tu4_plA, tu4_tpA, tu4_pl1P, tu4_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(tu4_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL tu4_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4, dt) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL tu4_discard(t, npl, ntp, nsp, tu4_pl1P, tu4_tp1P, tu4_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => tu4_tp1P%swifter - swifter_tpd1P => tu4_tpd1P%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(tu4_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(tu4_plA)) DEALLOCATE(tu4_plA) - IF (ALLOCATED(tu4_tpA)) DEALLOCATE(tu4_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_tu4 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/main/swifter_whm.f90 b/main/swifter_whm.f90 deleted file mode 100644 index 934154a64..000000000 --- a/main/swifter_whm.f90 +++ /dev/null @@ -1,180 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : swifter_whm -! Unit Type : program -! Project : Swifter -! Package : main -! Language : Fortran 90/95 -! -! Description : Driver program for the Wisdom-Holman Mapping -! -! Input -! Arguments : none -! Terminal : parameter file name -! File : none -! -! Output -! Arguments : none -! Terminal : status messages -! File : none -! -! Invocation : % swifter_whm -! -! Notes : Reference: Wisdom, J. & Holman, M. 1991. Astron. J., 102, 1528. -! -! Adapted from Hal Levison and Martin Duncan's Swift program swift_whm.f -! -!********************************************************************************************************************************** -PROGRAM swifter_whm - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - -! Internals - LOGICAL(LGT) :: lfirst - INTEGER(I4B) :: npl, ntp, ntp0, nsp, iout, idump, iloop - REAL(DP) :: t, tfrac, tbase, eoffset - CHARACTER(STRMAX) :: inparfile - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpd1P - TYPE(whm_pl), DIMENSION(:), ALLOCATABLE, TARGET :: whm_plA - TYPE(whm_tp), DIMENSION(:), ALLOCATABLE, TARGET :: whm_tpA - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpd1P - -! Executable code - CALL util_version - WRITE(*, 100, ADVANCE = "NO") "Enter name of parameter data file: " - READ(*, 100) inparfile - 100 FORMAT(A) - inparfile = TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, out_type, & - out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - ALLOCATE(whm_plA(nplmax)) - CALL set_point(whm_plA) - IF (ntp > 0) THEN - ALLOCATE(whm_tpA(ntpmax)) - CALL set_point(whm_tpA) - END IF - CALL whm_setup(npl, ntp, whm_plA, whm_tpA, whm_pl1P, whm_tp1P, swifter_pl1P, swifter_tp1P) - CALL io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - CALL io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - lfirst = .TRUE. - ntp0 = ntp - t = t0 - tbase = t0 - iloop = 0 - iout = istep_out - idump = istep_dump - nsp = 0 - eoffset = 0.0_DP - NULLIFY(whm_tpd1P) - IF (istep_out > 0) CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - WRITE(*, *) " *************** MAIN LOOP *************** " - DO WHILE ((t < tstop) .AND. ((ntp0 == 0) .OR. (ntp > 0))) - CALL whm_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, j2rp2, j4rp4, dt) - iloop = iloop + 1 - IF (iloop == LOOPMAX) THEN - tbase = tbase + iloop*dt - iloop = 0 - END IF - t = tbase + iloop*dt - CALL whm_discard(t, npl, ntp, nsp, whm_pl1P, whm_tp1P, whm_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - IF (nsp > 0) THEN - swifter_tp1P => whm_tp1P%swifter - swifter_tpd1P => whm_tpd1P%swifter - CALL io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, DISCARD_FILE, lbig_discard) - nsp = 0 - NULLIFY(whm_tpd1P) - END IF - IF (istep_out > 0) THEN - iout = iout - 1 - IF (iout == 0) THEN - CALL io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - iout = istep_out - END IF - END IF - IF (istep_dump > 0) THEN - idump = idump - 1 - IF (idump == 0) THEN - tfrac = (t - t0)/(tstop - t0) - WRITE(*, 200) t, tfrac, npl, ntp - 200 FORMAT(" Time = ", ES12.5, "; fraction done = ", F5.3, "; Number of active pl, tp = ", I5, ", ", I5) - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, & - encounter_file, lextra_force, lbig_discard, lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - idump = istep_dump - END IF - END IF - END DO - CALL io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, istep_dump, j2rp2, & - j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, lextra_force, lbig_discard, & - lrhill_present) - CALL io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - IF (ntp > 0) CALL io_dump_tp(ntp, swifter_tp1P) - IF (ALLOCATED(whm_plA)) DEALLOCATE(whm_plA) - IF (ALLOCATED(whm_tpA)) DEALLOCATE(whm_tpA) - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM swifter_whm -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_bs.f90 b/module/module_bs.f90 deleted file mode 100644 index c787aa894..000000000 --- a/module/module_bs.f90 +++ /dev/null @@ -1,86 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_bs -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the Bulirsch-Stoer integrator -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_bs - - USE module_parameters - USE module_swifter - IMPLICIT NONE - - INTEGER(I4B), PARAMETER :: IEST_MAX = 7 - REAL(DP), PARAMETER :: DELTABS = 1.0E-7_DP - REAL(DP), PARAMETER :: TINYBS = 1.0E-30_DP - - TYPE bs_pl - REAL(DP), DIMENSION(NDIM2) :: y ! dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: dydx ! derivative of dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: ysav ! dependent variable vector (saved at bsstep start) - REAL(DP), DIMENSION(NDIM2) :: dydxsav ! derivative of dependent variable vector (saved at bsstep start) - REAL(DP), DIMENSION(NDIM2) :: yscal ! error scaling vector - REAL(DP), DIMENSION(NDIM2) :: ym ! intermediate work vector for mmid - REAL(DP), DIMENSION(NDIM2) :: yseq ! current sequence estimate of final dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: yerr ! extrapolation error of final dependent variable vector - REAL(DP), DIMENSION(NDIM2, IEST_MAX) :: qcol ! extrapolation tableau - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - TYPE(swifter_pl) :: swifter ! SWIFTER planet structure - TYPE(bs_pl), POINTER :: prevP ! pointer to previous BS planet - TYPE(bs_pl), POINTER :: nextP ! pointer to next BS planet - END TYPE bs_pl - - TYPE bs_tp - REAL(DP), DIMENSION(NDIM2) :: y ! dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: dydx ! derivative of dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: ysav ! dependent variable vector (saved at bsstep start) - REAL(DP), DIMENSION(NDIM2) :: dydxsav ! derivative of dependent variable vector (saved at bsstep start) - REAL(DP), DIMENSION(NDIM2) :: yscal ! error scaling vector - REAL(DP), DIMENSION(NDIM2) :: ym ! intermediate work vector for mmid - REAL(DP), DIMENSION(NDIM2) :: yseq ! current sequence estimate of final dependent variable vector - REAL(DP), DIMENSION(NDIM2) :: yerr ! extrapolation error of final dependent variable vector - REAL(DP), DIMENSION(NDIM2, IEST_MAX) :: qcol ! extrapolation tableau - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - TYPE(swifter_tp) :: swifter ! SWIFTER test particle structure - TYPE(bs_tp), POINTER :: prevP ! pointer to previous BS test particle - TYPE(bs_tp), POINTER :: nextP ! pointer to next BS test particle - END TYPE bs_tp - -END MODULE module_bs -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_fxdr.f90 b/module/module_fxdr.f90 deleted file mode 100644 index 823aaa884..000000000 --- a/module/module_fxdr.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_fxdr -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of interfaces of functions in the FXDR (Fortran eXternal Data Representation) library -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : FXDR is a library, written and maintained by David W. Pierce, that enables calls to the XDR (eXternal Data -! Representation) routines from Fortran. -! -! Reference : http://meteora.ucsd.edu/~pierce/fxdr_home_page.html -! -!********************************************************************************************************************************** -MODULE module_fxdr - - IMPLICIT NONE - - INTERFACE - FUNCTION initxdr(filename, mode, returnonerror) - CHARACTER(*), INTENT(IN) :: filename - CHARACTER(1), INTENT(IN) :: mode - LOGICAL, INTENT(IN) :: returnonerror - INTEGER :: initxdr - END FUNCTION initxdr - END INTERFACE - - INTERFACE - FUNCTION ixdrclose(ixdr) - INTEGER, INTENT(IN) :: ixdr - INTEGER :: ixdrclose - END FUNCTION ixdrclose - END INTERFACE - - INTERFACE - FUNCTION ixdrdmat(ixdrs, nels, dval) - INTEGER, INTENT(IN) :: ixdrs, nels - DOUBLE PRECISION, DIMENSION(nels), INTENT(IN) :: dval - INTEGER :: ixdrdmat - END FUNCTION ixdrdmat - END INTERFACE - - INTERFACE - FUNCTION ixdrdouble(ixdrs, dval) - INTEGER, INTENT(IN) :: ixdrs - DOUBLE PRECISION, INTENT(IN) :: dval - INTEGER :: ixdrdouble - END FUNCTION ixdrdouble - END INTERFACE - - INTERFACE - FUNCTION ixdrimat(ixdrs, nels, ival) - INTEGER, INTENT(IN) :: ixdrs, nels - INTEGER, DIMENSION(nels), INTENT(IN) :: ival - INTEGER :: ixdrimat - END FUNCTION ixdrimat - END INTERFACE - - INTERFACE - FUNCTION ixdrint(ixdrs, ival) - INTEGER, INTENT(IN) :: ixdrs, ival - INTEGER :: ixdrint - END FUNCTION ixdrint - END INTERFACE - - INTERFACE - FUNCTION ixdrreal(ixdrs, rval) - INTEGER, INTENT(IN) :: ixdrs - REAL, INTENT(IN) :: rval - INTEGER :: ixdrreal - END FUNCTION ixdrreal - END INTERFACE - - INTERFACE - FUNCTION ixdrrmat(ixdrs, nels, rval) - INTEGER, INTENT(IN) :: ixdrs, nels - REAL, DIMENSION(nels), INTENT(IN) :: rval - INTEGER :: ixdrrmat - END FUNCTION ixdrrmat - END INTERFACE - -END MODULE module_fxdr -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_helio.f90 b/module/module_helio.f90 deleted file mode 100644 index 0be2cc796..000000000 --- a/module/module_helio.f90 +++ /dev/null @@ -1,83 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_helio -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the Democratic Heliocentric Method -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_helio - - USE module_parameters - USE module_swifter - IMPLICIT NONE - - ! Added by D. Minton - TYPE helio_ptr_arr - TYPE(helio_pl), POINTER :: thisP ! pointer to current swifter planet - END TYPE helio_ptr_arr - TYPE helio_ptr_arr_tp - TYPE(helio_tp), POINTER :: thisP ! pointer to current swifter particle - END TYPE helio_ptr_arr_tp - !^^^^^^^^^^^^^^^^^^^ - - TYPE helio_pl - REAL(DP), DIMENSION(NDIM) :: ah ! total heliocentric acceleration - REAL(DP), DIMENSION(NDIM) :: ahi ! heliocentric acceleration due to interactions - TYPE(swifter_pl) :: swifter ! SWIFTER planet structure - TYPE(helio_pl), POINTER :: prevP ! pointer to previous HELIO planet - TYPE(helio_pl), POINTER :: nextP ! pointer to next HELIO planet - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(helio_ptr_arr),DIMENSION(:),ALLOCATABLE :: helio_plPA ! Array of pointers to Swifter planet structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE helio_pl - - TYPE helio_tp - REAL(DP), DIMENSION(NDIM) :: ah ! total heliocentric acceleration - REAL(DP), DIMENSION(NDIM) :: ahi ! heliocentric acceleration due to interactions - TYPE(swifter_tp) :: swifter ! SWIFTER test particle structure - TYPE(helio_tp), POINTER :: prevP ! pointer to previous HELIO test particle - TYPE(helio_tp), POINTER :: nextP ! pointer to next HELIO test particle - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(helio_ptr_arr_tp),DIMENSION(:),ALLOCATABLE :: helio_tpPA ! Array of pointers to Swifter planet structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE helio_tp - -END MODULE module_helio -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_interfaces.f90 b/module/module_interfaces.f90 deleted file mode 100644 index fa6578017..000000000 --- a/module/module_interfaces.f90 +++ /dev/null @@ -1,2336 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_interfaces -! Unit Type : module -! Project : Swifter -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of interfaces of subroutines and functions used in Swifter package -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_interfaces - - IMPLICIT NONE - - INTERFACE - SUBROUTINE bs_bsstep(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, x, htry, eps, hdid, hnext, j2rp2, j4rp4, lextra_force, & - derivs) - USE module_parameters - USE module_bs - USE module_nrutil - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: htry, eps, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: hdid, hnext - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - INTERFACE - SUBROUTINE derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE derivs - END INTERFACE - END SUBROUTINE bs_bsstep - END INTERFACE - - INTERFACE - SUBROUTINE bs_derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_derivs - END INTERFACE - - INTERFACE - SUBROUTINE bs_discard(t, npl, ntp, nsp, bs_pl1P, bs_tp1P, bs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P, bs_tpd1P - END SUBROUTINE bs_discard - END INTERFACE - - INTERFACE - SUBROUTINE bs_discard_spill(ntp, nsp, bs_tp1P, bs_tpd1P, bs_tpspP) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(bs_tp), POINTER :: bs_tp1P, bs_tpd1P, bs_tpspP - END SUBROUTINE bs_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE bs_getaccb(lextra_force, t, npl, nplmax, bs_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - END SUBROUTINE bs_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE bs_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE bs_mmid(npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, xs, htot, nstep, j2rp2, j4rp4, lextra_force, derivs) - USE module_parameters - USE module_bs - USE module_nrutil - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax, nstep - REAL(DP), INTENT(IN) :: xs, htot, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - INTERFACE - SUBROUTINE derivs(lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE derivs - END INTERFACE - END SUBROUTINE bs_mmid - END INTERFACE - - INTERFACE - SUBROUTINE bs_pzextr(iest, xest, npl, ntp, bs_pl1P, bs_tp1P) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: iest, npl, ntp - REAL(DP), INTENT(IN) :: xest - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_pzextr - END INTERFACE - - INTERFACE - SUBROUTINE bs_setup(npl, ntp, bs_plA, bs_tpA, bs_pl1P, bs_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(bs_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: bs_plA - TYPE(bs_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: bs_tpA - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_setup - END INTERFACE - - INTERFACE - SUBROUTINE bs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, bs_pl1P, bs_tp1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_swifter - USE module_bs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(bs_pl), POINTER :: bs_pl1P - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_step - END INTERFACE - - INTERFACE - SUBROUTINE bs_user_getaccb(t, npl, bs_pl1P) - USE module_parameters - USE module_bs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(bs_pl), POINTER :: bs_pl1P - END SUBROUTINE bs_user_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE bs_user_getaccb_tp(t, ntp, bs_tp1P) - USE module_parameters - USE module_bs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(bs_tp), POINTER :: bs_tp1P - END SUBROUTINE bs_user_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE coord_b2h(npl, swifter_pl1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_b2h - END INTERFACE - - INTERFACE - SUBROUTINE coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_b2h_tp - END INTERFACE - - INTERFACE - SUBROUTINE coord_h2b(npl, swifter_pl1P, msys) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(OUT) :: msys - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_h2b - END INTERFACE - - INTERFACE - SUBROUTINE coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_h2b_tp - END INTERFACE - - INTERFACE - SUBROUTINE coord_h2j(npl, whm_pl1P) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE coord_h2j - END INTERFACE - - INTERFACE - SUBROUTINE coord_j2h(npl, whm_pl1P) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE coord_j2h - END INTERFACE - - INTERFACE - SUBROUTINE coord_vb2vh(npl, swifter_pl1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_vb2vh - END INTERFACE - - INTERFACE - SUBROUTINE coord_vb2vh_tp(ntp, swifter_tp1P, vs) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vs - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE coord_vb2vh_tp - END INTERFACE - - INTERFACE - SUBROUTINE coord_vh2vb(npl, swifter_pl1P, msys) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(OUT) :: msys - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE coord_vh2vb - END INTERFACE - - INTERFACE - SUBROUTINE coord_vh2vb_tp(ntp, swifter_tp1P, vs) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vs - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE coord_vh2vb_tp - END INTERFACE - - INTERFACE - SUBROUTINE coord_vh2vj(npl, whm_pl1P) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE coord_vh2vj - END INTERFACE - - INTERFACE - SUBROUTINE discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, & - qmin_coord, lclose, lrhill_present) - USE module_parameters - USE module_swifter - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE discard - END INTERFACE - - INTERFACE - SUBROUTINE discard_peri(t, npl, ntp, swifter_pl1P, swifter_tp1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, & - lrhill_present) - USE module_parameters - USE module_swifter - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lrhill_present - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, msys, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE discard_peri - END INTERFACE - - INTERFACE - SUBROUTINE discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r2crit - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: dx, dv - REAL(DP), INTENT(OUT) :: r2min - END SUBROUTINE discard_pl_close - END INTERFACE - - INTERFACE - SUBROUTINE discard_pl(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t, dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE discard_pl - END INTERFACE - - INTERFACE - SUBROUTINE discard_sun(t, ntp, msys, swifter_tp1P, rmin, rmax, rmaxu) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t, msys, rmin, rmax, rmaxu - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE discard_sun - END INTERFACE - - INTERFACE - SUBROUTINE drift_dan(mu, x0, v0, dt0, iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: mu, dt0 - REAL(DP), DIMENSION(NDIM), INTENT(INOUT) :: x0, v0 - END SUBROUTINE drift_dan - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepmd(dm, es, ec, x, s, c) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: dm, es, ec - REAL(DP), INTENT(OUT) :: x, s, c - END SUBROUTINE drift_kepmd - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu(dt,r0,mu,alpha,u,fp,c1,c2,c3,iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - END SUBROUTINE drift_kepu - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_fchk(dt, r0, mu, alpha, u, s, f) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u, s - REAL(DP), INTENT(OUT) :: f - END SUBROUTINE drift_kepu_fchk - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_guess(dt, r0, mu, alpha, u, s) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: s - END SUBROUTINE drift_kepu_guess - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(INOUT) :: s - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - END SUBROUTINE drift_kepu_lag - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(INOUT) :: s - REAL(DP), INTENT(OUT) :: fp, c1, c2, c3 - END SUBROUTINE drift_kepu_new - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: dt, r0, mu, alpha, u - REAL(DP), INTENT(OUT) :: s - END SUBROUTINE drift_kepu_p3solve - END INTERFACE - - INTERFACE - SUBROUTINE drift_kepu_stumpff(x, c0, c1, c2, c3) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: c0, c1, c2, c3 - END SUBROUTINE drift_kepu_stumpff - END INTERFACE - - INTERFACE - SUBROUTINE drift_one(mu, x, v, dt, iflag) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(OUT) :: iflag - REAL(DP), INTENT(IN) :: mu, dt - REAL(DP), DIMENSION(NDIM), INTENT(INOUT) :: x, v - END SUBROUTINE drift_one - END INTERFACE - - INTERFACE - SUBROUTINE helio_discard(t, npl, ntp, nsp, helio_pl1P, helio_tp1P, helio_tpd1P, dt, rmin, rmax, rmaxu, qmin, & - qmin_coord, qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpd1P - END SUBROUTINE helio_discard - END INTERFACE - - INTERFACE - SUBROUTINE helio_discard_spill(ntp, nsp, helio_tp1P, helio_tpd1P, helio_tpspP) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpd1P, helio_tpspP - END SUBROUTINE helio_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE helio_drift(npl, swifter_pl1P, dt) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE helio_drift - END INTERFACE - - INTERFACE - SUBROUTINE helio_drift_tp(ntp, swifter_tp1P, mu, dt) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE helio_drift_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_getacch(lflag, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE helio_getacch - END INTERFACE - - INTERFACE - SUBROUTINE helio_getacch_int(npl, helio_pl1P) - USE module_parameters - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE helio_getacch_int - END INTERFACE - - INTERFACE - SUBROUTINE helio_getacch_int_tp(npl, ntp, swifter_pl1P, helio_tp1P, xh) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_getacch_int_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_getacch_tp(lflag, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, xh, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_kickvb(npl, helio_pl1P, dt) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE helio_kickvb - END INTERFACE - - INTERFACE - SUBROUTINE helio_kickvb_tp(ntp, helio_tp1P, dt) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_kickvb_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_lindrift(npl, swifter_pl1P, dt, pt) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: pt - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE helio_lindrift - END INTERFACE - - INTERFACE - SUBROUTINE helio_lindrift_tp(ntp, swifter_tp1P, dt, pt) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: pt - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE helio_lindrift_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_setup(npl, ntp, helio_plA, helio_tpA, helio_pl1P, helio_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(helio_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: helio_plA - TYPE(helio_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: helio_tpA - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_setup - END INTERFACE - - INTERFACE - SUBROUTINE helio_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_step - END INTERFACE - - INTERFACE - SUBROUTINE helio_step_pl(lfirst, lextra_force, t, npl, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: ptb, pte - REAL(DP), DIMENSION(NDIM, npl), INTENT(OUT) :: xbeg,xend - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE helio_step_pl - END INTERFACE - - INTERFACE - SUBROUTINE helio_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt, & - xbeg, xend, ptb, pte) - USE module_parameters - USE module_swifter - USE module_helio - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirsttp - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: ptb, pte - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xbeg, xend - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_step_tp - END INTERFACE - - INTERFACE - SUBROUTINE helio_user_getacch(t, npl, helio_pl1P) - USE module_parameters - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE helio_user_getacch - END INTERFACE - - INTERFACE - SUBROUTINE helio_user_getacch_tp(t, ntp, helio_tp1P) - USE module_parameters - USE module_helio - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE helio_user_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE io_discard_write(t, npl, nsp, swifter_pl1P, swifter_tpd1P, fname, lbig_discard) - USE module_parameters - USE module_swifter - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lbig_discard - INTEGER(I4B), INTENT(IN) :: npl, nsp - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: fname - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tpd1P - END SUBROUTINE io_discard_write - END INTERFACE - - INTERFACE - SUBROUTINE io_discard_write_symba(t, mtiny, npl, nsppl, nsptp, nmergeadd, nmergesub, symba_pl1P, symba_pld1P, & - symba_tpd1P, mergeadd_list, mergesub_list, fname, lbig_discard) - USE module_parameters - USE module_swifter - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lbig_discard - INTEGER(I4B), INTENT(IN) :: npl, nsppl, nsptp, nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, mtiny - CHARACTER(*), INTENT(IN) :: fname - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - TYPE(symba_tp), POINTER :: symba_tpd1P - TYPE(symba_merger), DIMENSION(:), INTENT(IN) :: mergeadd_list, mergesub_list - END SUBROUTINE io_discard_write_symba - END INTERFACE - - INTERFACE - SUBROUTINE io_dump_param(nplmax, ntpmax, ntp, t, tstop, dt, in_type, istep_out, outfile, out_type, out_form, & - istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, qmin_ahi, encounter_file, & - lextra_force, lbig_discard, lrhill_present) - USE module_parameters - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lextra_force, lbig_discard, lrhill_present - INTEGER(I4B), INTENT(IN) :: nplmax, ntpmax, ntp, istep_out, istep_dump - REAL(DP), INTENT(IN) :: t, tstop, dt, j2rp2, j4rp4, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord, encounter_file, in_type, outfile, out_type, out_form - END SUBROUTINE io_dump_param - END INTERFACE - - INTERFACE - SUBROUTINE io_dump_pl(npl, swifter_pl1P, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_fxdr - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE io_dump_pl - END INTERFACE - - INTERFACE - SUBROUTINE io_dump_tp(ntp, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE io_dump_tp - END INTERFACE - - INTERFACE - SUBROUTINE io_getn(inplfile, intpfile, in_type, npl, nplmax, ntp, ntpmax) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: nplmax, ntpmax - INTEGER(I4B), INTENT(OUT) :: npl, ntp - CHARACTER(*), INTENT(IN) :: inplfile, intpfile, in_type - END SUBROUTINE io_getn - END INTERFACE - - INTERFACE - SUBROUTINE io_get_token(buffer, ilength, ifirst, ilast, ierr) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ilength - INTEGER(I4B), INTENT(INOUT) :: ifirst - INTEGER(I4B), INTENT(OUT) :: ilast, ierr - CHARACTER(*), INTENT(IN) :: buffer - END SUBROUTINE io_get_token - END INTERFACE - - INTERFACE - SUBROUTINE io_init_param(inparfile, nplmax, ntpmax, t0, tstop, dt, inplfile, intpfile, in_type, istep_out, outfile, & - out_type, out_form, out_stat, istep_dump, j2rp2, j4rp4, lclose, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, encounter_file, lextra_force, lbig_discard, lrhill_present) - USE module_parameters - IMPLICIT NONE - LOGICAL(LGT), INTENT(OUT) :: lclose, lextra_force, lbig_discard, lrhill_present - INTEGER(I4B), INTENT(OUT) :: nplmax, ntpmax, istep_out, istep_dump - REAL(DP), INTENT(OUT) :: t0, tstop, dt, j2rp2, j4rp4, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: inparfile - CHARACTER(*), INTENT(OUT) :: qmin_coord, encounter_file, inplfile, intpfile, in_type, outfile, out_type, out_form, & - out_stat - END SUBROUTINE io_init_param - END INTERFACE - - INTERFACE - SUBROUTINE io_init_pl(inplfile, in_type, lclose, lrhill_present, npl, swifter_pl1P) - USE module_parameters - USE module_swifter - USE module_fxdr - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - CHARACTER(*), INTENT(IN) :: inplfile, in_type - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE io_init_pl - END INTERFACE - - INTERFACE - SUBROUTINE io_init_tp(intpfile, in_type, ntp, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - CHARACTER(*), INTENT(IN) :: intpfile, in_type - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE io_init_tp - END INTERFACE - - INTERFACE - SUBROUTINE io_open(iu, fname, fopenstat, fmt, ierr) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: ierr - CHARACTER(*), INTENT(IN) :: fname, fopenstat, fmt - END SUBROUTINE io_open - END INTERFACE - - INTERFACE - SUBROUTINE io_open_fxdr(fname, fopenstat, lflag, iu, ierr) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lflag - INTEGER(I4B), INTENT(OUT) :: iu, ierr - CHARACTER(*), INTENT(IN) :: fname - CHARACTER(1), INTENT(IN) :: fopenstat - END SUBROUTINE io_open_fxdr - END INTERFACE - - INTERFACE - FUNCTION io_read_encounter(t, id1, id2, mass1, mass2, xh1, xh2, vh1, vh2, encounter_file, out_type) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B) :: io_read_encounter - INTEGER(I4B), INTENT(OUT) :: id1, id2 - REAL(DP), INTENT(OUT) :: t, mass1, mass2 - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: xh1, xh2, vh1, vh2 - CHARACTER(*), INTENT(IN) :: encounter_file,out_type - END FUNCTION io_read_encounter - END INTERFACE - - INTERFACE - FUNCTION io_read_hdr(iu, t, npl, ntp, iout_form, out_type) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B) :: io_read_hdr - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: npl, ntp, iout_form - REAL(DP), INTENT(OUT) :: t - CHARACTER(*), INTENT(IN) :: out_type - END FUNCTION io_read_hdr - END INTERFACE - - INTERFACE - FUNCTION io_read_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B) :: io_read_line - INTEGER(I4B), INTENT(IN) :: iu - INTEGER(I4B), INTENT(OUT) :: id - REAL(DP), INTENT(OUT) :: d1, d2, d3, d4, d5, d6 - REAL(DP), OPTIONAL, INTENT(OUT) :: MASS, RADIUS - CHARACTER(*), INTENT(IN) :: out_type - END FUNCTION io_read_line - END INTERFACE - - INTERFACE - SUBROUTINE io_write_encounter(t, id1, id2, mass1, mass2, radius1, radius2, xh1, xh2, vh1, vh2, encounter_file, out_type) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: id1, id2 - REAL(DP), INTENT(IN) :: t, mass1, mass2, radius1, radius2 - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: xh1, xh2, vh1, vh2 - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - END SUBROUTINE io_write_encounter - END INTERFACE - - INTERFACE - SUBROUTINE io_write_frame(t, npl, ntp, swifter_pl1P, swifter_tp1P, outfile, out_type, out_form, out_stat) - USE module_parameters - USE module_swifter - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: outfile, out_type, out_form, out_stat - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE io_write_frame - END INTERFACE - - INTERFACE - SUBROUTINE io_write_hdr(iu, t, npl, ntp, iout_form, out_type) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: iu, npl, ntp, iout_form - REAL(DP), INTENT(IN) :: t - CHARACTER(*), INTENT(IN) :: out_type - END SUBROUTINE io_write_hdr - END INTERFACE - - INTERFACE - SUBROUTINE io_write_line(iu, id, d1, d2, d3, d4, d5, d6, out_type, MASS, RADIUS) - USE module_parameters - USE module_fxdr - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: iu, id - REAL(DP), INTENT(IN) :: d1, d2, d3, d4, d5, d6 - REAL(DP), OPTIONAL, INTENT(IN) :: MASS, RADIUS - CHARACTER(*), INTENT(IN) :: out_type - END SUBROUTINE io_write_line - END INTERFACE - - INTERFACE - SUBROUTINE obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), DIMENSION(npl), INTENT(IN) :: irh - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - REAL(DP), DIMENSION(NDIM, npl), INTENT(OUT) :: aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE obl_acc - END INTERFACE - - INTERFACE - SUBROUTINE obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, msun) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: j2rp2, j4rp4, msun - REAL(DP), DIMENSION(ntp), INTENT(IN) :: irht - REAL(DP), DIMENSION(NDIM, ntp), INTENT(IN) :: xht - REAL(DP), DIMENSION(NDIM, ntp), INTENT(OUT) :: aoblt - END SUBROUTINE obl_acc_tp - END INTERFACE - - INTERFACE - SUBROUTINE obl_pot(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, oblpot) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), INTENT(OUT) :: oblpot - REAL(DP), DIMENSION(npl), INTENT(IN) :: irh - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE obl_pot - END INTERFACE - - INTERFACE - SUBROUTINE orbel_scget(angle, sx, cx) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: angle - REAL(DP), INTENT(OUT) :: sx, cx - END SUBROUTINE orbel_scget - END INTERFACE - - INTERFACE - SUBROUTINE orbel_xv2aeq(x, v, mu, a, e, q) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, e, q - END SUBROUTINE orbel_xv2aeq - END INTERFACE - - INTERFACE - SUBROUTINE orbel_xv2aqt(x, v, mu, a, q, capm, tperi) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, q, capm, tperi - END SUBROUTINE orbel_xv2aqt - END INTERFACE - - INTERFACE - SUBROUTINE orbel_xv2el(x, v, mu, a, e, inc, capom, omega, capm) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, e, inc, capom, omega, capm - END SUBROUTINE orbel_xv2el - END INTERFACE - - INTERFACE - SUBROUTINE ra15_discard(t, npl, ntp, nsp, ra15_pl1P, ra15_tp1P, ra15_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P, ra15_tpd1P - END SUBROUTINE ra15_discard - END INTERFACE - - INTERFACE - SUBROUTINE ra15_discard_spill(ntp, nsp, ra15_tp1P, ra15_tpd1P, ra15_tpspP) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(ra15_tp), POINTER :: ra15_tp1P, ra15_tpd1P, ra15_tpspP - END SUBROUTINE ra15_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE ra15_getaccb(lextra_force, t, npl, nplmax, ra15_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(ra15_pl), POINTER :: ra15_pl1P - END SUBROUTINE ra15_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE ra15_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - END SUBROUTINE ra15_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE ra15_sequence(niter, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, x, htry, hdid, hnext, j2rp2, j4rp4, & - lextra_force) - USE module_parameters - USE module_ra15 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: niter, npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: htry, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: hdid, hnext - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - END SUBROUTINE ra15_sequence - END INTERFACE - - INTERFACE - SUBROUTINE ra15_setup(npl, ntp, ra15_plA, ra15_tpA, ra15_pl1P, ra15_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(ra15_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: ra15_plA - TYPE(ra15_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: ra15_tpA - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - END SUBROUTINE ra15_setup - END INTERFACE - - INTERFACE - SUBROUTINE ra15_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_swifter - USE module_ra15 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - END SUBROUTINE ra15_step - END INTERFACE - - INTERFACE - SUBROUTINE ra15_user_getaccb(t, npl, ra15_pl1P) - USE module_parameters - USE module_ra15 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(ra15_pl), POINTER :: ra15_pl1P - END SUBROUTINE ra15_user_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE ra15_user_getaccb_tp(t, ntp, ra15_tp1P) - USE module_parameters - USE module_ra15 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(ra15_tp), POINTER :: ra15_tp1P - END SUBROUTINE ra15_user_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_chk(npl, ntp, rmvs_pl1P, rmvs_tp1P, xh, vh, dt, rts, lencounter) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(OUT) :: lencounter - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt, rts - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh,vh - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_chk - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_chk_ind(xr, vr, dt, r2crit, iflag) - USE module_parameters - IMPLICIT NONE - REAL(DP), INTENT(IN) :: dt, r2crit - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: xr, vr - INTEGER(I4B), INTENT(OUT) :: iflag - END SUBROUTINE rmvs_chk_ind - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_discard(t, npl, ntp, nsp, rmvs_pl1P, rmvs_tp1P, rmvs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P, rmvs_tpd1P - END SUBROUTINE rmvs_discard - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_discard_pl(t, ntp, rmvs_tp1P) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_discard_pl - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_discard_spill(ntp, nsp, rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP) - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(rmvs_tp), POINTER :: rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP - END SUBROUTINE rmvs_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_drift_tp(nenc, rmvs_tpenc1P, mu, dt) - USE module_parameters - USE module_swifter - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: mu, dt - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - END SUBROUTINE rmvs_drift_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_getaccp_ah3_tp(index, npl, nenc, rmvs_pl1P, rmvs_pleP) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: index, npl, nenc - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - END SUBROUTINE rmvs_getaccp_ah3_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_getaccp_tp(index, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, nenc, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - END SUBROUTINE rmvs_getaccp_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_interp_in(npl, rmvs_pl1P, dt) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - END SUBROUTINE rmvs_interp_in - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_interp_out(npl, rmvs_pl1P, dt) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - END SUBROUTINE rmvs_interp_out - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_kickvp_tp(nenc, rmvs_tpenc1P, dt) - USE module_parameters - USE module_swifter - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - END SUBROUTINE rmvs_kickvp_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_peri(lfirst, index, nenc, rmvs_pleP, rmvs_tpenc1P, mu, rhill, t, dt, encounter_file, out_type) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: index, nenc - REAL(DP), INTENT(IN) :: mu, rhill, t, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pleP - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - END SUBROUTINE rmvs_peri - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_setup(npl, ntp, rmvs_plA, rmvs_tpA, rmvs_pl1P, rmvs_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(rmvs_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: rmvs_plA - TYPE(rmvs_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: rmvs_tpA - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_setup - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_step - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_step_in(lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_step_in - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_step_in_tp(index, lfirst, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, & - j4rp4, dt) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, nenc, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - END SUBROUTINE rmvs_step_in_tp - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_step_out2(index, lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, & - dt, encounter_file, out_type) - USE module_parameters - USE module_whm - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirst, lextra_force - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_step_out2 - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_step_out(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirst, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - END SUBROUTINE rmvs_step_out - END INTERFACE - - INTERFACE - SUBROUTINE rmvs_user_getacch_tp(t, nenc, rmvs_tpenc1P) - USE module_parameters - USE module_rmvs - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: t - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - END SUBROUTINE rmvs_user_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_chk(xr, vr, rhill1, rhill2, dt, irec, lencounter, lvdotr) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(OUT) :: lencounter, lvdotr - INTEGER(I4B), INTENT(IN) :: irec - REAL(DP), INTENT(IN) :: rhill1, rhill2, dt - REAL(DP), DIMENSION(:), INTENT(IN) :: xr, vr - END SUBROUTINE symba_chk - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_merge_pl(t, npl, nsppl, symba_pl1P, symba_pld1P, nplplenc, plplenc_list) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: nplplenc - INTEGER(I4B), INTENT(INOUT) :: npl, nsppl - REAL(DP), INTENT(IN) :: t - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - END SUBROUTINE symba_discard_merge_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_peri_pl(t, npl, symba_pl1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, ldiscards) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(INOUT) :: ldiscards - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t, msys, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - END SUBROUTINE symba_discard_peri_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_pl(t, npl, nplmax, nsp, symba_pl1P, symba_pld1P, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, j2rp2, j4rp4, eoffset) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: nplmax - INTEGER(I4B), INTENT(INOUT) :: npl, nsp - REAL(DP), INTENT(IN) :: t, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - END SUBROUTINE symba_discard_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_spill_pl(npl, nsp, symba_pld1P, symba_plspP) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: npl, nsp - TYPE(symba_pl), POINTER :: symba_pld1P, symba_plspP - END SUBROUTINE symba_discard_spill_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_spill_tp(ntp, nsp, symba_tp1P, symba_tpd1P, symba_tpspP) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(symba_tp), POINTER :: symba_tp1P, symba_tpd1P, symba_tpspP - END SUBROUTINE symba_discard_spill_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_sun_pl(t, npl, msys, swifter_pl1P, rmin, rmax, rmaxu, ldiscards) - USE module_parameters - USE module_swifter - IMPLICIT NONE - LOGICAL(LGT), INTENT(INOUT) :: ldiscards - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t, msys, rmin, rmax, rmaxu - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE symba_discard_sun_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_discard_tp(t, npl, ntp, nsp, symba_pl1P, symba_tp1P, symba_tpd1P, dt, rmin, rmax, rmaxu, qmin, & - qmin_coord, qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P,symba_tpd1P - END SUBROUTINE symba_discard_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_energy(npl, nplmax, swifter_pl1P, j2rp2, j4rp4, ke, pe, te, htot) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), INTENT(OUT) :: ke, pe, te - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: htot - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE symba_energy - END INTERFACE - - INTERFACE - SUBROUTINE symba_getacch(lextra_force, t, npl, nplm, nplmax, symba_pl1P, j2rp2, j4rp4, nplplenc, plplenc_list) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, nplplenc - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - END SUBROUTINE symba_getacch - END INTERFACE - - INTERFACE - SUBROUTINE symba_getacch_tp(lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, xh, j2rp2, j4rp4, & - npltpenc, pltpenc_list) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax, npltpenc - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_pltpenc), DIMENSION(:), INTENT(IN) :: pltpenc_list - END SUBROUTINE symba_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_helio_drift(irec, npl, symba_pl1P, dt) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: irec, npl - REAL(DP), INTENT(IN) :: dt - TYPE(symba_pl), POINTER :: symba_pl1P - END SUBROUTINE symba_helio_drift - END INTERFACE - - INTERFACE - SUBROUTINE symba_helio_drift_tp(irec, ntp, symba_tp1P, mu, dt) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: irec, ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(symba_tp), POINTER :: symba_tp1P - END SUBROUTINE symba_helio_drift_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_helio_getacch(lflag, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE symba_helio_getacch - END INTERFACE - - INTERFACE - SUBROUTINE symba_helio_getacch_int(npl, nplm, helio_pl1P) - USE module_parameters - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, nplm - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE symba_helio_getacch_int - END INTERFACE - - INTERFACE - SUBROUTINE symba_kick(irec, nplplenc, npltpenc, plplenc_list, pltpenc_list, dt, sgn) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: irec, nplplenc, npltpenc - REAL(DP), INTENT(IN) :: dt, sgn - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(IN) :: pltpenc_list - END SUBROUTINE symba_kick - END INTERFACE - - INTERFACE - SUBROUTINE symba_merge_pl(t, dt, index, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - eoffset, vbs, encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: index, nplplenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, dt - REAL(DP), INTENT(INOUT) :: eoffset - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vbs - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - END SUBROUTINE symba_merge_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_merge_tp(t, dt, index, npltpenc, pltpenc_list, vbs, encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: index, npltpenc - REAL(DP), INTENT(IN) :: t, dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vbs - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - END SUBROUTINE symba_merge_tp - END INTERFACE - - INTERFACE - SUBROUTINE symba_peri(lfirst, npl, symba_pl1P, msys, qmin_coord) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: msys - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - END SUBROUTINE symba_peri - END INTERFACE - - INTERFACE - SUBROUTINE symba_reorder_pl(npl, symba_pl1P) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(symba_pl), POINTER :: symba_pl1P - END SUBROUTINE symba_reorder_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_setup(npl, ntp, symba_plA, symba_tpA, symba_pl1P, symba_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(symba_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: symba_plA - TYPE(symba_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: symba_tpA - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - END SUBROUTINE symba_setup - END INTERFACE - - INTERFACE - SUBROUTINE symba_step(lfirst, lextra_force, lclose, t, npl, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, & - dt, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, & - mtiny, encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force, lclose - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - INTEGER(I4B), INTENT(INOUT) :: nplplenc, npltpenc, nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt, mtiny - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - END SUBROUTINE symba_step - END INTERFACE - - INTERFACE - SUBROUTINE symba_step_helio(lfirst, lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, & - j4rp4, dt) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - END SUBROUTINE symba_step_helio - END INTERFACE - - INTERFACE - SUBROUTINE symba_step_helio_pl(lfirst, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, & - ptb, pte) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM, nplm), INTENT(OUT) :: xbeg, xend - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: ptb, pte - TYPE(helio_pl), POINTER :: helio_pl1P - END SUBROUTINE symba_step_helio_pl - END INTERFACE - - INTERFACE - SUBROUTINE symba_step_interp(lextra_force, lclose, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, & - j4rp4, dt, eoffset, mtiny, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force, lclose - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax, nplplenc, npltpenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt, mtiny - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - END SUBROUTINE symba_step_interp - END INTERFACE - - INTERFACE - RECURSIVE SUBROUTINE symba_step_recur(lclose, t, ireci, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt0, eoffset, nplplenc, & - npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose - INTEGER(I4B), INTENT(IN) :: ireci, npl, nplm, ntp, nplplenc, npltpenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, dt0 - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - END SUBROUTINE symba_step_recur - END INTERFACE - - INTERFACE - SUBROUTINE symba_user_getacch(t, npl, symba_pl1P) - USE module_parameters - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(symba_pl), POINTER :: symba_pl1P - END SUBROUTINE symba_user_getacch - END INTERFACE - - INTERFACE - SUBROUTINE symba_user_getacch_tp(t, ntp, symba_tp1P) - USE module_parameters - USE module_symba - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(symba_tp), POINTER :: symba_tp1P - END SUBROUTINE symba_user_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE tu4_discard(t, npl, ntp, nsp, tu4_pl1P, tu4_tp1P, tu4_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P,tu4_tpd1P - END SUBROUTINE tu4_discard - END INTERFACE - - INTERFACE - SUBROUTINE tu4_discard_spill(ntp, nsp, tu4_tp1P, tu4_tpd1P, tu4_tpspP) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(tu4_tp), POINTER :: tu4_tp1P, tu4_tpd1P, tu4_tpspP - END SUBROUTINE tu4_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE tu4_getaccb(lextra_force, t, npl, nplmax, tu4_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(tu4_pl), POINTER :: tu4_pl1P - END SUBROUTINE tu4_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE tu4_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - END SUBROUTINE tu4_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE tu4_kickvb(npl, ntp, tu4_pl1P, tu4_tp1P, dt) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - END SUBROUTINE tu4_kickvb - END INTERFACE - - INTERFACE - SUBROUTINE tu4_ldrift(npl, ntp, swifter_pl1P, swifter_tp1P, dt) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE tu4_ldrift - END INTERFACE - - INTERFACE - SUBROUTINE tu4_setup(npl, ntp, tu4_plA, tu4_tpA, tu4_pl1P, tu4_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(tu4_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: tu4_plA - TYPE(tu4_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: tu4_tpA - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - END SUBROUTINE tu4_setup - END INTERFACE - - INTERFACE - SUBROUTINE tu4_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_swifter - USE module_tu4 - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - END SUBROUTINE tu4_step - END INTERFACE - - INTERFACE - SUBROUTINE tu4_user_getaccb(t, npl, tu4_pl1P) - USE module_parameters - USE module_tu4 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(tu4_pl), POINTER :: tu4_pl1P - END SUBROUTINE tu4_user_getaccb - END INTERFACE - - INTERFACE - SUBROUTINE tu4_user_getaccb_tp(t, ntp, tu4_tp1P) - USE module_parameters - USE module_tu4 - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(tu4_tp), POINTER :: tu4_tp1P - END SUBROUTINE tu4_user_getaccb_tp - END INTERFACE - - INTERFACE - SUBROUTINE util_exit(code) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: code - END SUBROUTINE util_exit - END INTERFACE - - INTERFACE - SUBROUTINE util_hills(npl, swifter_pl1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - END SUBROUTINE util_hills - END INTERFACE - - INTERFACE - SUBROUTINE util_index(arr, index) - USE module_parameters - USE module_nrutil - IMPLICIT NONE - INTEGER(I4B), DIMENSION(:), INTENT(OUT) :: index - REAL(DP), DIMENSION(:), INTENT(IN) :: arr - END SUBROUTINE util_index - END INTERFACE - - INTERFACE - SUBROUTINE util_peri(lfirst, ntp, swifter_tp1P, mu, msys, qmin_coord) - USE module_parameters - USE module_swifter - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, msys - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE util_peri - END INTERFACE - - INTERFACE util_sort - SUBROUTINE util_sort_i4b(arr) - USE module_parameters - IMPLICIT NONE - INTEGER(I4B), DIMENSION(:), INTENT(INOUT) :: arr - END SUBROUTINE util_sort_i4b - SUBROUTINE util_sort_sp(arr) - USE module_parameters - IMPLICIT NONE - REAL(SP), DIMENSION(:), INTENT(INOUT) :: arr - END SUBROUTINE util_sort_sp - SUBROUTINE util_sort_dp(arr) - USE module_parameters - IMPLICIT NONE - REAL(DP), DIMENSION(:), INTENT(INOUT) :: arr - END SUBROUTINE util_sort_dp - END INTERFACE - - INTERFACE - SUBROUTINE util_toupper(string) - USE module_parameters - IMPLICIT NONE - CHARACTER(*), INTENT(INOUT) :: string - END SUBROUTINE util_toupper - END INTERFACE - - INTERFACE - SUBROUTINE util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - END SUBROUTINE util_valid - END INTERFACE - - INTERFACE - SUBROUTINE util_version - USE module_parameters - IMPLICIT NONE - END SUBROUTINE util_version - END INTERFACE - - ! Added by D. Minton - INTERFACE - FUNCTION util_kahan_sum(xsum_current, xi, xerror) - USE module_parameters - IMPLICIT NONE - REAL(DP) :: util_kahan_sum - REAL(DP), INTENT(IN) :: xsum_current, xi - REAL(DP), INTENT(INOUT) :: xerror - END FUNCTION - END INTERFACE - - INTERFACE - SUBROUTINE whm_discard(t, npl, ntp, nsp, whm_pl1P, whm_tp1P, whm_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpd1P - END SUBROUTINE whm_discard - END INTERFACE - - INTERFACE - SUBROUTINE whm_discard_spill(ntp, nsp, whm_tp1P, whm_tpd1P, whm_tpspP) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpd1P, whm_tpspP - END SUBROUTINE whm_discard_spill - END INTERFACE - - INTERFACE - SUBROUTINE whm_drift(npl, whm_pl1P, dt) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_drift - END INTERFACE - - INTERFACE - SUBROUTINE whm_drift_tp(ntp, whm_tp1P, mu, dt) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_drift_tp - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch_ah1(npl, whm_pl1P, ir3h, ir3j) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), DIMENSION(:), INTENT(IN) :: ir3h, ir3j - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_getacch_ah1 - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch_ah2(npl, whm_pl1P, ir3j) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), DIMENSION(:), INTENT(IN) :: ir3j - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_getacch_ah2 - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch_ah3(npl, whm_pl1P) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_getacch_ah3 - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch_ah3_tp(npl, ntp, whm_pl1P, whm_tp1P, xh) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_getacch_ah3_tp - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch(lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_getacch - END INTERFACE - - INTERFACE - SUBROUTINE whm_getacch_tp(lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xh, j2rp2, j4rp4) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_getacch_tp - END INTERFACE - - INTERFACE - SUBROUTINE whm_kickvh(npl, whm_pl1P, dt) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_kickvh - END INTERFACE - - INTERFACE - SUBROUTINE whm_kickvh_tp(ntp, whm_tp1P, dt) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_kickvh_tp - END INTERFACE - - INTERFACE - SUBROUTINE whm_setup(npl, ntp, whm_plA, whm_tpA, whm_pl1P, whm_tp1P, swifter_pl1P, swifter_tp1P) - USE module_parameters - USE module_swifter - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(whm_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: whm_plA - TYPE(whm_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: whm_tpA - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_setup - END INTERFACE - - INTERFACE - SUBROUTINE whm_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_step - END INTERFACE - - INTERFACE - SUBROUTINE whm_step_pl(lfirst, lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4, dt) - USE module_parameters - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_step_pl - END INTERFACE - - INTERFACE - SUBROUTINE whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, & - j4rp4, dt) - USE module_parameters - USE module_whm - IMPLICIT NONE - LOGICAL(LGT), INTENT(IN) :: lfirsttp, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xbeg, xend - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_step_tp - END INTERFACE - - INTERFACE - SUBROUTINE whm_user_getacch(t, npl, whm_pl1P) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(whm_pl), POINTER :: whm_pl1P - END SUBROUTINE whm_user_getacch - END INTERFACE - - INTERFACE - SUBROUTINE whm_user_getacch_tp(t, ntp, whm_tp1P) - USE module_parameters - USE module_whm - IMPLICIT NONE - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(whm_tp), POINTER :: whm_tp1P - END SUBROUTINE whm_user_getacch_tp - END INTERFACE - -END MODULE module_interfaces -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_nrutil.f90 b/module/module_nrutil.f90 deleted file mode 100644 index 254581500..000000000 --- a/module/module_nrutil.f90 +++ /dev/null @@ -1,189 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_nrutil -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and utility functions taken from Numerical Recipes in Fortran 90 -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : Reference: Press, W. H., Teukolsky, S. A., Vetterling, W. T. & Flannery B. P. 1996. Numerical Recipes in -! Fortran 90, The Art of Scientific Computing, 2nd Edition, Vol. 2 of Fortran Numerical Recipes, -! (Cambridge University Press). -! -!********************************************************************************************************************************** -MODULE module_nrutil - - USE module_parameters - IMPLICIT NONE - - INTEGER(I4B), PARAMETER :: NPAR_ARTH = 16 - INTEGER(I4B), PARAMETER :: NPAR2_ARTH = 8 - INTEGER(I4B), PARAMETER :: NPAR_CUMSUM = 16 - - INTERFACE arth - MODULE PROCEDURE arth_d, arth_i - END INTERFACE - - INTERFACE cumsum - MODULE PROCEDURE cumsum_i - END INTERFACE - - INTERFACE outerdiff - MODULE PROCEDURE outerdiff_d, outerdiff_i - END INTERFACE - - INTERFACE outerprod - MODULE PROCEDURE outerprod_d - END INTERFACE - -CONTAINS - - FUNCTION arth_d(first, increment, n) - INTEGER(I4B), INTENT(IN) :: n - REAL(DP), INTENT(IN) :: first, increment - REAL(DP), DIMENSION(n) :: arth_d - INTEGER(I4B) :: k, k2 - REAL(DP) :: temp - IF (n > 0) arth_d(1) = first - IF (n <= NPAR_ARTH) THEN - DO k = 2, n - arth_d(k) = arth_d(k-1) + increment - END DO - ELSE - DO k = 2, NPAR2_ARTH - arth_d(k) = arth_d(k-1) + increment - END DO - temp = increment*NPAR2_ARTH - k = NPAR2_ARTH - DO - IF (k >= n) EXIT - k2 = k + k - arth_d(k+1:MIN(k2, n)) = temp + arth_d(1:MIN(k, n-k)) - temp = temp + temp - k = k2 - END DO - END IF - RETURN - END FUNCTION arth_d - - FUNCTION arth_i(first, increment, n) - INTEGER(I4B), INTENT(IN) :: first, increment, n - INTEGER(I4B), DIMENSION(n) :: arth_i - INTEGER(I4B) :: k, k2, temp - IF (n > 0) arth_i(1) = first - IF (n <= NPAR_ARTH) THEN - DO k = 2, n - arth_i(k) = arth_i(k-1) + increment - END DO - ELSE - DO k = 2, NPAR2_ARTH - arth_i(k) = arth_i(k-1) + increment - END DO - temp = increment*NPAR2_ARTH - k = NPAR2_ARTH - DO - IF (k >= n) EXIT - k2 = k + k - arth_i(k+1:MIN(k2, n)) = temp + arth_i(1:MIN(k, n-k)) - temp = temp + temp - k = k2 - END DO - END IF - RETURN - END FUNCTION arth_i - - RECURSIVE FUNCTION cumsum_i(arr, seed) RESULT(ans) - INTEGER(I4B), DIMENSION(:), INTENT(IN) :: arr - INTEGER(I4B), OPTIONAL, INTENT(IN) :: seed - INTEGER(I4B), DIMENSION(SIZE(arr)) :: ans - INTEGER(I4B) :: n, j, sd - n = SIZE(arr) - IF (n == 0_I4B) RETURN - sd = 0_I4B - IF (PRESENT(seed)) sd = seed - ans(1) = arr(1) + sd - IF (n < NPAR_CUMSUM) THEN - DO j = 2, n - ans(j) = ans(j-1) + arr(j) - END DO - ELSE - ans(2:n:2) = cumsum_i(arr(2:n:2) + arr(1:n-1:2), sd) - ans(3:n:2) = ans(2:n-1:2) + arr(3:n:2) - END IF - RETURN - END FUNCTION cumsum_i - - FUNCTION iminloc(arr) - REAL(DP), DIMENSION(:), INTENT(IN) :: arr - INTEGER(I4B), DIMENSION(1) :: imin - INTEGER(I4B) :: iminloc - imin = MINLOC(arr(:)) - iminloc = imin(1) - RETURN - END FUNCTION iminloc - - FUNCTION outerdiff_d(a, b) - REAL(DP), DIMENSION(:), INTENT(IN) :: a, b - REAL(DP), DIMENSION(SIZE(a), SIZE(b)) :: outerdiff_d - outerdiff_d = SPREAD(a, DIM = 2, NCOPIES = SIZE(b)) - SPREAD(b, DIM = 1, NCOPIES = SIZE(a)) - RETURN - END FUNCTION outerdiff_d - - FUNCTION outerdiff_i(a, b) - INTEGER(I4B), DIMENSION(:), INTENT(IN) :: a, b - INTEGER(I4B), DIMENSION(SIZE(a), SIZE(b)) :: outerdiff_i - outerdiff_i = SPREAD(a, DIM = 2, NCOPIES = SIZE(b)) - SPREAD(b, DIM = 1, NCOPIES = SIZE(a)) - RETURN - END FUNCTION outerdiff_i - - FUNCTION outerprod_d(a, b) - REAL(DP), DIMENSION(:), INTENT(IN) :: a, b - REAL(DP), DIMENSION(SIZE(a), SIZE(b)) :: outerprod_d - outerprod_d = SPREAD(a, DIM = 2, NCOPIES = SIZE(b))*SPREAD(b, DIM = 1, NCOPIES = SIZE(a)) - RETURN - END FUNCTION outerprod_d - - FUNCTION upper_triangle(j, k, extra) - INTEGER(I4B), INTENT(IN) :: j, k - INTEGER(I4B), OPTIONAL, INTENT(IN) :: extra - LOGICAL(LGT), DIMENSION(j, k) :: upper_triangle - INTEGER(I4B) :: n - n = 0 - IF (PRESENT(extra)) n = extra - upper_triangle = (outerdiff(arth_i(1, 1, j), arth_i(1, 1, k)) < n) - RETURN - END FUNCTION upper_triangle - -END MODULE module_nrutil -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_parameters.f90 b/module/module_parameters.f90 deleted file mode 100644 index 3594170d1..000000000 --- a/module/module_parameters.f90 +++ /dev/null @@ -1,149 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_parameters -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of global parameters -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_parameters - - IMPLICIT NONE - -! Symbolic names for kind types of 4-, 2-, and 1-byte integers: - INTEGER, PARAMETER :: I4B = SELECTED_INT_KIND(9) - INTEGER, PARAMETER :: I2B = SELECTED_INT_KIND(4) - INTEGER, PARAMETER :: I1B = SELECTED_INT_KIND(2) - -! Symbolic names for kind types of single- and double-precision reals: - INTEGER, PARAMETER :: SP = KIND(1.0) - INTEGER, PARAMETER :: DP = KIND(1.0D0) - -! Symbolic name for kind type of default logical: - INTEGER, PARAMETER :: LGT = KIND(.TRUE.) - -! Frequently used mathematical constants (with precision to spare): - REAL(DP), PARAMETER :: PIBY2 = 1.570796326794896619231321691639751442099_DP - REAL(DP), PARAMETER :: PI = 3.141592653589793238462643383279502884197_DP - REAL(DP), PARAMETER :: PI3BY2 = 4.712388980384689857693965074919254326296_DP - REAL(DP), PARAMETER :: TWOPI = 6.283185307179586476925286766559005768394_DP - REAL(DP), PARAMETER :: DEGRAD = 180.0_DP/PI - -! ASCII character set parameters: - INTEGER(I4B), PARAMETER :: LOWERCASE_BEGIN = IACHAR('a') - INTEGER(I4B), PARAMETER :: LOWERCASE_END = IACHAR('z') - INTEGER(I4B), PARAMETER :: UPPERCASE_OFFSET = IACHAR('A') - IACHAR('a') - -! SWIFTER version: - REAL(SP), PARAMETER :: VERSION_NUMBER = 0.1_SP - -! Symbolic names for structure types - INTEGER(I4B), PARAMETER :: SWIFTER = 1 - INTEGER(I4B), PARAMETER :: BS = 2 - INTEGER(I4B), PARAMETER :: HELIO = 3 - INTEGER(I4B), PARAMETER :: RA15 = 4 - INTEGER(I4B), PARAMETER :: TU4 = 5 - INTEGER(I4B), PARAMETER :: WHM = 6 - INTEGER(I4B), PARAMETER :: RMVS = 7 - INTEGER(I4B), PARAMETER :: SYMBA = 8 - -! Maximum array sizes: - INTEGER(I4B), PARAMETER :: STRMAX = 128 - -! Symbolic names for binary output file types - CHARACTER(*), PARAMETER :: REAL4_TYPE = "REAL4" - CHARACTER(*), PARAMETER :: REAL8_TYPE = "REAL8" - CHARACTER(*), PARAMETER :: XDR4_TYPE = "XDR4" - CHARACTER(*), PARAMETER :: XDR8_TYPE = "XDR8" - -! Symbolic names for binary output file contents - INTEGER(I4B), PARAMETER :: EL = 1 - INTEGER(I4B), PARAMETER :: XV = 2 - INTEGER(I4B), PARAMETER :: FILT = 3 - -! OPENMP code added by D. Minton -! OpenMP Parameters - INTEGER(I4B), SAVE :: nthreads = 1 - INTEGER(I4B), PARAMETER :: NTHERSHOLD = 1000 - -! Symbolic names for function return/flag codes: - INTEGER(I4B), PARAMETER :: SUCCESS = 0 - INTEGER(I4B), PARAMETER :: FAILURE = -1 - -! Symbolic names for orbit types: - INTEGER(I4B), PARAMETER :: ELLIPSE = -1 - INTEGER(I4B), PARAMETER :: PARABOLA = 0 - INTEGER(I4B), PARAMETER :: HYPERBOLA = 1 - -! Symbolic names for body/particle status codes: - INTEGER(I4B), PARAMETER :: ACTIVE = 0 - INTEGER(I4B), PARAMETER :: INACTIVE = 1 - INTEGER(I4B), PARAMETER :: DISCARDED_RMAX = -1 - INTEGER(I4B), PARAMETER :: DISCARDED_RMIN = -2 - INTEGER(I4B), PARAMETER :: DISCARDED_RMAXU = -3 - INTEGER(I4B), PARAMETER :: DISCARDED_PERI = -4 - INTEGER(I4B), PARAMETER :: DISCARDED_PLR = -5 - INTEGER(I4B), PARAMETER :: DISCARDED_PLQ = -6 - INTEGER(I4B), PARAMETER :: DISCARDED_DRIFTERR = -7 - INTEGER(I4B), PARAMETER :: MERGED = -8 - -! String labels for body/particle addition/subtraction in discard file - CHARACTER(*), PARAMETER :: ADD = "+1" - CHARACTER(*), PARAMETER :: SUB = "-1" - -! Standard file names - CHARACTER(*), PARAMETER :: DISCARD_FILE = "discard.out" - CHARACTER(*), DIMENSION(2), PARAMETER :: DUMP_PARAM_FILE = (/ "dump_param1.dat", "dump_param2.dat" /) - CHARACTER(*), DIMENSION(2), PARAMETER :: DUMP_PL_FILE = (/ "dump_pl1.bin", "dump_pl2.bin" /) - CHARACTER(*), DIMENSION(2), PARAMETER :: DUMP_TP_FILE = (/ "dump_tp1.bin", "dump_tp2.bin" /) - -! Integration control parameters: - REAL(DP), PARAMETER :: E2MAX = 0.36_DP - REAL(DP), PARAMETER :: DM2MAX = 0.16_DP - REAL(DP), PARAMETER :: E2DM2MAX = 0.0016_DP - REAL(DP), PARAMETER :: DANBYB = 1.0E-13_DP - INTEGER(I2B), PARAMETER :: NLAG1 = 50 - INTEGER(I2B), PARAMETER :: NLAG2 = 400 - -! Miscellaneous constants: - INTEGER(I4B), PARAMETER :: NDIM = 3 - INTEGER(I4B), PARAMETER :: NDIM2 = 2*NDIM - INTEGER(I4B), PARAMETER :: LOOPMAX = 2147483647 ! 2**31 - 1 - REAL(DP), PARAMETER :: TINY = 4.0E-15_DP - -END MODULE module_parameters -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_ra15.f90 b/module/module_ra15.f90 deleted file mode 100644 index 81bc92545..000000000 --- a/module/module_ra15.f90 +++ /dev/null @@ -1,93 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_ra15 -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the 15th-order RADAU integrator -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_ra15 - - USE module_parameters - USE module_swifter - IMPLICIT NONE - - INTEGER(I4B), DIMENSION(8), PARAMETER :: NW = (/ 0, 0, 1, 3, 6, 10, 15, 21 /) - REAL(DP), DIMENSION(8), PARAMETER :: H = (/ 0.00000000000000000_DP, & - 0.05626256053692215_DP, & - 0.18024069173689236_DP, & - 0.35262471711316964_DP, & - 0.54715362633055538_DP, & - 0.73421017721541053_DP, & - 0.88532094683909577_DP, & - 0.97752061356128750_DP /) - REAL(DP), PARAMETER :: ZERO = 0.0_DP, HALF = 0.5_DP, ONE = 1.0_DP, SR = 1.4_DP, PW = 1.0_DP/9.0_DP - REAL(DP), PARAMETER :: DELTARA15 = 1.0E-7_DP - REAL(DP), DIMENSION(7) :: u, w - REAL(DP), DIMENSION(21) :: c, d, r - REAL(DP) :: eps, w1 - - TYPE ra15_pl - REAL(DP), DIMENSION(NDIM) :: xbsav ! barycentric position saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: vbsav ! barycentric velocity saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: absav ! barycentric acceleration saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - REAL(DP), DIMENSION(7, NDIM) :: b ! B-values - REAL(DP), DIMENSION(7, NDIM) :: e ! B(new)-values saved from previous RADAU step - REAL(DP), DIMENSION(7, NDIM) :: bd ! corrections to apply to current B(new)-values - REAL(DP), DIMENSION(7, NDIM) :: g ! G-values - TYPE(swifter_pl) :: swifter ! SWIFTER planet structure - TYPE(ra15_pl), POINTER :: prevP ! pointer to previous RA15 planet - TYPE(ra15_pl), POINTER :: nextP ! pointer to next RA15 planet - END TYPE ra15_pl - - TYPE ra15_tp - REAL(DP), DIMENSION(NDIM) :: xbsav ! barycentric position saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: vbsav ! barycentric velocity saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: absav ! barycentric acceleration saved at the start of each RADAU step - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - REAL(DP), DIMENSION(7, NDIM) :: b ! B-values - REAL(DP), DIMENSION(7, NDIM) :: e ! B(new)-values saved from previous RADAU step - REAL(DP), DIMENSION(7, NDIM) :: bd ! corrections to apply to current B(new)-values - REAL(DP), DIMENSION(7, NDIM) :: g ! G-values - TYPE(swifter_tp) :: swifter ! SWIFTER test particle structure - TYPE(ra15_tp), POINTER :: prevP ! pointer to previous RA15 test particle - TYPE(ra15_tp), POINTER :: nextP ! pointer to next RA15 test particle - END TYPE ra15_tp - -END MODULE module_ra15 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_random_access.f90 b/module/module_random_access.f90 deleted file mode 100644 index a7686f48d..000000000 --- a/module/module_random_access.f90 +++ /dev/null @@ -1,658 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_random_access -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and procedures to enable random (indexed) access to planet and test particle arrays -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_random_access - - USE module_parameters - USE module_swifter - USE module_bs - USE module_helio - USE module_ra15 - USE module_tu4 - USE module_whm - USE module_rmvs - USE module_symba - USE module_interfaces - IMPLICIT NONE - - INTEGER(I4B) :: istruct_pl, istruct_tp - TYPE(swifter_pl), DIMENSION(:), POINTER :: lswifter_pl1P - TYPE(swifter_tp), DIMENSION(:), POINTER :: lswifter_tp1P - TYPE(bs_pl), DIMENSION(:), POINTER :: lbs_pl1P - TYPE(bs_tp), DIMENSION(:), POINTER :: lbs_tp1P - TYPE(helio_pl), DIMENSION(:), POINTER :: lhelio_pl1P - TYPE(helio_tp), DIMENSION(:), POINTER :: lhelio_tp1P - TYPE(ra15_pl), DIMENSION(:), POINTER :: lra15_pl1P - TYPE(ra15_tp), DIMENSION(:), POINTER :: lra15_tp1P - TYPE(tu4_pl), DIMENSION(:), POINTER :: ltu4_pl1P - TYPE(tu4_tp), DIMENSION(:), POINTER :: ltu4_tp1P - TYPE(whm_pl), DIMENSION(:), POINTER :: lwhm_pl1P - TYPE(whm_tp), DIMENSION(:), POINTER :: lwhm_tp1P - TYPE(rmvs_pl), DIMENSION(:), POINTER :: lrmvs_pl1P - TYPE(rmvs_tp), DIMENSION(:), POINTER :: lrmvs_tp1P - TYPE(symba_pl), DIMENSION(:), POINTER :: lsymba_pl1P - TYPE(symba_tp), DIMENSION(:), POINTER :: lsymba_tp1P - - INTERFACE set_point - MODULE PROCEDURE set_point_swifter_pl - MODULE PROCEDURE set_point_swifter_tp - MODULE PROCEDURE set_point_bs_pl - MODULE PROCEDURE set_point_bs_tp - MODULE PROCEDURE set_point_helio_pl - MODULE PROCEDURE set_point_helio_tp - MODULE PROCEDURE set_point_ra15_pl - MODULE PROCEDURE set_point_ra15_tp - MODULE PROCEDURE set_point_tu4_pl - MODULE PROCEDURE set_point_tu4_tp - MODULE PROCEDURE set_point_whm_pl - MODULE PROCEDURE set_point_whm_tp - MODULE PROCEDURE set_point_rmvs_pl - MODULE PROCEDURE set_point_rmvs_tp - MODULE PROCEDURE set_point_symba_pl - MODULE PROCEDURE set_point_symba_tp - END INTERFACE - - INTERFACE get_point - MODULE PROCEDURE get_point_swifter_pl - MODULE PROCEDURE get_point_swifter_tp - MODULE PROCEDURE get_point_bs_pl - MODULE PROCEDURE get_point_bs_tp - MODULE PROCEDURE get_point_helio_pl - MODULE PROCEDURE get_point_helio_tp - MODULE PROCEDURE get_point_ra15_pl - MODULE PROCEDURE get_point_ra15_tp - MODULE PROCEDURE get_point_tu4_pl - MODULE PROCEDURE get_point_tu4_tp - MODULE PROCEDURE get_point_whm_pl - MODULE PROCEDURE get_point_whm_tp - MODULE PROCEDURE get_point_rmvs_pl - MODULE PROCEDURE get_point_rmvs_tp - MODULE PROCEDURE get_point_symba_pl - MODULE PROCEDURE get_point_symba_tp - END INTERFACE - -CONTAINS - - SUBROUTINE set_point_swifter_pl(s_in) - TYPE(swifter_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = SWIFTER - lswifter_pl1P => s_in - RETURN - END SUBROUTINE set_point_swifter_pl - - SUBROUTINE set_point_swifter_tp(s_in) - TYPE(swifter_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = SWIFTER - lswifter_tp1P => s_in - RETURN - END SUBROUTINE set_point_swifter_tp - - SUBROUTINE set_point_bs_pl(s_in) - TYPE(bs_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = BS - lbs_pl1P => s_in - RETURN - END SUBROUTINE set_point_bs_pl - - SUBROUTINE set_point_bs_tp(s_in) - TYPE(bs_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = BS - lbs_tp1P => s_in - RETURN - END SUBROUTINE set_point_bs_tp - - SUBROUTINE set_point_helio_pl(s_in) - TYPE(helio_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = HELIO - lhelio_pl1P => s_in - RETURN - END SUBROUTINE set_point_helio_pl - - SUBROUTINE set_point_helio_tp(s_in) - TYPE(helio_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = HELIO - lhelio_tp1P => s_in - RETURN - END SUBROUTINE set_point_helio_tp - - SUBROUTINE set_point_ra15_pl(s_in) - TYPE(ra15_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = RA15 - lra15_pl1P => s_in - RETURN - END SUBROUTINE set_point_ra15_pl - - SUBROUTINE set_point_ra15_tp(s_in) - TYPE(ra15_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = RA15 - lra15_tp1P => s_in - RETURN - END SUBROUTINE set_point_ra15_tp - - SUBROUTINE set_point_tu4_pl(s_in) - TYPE(tu4_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = TU4 - ltu4_pl1P => s_in - RETURN - END SUBROUTINE set_point_tu4_pl - - SUBROUTINE set_point_tu4_tp(s_in) - TYPE(tu4_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = TU4 - ltu4_tp1P => s_in - RETURN - END SUBROUTINE set_point_tu4_tp - - SUBROUTINE set_point_whm_pl(s_in) - TYPE(whm_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = WHM - lwhm_pl1P => s_in - RETURN - END SUBROUTINE set_point_whm_pl - - SUBROUTINE set_point_whm_tp(s_in) - TYPE(whm_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = WHM - lwhm_tp1P => s_in - RETURN - END SUBROUTINE set_point_whm_tp - - SUBROUTINE set_point_rmvs_pl(s_in) - TYPE(rmvs_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = RMVS - lrmvs_pl1P => s_in - RETURN - END SUBROUTINE set_point_rmvs_pl - - SUBROUTINE set_point_rmvs_tp(s_in) - TYPE(rmvs_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = RMVS - lrmvs_tp1P => s_in - RETURN - END SUBROUTINE set_point_rmvs_tp - - SUBROUTINE set_point_symba_pl(s_in) - TYPE(symba_pl), DIMENSION(:), TARGET :: s_in - istruct_pl = SYMBA - lsymba_pl1P => s_in - RETURN - END SUBROUTINE set_point_symba_pl - - SUBROUTINE set_point_symba_tp(s_in) - TYPE(symba_tp), DIMENSION(:), TARGET :: s_in - istruct_tp = SYMBA - lsymba_tp1P => s_in - RETURN - END SUBROUTINE set_point_symba_tp - - SUBROUTINE get_point_swifter_pl(i, swifter_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - SELECT CASE (istruct_pl) - CASE (SWIFTER) - IF (ASSOCIATED(lswifter_pl1P)) THEN - swifter_plP => lswifter_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (BS) - IF (ASSOCIATED(lbs_pl1P)) THEN - swifter_plP => lbs_pl1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (HELIO) - IF (ASSOCIATED(lhelio_pl1P)) THEN - swifter_plP => lhelio_pl1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (RA15) - IF (ASSOCIATED(lra15_pl1P)) THEN - swifter_plP => lra15_pl1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (TU4) - IF (ASSOCIATED(ltu4_pl1P)) THEN - swifter_plP => ltu4_pl1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (WHM) - IF (ASSOCIATED(lwhm_pl1P)) THEN - swifter_plP => lwhm_pl1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (RMVS) - IF (ASSOCIATED(lrmvs_pl1P)) THEN - swifter_plP => lrmvs_pl1P(i)%whm%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF - CASE (SYMBA) - IF (ASSOCIATED(lsymba_pl1P)) THEN - swifter_plP => lsymba_pl1P(i)%helio%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_swifter_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_swifter_pl - - SUBROUTINE get_point_swifter_tp(i, swifter_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - SELECT CASE (istruct_tp) - CASE (SWIFTER) - IF (ASSOCIATED(lswifter_tp1P)) THEN - swifter_tpP => lswifter_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (BS) - IF (ASSOCIATED(lbs_tp1P)) THEN - swifter_tpP => lbs_tp1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (HELIO) - IF (ASSOCIATED(lhelio_tp1P)) THEN - swifter_tpP => lhelio_tp1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (RA15) - IF (ASSOCIATED(lra15_tp1P)) THEN - swifter_tpP => lra15_tp1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (TU4) - IF (ASSOCIATED(ltu4_tp1P)) THEN - swifter_tpP => ltu4_tp1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (WHM) - IF (ASSOCIATED(lwhm_tp1P)) THEN - swifter_tpP => lwhm_tp1P(i)%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (RMVS) - IF (ASSOCIATED(lrmvs_tp1P)) THEN - swifter_tpP => lrmvs_tp1P(i)%whm%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF - CASE (SYMBA) - IF (ASSOCIATED(lsymba_tp1P)) THEN - swifter_tpP => lsymba_tp1P(i)%helio%swifter - ELSE - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_swifter_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_swifter_tp - - SUBROUTINE get_point_bs_pl(i, bs_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(bs_pl), POINTER :: bs_plP - SELECT CASE (istruct_pl) - CASE (BS) - IF (ASSOCIATED(lbs_pl1P)) THEN - bs_plP => lbs_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_bs_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_bs_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_bs_pl - - SUBROUTINE get_point_bs_tp(i, bs_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(bs_tp), POINTER :: bs_tpP - SELECT CASE (istruct_tp) - CASE (BS) - IF (ASSOCIATED(lbs_tp1P)) THEN - bs_tpP => lbs_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_bs_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_bs_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_bs_tp - - SUBROUTINE get_point_helio_pl(i, helio_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(helio_pl), POINTER :: helio_plP - SELECT CASE (istruct_pl) - CASE (HELIO) - IF (ASSOCIATED(lhelio_pl1P)) THEN - helio_plP => lhelio_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_helio_pl" - CALL util_exit(FAILURE) - END IF - CASE (SYMBA) - IF (ASSOCIATED(lsymba_pl1P)) THEN - helio_plP => lsymba_pl1P(i)%helio - ELSE - WRITE(*, *) "Error in get_point_helio_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_helio_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_helio_pl - - SUBROUTINE get_point_helio_tp(i, helio_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(helio_tp), POINTER :: helio_tpP - SELECT CASE (istruct_tp) - CASE (HELIO) - IF (ASSOCIATED(lhelio_tp1P)) THEN - helio_tpP => lhelio_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_helio_tp" - CALL util_exit(FAILURE) - END IF - CASE (SYMBA) - IF (ASSOCIATED(lsymba_tp1P)) THEN - helio_tpP => lsymba_tp1P(i)%helio - ELSE - WRITE(*, *) "Error in get_point_helio_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_helio_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_helio_tp - - SUBROUTINE get_point_ra15_pl(i, ra15_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(ra15_pl), POINTER :: ra15_plP - SELECT CASE (istruct_pl) - CASE (RA15) - IF (ASSOCIATED(lra15_pl1P)) THEN - ra15_plP => lra15_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_ra15_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_ra15_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_ra15_pl - - SUBROUTINE get_point_ra15_tp(i, ra15_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(ra15_tp), POINTER :: ra15_tpP - SELECT CASE (istruct_tp) - CASE (RA15) - IF (ASSOCIATED(lra15_tp1P)) THEN - ra15_tpP => lra15_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_ra15_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_ra15_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_ra15_tp - - SUBROUTINE get_point_tu4_pl(i, tu4_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(tu4_pl), POINTER :: tu4_plP - SELECT CASE (istruct_pl) - CASE (TU4) - IF (ASSOCIATED(ltu4_pl1P)) THEN - tu4_plP => ltu4_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_tu4_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_tu4_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_tu4_pl - - SUBROUTINE get_point_tu4_tp(i, tu4_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(tu4_tp), POINTER :: tu4_tpP - SELECT CASE (istruct_tp) - CASE (TU4) - IF (ASSOCIATED(ltu4_tp1P)) THEN - tu4_tpP => ltu4_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_tu4_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_tu4_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_tu4_tp - - SUBROUTINE get_point_whm_pl(i, whm_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(whm_pl), POINTER :: whm_plP - SELECT CASE (istruct_pl) - CASE (WHM) - IF (ASSOCIATED(lwhm_pl1P)) THEN - whm_plP => lwhm_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_whm_pl" - CALL util_exit(FAILURE) - END IF - CASE (RMVS) - IF (ASSOCIATED(lrmvs_pl1P)) THEN - whm_plP => lrmvs_pl1P(i)%whm - ELSE - WRITE(*, *) "Error in get_point_whm_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_whm_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_whm_pl - - SUBROUTINE get_point_whm_tp(i, whm_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(whm_tp), POINTER :: whm_tpP - SELECT CASE (istruct_tp) - CASE (WHM) - IF (ASSOCIATED(lwhm_tp1P)) THEN - whm_tpP => lwhm_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_whm_tp" - CALL util_exit(FAILURE) - END IF - CASE (RMVS) - IF (ASSOCIATED(lrmvs_tp1P)) THEN - whm_tpP => lrmvs_tp1P(i)%whm - ELSE - WRITE(*, *) "Error in get_point_whm_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_whm_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_whm_tp - - SUBROUTINE get_point_rmvs_pl(i, rmvs_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(rmvs_pl), POINTER :: rmvs_plP - SELECT CASE (istruct_pl) - CASE (RMVS) - IF (ASSOCIATED(lrmvs_pl1P)) THEN - rmvs_plP => lrmvs_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_rmvs_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_rmvs_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_rmvs_pl - - SUBROUTINE get_point_rmvs_tp(i, rmvs_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(rmvs_tp), POINTER :: rmvs_tpP - SELECT CASE (istruct_tp) - CASE (RMVS) - IF (ASSOCIATED(lrmvs_tp1P)) THEN - rmvs_tpP => lrmvs_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_rmvs_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_rmvs_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_rmvs_tp - - SUBROUTINE get_point_symba_pl(i, symba_plP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(symba_pl), POINTER :: symba_plP - SELECT CASE (istruct_pl) - CASE (SYMBA) - IF (ASSOCIATED(lsymba_pl1P)) THEN - symba_plP => lsymba_pl1P(i) - ELSE - WRITE(*, *) "Error in get_point_symba_pl" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_symba_pl" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_symba_pl - - SUBROUTINE get_point_symba_tp(i, symba_tpP) - INTEGER(I4B), INTENT(IN) :: i - TYPE(symba_tp), POINTER :: symba_tpP - SELECT CASE (istruct_tp) - CASE (SYMBA) - IF (ASSOCIATED(lsymba_tp1P)) THEN - symba_tpP => lsymba_tp1P(i) - ELSE - WRITE(*, *) "Error in get_point_symba_tp" - CALL util_exit(FAILURE) - END IF -! DEK - improve error handler - CASE DEFAULT - WRITE(*, *) "Error in get_point_symba_tp" - CALL util_exit(FAILURE) - END SELECT - RETURN - END SUBROUTINE get_point_symba_tp - -END MODULE module_random_access -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_rmvs.f90 b/module/module_rmvs.f90 deleted file mode 100644 index a406f0706..000000000 --- a/module/module_rmvs.f90 +++ /dev/null @@ -1,91 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_rmvs -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the Regularized Mixed Variable Symplectic algorithm -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_rmvs - - USE module_parameters - USE module_whm - IMPLICIT NONE - - INTEGER(I4B), PARAMETER :: NTENC = 10 - INTEGER(I4B), PARAMETER :: NTPHENC = 3 - INTEGER(I4B), PARAMETER :: NTPENC = NTENC*NTPHENC - REAL(DP), PARAMETER :: RHSCALE = 3.5_DP - REAL(DP), PARAMETER :: RHPSCALE = 1.0_DP - REAL(DP), PARAMETER :: FACQDT = 2.0_DP - - TYPE rmvs_pl - INTEGER(I4B) :: nenc ! number of test particles encountering planet this full RMVS time step - REAL(DP), DIMENSION(NDIM, 0:NTENC) :: xout ! interpolated heliocentric planet position for outer encounter - REAL(DP), DIMENSION(NDIM, 0:NTENC) :: vout ! interpolated heliocentric planet velocity for outer encounter - REAL(DP), DIMENSION(NDIM, 0:NTPHENC) :: xin ! interpolated heliocentric planet position for inner encounter - REAL(DP), DIMENSION(NDIM, 0:NTPHENC) :: vin ! interpolated heliocentric planet velocity for inner encounter - REAL(DP), DIMENSION(NDIM, 0:NTPHENC) :: xpc ! interpolated planetocentric planet position for inner encounter - REAL(DP), DIMENSION(NDIM, 0:NTPHENC) :: aobl ! barycentric acceleration due to central body oblateness during - ! inner encounter - TYPE(rmvs_tp), POINTER :: tpenc1P ! pointer to first test particle encountering planet - TYPE(whm_pl) :: whm ! WHM planet structure - TYPE(rmvs_pl), POINTER :: prevP ! pointer to previous RMVS planet - TYPE(rmvs_pl), POINTER :: nextP ! pointer to next RMVS planet - END TYPE rmvs_pl - - TYPE rmvs_tp - INTEGER(I4B) :: isperi ! planetocentric pericenter passage flag (not persistent for a set of inner - ! encounter steps) - LOGICAL(LGT) :: lperi ! planetocentric pericenter passage flag (persistent for a full RMVS time step) - REAL(DP) :: peri ! planetocentric pericenter distance (set to smallest pericenter distance achieved - ! over a full RMVS time step) - REAL(DP), DIMENSION(NDIM) :: xpc ! planetocentric position - REAL(DP), DIMENSION(NDIM) :: vpc ! planetocentric velocity - REAL(DP), DIMENSION(NDIM) :: apc ! total planetocentric acceleration - TYPE(rmvs_pl), POINTER :: plperP ! pointer to planet associated with pericenter distance peri (persistent over a - ! full RMVS time step) - TYPE(rmvs_pl), POINTER :: plencP ! pointer to planet that test particle is encountering (not persistent for a full - ! RMVS time step) - TYPE(rmvs_tp), POINTER :: tpencP ! pointer to next test particle encountering planet - TYPE(whm_tp) :: whm ! WHM test particle structure - TYPE(rmvs_tp), POINTER :: prevP ! pointer to previous RMVS test particle - TYPE(rmvs_tp), POINTER :: nextP ! pointer to next RMVS test particle - END TYPE rmvs_tp - -END MODULE module_rmvs -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_swifter.f90 b/module/module_swifter.f90 deleted file mode 100644 index 80b154ec6..000000000 --- a/module/module_swifter.f90 +++ /dev/null @@ -1,94 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_swifter -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures generic to all integrators -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_swifter - - USE module_parameters - IMPLICIT NONE - - ! Added by D. Minton - TYPE swifter_ptr_arr - TYPE(swifter_pl), POINTER :: thisP ! pointer to current swifter planet - END TYPE swifter_ptr_arr - TYPE swifter_ptr_arr_tp - TYPE(swifter_tp), POINTER :: thisP ! pointer to current swifter planet - END TYPE swifter_ptr_arr_tp - !^^^^^^^^^^^^^^^^^^^ - - TYPE swifter_pl - INTEGER(I4B) :: id ! external identifier - INTEGER(I4B) :: status ! status - REAL(DP) :: mass ! mass - REAL(DP) :: radius ! radius - REAL(DP) :: rhill ! Hill's sphere radius - REAL(DP), DIMENSION(NDIM) :: xh ! heliocentric position - REAL(DP), DIMENSION(NDIM) :: vh ! heliocentric velocity - REAL(DP), DIMENSION(NDIM) :: xb ! barycentric position - REAL(DP), DIMENSION(NDIM) :: vb ! barycentric velocity - TYPE(swifter_pl), POINTER :: prevP ! pointer to previous planet - TYPE(swifter_pl), POINTER :: nextP ! pointer to next planet - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(swifter_ptr_arr),DIMENSION(:),ALLOCATABLE :: swifter_plPA ! Array of pointers to Swifter planet structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE swifter_pl - - TYPE swifter_tp - INTEGER(I4B) :: id ! external identifier - INTEGER(I4B) :: status ! status - INTEGER(I4B) :: isperi ! perihelion passage flag - REAL(DP) :: peri ! perihelion distance - REAL(DP) :: atp ! semimajor axis following perihelion passage - REAL(DP), DIMENSION(NDIM) :: xh ! heliocentric position - REAL(DP), DIMENSION(NDIM) :: vh ! heliocentric velocity - REAL(DP), DIMENSION(NDIM) :: xb ! barycentric position - REAL(DP), DIMENSION(NDIM) :: vb ! barycentric velocity - TYPE(swifter_tp), POINTER :: prevP ! pointer to previous test particle - TYPE(swifter_tp), POINTER :: nextP ! pointer to next test particle - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(swifter_ptr_arr_tp),DIMENSION(:),ALLOCATABLE :: swifter_tpPA ! Array of pointers to Swifter planet structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE swifter_tp - -END MODULE module_swifter -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_symba.f90 b/module/module_symba.f90 deleted file mode 100644 index 68e573a7f..000000000 --- a/module/module_symba.f90 +++ /dev/null @@ -1,123 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_symba -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the Symplectic Massive Body Algorithm -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_symba - - USE module_parameters - USE module_helio - IMPLICIT NONE - - INTEGER(I4B), PARAMETER :: NENMAX = 32767 - INTEGER(I4B), PARAMETER :: NTENC = 3 - REAL(DP), PARAMETER :: RHSCALE = 6.5_DP - REAL(DP), PARAMETER :: RSHELL = 0.48075_DP - - ! Added by D. Minton - TYPE symba_ptr_arr - TYPE(symba_pl), POINTER :: thisP ! pointer to current SyMBA planet - END TYPE symba_ptr_arr - - TYPE symba_ptr_arr_tp - TYPE(symba_tp), POINTER :: thisP ! pointer to current SyMBA planet - END TYPE symba_ptr_arr_tp - !^^^^^^^^^^^^^^^^^^^ - - TYPE symba_pl - LOGICAL(LGT) :: lmerged ! flag indicating whether body has merged with another this time step - INTEGER(I4B) :: nplenc ! number of encounters with other planets this time step - INTEGER(I4B) :: ntpenc ! number of encounters with test particles this time step - INTEGER(I4B) :: levelg ! level at which this body should be moved - INTEGER(I4B) :: levelm ! deepest encounter level achieved this time step - INTEGER(I4B) :: nchild ! number of children in merger list - INTEGER(I4B) :: isperi ! perihelion passage flag - REAL(DP) :: peri ! perihelion distance - REAL(DP) :: atp ! semimajor axis following perihelion passage - TYPE(helio_pl) :: helio ! HELIO planet structure - TYPE(symba_pl), POINTER :: parentP ! pointer to parent of merger list - TYPE(symba_pl), POINTER :: childP ! pointer to next child in merger list - TYPE(symba_pl), POINTER :: prevP ! pointer to previous SyMBA planet - TYPE(symba_pl), POINTER :: nextP ! pointer to next SyMBA planet - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(symba_ptr_arr),DIMENSION(:),ALLOCATABLE :: symba_plPA ! Array of pointers to SyMBA planet structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE symba_pl - - TYPE symba_tp - INTEGER(I4B) :: nplenc ! number of encounters with planets this time step - INTEGER(I4B) :: levelg ! level at which this particle should be moved - INTEGER(I4B) :: levelm ! deepest encounter level achieved this time step - TYPE(helio_tp) :: helio ! HELIO test particle structure - TYPE(symba_tp), POINTER :: prevP ! pointer to previous SyMBA test particle - TYPE(symba_tp), POINTER :: nextP ! pointer to next SyMBA test particle - ! Added by D. Minton - ! Used for OpenMP parallelized loops - TYPE(symba_ptr_arr_tp),DIMENSION(:),ALLOCATABLE :: symba_tpPA ! Array of pointers to SyMBA test particle structures - !^^^^^^^^^^^^^^^^^^^ - END TYPE symba_tp - - TYPE symba_plplenc - LOGICAL(LGT) :: lvdotr ! relative vdotr flag - INTEGER(I4B) :: status ! status of the interaction - INTEGER(I4B) :: level ! encounter recursion level - TYPE(symba_pl), POINTER :: pl1P ! pointer to first planet in encounter - TYPE(symba_pl), POINTER :: pl2P ! pointer to second planet in encounter - END TYPE symba_plplenc - - TYPE symba_pltpenc - LOGICAL(LGT) :: lvdotr ! relative vdotr flag - INTEGER(I4B) :: status ! status of the interaction - INTEGER(I4B) :: level ! encounter recursion level - TYPE(symba_pl), POINTER :: plP ! pointer to planet in encounter - TYPE(symba_tp), POINTER :: tpP ! pointer to test particle in encounter - END TYPE symba_pltpenc - - TYPE symba_merger - INTEGER(I4B) :: id ! external identifier - INTEGER(I4B) :: status ! status - INTEGER(I4B) :: ncomp ! number of component bodies in this one during this merger - REAL(DP), DIMENSION(NDIM) :: xh ! heliocentric position - REAL(DP), DIMENSION(NDIM) :: vh ! heliocentric velocity - END TYPE symba_merger - -END MODULE module_symba -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_tu4.f90 b/module/module_tu4.f90 deleted file mode 100644 index 747bb5ba1..000000000 --- a/module/module_tu4.f90 +++ /dev/null @@ -1,67 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_tu4 -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the 4th-order T + V integrator -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_tu4 - - USE module_parameters - USE module_swifter - IMPLICIT NONE - - REAL(DP) :: w0, w1 - REAL(DP), DIMENSION(4) :: asymp, bsymp - - TYPE tu4_pl - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - TYPE(swifter_pl) :: swifter ! SWIFTER planet structure - TYPE(tu4_pl), POINTER :: prevP ! pointer to previous TU4 planet - TYPE(tu4_pl), POINTER :: nextP ! pointer to next TU4 planet - END TYPE tu4_pl - - TYPE tu4_tp - REAL(DP), DIMENSION(NDIM) :: ab ! total barycentric acceleration - TYPE(swifter_tp) :: swifter ! SWIFTER test particle structure - TYPE(tu4_tp), POINTER :: prevP ! pointer to previous TU4 test particle - TYPE(tu4_tp), POINTER :: nextP ! pointer to next TU4 test particle - END TYPE tu4_tp - -END MODULE module_tu4 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/module/module_whm.f90 b/module/module_whm.f90 deleted file mode 100644 index cd2b0a40e..000000000 --- a/module/module_whm.f90 +++ /dev/null @@ -1,72 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : module_whm -! Unit Type : module -! Project : SWIFTER -! Package : module -! Language : Fortran 90/95 -! -! Description : Definition of data and structures specific to the Wisdom-Holman Mapping -! -! Input -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Output -! Arguments : N/A -! Terminal : N/A -! File : N/A -! -! Invocation : N/A -! -! Notes : -! -!********************************************************************************************************************************** -MODULE module_whm - - USE module_parameters - USE module_swifter - IMPLICIT NONE - - REAL(DP), DIMENSION(NDIM) :: ah0 ! zeroth term of heliocentric acceleration - - TYPE whm_pl - REAL(DP) :: eta ! Jacobi mass - REAL(DP), DIMENSION(NDIM) :: xj ! Jacobi position - REAL(DP), DIMENSION(NDIM) :: vj ! Jacobi velocity - REAL(DP), DIMENSION(NDIM) :: ah1 ! first term of heliocentric acceleration - REAL(DP), DIMENSION(NDIM) :: ah2 ! second term of heliocentric acceleration - REAL(DP), DIMENSION(NDIM) :: ah3 ! third term of heliocentric acceleration - REAL(DP), DIMENSION(NDIM) :: ah ! total heliocentric acceleration - TYPE(swifter_pl) :: swifter ! SWIFTER planet structure - TYPE(whm_pl), POINTER :: prevP ! pointer to previous WHM planet - TYPE(whm_pl), POINTER :: nextP ! pointer to next WHM planet - END TYPE whm_pl - - TYPE whm_tp - REAL(DP), DIMENSION(NDIM) :: ah ! total heliocentric acceleration - TYPE(swifter_tp) :: swifter ! SWIFTER test particle structure - TYPE(whm_tp), POINTER :: prevP ! pointer to previous WHM test particle - TYPE(whm_tp), POINTER :: nextP ! pointer to next WHM test particle - END TYPE whm_tp - -END MODULE module_whm -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/obl/obl_acc.f90 b/obl/obl_acc.f90 deleted file mode 100644 index dd915780c..000000000 --- a/obl/obl_acc.f90 +++ /dev/null @@ -1,120 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : obl_acc -! Unit Type : subroutine -! Project : Swifter -! Package : obl -! Language : Fortran 90/95 -! -! Description : Compute the barycentric accelerations of planets due to the oblateness of the central body -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! xh : heliocentric positions of planets -! irh : inverse heliocentric radii of planets -! Terminal : none -! File : none -! -! Output -! Arguments : aobl : barycentric accelerations of planets due to central body oblateness -! Terminal : none -! File : none -! -! Invocation : CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) -! -! Notes : Adapted from Martin Duncan's Swift routine obl_acc.f -! -! Returned values do not include monopole term or terms higher than J4 -! -!********************************************************************************************************************************** -SUBROUTINE obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => obl_acc - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), DIMENSION(npl), INTENT(IN) :: irh - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - REAL(DP), DIMENSION(NDIM, npl), INTENT(OUT) :: aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: rinv2, t0, t1, t2, t3, fac1, fac2, msun - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - msun = swifter_pl1P%mass - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP,rinv2,t0,t1,t2,t3,fac1,fac2) & - !$OMP SHARED(npl,swifter_pl1P,aobl,irh,msun,j2rp2,xh,j4rp4) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP => swifter_pl1P%swifter_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^ - rinv2 = irh(i)**2 - t0 = -msun*rinv2*rinv2*irh(i) - t1 = 1.5_DP*j2rp2 - t2 = xh(3, i)*xh(3, i)*rinv2 - t3 = 1.875_DP*j4rp4*rinv2 - fac1 = t0*(t1 - t3 - (5.0_DP*t1 - (14.0_DP - 21.0_DP*t2)*t3)*t2) - fac2 = 2.0_DP*t0*(t1 - (2.0_DP - (14.0_DP*t2/3.0_DP))*t3) - aobl(:, i) = fac1*xh(:, i) - aobl(3, i) = fac2*xh(3, i) + aobl(3, i) - END DO - !$OMP END PARALLEL DO - aobl(:, 1) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP) & - !$OMP SHARED(npl,swifter_pl1P,aobl,msun) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !aobl(:, 1) = aobl(:, 1) - swifter_plP%mass*aobl(:, i)/msun - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - aobl(:, 1) = aobl(:, 1) - swifter_pl1P%swifter_plPA(i)%thisP%mass*aobl(:, i)/msun - !^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE obl_acc -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/obl/obl_acc_tp.f90 b/obl/obl_acc_tp.f90 deleted file mode 100644 index d8de627b6..000000000 --- a/obl/obl_acc_tp.f90 +++ /dev/null @@ -1,84 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : obl_acc_tp -! Unit Type : subroutine -! Project : Swifter -! Package : obl -! Language : Fortran 90/95 -! -! Description : Compute the barycentric accelerations of test particles due to the oblateness of the central body -! -! Input -! Arguments : ntp : number of active test particles -! xht : heliocentric positions of test particles -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! irht : inverse heliocentric radii of test particles -! msun : mass of the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : aoblt : barycentric accelerations of test particles due to central body oblateness -! Terminal : none -! File : none -! -! Invocation : CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, msun) -! -! Notes : Adapted from Hal Levison's Swift routine obl_acc_tp.f -! -! Returned values do not include monopole term or terms higher than J4 -! -!********************************************************************************************************************************** -SUBROUTINE obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, msun) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => obl_acc_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: j2rp2, j4rp4, msun - REAL(DP), DIMENSION(ntp), INTENT(IN) :: irht - REAL(DP), DIMENSION(NDIM, ntp), INTENT(IN) :: xht - REAL(DP), DIMENSION(NDIM, ntp), INTENT(OUT) :: aoblt - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: rinv2, t0, t1, t2, t3, r2, fac1, fac2 - -! Executable code - DO i = 1, ntp - rinv2 = irht(i)**2 - t0 = -msun*rinv2*rinv2*irht(i) - t1 = 1.5_DP*j2rp2 - t2 = xht(3, i)*xht(3, i)*rinv2 - t3 = 1.875_DP*j4rp4*rinv2 - fac1 = t0*(t1 - t3 - (5.0_DP*t1 - (14.0_DP - 21.0_DP*t2)*t3)*t2) - fac2 = 2.0_DP*t0*(t1 - (2.0_DP - (14.0_DP*t2/3.0_DP))*t3) - aoblt(:, i) = fac1*xht(:, i) - aoblt(3, i) = aoblt(3, i) + fac2*xht(3, i) - END DO - - RETURN - -END SUBROUTINE obl_acc_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/obl/obl_pot.f90 b/obl/obl_pot.f90 deleted file mode 100644 index b6456c6cd..000000000 --- a/obl/obl_pot.f90 +++ /dev/null @@ -1,92 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : obl_pot -! Unit Type : subroutine -! Project : Swifter -! Package : obl -! Language : Fortran 90/95 -! -! Description : Compute the contribution to the total gravitational potential due solely to the oblateness of the central body -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! xh : heliocentric positions of the planets -! irh : inverse heliocentric radii of the planets -! Terminal : none -! File : none -! -! Output -! Arguments : oblpot : total gravitational potential due to J2 and J4 oblateness terms for the central body -! Terminal : none -! File : none -! -! Invocation : CALL obl_pot(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, oblpot) -! -! Notes : Adapted from Martin Duncan's Swift routine obl_pot.f -! -! Returned value does not include monopole term or terms higher than J4 -! -! Reference: MacMillan, W. D. 1958. The Theory of the Potential, (Dover Publications), 363. -! -!********************************************************************************************************************************** -SUBROUTINE obl_pot(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, oblpot) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => obl_pot - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), INTENT(OUT) :: oblpot - REAL(DP), DIMENSION(npl), INTENT(IN) :: irh - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: rinv2, t0, t1, t2, t3, p2, p4, mu - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - oblpot = 0.0_DP - mu = swifter_pl1P%mass - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - rinv2 = irh(i)**2 - t0 = mu*swifter_plP%mass*rinv2*irh(i) - t1 = j2rp2 - t2 = xh(3, i)*xh(3, i)*rinv2 - t3 = j4rp4*rinv2 - p2 = 0.5_DP*(3.0_DP*t2 - 1.0_DP) - p4 = 0.125_DP*((35.0_DP*t2 - 30.0_DP)*t2 + 3.0_DP) - oblpot = oblpot + t0*(t1*p2 + t3*p4) - END DO - - RETURN - -END SUBROUTINE obl_pot -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/orbel/orbel_scget.f90 b/orbel/orbel_scget.f90 deleted file mode 100644 index b845feadc..000000000 --- a/orbel/orbel_scget.f90 +++ /dev/null @@ -1,72 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : orbel_scget -! Unit Type : subroutine -! Project : Swifter -! Package : orbel -! Language : Fortran 90/95 -! -! Description : Efficiently compute the sine and cosine of an input angle -! -! Input -! Arguments : angle : input angle -! Terminal : none -! File : none -! -! Output -! Arguments : sx : sine of the angle -! cx : cosine of the angle -! Terminal : none -! File : none -! -! Invocation : CALL orbel_scget(angle, sx, cx) -! -! Notes : Adapted from Martin Duncan's Swift routine orbel_scget.f -! -! Input angle must be in radians -! -!********************************************************************************************************************************** -SUBROUTINE orbel_scget(angle, sx, cx) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => orbel_scget - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: angle - REAL(DP), INTENT(OUT) :: sx, cx - -! Internals - INTEGER(I4B) :: nper - REAL(DP) :: x - -! Executable code - nper = angle/TWOPI - x = angle - nper*TWOPI - IF (x < 0.0_DP) x = x + TWOPI - sx = SIN(x) - cx = SQRT(1.0_DP - sx*sx) - IF ((x > PIBY2) .AND. (x < PI3BY2)) cx = -cx - - RETURN - -END SUBROUTINE orbel_scget -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/orbel/orbel_xv2aeq.f90 b/orbel/orbel_xv2aeq.f90 deleted file mode 100644 index faf0b9d16..000000000 --- a/orbel/orbel_xv2aeq.f90 +++ /dev/null @@ -1,107 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : orbel_xv2aeq -! Unit Type : subroutine -! Project : Swifter -! Package : orbel -! Language : Fortran 90/95 -! -! Description : Compute semimajor axis, eccentricity, and pericentric distance from relative Cartesian position and velocity -! -! Input -! Arguments : x : relative position -! v : relative velocity -! mu : G * (m1 + m2) -! Terminal : none -! File : none -! -! Output -! Arguments : a : semimajor axis (pericentric distance for a parabolic orbit) -! e : eccentricity -! q : pericentric distance -! Terminal : none -! File : none -! -! Invocation : CALL orbel_xv2aeq(x, v, mu, a, e, q) -! -! Notes : Adapted from Luke Dones' Swift routine orbel_xv2aeq.f -! -!********************************************************************************************************************************** -SUBROUTINE orbel_xv2aeq(x, v, mu, a, e, q) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => orbel_xv2aeq - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, e, q - -! Internals - INTEGER(I4B) :: iorbit_type - REAL(DP) :: r, v2, hx, hy, hz, h2, energy, fac - -! Executable code - a = 0.0_DP - e = 0.0_DP - q = 0.0_DP - r = SQRT(DOT_PRODUCT(x(:), x(:))) - v2 = DOT_PRODUCT(v(:), v(:)) - hx = x(2)*v(3) - x(3)*v(2) - hy = x(3)*v(1) - x(1)*v(3) - hz = x(1)*v(2) - x(2)*v(1) - h2 = hx*hx + hy*hy + hz*hz - IF (h2 == 0.0_DP) RETURN - energy = 0.5_DP*v2 - mu/r - IF (ABS(energy*r/mu) < SQRT(TINY)) THEN - iorbit_type = PARABOLA - ELSE - a = -0.5_DP*mu/energy - IF (a < 0.0_DP) THEN - fac = -h2/(mu*a) - IF (fac > TINY) THEN - iorbit_type = HYPERBOLA - ELSE - iorbit_type = PARABOLA - END IF - ELSE - iorbit_type = ELLIPSE - END IF - END IF - SELECT CASE (iorbit_type) - CASE (ELLIPSE) - fac = 1.0_DP - h2/(mu*a) - IF (fac > TINY) e = SQRT(fac) - q = a*(1.0_DP - e) - CASE (PARABOLA) - a = 0.5_DP*h2/mu - e = 1.0_DP - q = a - CASE (HYPERBOLA) - e = SQRT(1.0_DP + fac) - q = a*(1.0_DP - e) - END SELECT - - RETURN - -END SUBROUTINE orbel_xv2aeq -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/orbel/orbel_xv2aqt.f90 b/orbel/orbel_xv2aqt.f90 deleted file mode 100644 index bb9a27cf0..000000000 --- a/orbel/orbel_xv2aqt.f90 +++ /dev/null @@ -1,153 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : orbel_xv2aqt -! Unit Type : subroutine -! Project : Swifter -! Package : orbel -! Language : Fortran 90/95 -! -! Description : Compute semimajor axis, pericentric distance, mean anomaly, and time to nearest pericenter passage from -! relative Cartesian position and velocity -! -! Input -! Arguments : x : relative position -! v : relative velocity -! mu : G * (m1 + m2) -! Terminal : none -! File : none -! -! Output -! Arguments : a : semimajor axis (pericentric distance for a parabolic orbit) -! q : pericentric distance -! capm : mean anomaly -! tperi : time to nearest pericenter passage -! Terminal : none -! File : none -! -! Invocation : CALL orbel_xv2aqt(x, v, mu, a, q, capm, tperi) -! -! Notes : Adapted from Hal Levison's Swift routine orbel_xv2aqt.f -! -! tperi > 0 means nearest pericenter passage is in the future -! tperi < 0 means nearest pericenter passage is in the past -! -!********************************************************************************************************************************** -SUBROUTINE orbel_xv2aqt(x, v, mu, a, q, capm, tperi) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => orbel_xv2aqt - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, q, capm, tperi - -! Internals - INTEGER(I4B) :: iorbit_type - REAL(DP) :: r, v2, hx, hy, hz, h2, rdotv, energy, fac, w, face, cape, e, tmpf, capf, mm - -! Executable code - a = 0.0_DP - q = 0.0_DP - capm = 0.0_DP - tperi = 0.0_DP - r = SQRT(DOT_PRODUCT(x(:), x(:))) - v2 = DOT_PRODUCT(v(:), v(:)) - hx = x(2)*v(3) - x(3)*v(2) - hy = x(3)*v(1) - x(1)*v(3) - hz = x(1)*v(2) - x(2)*v(1) - h2 = hx*hx + hy*hy + hz*hz - IF (h2 == 0.0_DP) RETURN - rdotv = DOT_PRODUCT(x(:), v(:)) - energy = 0.5_DP*v2 - mu/r - IF (ABS(energy*r/mu) < SQRT(TINY)) THEN - iorbit_type = PARABOLA - ELSE - a = -0.5_DP*mu/energy - IF (a < 0.0_DP) THEN - fac = -h2/(mu*a) - IF (fac > TINY) THEN - iorbit_type = HYPERBOLA - ELSE - iorbit_type = PARABOLA - END IF - ELSE - iorbit_type = ELLIPSE - END IF - END IF - SELECT CASE (iorbit_type) - CASE (ELLIPSE) - fac = 1.0_DP - h2/(mu*a) - IF (fac > TINY) THEN - e = SQRT(fac) - cape = 0.0_DP - face = (a - r)/(a*e) - IF (face < -1.0_DP) THEN - cape = PI - ELSE IF (face < 1.0_DP) THEN - cape = ACOS(face) - END IF - IF (rdotv < 0.0_DP) cape = TWOPI - cape - ELSE - e = 0.0_DP - cape = 0.0_DP - END IF - capm = cape - e*SIN(cape) - q = a*(1.0_DP - e) - mm = SQRT(mu/(a**3)) - IF (capm < PI) THEN - tperi = -1.0_DP*capm/mm - ELSE - tperi = -1.0_DP*(capm - TWOPI)/mm - END IF - CASE (PARABOLA) - a = 0.5_DP*h2/mu - e = 1.0_DP - w = 0.0_DP - fac = 2.0_DP*a/r - 1.0_DP - IF (fac < -1.0_DP) THEN - w = PI - ELSE IF (fac < 1.0_DP) THEN - w = ACOS(fac) - END IF - IF (rdotv < 0.0_DP) w = TWOPI - w - tmpf = TAN(0.5_DP*w) - capm = tmpf*(1.0_DP + tmpf*tmpf/3.0_DP) - q = a - mm = SQRT(0.5_DP*mu/(q**3)) - tperi = -1.0_DP*capm/mm - CASE (HYPERBOLA) - e = SQRT(1.0_DP + fac) - tmpf = (a - r)/(a*e) - IF (tmpf < 1.0_DP) tmpf = 1.0_DP - capf = LOG(tmpf + SQRT(tmpf*tmpf - 1.0_DP)) - IF (rdotv < 0.0_DP) capf = -capf - capm = e*SINH(capf) - capf - q = a*(1.0_DP - e) - mm = SQRT(-mu/(a**3)) - tperi = -1.0_DP*capm/mm - END SELECT - - RETURN - -END SUBROUTINE orbel_xv2aqt -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/orbel/orbel_xv2el.f90 b/orbel/orbel_xv2el.f90 deleted file mode 100644 index 5241e7b90..000000000 --- a/orbel/orbel_xv2el.f90 +++ /dev/null @@ -1,179 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : orbel_xv2el -! Unit Type : subroutine -! Project : Swifter -! Package : orbel -! Language : Fortran 90/95 -! -! Description : Compute osculating orbital elements from relative Cartesian position and velocity -! -! Input -! Arguments : x : relative position -! v : relative velocity -! mu : G * (m1 + m2) -! Terminal : none -! File : none -! -! Output -! Arguments : a : semimajor axis (pericentric distance for a parabolic orbit) -! e : eccentricity -! inc : inclination -! capom : longitude of ascending node -! omega : argument of pericenter -! capm : mean anomaly -! Terminal : none -! File : none -! -! Invocation : CALL orbel_xv2el(x, v, mu, a, e, inc, capom, omega, capm) -! -! Notes : Adapted from Martin Duncan's Swift routine orbel_xv2el.f -! -! All angular measures are returned in radians -! -! If inclination < TINY, longitude of the ascending node is arbitrarily set to 0 -! -! If eccentricity < sqrt(TINY), argument of pericenter is arbitrarily set to 0 -! -! References: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 201 - 206. -! Fitzpatrick, P. M. 1970. Principles of Celestial Mechanics, (Academic Press), 69 - 73. -! Roy, A. E. 1982. Orbital Motion, (Adam Hilger, Ltd.), 75 - 95. -! -!********************************************************************************************************************************** -SUBROUTINE orbel_xv2el(x, v, mu, a, e, inc, capom, omega, capm) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => orbel_xv2el - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: mu - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: x, v - REAL(DP), INTENT(OUT) :: a, e, inc, capom, omega, capm - -! Internals - INTEGER(I4B) :: iorbit_type - REAL(DP) :: r, v2, hx, hy, hz, h2, h, rdotv, energy, fac, u, w, cw, sw, face, cape, tmpf, capf - -! Executable code - a = 0.0_DP - e = 0.0_DP - inc = 0.0_DP - capom = 0.0_DP - omega = 0.0_DP - capm = 0.0_DP - r = SQRT(DOT_PRODUCT(x(:), x(:))) - v2 = DOT_PRODUCT(v(:), v(:)) - hx = x(2)*v(3) - x(3)*v(2) - hy = x(3)*v(1) - x(1)*v(3) - hz = x(1)*v(2) - x(2)*v(1) - h2 = hx*hx + hy*hy + hz*hz - h = SQRT(h2) - IF (h2 == 0.0_DP) RETURN - rdotv = DOT_PRODUCT(x(:), v(:)) - energy = 0.5_DP*v2 - mu/r - fac = hz/h - IF (fac < -1.0_DP) THEN - inc = PI - ELSE IF (fac < 1.0_DP) THEN - inc = ACOS(fac) - END IF - fac = SQRT(hx*hx + hy*hy)/h - IF (fac < TINY) THEN - u = ATAN2(x(2), x(1)) - IF (hz < 0.0_DP) u = -u - ELSE - capom = ATAN2(hx, -hy) - u = ATAN2(x(3)/SIN(inc), x(1)*COS(capom) + x(2)*SIN(capom)) - END IF - IF (capom < 0.0_DP) capom = capom + TWOPI - IF (u < 0.0_DP) u = u + TWOPI - IF (ABS(energy*r/mu) < SQRT(TINY)) THEN - iorbit_type = PARABOLA - ELSE - a = -0.5_DP*mu/energy - IF (a < 0.0_DP) THEN - fac = -h2/(mu*a) - IF (fac > TINY) THEN - iorbit_type = HYPERBOLA - ELSE - iorbit_type = PARABOLA - END IF - ELSE - iorbit_type = ELLIPSE - END IF - END IF - SELECT CASE (iorbit_type) - CASE (ELLIPSE) - fac = 1.0_DP - h2/(mu*a) - IF (fac > TINY) THEN - e = SQRT(fac) - cape = 0.0_DP - face = (a - r)/(a*e) - IF (face < -1.0_DP) THEN - cape = PI - ELSE IF (face < 1.0_DP) THEN - cape = ACOS(face) - END IF - IF (rdotv < 0.0_DP) cape = TWOPI - cape - fac = 1.0_DP - e*COS(cape) - cw = (COS(cape) - e)/fac - sw = SQRT(1.0_DP - e*e)*SIN(cape)/fac - w = ATAN2(sw, cw) - IF (w < 0.0_DP) w = w + TWOPI - ELSE - cape = u - w = u - END IF - capm = cape - e*SIN(cape) - CASE (PARABOLA) - a = 0.5_DP*h2/mu - e = 1.0_DP - w = 0.0_DP - fac = 2.0_DP*a/r - 1.0_DP - IF (fac < -1.0_DP) THEN - w = PI - ELSE IF (fac < 1.0_DP) THEN - w = ACOS(fac) - END IF - IF (rdotv < 0.0_DP) w = TWOPI - w - tmpf = TAN(0.5_DP*w) - capm = tmpf*(1.0_DP + tmpf*tmpf/3.0_DP) - CASE (HYPERBOLA) - e = SQRT(1.0_DP + fac) - tmpf = (a - r)/(a*e) - IF (tmpf < 1.0_DP) tmpf = 1.0_DP - capf = LOG(tmpf + SQRT(tmpf*tmpf - 1.0_DP)) - IF (rdotv < 0.0_DP) capf = -capf - fac = e*COSH(capf) - 1.0_DP - cw = (e - COSH(capf))/fac - sw = SQRT(e*e - 1.0_DP)*SINH(capf)/fac - w = ATAN2(sw, cw) - IF (w < 0.0_DP) w = w + TWOPI - capm = e*SINH(capf) - capf - END SELECT - omega = u - w - IF (omega < 0.0_DP) omega = omega + TWOPI - - RETURN - -END SUBROUTINE orbel_xv2el -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/param.restart.in b/param.restart.in new file mode 100644 index 000000000..e69de29bb diff --git a/ps_maker.py b/ps_maker.py new file mode 100644 index 000000000..9297ab9a1 --- /dev/null +++ b/ps_maker.py @@ -0,0 +1,89 @@ +import rebound +import numpy as np + +def setupSimulation(): + sim = rebound.Simulation() + sim.units = ('AU', 'yr', 'Msun') + sim.integrator = "mercurius" + sim.dt = 0.008 + sim.testparticle_type = 1 + sim.move_to_com() + return sim + +sim = setupSimulation() +ps = sim.particles +G_auy = 4 * np.pi * np.pi #G in units of AU^3 year^-2 M_sun^-1 +M_Sun = 1 +M_Sun_to_g = 1.989e33 +M_Sun_to_kg = 1.989e30 +AU_cubed_to_cm_cubed = 3.348e39 +AU_cubed_to_km_cubed = 3.348e24 +year_to_seconds = 3.154e7 +Mtot_disk = 6.006e-6 #~3*M_earth + +OUTFILE = open('pl.in', 'w') + +sim.add( m=1.0, hash="sun") # SUN - Adds a particle of mass 1 + +N_fully = 2001 +N_semi = 0 + +d_bodies = 2.0 * AU_cubed_to_cm_cubed * (1/M_Sun_to_g) #Changes 2 g/cm^3 to 3366515.837 M_sun/AU^3 + +m_semi = Mtot_disk / (N_semi + 2*N_fully) +m_fully = 2 * m_semi + +r_semi = ((3*m_semi)/(4*np.pi*d_bodies))**(1/3) +r_fully = ((3*m_fully)/(4*np.pi*d_bodies))**(1/3) + +np.random.seed(1) + +def uniform(minimum, maximum): + return np.random.uniform()*(maximum-minimum)+minimum + +while sim.N < N_fully: + a_fully = uniform(0.5,1) + e_fully = uniform(0.0, 0.3) + inc_fully = uniform(0.0, 0.3) + O_fully = uniform(0,2*np.pi) + o_fully = uniform(0,2*np.pi) + M_fully = uniform(-np.pi, np.pi) + fully = rebound.Particle(simulation=sim,primary=sim.particles[0],m=m_fully, r=r_fully, a=a_fully, e=e_fully, inc=inc_fully, Omega=O_fully, omega=o_fully, M=M_fully) + sim.add(fully) + +while sim.N < (N_fully+N_semi): + a_semi = uniform(0.5,1) + e_semi = uniform(0.0, 0.3) + inc_semi = uniform(0.0, 0.3) + O_semi = uniform(0,2*np.pi) + o_semi = uniform(0,2*np.pi) + M_semi = uniform(-np.pi, np.pi) + semi = rebound.Particle(simulation=sim,primary=sim.particles[0],m=m_semi, r=r_semi, a=a_semi, e=e_semi, inc=inc_semi, Omega=O_semi, omega=o_semi, M=M_semi) + sim.add(semi) + +x = [ps[i].x for i in range(1, sim.N)] +y = [ps[i].y for i in range(1, sim.N)] +z = [ps[i].z for i in range(1, sim.N)] +vx = [ps[i].vx for i in range(1, sim.N)] +vy = [ps[i].vy for i in range(1, sim.N)] +vz = [ps[i].vz for i in range(1, sim.N)] +m = [ps[i].m for i in range(1, sim.N)] +r = [ps[i].r for i in range(1, sim.N)] +Rhill = [ps[i].a*((ps[i].m/(3*M_Sun))**(0.333333)) for i in range(1, sim.N)] + +with OUTFILE as output: + output.write("%s ! Solar System in unit system AU, M_sun, and years\n" %(sim.N)) + output.write("1 %s\n"%"{:10.8e}".format(M_Sun*G_auy)) + output.write(".0 .0 .0 ! x y z\n") + output.write(".0 .0 .0 !vx vy vz\n") + for i in range (0, (sim.N-1)): + output.write("%s %s %s ! ID / G*Mass / Rhill\n"%((i+2),"{:10.8e}".format(m[i]*G_auy),"{:10.8e}".format(Rhill[i]))) + output.write("%s ! Radius\n"%("{:10.8e}".format(r[i]))) + output.write("%s %s %s ! x y z\n"%("{:10.8e}".format(x[i]),"{:10.8e}".format(y[i]),"{:10.8e}".format(z[i]))) + output.write("%s %s %s ! vx vy vz\n"%("{:10.8e}".format(vx[i]),"{:10.8e}".format(vy[i]),"{:10.8e}".format(vz[i]))) + + + + + + diff --git a/python/swiftest/.idea/.gitignore b/python/swiftest/.idea/.gitignore new file mode 100644 index 000000000..26d33521a --- /dev/null +++ b/python/swiftest/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/python/swiftest/README.md b/python/swiftest/README.md new file mode 100644 index 000000000..23ff2d7fc --- /dev/null +++ b/python/swiftest/README.md @@ -0,0 +1,2 @@ +swiftest +Documentation TBD diff --git a/python/swiftest/requirements.txt b/python/swiftest/requirements.txt new file mode 100644 index 000000000..db5d1078b --- /dev/null +++ b/python/swiftest/requirements.txt @@ -0,0 +1,86 @@ +argon2-cffi @ file:///tmp/build/80754af9/argon2-cffi_1613036642480/work +astropy==4.2.1 +astroquery==0.4.2 +async-generator==1.10 +attrs @ file:///tmp/build/80754af9/attrs_1620827162558/work +backcall @ file:///home/ktietz/src/ci/backcall_1611930011877/work +beautifulsoup4==4.9.3 +bleach @ file:///tmp/build/80754af9/bleach_1612211392645/work +certifi==2021.5.30 +cffi @ file:///tmp/build/80754af9/cffi_1613246939562/work +chardet==4.0.0 +cryptography==3.4.7 +cycler==0.10.0 +decorator @ file:///tmp/build/80754af9/decorator_1621259047763/work +defusedxml @ file:///tmp/build/80754af9/defusedxml_1615228127516/work +entrypoints==0.3 +html5lib==1.1 +idna==2.10 +importlib-metadata==4.5.0 +ipykernel==5.5.5 +ipython @ file:///tmp/build/80754af9/ipython_1617118429768/work +ipython-genutils @ file:///tmp/build/80754af9/ipython_genutils_1606773439826/work +ipywidgets @ file:///tmp/build/80754af9/ipywidgets_1610481889018/work +jedi==0.17.0 +jeepney==0.6.0 +Jinja2 @ file:///tmp/build/80754af9/jinja2_1621238361758/work +jsonschema @ file:///tmp/build/80754af9/jsonschema_1602607155483/work +jupyter==1.0.0 +jupyter-client @ file:///tmp/build/80754af9/jupyter_client_1616770841739/work +jupyter-console @ file:///tmp/build/80754af9/jupyter_console_1616615302928/work +jupyter-core @ file:///tmp/build/80754af9/jupyter_core_1612213308260/work +jupyterlab-pygments @ file:///tmp/build/80754af9/jupyterlab_pygments_1601490720602/work +jupyterlab-widgets @ file:///tmp/build/80754af9/jupyterlab_widgets_1609884341231/work +keyring==23.0.1 +kiwisolver @ file:///tmp/build/80754af9/kiwisolver_1612282414123/work +MarkupSafe @ file:///tmp/build/80754af9/markupsafe_1621528142364/work +matplotlib==3.4.2 +mistune @ file:///tmp/build/80754af9/mistune_1594373098390/work +mkl-random @ file:///tmp/build/80754af9/mkl_random_1618853974840/work +mkl-service==2.3.0 +nbclient @ file:///tmp/build/80754af9/nbclient_1614364831625/work +nbconvert @ file:///tmp/build/80754af9/nbconvert_1601914821128/work +nbformat @ file:///tmp/build/80754af9/nbformat_1617383369282/work +nest-asyncio @ file:///tmp/build/80754af9/nest-asyncio_1613680548246/work +notebook @ file:///tmp/build/80754af9/notebook_1621523661196/work +numpy==1.20.3 +olefile==0.46 +packaging @ file:///tmp/build/80754af9/packaging_1611952188834/work +pandas==1.2.4 +pandocfilters @ file:///tmp/build/80754af9/pandocfilters_1605120451932/work +parso @ file:///tmp/build/80754af9/parso_1617223946239/work +pexpect @ file:///tmp/build/80754af9/pexpect_1605563209008/work +pickleshare @ file:///tmp/build/80754af9/pickleshare_1606932040724/work +Pillow @ file:///tmp/build/80754af9/pillow_1617386154241/work +prometheus-client @ file:///tmp/build/80754af9/prometheus_client_1623189609245/work +prompt-toolkit @ file:///tmp/build/80754af9/prompt-toolkit_1616415428029/work +ptyprocess @ file:///tmp/build/80754af9/ptyprocess_1609355006118/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl +pycparser @ file:///tmp/build/80754af9/pycparser_1594388511720/work +pyerfa==2.0.0 +Pygments @ file:///tmp/build/80754af9/pygments_1621606182707/work +pyparsing @ file:///home/linux1/recipes/ci/pyparsing_1610983426697/work +pyrsistent @ file:///tmp/build/80754af9/pyrsistent_1600141707582/work +pySLALIB==1.0.4 +python-dateutil @ file:///home/ktietz/src/ci/python-dateutil_1611928101742/work +pytz @ file:///tmp/build/80754af9/pytz_1612215392582/work +pyvo==1.1 +pyzmq==20.0.0 +qtconsole @ file:///tmp/build/80754af9/qtconsole_1623278325812/work +QtPy==1.9.0 +requests==2.25.1 +scipy==1.6.3 +Send2Trash @ file:///tmp/build/80754af9/send2trash_1607525499227/work +six @ file:///tmp/build/80754af9/six_1623709665295/work +soupsieve==2.2.1 +-e git+https://github.itap.purdue.edu/MintonGroup/swiftest.git@19f9e7d0b735f38b5b2e0f5d21fe9b4fb2b79838#egg=swiftest&subdirectory=python/swiftest +terminado==0.9.4 +testpath @ file:///home/ktietz/src/ci/testpath_1611930608132/work +tornado @ file:///tmp/build/80754af9/tornado_1606942283357/work +traitlets @ file:///home/ktietz/src/ci/traitlets_1611929699868/work +typing-extensions==3.10.0.0 +urllib3==1.26.5 +wcwidth @ file:///tmp/build/80754af9/wcwidth_1593447189090/work +webencodings==0.5.1 +widgetsnbextension==3.5.1 +xarray==0.18.2 +zipp @ file:///tmp/build/80754af9/zipp_1615904174917/work diff --git a/python/swiftest/setup.py b/python/swiftest/setup.py new file mode 100644 index 000000000..2d0e35f2d --- /dev/null +++ b/python/swiftest/setup.py @@ -0,0 +1,6 @@ +from setuptools import setup, find_packages + +setup(name='swiftest', + version='0.2', + author='David A. Minton', + packages=find_packages()) \ No newline at end of file diff --git a/python/swiftest/swiftest/__init__.py b/python/swiftest/swiftest/__init__.py new file mode 100644 index 000000000..61f0a6c2a --- /dev/null +++ b/python/swiftest/swiftest/__init__.py @@ -0,0 +1,2 @@ +from swiftest.constants import * +from swiftest.simulation_class import Simulation \ No newline at end of file diff --git a/python/swiftest/swiftest/constants.py b/python/swiftest/swiftest/constants.py new file mode 100644 index 000000000..7b031b4b7 --- /dev/null +++ b/python/swiftest/swiftest/constants.py @@ -0,0 +1,15 @@ +import numpy as np +import astropy.constants as const + +# Constants in SI units +GC = np.longdouble(const.G.value) +AU2M = np.longdouble(const.au.value) +GMSunSI = np.longdouble(const.GM_sun.value) +MSun = np.longdouble(const.M_sun.value) +RSun = np.longdouble(const.R_sun.value) +JD2S = 86400 +YR2S = np.longdouble(365.25 * JD2S) +einsteinC = np.longdouble(299792458.0) +# Solar oblatenes values: From Mecheri et al. (2004), using Corbard (b) 2002 values (Table II) +J2Sun = np.longdouble(2.198e-7) +J4Sun = np.longdouble(-4.805e-9) diff --git a/python/swiftest/swiftest/init_cond.py b/python/swiftest/swiftest/init_cond.py new file mode 100644 index 000000000..f9a7378c0 --- /dev/null +++ b/python/swiftest/swiftest/init_cond.py @@ -0,0 +1,218 @@ +import swiftest +import numpy as np +from astroquery.jplhorizons import Horizons +import datetime +from datetime import date +import xarray as xr + +def solar_system_horizons(plname, idval, param, ephemerides_start_date, ds): + """ + Initializes a Swiftest dataset containing the major planets of the Solar System at a particular data from JPL/Horizons + + Parameters + ---------- + param : dict + Swiftest paramuration parameters. This method uses the unit conversion factors to convert from JPL's AU-day system into the system specified in the param file + ephemerides_start_date : string + Date to use when obtaining the ephemerides in the format YYYY-MM-DD. + ds : xarray Dataset + Dataset to append + + Returns + ------- + xarray dataset + """ + # Planet ids + planetid = { + 'Sun': '0', + 'Mercury': '1', + 'Venus': '2', + 'Earth': '3', + 'Mars': '4', + 'Jupiter': '5', + 'Saturn': '6', + 'Uranus': '7', + 'Neptune': '8', + 'Pluto': '9' + } + + if plname in planetid: + ispl = True + else: + ispl = False + print(f"\nMassive body {plname} not found or not yet supported") + print("This will be created as a massless test particle") + if idval is None: + print("ID value required for this input type") + return + + # Planet MSun/M ratio + MSun_over_Mpl = { + 'Sun' : np.longdouble(1.0), + 'Mercury': np.longdouble(6023600.0), + 'Venus': np.longdouble(408523.71), + 'Earth': np.longdouble(328900.56), + 'Mars': np.longdouble(3098708.), + 'Jupiter': np.longdouble(1047.3486), + 'Saturn': np.longdouble(3497.898), + 'Uranus': np.longdouble(22902.98), + 'Neptune': np.longdouble(19412.24), + 'Pluto': np.longdouble(1.35e8) + } + + # Planet radii in AU + planetradius = { + 'Sun' : swiftest.RSun / swiftest.AU2M, + 'Mercury': np.longdouble(2439.4e3) / swiftest.AU2M, + 'Venus': np.longdouble(6051.8e3) / swiftest.AU2M, + 'Earth': np.longdouble(6371.0084e3) / swiftest.AU2M, # Earth only for radius + 'Mars': np.longdouble(3389.50e3) / swiftest.AU2M, + 'Jupiter': np.longdouble(69911e3) / swiftest.AU2M, + 'Saturn': np.longdouble(58232.0e3) / swiftest.AU2M, + 'Uranus': np.longdouble(25362.e3) / swiftest.AU2M, + 'Neptune': np.longdouble(24622.e3) / swiftest.AU2M, + 'Pluto': np.longdouble(1188.3e3 / swiftest.AU2M) + } + + # Unit conversion factors + DCONV = swiftest.AU2M / param['DU2M'] + VCONV = (swiftest.AU2M / swiftest.JD2S) / (param['DU2M'] / param['TU2S']) + THIRDLONG = np.longdouble(1.0) / np.longdouble(3.0) + + # Central body value vectors + GMcb = np.array([swiftest.GMSunSI * param['TU2S'] ** 2 / param['DU2M'] ** 3]) + Rcb = np.array([swiftest.RSun / param['DU2M']]) + J2RP2 = np.array([swiftest.J2Sun * (swiftest.RSun / param['DU2M']) ** 2]) + J4RP4 = np.array([swiftest.J4Sun * (swiftest.RSun / param['DU2M']) ** 4]) + cbid = np.array([0]) + cvec = np.vstack([GMcb, Rcb, J2RP2, J4RP4]) + + # Horizons date time internal variables + tstart = datetime.date.fromisoformat(ephemerides_start_date) + tstep = datetime.timedelta(days=1) + tend = tstart + tstep + ephemerides_end_date = tend.isoformat() + ephemerides_step = '1d' + + clab, plab, tlab = swiftest.io.make_swiftest_labels(param) + if param['OUT_FORM'] == 'XV': + plab.append('a') + plab.append('e') + plab.append('inc') + plab.append('capom') + plab.append('omega') + plab.append('capm') + tlab.append('a') + tlab.append('e') + tlab.append('inc') + tlab.append('capom') + tlab.append('omega') + tlab.append('capm') + elif param['OUT_FORM'] == 'EL': + plab.append('px') + plab.append('py') + plab.append('pz') + plab.append('vx') + plab.append('vy') + plab.append('vz') + tlab.append('px') + tlab.append('py') + tlab.append('pz') + tlab.append('vx') + tlab.append('vy') + tlab.append('vz') + + dims = ['time', 'id', 'vec'] + t = np.array([0.0]) + + key = plname + if ispl: + val = planetid[key] + else: + val = -1 + if key == "Sun" : # Create central body + print("Creating the Sun as a central body") + cb = [] + cbframe = np.expand_dims(cvec.T, axis=0) + cbxr = xr.DataArray(cbframe, dims=dims, coords={'time': t, 'id': cbid, 'vec': clab}) + cbds = cbxr.to_dataset(dim='vec') + ds = xr.combine_by_coords([ds, cbds]) + else: # Fetch solar system ephemerides from Horizons + print(f"Fetching ephemerides data for {key} from JPL/Horizons") + pl = [] + p1 = [] + p2 = [] + p3 = [] + p4 = [] + p5 = [] + p6 = [] + p7 = [] + p8 = [] + p9 = [] + p10 = [] + p11 = [] + p12 = [] + Rhill = [] + Rpl = [] + GMpl = [] + + pldata = {} + if ispl: + pldata[key] = Horizons(id=val, id_type='majorbody', location='@sun', + epochs={'start': ephemerides_start_date, 'stop': ephemerides_end_date, + 'step': ephemerides_step}) + else: + pldata[key] = Horizons(id=key, id_type='smallbody', location='@sun', + epochs={'start': ephemerides_start_date, 'stop': ephemerides_end_date, + 'step': ephemerides_step}) + if param['OUT_FORM'] == 'XV': + p1.append(pldata[key].vectors()['x'][0] * DCONV) + p2.append(pldata[key].vectors()['y'][0] * DCONV) + p3.append(pldata[key].vectors()['z'][0] * DCONV) + p4.append(pldata[key].vectors()['vx'][0] * VCONV) + p5.append(pldata[key].vectors()['vy'][0] * VCONV) + p6.append(pldata[key].vectors()['vz'][0] * VCONV) + p7.append(pldata[key].elements()['a'][0] * DCONV) + p8.append(pldata[key].elements()['e'][0]) + p9.append(pldata[key].elements()['incl'][0] * np.pi / 180.0) + p10.append(pldata[key].elements()['Omega'][0] * np.pi / 180.0) + p11.append(pldata[key].elements()['w'][0] * np.pi / 180.0) + p12.append(pldata[key].elements()['M'][0] * np.pi / 180.0) + elif param['OUT_FORM'] == 'EL': + p1.append(pldata[key].elements()['a'][0] * DCONV) + p2.append(pldata[key].elements()['e'][0]) + p3.append(pldata[key].elements()['incl'][0] * np.pi / 180.0) + p4.append(pldata[key].elements()['Omega'][0] * np.pi / 180.0) + p5.append(pldata[key].elements()['w'][0] * np.pi / 180.0) + p6.append(pldata[key].elements()['M'][0] * np.pi / 180.0) + p7.append(pldata[key].vectors()['x'][0] * DCONV) + p8.append(pldata[key].vectors()['y'][0] * DCONV) + p9.append(pldata[key].vectors()['z'][0] * DCONV) + p10.append(pldata[key].vectors()['vx'][0] * VCONV) + p11.append(pldata[key].vectors()['vy'][0] * VCONV) + p12.append(pldata[key].vectors()['vz'][0] * VCONV) + if ispl: + Rpl.append(planetradius[key] * DCONV) + GMpl.append(GMcb[0] / MSun_over_Mpl[key]) + # Generate planet value vectors + if (param['RHILL_PRESENT'] == 'YES'): + Rhill.append(pldata[key].elements()['a'][0] * DCONV * (3 * MSun_over_Mpl[key]) ** (-THIRDLONG)) + pvec = np.vstack([p1, p2, p3, p4, p5, p6, GMpl, Rpl, Rhill, p7, p8, p9, p10, p11, p12]) + else: + pvec = np.vstack([p1, p2, p3, p4, p5, p6, GMpl, Rpl, p7, p8, p9, p10, p11, p12]) + else: + pvec = np.vstack([p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12]) + plab = tlab.copy() + + if idval is None: + plid = np.array([planetid[key]], dtype=int) + else: + plid = np.array([idval], dtype=int) + + # Prepare frames by adding an extra axis for the time coordinate + plframe = np.expand_dims(pvec.T, axis=0) + plxr = xr.DataArray(plframe, dims=dims, coords={'time': t, 'id': plid, 'vec': plab}) + plds = plxr.to_dataset(dim='vec') + ds = xr.combine_by_coords([ds, plds]) + + return ds \ No newline at end of file diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py new file mode 100644 index 000000000..ce8b800ce --- /dev/null +++ b/python/swiftest/swiftest/io.py @@ -0,0 +1,1288 @@ +import swiftest +import numpy as np +from scipy.io import FortranFile +import xarray as xr +import sys +import tempfile + +newfeaturelist = ("FRAGMENTATION", "ROTATION", "TIDES", "ENERGY", "GR", "YARKOVSKY", "YORP") + +def real2float(realstr): + """ + Converts a Fortran-generated ASCII string of a real value into a numpy float type. Handles cases where double precision + numbers in exponential notation use 'd' or 'D' instead of 'e' or 'E' + + Parameters + ---------- + realstr : string + Fortran-generated ASCII string of a real value. + + Returns + ------- + : float + The converted floating point value of the input string + """ + return float(realstr.replace('d', 'E').replace('D', 'E')) + +def read_swiftest_param(param_file_name, param): + """ + Reads in a Swiftest param.in file and saves it as a dictionary + + Parameters + ---------- + param_file_name : string + File name of the input parameter file + + Returns + ------- + param : dict + A dictionary containing the entries in the user parameter file + """ + param['! VERSION'] = f"Swiftest parameter input from file {param_file_name}" + + # Read param.in file + print(f'Reading Swiftest file {param_file_name}') + try: + with open(param_file_name, 'r') as f: + for line in f.readlines(): + fields = line.split() + if len(fields) > 0: + for key in param: + if (key == fields[0].upper()): param[key] = fields[1] + # Special case of CHK_QMIN_RANGE requires a second input + if fields[0].upper() == 'CHK_QMIN_RANGE': + alo = real2float(fields[1]) + ahi = real2float(fields[2]) + param['CHK_QMIN_RANGE'] = f"{alo} {ahi}" + + param['ISTEP_OUT'] = int(param['ISTEP_OUT']) + param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) + param['T0'] = real2float(param['T0']) + param['TSTOP'] = real2float(param['TSTOP']) + param['DT'] = real2float(param['DT']) + param['CHK_RMIN'] = real2float(param['CHK_RMIN']) + param['CHK_RMAX'] = real2float(param['CHK_RMAX']) + param['CHK_EJECT'] = real2float(param['CHK_EJECT']) + param['CHK_QMIN'] = real2float(param['CHK_QMIN']) + param['MTINY'] = real2float(param['MTINY']) + param['DU2M'] = real2float(param['DU2M']) + param['MU2KG'] = real2float(param['MU2KG']) + param['TU2S'] = real2float(param['TU2S']) + param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() + param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() + param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() + param['RHILL_PRESENT'] = param['RHILL_PRESENT'].upper() + param['FRAGMENTATION'] = param['FRAGMENTATION'].upper() + param['ROTATION'] = param['ROTATION'].upper() + param['TIDES'] = param['TIDES'].upper() + param['ENERGY'] = param['ENERGY'].upper() + param['GR'] = param['GR'].upper() + param['YORP'] = param['YORP'].upper() + except IOError: + print(f"{param_file_name} not found.") + return param + +def read_swifter_param(param_file_name): + """ + Reads in a Swifter param.in file and saves it as a dictionary + + Parameters + ---------- + param_file_name : string + File name of the input parameter file + + Returns + ------- + param + A dictionary containing the entries in the user parameter file + """ + param = { + '! VERSION': f"Swifter parameter input from file {param_file_name}", + 'T0': "0.0", + 'TSTOP': "0.0", + 'DT': "0.0", + 'PL_IN': "", + 'TP_IN': "", + 'IN_TYPE': "ASCII", + 'ISTEP_OUT': "-1", + 'ISTEP_DUMP': "-1", + 'BIN_OUT': "bin.dat", + 'OUT_TYPE': "REAL8", + 'OUT_FORM': "XV", + 'OUT_STAT': "NEW", + 'J2': "0.0", + 'J4': "0.0", + 'CHK_CLOSE': 'NO', + 'CHK_RMIN': "-1.0", + 'CHK_RMAX': "-1.0", + 'CHK_EJECT': "-1.0", + 'CHK_QMIN': "-1.0", + 'CHK_QMIN_COORD': "HELIO", + 'CHK_QMIN_RANGE': "", + 'ENC_OUT': "", + 'EXTRA_FORCE': 'NO', + 'BIG_DISCARD': 'NO', + 'RHILL_PRESENT': 'NO', + 'C': "-1.0", + } + + # Read param.in file + print(f'Reading Swifter file {param_file_name}') + try: + with open(param_file_name, 'r') as f: + for line in f.readlines(): + fields = line.split() + if len(fields) > 0: + for key in param: + if (key == fields[0].upper()): param[key] = fields[1] + # Special case of CHK_QMIN_RANGE requires a second input + if fields[0].upper() == 'CHK_QMIN_RANGE': + alo = real2float(fields[1]) + ahi = real2float(fields[2]) + param['CHK_QMIN_RANGE'] = f"{alo} {ahi}" + + param['ISTEP_OUT'] = int(param['ISTEP_OUT']) + param['ISTEP_DUMP'] = int(param['ISTEP_DUMP']) + param['T0'] = real2float(param['T0']) + param['TSTOP'] = real2float(param['TSTOP']) + param['DT'] = real2float(param['DT']) + param['J2'] = real2float(param['J2']) + param['J4'] = real2float(param['J4']) + param['CHK_RMIN'] = real2float(param['CHK_RMIN']) + param['CHK_RMAX'] = real2float(param['CHK_RMAX']) + param['CHK_EJECT'] = real2float(param['CHK_EJECT']) + param['CHK_QMIN'] = real2float(param['CHK_QMIN']) + param['EXTRA_FORCE'] = param['EXTRA_FORCE'].upper() + param['BIG_DISCARD'] = param['BIG_DISCARD'].upper() + param['CHK_CLOSE'] = param['CHK_CLOSE'].upper() + param['RHILL_PRESENT'] = param['RHILL_PRESENT'].upper() + if param['C'] != '-1.0': + param['C'] = real2float(param['C']) + else: + param.pop('C', None) + except IOError: + print(f"{param_file_name} not found.") + + return param + +def read_swift_param(param_file_name, startfile="swift.in"): + """ + Reads in a Swift param.in file and saves it as a dictionary + + Parameters + ---------- + param_file_name : string + File name of the input parameter file + + Returns + ------- + param : dict + A dictionary containing the entries in the user parameter file + """ + param = { + '! VERSION': f"Swift parameter input from file {param_file_name}", + 'T0': 0.0, + 'TSTOP': 0.0, + 'DT': 0.0, + 'DTOUT': 0.0, + 'DTDUMP': 0.0, + 'L1': "F", + 'L1': "F", + 'L2': "F", + 'L3': "F", + 'L4': "F", + 'L5': "F", + 'L6': "F", + 'RMIN': -1, + 'RMAX': -1, + 'RMAXU': -1, + 'QMIN': -1, + 'LCLOSE': "F", + 'BINARY_OUTPUTFILE': "bin.dat", + 'STATUS_FLAG_FOR_OPEN_STATEMENTS': "NEW", + } + + try: + with open(startfile, 'r') as f: + line = f.readline() + plname = f.readline().split()[0] + tpname = f.readline().split()[0] + except: + plname = "pl.in" + tpname = "tp.in" + param['PL_IN'] = plname + param['TP_IN'] = tpname + + # Read param.in file + print(f'Reading Swift file {param_file_name}') + try: + with open(param_file_name, 'r') as f: + line = f.readline().split() + for i, l in enumerate(line): + line[i] = l + param['T0'] = real2float(line[0]) + param['TSTOP'] = real2float(line[1]) + param['DT'] = real2float(line[2]) + line = f.readline().split() + for i, l in enumerate(line): + line[i] = l + param['DTOUT'] = real2float(line[0]) + param['DTDUMP'] = real2float(line[1]) + line = f.readline().split() + param['L1'] = line[0].upper() + param['L2'] = line[1].upper() + param['L3'] = line[2].upper() + param['L4'] = line[3].upper() + param['L5'] = line[4].upper() + param['L6'] = line[5].upper() + if param['L2'] == "T": + line = f.readline().split() + for i, l in enumerate(line): + line[i] = l + param['RMIN'] = real2float(line[0]) + param['RMAX'] = real2float(line[1]) + param['RMAXU'] = real2float(line[2]) + param['QMIN'] = real2float(line[3]) + param['LCLOSE'] = line[4].upper() + param['BINARY_OUTPUTFILE'] = f.readline().strip() + param['STATUS_FLAG_FOR_OPEN_STATEMENTS'] = f.readline().strip().upper() + except IOError: + print(f"{param_file_name} not found.") + + return param + +def write_swift_param(param, param_file_name): + outfile = open(param_file_name, 'w') + print(param['T0'], param['TSTOP'], param['DT'], file=outfile) + print(param['DTOUT'], param['DTDUMP'], file=outfile) + print(param['L1'], param['L2'], param['L3'], param['L4'], param['L5'], param['L6'], file=outfile) + print(param['RMIN'], param['RMAX'], param['RMAXU'], param['QMIN'], param['LCLOSE'], file=outfile) + print(param['BINARY_OUTPUTFILE'], file=outfile) + print(param['STATUS_FLAG_FOR_OPEN_STATEMENTS'], file=outfile) + outfile.close() + return + +def write_labeled_param(param, param_file_name): + outfile = open(param_file_name, 'w') + keylist = ['! VERSION', + 'T0', + 'TSTOP', + 'DT', + 'ISTEP_OUT', + 'ISTEP_DUMP', + 'OUT_FORM', + 'OUT_TYPE', + 'OUT_STAT', + 'IN_TYPE', + 'PL_IN', + 'TP_IN', + 'CB_IN', + 'BIN_OUT', + 'ENC_OUT', + 'DISCARD_OUT', + 'CHK_QMIN', + 'CHK_RMIN', + 'CHK_RMAX', + 'CHK_EJECT', + 'CHK_QMIN_COORD', + 'CHK_QMIN_RANGE', + 'MU2KG', + 'TU2S', + 'DU2M' ] + ptmp = param.copy() + # Print the list of key/value pairs in the preferred order + for key in keylist: + val = ptmp.pop(key, None) + if val is not None: print(f"{key:<16} {val}", file=outfile) + # Print the remaining key/value pairs in whatever order + for key, val in ptmp.items(): + print(f"{key:<16} {val}", file=outfile) + outfile.close() + return + +def swifter_stream(f, param): + """ + Reads in a Swifter bin.dat file and returns a single frame of data as a datastream + + Parameters + ---------- + f : file object + param : dict + + Yields + ------- + t : float + Time of this frame + npl : int + Number of massive bodies + plid : int array + IDs of massive bodies + pvec : float array + (npl,N) - vector of N quantities or each particle (6 of XV/EL + Mass, Radius, etc) + plab : string list + Labels for the pvec data + ntp : int + Number of test particles + tpid : int array + Ids of test particles + tvec : float array + (ntp,N) - vector of N quantities for each particle (6 of XV/EL, etc.) + tlab : string list + Labels for the tvec data + """ + while True: # Loop until you read the end of file + try: + # Read single-line header + record = f.read_record(' 0: + Mpl = np.empty(npl) + Rpl = np.empty(npl) + for i in range(npl): + # Read single-line pl frame for + record = f.read_record(' 0: + for i in range(ntp): + record = f.read_record(' 0: + plid = f.read_ints() + p1 = f.read_reals(np.float64) + p2 = f.read_reals(np.float64) + p3 = f.read_reals(np.float64) + p4 = f.read_reals(np.float64) + p5 = f.read_reals(np.float64) + p6 = f.read_reals(np.float64) + Mpl = f.read_reals(np.float64) + Rpl = f.read_reals(np.float64) + if param['RHILL_PRESENT'] == 'YES': + Rhill = f.read_reals(np.float64) + if param['ROTATION'] == 'YES': + Ipplx = f.read_reals(np.float64) + Ipply = f.read_reals(np.float64) + Ipplz = f.read_reals(np.float64) + rotplx = f.read_reals(np.float64) + rotply = f.read_reals(np.float64) + rotplz = f.read_reals(np.float64) + if param['TIDES'] == 'YES': + k2pl = f.read_reals(np.float64) + Qpl = f.read_reals(np.float64) + if ntp[0] > 0: + tpid = f.read_ints() + t1 = f.read_reals(np.float64) + t2 = f.read_reals(np.float64) + t3 = f.read_reals(np.float64) + t4 = f.read_reals(np.float64) + t5 = f.read_reals(np.float64) + t6 = f.read_reals(np.float64) + + clab, plab, tlab = make_swiftest_labels(param) + + if npl > 0: + pvec = np.vstack([p1, p2, p3, p4, p5, p6, Mpl, Rpl]) + else: + pvec = np.empty((8, 0)) + plid = np.empty(0) + if ntp > 0: + tvec = np.vstack([t1, t2, t3, t4, t5, t6]) + else: + tvec = np.empty((6, 0)) + tpid = np.empty(0) + cvec = np.array([Mcb, Rcb, J2cb, J4cb]) + if param['RHILL_PRESENT'] == 'YES': + if npl > 0: + pvec = np.vstack([pvec, Rhill]) + if param['ROTATION'] == 'YES': + cvec = np.vstack([cvec, Ipcbx, Ipcby, Ipcbz, rotcbx, rotcby, rotcbz]) + if npl > 0: + pvec = np.vstack([pvec, Ipplx, Ipply, Ipplz, rotplx, rotply, rotplz]) + if param['TIDES'] == 'YES': + cvec = np.vstack([cvec, k2cb, Qcb]) + if npl > 0: + pvec = np.vstack([pvec, k2pl, Qpl]) + yield t, cbid, cvec.T, clab, \ + npl, plid, pvec.T, plab, \ + ntp, tpid, tvec.T, tlab + +def swifter2xr(param): + """ + Converts a Swifter binary data file into an xarray DataSet. + + Parameters + ---------- + param : dict + Swifter parameters + + Returns + ------- + xarray dataset + """ + dims = ['time', 'id', 'vec'] + pl = [] + tp = [] + with FortranFile(param['BIN_OUT'], 'r') as f: + for t, npl, plid, pvec, plab, \ + ntp, tpid, tvec, tlab in swifter_stream(f, param): + # Prepare frames by adding an extra axis for the time coordinate + plframe = np.expand_dims(pvec, axis=0) + tpframe = np.expand_dims(tvec, axis=0) + + # Create xarray DataArrays out of each body type + plxr = xr.DataArray(plframe, dims=dims, coords={'time': t, 'id': plid, 'vec': plab}) + tpxr = xr.DataArray(tpframe, dims=dims, coords={'time': t, 'id': tpid, 'vec': tlab}) + + pl.append(plxr) + tp.append(tpxr) + sys.stdout.write('\r' + f"Reading in time {t[0]:.3e}") + sys.stdout.flush() + + plda = xr.concat(pl, dim='time') + tpda = xr.concat(tp, dim='time') + + plds = plda.to_dataset(dim='vec') + tpds = tpda.to_dataset(dim='vec') + print('\nCreating Dataset') + ds = xr.combine_by_coords([plds, tpds]) + print(f"Successfully converted {ds.sizes['time']} output frames.") + return ds + +def swiftest2xr(param): + """ + Converts a Swiftest binary data file into an xarray DataSet. + + Parameters + ---------- + param : dict + Swiftest parameters + + Returns + ------- + xarray dataset + """ + + dims = ['time', 'id', 'vec'] + cb = [] + pl = [] + tp = [] + with FortranFile(param['BIN_OUT'], 'r') as f: + for t, cbid, cvec, clab, \ + npl, plid, pvec, plab, \ + ntp, tpid, tvec, tlab in swiftest_stream(f, param): + # Prepare frames by adding an extra axis for the time coordinate + cbframe = np.expand_dims(cvec, axis=0) + plframe = np.expand_dims(pvec, axis=0) + tpframe = np.expand_dims(tvec, axis=0) + + # Create xarray DataArrays out of each body type + cbxr = xr.DataArray(cbframe, dims=dims, coords={'time': t, 'id': cbid, 'vec': clab}) + plxr = xr.DataArray(plframe, dims=dims, coords={'time': t, 'id': plid, 'vec': plab}) + tpxr = xr.DataArray(tpframe, dims=dims, coords={'time': t, 'id': tpid, 'vec': tlab}) + + cb.append(cbxr) + pl.append(plxr) + tp.append(tpxr) + sys.stdout.write('\r' + f"Reading in time {t[0]:.3e}") + sys.stdout.flush() + + cbda = xr.concat(cb, dim='time') + plda = xr.concat(pl, dim='time') + tpda = xr.concat(tp, dim='time') + + cbds = cbda.to_dataset(dim='vec') + plds = plda.to_dataset(dim='vec') + tpds = tpda.to_dataset(dim='vec') + print('\nCreating Dataset') + ds = xr.combine_by_coords([cbds, plds, tpds]) + print(f"Successfully converted {ds.sizes['time']} output frames.") + return ds + +def swiftest_xr2infile(ds, param, framenum=-1): + """ + Writes a set of Swiftest input files from a single frame of a Swiftest xarray dataset + + Parameters + ---------- + ds : xarray dataset + Dataset containing Swiftest n-body data in XV format + framenum : int + Time frame to use to generate the initial conditions. If this argument is not passed, the default is to use the last frame in the dataset. + param : dict + Swiftest input parameters. This method uses the names of the cb, pl, and tp files from the input + + Returns + ------- + A set of three input files for a Swiftest run + """ + frame = ds.isel(time=framenum) + cb = frame.where(frame.id == 0, drop=True) + pl = frame.where(frame.id > 0, drop=True) + pl = pl.where(np.invert(np.isnan(pl['Mass'])), drop=True).drop_vars(['J_2', 'J_4']) + tp = frame.where(np.isnan(frame['Mass']), drop=True).drop_vars(['Mass', 'Radius', 'J_2', 'J_4']) + + GMSun = np.double(cb['Mass']) + RSun = np.double(cb['Radius']) + J2 = np.double(cb['J_2']) + J4 = np.double(cb['J_4']) + cbid = int(0) + + if param['IN_TYPE'] == 'ASCII': + # Swiftest Central body file + cbfile = open(param['CB_IN'], 'w') + print(0, file=cbfile) + print(GMSun, file=cbfile) + print(RSun, file=cbfile) + print(J2, file=cbfile) + print(J4, file=cbfile) + cbfile.close() + + plfile = open(param['PL_IN'], 'w') + print(pl.id.count().values, file=plfile) + for i in pl.id: + pli = pl.sel(id=i) + if param['RHILL_PRESENT'] == 'YES': + print(i.values, pli['Mass'].values, pli['Rhill'].values, file=plfile) + else: + print(i.values, pli['Mass'].values, file=plfile) + print(pli['Radius'].values, file=plfile) + print(pli['px'].values, pli['py'].values, pli['pz'].values, file=plfile) + print(pli['vx'].values, pli['vy'].values, pli['vz'].values, file=plfile) + plfile.close() + + # TP file + tpfile = open(param['TP_IN'], 'w') + print(tp.id.count().values, file=tpfile) + for i in tp.id: + tpi = tp.sel(id=i) + print(i.values, file=tpfile) + print(tpi['px'].values, tpi['py'].values, tpi['pz'].values, file=tpfile) + print(tpi['vx'].values, tpi['vy'].values, tpi['vz'].values, file=tpfile) + tpfile.close() + elif param['IN_TYPE'] == 'REAL8': + # Now make Swiftest files + cbfile = FortranFile(param['CB_IN'], 'w') + cbfile.write_record(cbid) + cbfile.write_record(np.double(GMSun)) + cbfile.write_record(np.double(RSun)) + cbfile.write_record(np.double(J2)) + cbfile.write_record(np.double(J4)) + cbfile.close() + + plfile = FortranFile(param['PL_IN'], 'w') + npl = pl.id.count().values + plid = pl.id.values + px = pl['px'].values + py = pl['py'].values + pz = pl['pz'].values + vx = pl['vx'].values + vy = pl['vy'].values + vz = pl['vz'].values + mass = pl['Mass'].values + radius = pl['Radius'].values + + plfile.write_record(npl) + plfile.write_record(plid) + plfile.write_record(px) + plfile.write_record(py) + plfile.write_record(pz) + plfile.write_record(vx) + plfile.write_record(vy) + plfile.write_record(vz) + plfile.write_record(mass) + if param['RHILL_PRESENT'] == 'YES': + rhill = pl['Rhill'].values + plfile.write_record(rhill) + plfile.write_record(radius) + plfile.close() + tpfile = FortranFile(param['TP_IN'], 'w') + ntp = tp.id.count().values + tpid = tp.id.values + px = tp['px'].values + py = tp['py'].values + pz = tp['pz'].values + vx = tp['vx'].values + vy = tp['vy'].values + vz = tp['vz'].values + tpfile.write_record(ntp) + tpfile.write_record(tpid) + tpfile.write_record(px) + tpfile.write_record(py) + tpfile.write_record(pz) + tpfile.write_record(vx) + tpfile.write_record(vy) + tpfile.write_record(vz) + else: + print(f"{param['IN_TYPE']} is an unknown file type") + + +def swifter_xr2infile(ds, param, framenum=-1): + """ + Writes a set of Swifter input files from a single frame of a Swiftest xarray dataset + + Parameters + ---------- + ds : xarray dataset + Dataset containing Swifter n-body data in XV format + framenum : int + Time frame to use to generate the initial conditions. If this argument is not passed, the default is to use the last frame in the dataset. + param : dict + Swifter input parameters. This method uses the names of the pl and tp files from the input + + Returns + ------- + A set of input files for a Swifter run + """ + frame = ds.isel(time=framenum) + cb = frame.where(frame.id == 0, drop=True) + pl = frame.where(frame.id > 0, drop=True) + pl = pl.where(np.invert(np.isnan(pl['Mass'])), drop=True).drop_vars(['J_2', 'J_4']) + tp = frame.where(np.isnan(frame['Mass']), drop=True).drop_vars(['Mass', 'Radius', 'J_2', 'J_4']) + + GMSun = np.double(cb['Mass']) + RSun = np.double(cb['Radius']) + param['J2'] = np.double(cb['J_2']) + param['J4'] = np.double(cb['J_4']) + param['RHILL_PRESENT'] = "YES" + + if param['IN_TYPE'] == 'ASCII': + # Swiftest Central body file + plfile = open(param['PL_IN'], 'w') + print(pl.id.count().values + 1, file=plfile) + print(cb.id.values[0], cb['Mass'].values[0], file=plfile) + print('0.0 0.0 0.0', file=plfile) + print('0.0 0.0 0.0', file=plfile) + for i in pl.id: + pli = pl.sel(id=i) + if param['RHILL_PRESENT'] == "YES": + print(i.values, pli['Mass'].values, pli['Rhill'].values, file=plfile) + else: + print(i.values, pli['Mass'].values, file=plfile) + if param['CHK_CLOSE'] == "YES": + print(pli['Radius'].values, file=plfile) + print(pli['px'].values, pli['py'].values, pli['pz'].values, file=plfile) + print(pli['vx'].values, pli['vy'].values, pli['vz'].values, file=plfile) + plfile.close() + + # TP file + tpfile = open(param['TP_IN'], 'w') + print(tp.id.count().values, file=tpfile) + for i in tp.id: + tpi = tp.sel(id=i) + print(i.values, file=tpfile) + print(tpi['px'].values, tpi['py'].values, tpi['pz'].values, file=tpfile) + print(tpi['vx'].values, tpi['vy'].values, tpi['vz'].values, file=tpfile) + tpfile.close() + else: + # Now make Swiftest files + print(f"{param['IN_TYPE']} is an unknown input file type") + + +def swift2swifter(swift_param, plname="", tpname="", conversion_questions={}): + swifter_param = {} + intxt = conversion_questions.get('RHILL', None) + if not intxt: + intxt = input("Is this a SyMBA input file with RHILL values in pl.in? (y/N)> ") + if intxt.upper() == 'Y': + isSyMBA = True + swifter_param['RHILL_PRESENT'] = 'YES' + else: + isSyMBA = False + swifter_param['RHILL_PRESENT'] = 'NO' + + isDouble = conversion_questions.get('DOUBLE', None) + if not isDouble: + print("Use single precision or double precision for real outputs?") + print(" 1) Single (real*4)") + print("*2) Double (real*8)") + intxt = input("> ") + if intxt == '1': + isDouble = False + else: + isDouble = True + + # Convert the parameter file values + swifter_param['T0'] = swift_param['T0'] + swifter_param['TSTOP'] = swift_param['TSTOP'] + swifter_param['DT'] = swift_param['DT'] + swifter_param['ISTEP_OUT'] = int(swift_param['DTOUT'] / swift_param['DT']) + swifter_param['ISTEP_DUMP'] = int(swift_param['DTDUMP'] / swift_param['DT']) + swifter_param['BIN_OUT'] = swift_param['BINARY_OUTPUTFILE'] + swifter_param['OUT_STAT'] = swift_param['STATUS_FLAG_FOR_OPEN_STATEMENTS'] + + if swift_param['L5'] == "T": + swifter_param['OUT_FORM'] = 'EL' + else: + swifter_param['OUT_FORM'] = 'XV' + + if swift_param['LCLOSE'] == "T": + swifter_param['CHK_CLOSE'] = "YES" + else: + swifter_param['CHK_CLOSE'] = "NO" + + swifter_param['CHK_RMIN'] = swift_param['RMIN'] + swifter_param['CHK_RMAX'] = swift_param['RMAX'] + swifter_param['CHK_QMIN'] = swift_param['QMIN'] + if swift_param['QMIN'] != '-1': + + swifter_param['CHK_QMIN_COORD'] = conversion_questions.get('CHK_QMIN_COORD', None) + if not swifter_param['CHK_QMIN_COORD']: + print("CHK_QMIN_COORD value:") + print("*1) HELIO") + print(" 2) BARY") + intxt = input("> ") + if intxt == '2': + swifter_param['CHK_QMIN_COORD'] = "BARY" + else: + swifter_param['CHK_QMIN_COORD'] = "HELIO" + + swifter_param['CHK_QMIN_RANGE'] = conversion_questions.get('CHK_QMIN_RANGE', None) + if not swifter_param['CHK_QMIN_RANGE']: + alo = input(f"Lower bound on CHK_QMIN_RANGE [{swift_param['RMIN']}]: ") + if alo == '': + alo = swift_param['RMIN'] + ahi = input(f"Upper bound on CHK_QMIN_RANGE: [{swift_param['RMAXU']}]: ") + if ahi == '': + ahi = swift_param['RMAXU'] + swifter_param['CHK_QMIN_RANGE'] = f"{alo} {ahi}" + + + swifter_param['ENC_OUT'] = conversion_questions.get('ENC_OUT', None) + if not swifter_param['ENC_OUT']: + swifter_param['ENC_OUT'] = input("ENC_OUT: Encounter file name: [enc.dat]> ") + if swifter_param['ENC_OUT'] == '': + swifter_param['ENC_OUT'] = "enc.dat" + + intxt = conversion_questions.get('EXTRA_FORCE', None) + if not intxt: + intxt = input("EXTRA_FORCE: Use additional user-specified force routines? (y/N)> ") + if intxt.upper() == 'Y': + swifter_param['EXTRA_FORCE'] = 'YES' + else: + swifter_param['EXTRA_FORCE'] = 'NO' + + intxt = conversion_questions.get('BIG_DISCARD', None) + if not intxt: + intxt = input("BIG_DISCARD: include data for all bodies > MTINY for each discard record? (y/N)> ") + if intxt.upper() == 'Y': + swifter_param['BIG_DISCARD'] = 'YES' + else: + swifter_param['BIG_DISCARD'] = 'NO' + + # Convert the PL file + if plname == '': + plname = input("PL_IN: Name of new planet input file: [pl.swifter.in]> ") + if plname == '': + plname = "pl.swifter.in" + swifter_param['PL_IN'] = plname + try: + plnew = open(swifter_param['PL_IN'], 'w') + except IOError: + print(f"Cannot write to file {swifter_param['PL_IN']}") + return swift_param + + print(f"Converting PL file: {swift_param['PL_IN']} -> {swifter_param['PL_IN']}") + try: + with open(swift_param['PL_IN'], 'r') as plold: + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + npl = int(i_list[0]) + print(npl, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + GMcb = real2float(i_list[0]) + if swift_param['L1'] == "T": + swifter_param['J2'] = real2float(i_list[1]) + swifter_param['J4'] = real2float(i_list[2]) + else: + swifter_param['J2'] = 0.0 + swifter_param['J4'] = 0.0 + print(1, GMcb, file=plnew) + print(0.0, 0.0, 0.0, file=plnew) + print(0.0, 0.0, 0.0, file=plnew) + line = plold.readline() # Ignore the two zero vector lines + line = plold.readline() + for n in range(1, npl): # Loop over planets + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + GMpl = real2float(i_list[0]) + if isSyMBA: + Rhill = real2float(i_list[1]) + if swift_param['LCLOSE'] == "T": + plrad = real2float(i_list[2]) + else: + if swift_param['LCLOSE'] == "T": + plrad = real2float(i_list[1]) + if swifter_param['RHILL_PRESENT'] == 'YES': + print(n + 1, GMpl, Rhill, file=plnew) + else: + print(n + 1, GMpl, file=plnew) + if swifter_param['CHK_CLOSE'] == 'YES': + print(plrad, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = real2float(i_list[0]) + yh = real2float(i_list[1]) + zh = real2float(i_list[2]) + print(xh, yh, zh, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = real2float(i_list[0]) + vy = real2float(i_list[1]) + vz = real2float(i_list[2]) + print(vx, vy, vz, file=plnew) + plnew.close() + plold.close() + except IOError: + print(f"Error converting PL file") + + # Convert the TP file + if tpname == '': + tpname = input("TP_IN: Name of new test particle input file: [tp.swifter.in]> ") + if tpname == '': + tpname = "tp.swifter.in" + swifter_param['TP_IN'] = tpname + + try: + tpnew = open(swifter_param['TP_IN'], 'w') + except IOError: + print(f"Cannot write to file {swifter_param['TP_IN']}") + + print(f"Converting TP file: {swift_param['TP_IN']} -> {swifter_param['TP_IN']}") + try: + print(f'Writing out new TP file: {swifter_param["TP_IN"]}') + with open(swift_param['TP_IN'], 'r') as tpold: + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + ntp = int(i_list[0]) + print(ntp, file=tpnew) + for n in range(0, ntp): # Loop over test particles + print(npl + n + 1, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = real2float(i_list[0]) + yh = real2float(i_list[1]) + zh = real2float(i_list[2]) + print(xh, yh, zh, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = real2float(i_list[0]) + vy = real2float(i_list[1]) + vz = real2float(i_list[2]) + print(vx, vy, vz, file=tpnew) + # Ignore STAT lines + line = tpold.readline() + line = tpold.readline() + except IOError: + print(f"Error converting TP file") + swifter_param['! VERSION'] = "Swifter parameter file converted from Swift" + + return swifter_param + +def swifter2swiftest(swifter_param, plname="", tpname="", cbname="", conversion_questions={}): + swiftest_param = swifter_param.copy() + # Pull additional feature status from the conversion_questions dictionary + + for key in newfeaturelist: + swiftest_param[key] = conversion_questions.get(key, "NO") + # Convert the PL file + if plname == '': + plname = input("PL_IN: Name of new planet input file: [pl.swiftest.in]> ") + if plname == '': + plname = "pl.swiftest.in" + swiftest_param['PL_IN'] = plname + + try: + plnew = open(swiftest_param['PL_IN'], 'w') + except IOError: + print(f"Cannot write to file {swiftest_param['PL_IN']}") + return swifter_param + + print(f"Converting PL file: {swifter_param['PL_IN']} -> {swiftest_param['PL_IN']}") + try: + with open(swifter_param['PL_IN'], 'r') as plold: + line = plold.readline() + line = line.split("!")[0] # Ignore comments + i_list = [i for i in line.split(" ") if i.strip()] + npl = int(i_list[0]) + print(npl - 1, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + GMcb = real2float(i_list[1]) # Store central body GM for later + line = plold.readline() # Ignore the two zero vector lines + line = plold.readline() + for n in range(1, npl): # Loop over planets + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + idnum = int(i_list[0]) + GMpl = real2float(i_list[1]) + if swifter_param['RHILL_PRESENT'] == 'YES': + Rhill = real2float(i_list[2]) + print(idnum, GMpl, Rhill, file=plnew) + else: + print(idnum, GMpl, file=plnew) + if swifter_param['CHK_CLOSE'] == 'YES': + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + plrad = real2float(i_list[0]) + print(plrad, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = real2float(i_list[0]) + yh = real2float(i_list[1]) + zh = real2float(i_list[2]) + print(xh, yh, zh, file=plnew) + line = plold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = real2float(i_list[0]) + vy = real2float(i_list[1]) + vz = real2float(i_list[2]) + print(vx, vy, vz, file=plnew) + plnew.close() + plold.close() + except IOError: + print(f"Error converting PL file") + + # Convert the TP file + if tpname == '': + tpname = input("TP_IN: Name of new planet input file: [tp.swiftest.in]> ") + if tpname == '': + tpname = "tp.swiftest.in" + swiftest_param['TP_IN'] = tpname + + try: + tpnew = open(swiftest_param['TP_IN'], 'w') + except IOError: + print(f"Cannot write to file {swiftest_param['TP_IN']}") + return swifter_param + + print(f"Converting TP file: {swifter_param['TP_IN']} -> {swiftest_param['TP_IN']}") + try: + print(f'Writing out new TP file: {swiftest_param["TP_IN"]}') + with open(swifter_param['TP_IN'], 'r') as tpold: + line = tpold.readline() + line = line.split("!")[0] # Ignore comments + i_list = [i for i in line.split(" ") if i.strip()] + ntp = int(i_list[0]) + print(ntp, file=tpnew) + for n in range(0, ntp): # Loop over test particles + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + name = int(i_list[0]) + print(name, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + xh = real2float(i_list[0]) + yh = real2float(i_list[1]) + zh = real2float(i_list[2]) + print(xh, yh, zh, file=tpnew) + line = tpold.readline() + i_list = [i for i in line.split(" ") if i.strip()] + vx = real2float(i_list[0]) + vy = real2float(i_list[1]) + vz = real2float(i_list[2]) + print(vx, vy, vz, file=tpnew) + + tpold.close() + tpnew.close() + except IOError: + print(f"Error converting TP file") + + # Create the CB file + if cbname == '': + cbname = input("CB_IN: Name of new planet input file: [cb.swiftest.in]> ") + if cbname == '': + cbname = "cb.swiftest.in" + swiftest_param['CB_IN'] = cbname + + unit_system = conversion_questions.get('UNITS', '') + unit_type = 5 + if not unit_system: + print(f"\nCentral body G*M = {GMcb}\n") + print("Select the unit system to use:") + print("1) MSun-AU-year") + print("2) MSun-AU-day") + print("3) SI: kg-m-s") + print("4) CGS: g-cm-s") + print("5) Set units manually") + inval = input("> ") + try: + unit_type = int(inval) + except ValueError: + goodval = False + else: + goodval = (unit_type > 0 and unit_type < 6) + if not goodval: + print(f"{inval} is not a valid menu option") + sys.exit(-1) + if unit_type == 1 or unit_system.upper() == 'MSUN-AU-YEAR': + print("Unit system is MSun-AU-year") + swiftest_param['MU2KG'] = swiftest.MSun + swiftest_param['DU2M'] = swiftest.AU2M + swiftest_param['TU2S'] = swiftest.YR2S + elif unit_type == 2 or unit_system.upper() == 'MSUN-AU-DAY': + print("Unit system is MSun-AU-day") + swiftest_param['MU2KG'] = swiftest.MSun + swiftest_param['DU2M'] = swiftest.AU2M + swiftest_param['TU2S'] = swiftest.JD2S + elif unit_type == 3 or unit_system.upper() == 'SI': + print("Unit system is SI: kg-m-s") + swiftest_param['MU2KG'] = 1.0 + swiftest_param['DU2M'] = 1.0 + swiftest_param['TU2S'] = 1.0 + elif unit_type == 4 or unit_system.upper() == 'CGS': + print("Unit system is CGS: g-cm-s") + swiftest_param['MU2KG'] = 1e-3 + swiftest_param['DU2M'] = 1.0e-2 + swiftest_param['TU2S'] = 1.0 + elif unit_type == 5: + print("User-defined units.") + print("Define each unit (mass, distance, and time) by its corresponding SI value.") + swiftest_param['MU2KG'] = input("Mass value in kilograms: ") + swiftest_param['DU2M'] = input("Distance value in meters: ") + swiftest_param['TU2S'] = input("Time unit in seconds: ") + GU = swiftest.GC / (swiftest_param['DU2M'] ** 3 / (swiftest_param['MU2KG'] * swiftest_param['TU2S'] ** 2)) + print(f"Central body mass: {GMcb / GU} MU ({(GMcb / GU) * swiftest_param['MU2KG']} kg)") + + cbrad = conversion_questions.get('CBRAD', None) + if not cbrad: + print("Set central body radius:") + print(f"1) Use Swifter parameter value of CHK_RMIN = {swifter_param['CHK_RMIN']}") + print(f"2) Set value manually") + inval = input("> ") + try: + cbrad_type = int(inval) + except ValueError: + goodval = False + else: + goodval = (cbrad_type > 0 and cbrad_type < 3) + if not goodval: + print(f"{inval} is not a valid menu option") + sys.exit(-1) + if cbrad_type == 1: + cbrad = swifter_param['CHK_RMIN'] + elif cbrad_type == 2: + cbrad = input("Enter radius of central body in simulation Distance Units: ") + cbrad = real2float(cbrad.strip()) + + print(f'Writing out new CB file: {swiftest_param["CB_IN"]}') + # Write out new central body file + try: + cbnew = open(swiftest_param['CB_IN'], 'w') + print(GMcb, file=cbnew) + print(cbrad, file=cbnew) + print(swifter_param['J2'], file=cbnew) + print(swifter_param['J4'], file=cbnew) + cbnew.close() + except IOError: + print(f"Cannot write to file {swiftest_param['CB_IN']}") + return swifter_param + + MTINY = conversion_questions.get('MTINY', None) + if not MTINY: + MTINY = input(f"Value of MTINY if this is a SyMBA simulation (enter nothing if this is not a SyMBA parameter file)> ") + if MTINY != '' and real2float(MTINY.strip()) > 0: + swiftest_param['MTINY'] = real2float(MTINY.strip()) + + # Remove the unneeded parameters + if 'C' in swiftest_param: + swiftest_param['GR'] = 'YES' + swiftest_param.pop('C', None) + swiftest_param.pop('J2', None) + swiftest_param.pop('J4', None) + swiftest_param.pop('RHILL_PRESENT', None) + + swiftest_param['DISCARD_OUT'] = conversion_questions.get('DISCARD_OUT', '') + if not swiftest_param['DISCARD_OUT']: + swiftest_param['DISCARD_OUT'] = input("DISCARD_OUT: Discard file name: [discard.out]> ") + if swiftest_param['DISCARD_OUT'] == '': + swiftest_param['DISCARD_OUT'] = "discard.out" + + swiftest_param['! VERSION'] = "Swiftest parameter file converted from Swifter" + return swiftest_param + +def swift2swiftest(swift_param, plname="", tpname="", cbname="", conversion_questions={}): + if plname == '': + plname = input("PL_IN: Name of new planet input file: [pl.swiftest.in]> ") + if plname == '': + plname = "pl.swiftest.in" + pltmp = tempfile.NamedTemporaryFile() + pltmpname = pltmp.name + + if tpname == '': + tpname = input("TP_IN: Name of new planet input file: [tp.swiftest.in]> ") + if tpname == '': + tpname = "tp.swiftest.in" + tptmp = tempfile.NamedTemporaryFile() + tptmpname = tptmp.name + + # Create the CB file + if cbname == '': + cbname = input("CB_IN: Name of new planet input file: [cb.swiftest.in]> ") + if cbname == '': + cbname = "cb.swiftest.in" + swifter_param = swift2swifter(swift_param, pltmpname, tptmpname, conversion_questions) + swiftest_param = swifter2swiftest(swifter_param, plname, tpname, cbname, conversion_questions) + swiftest_param['! VERSION'] = "Swiftest parameter file converted from Swift" + return swiftest_param + +def swiftest2swifter_param(swiftest_param, J2=0.0, J4=0.0): + swifter_param = swiftest_param + CBIN = swifter_param.pop("CB_IN", None) + MTINY = swifter_param.pop("MTINY", None) + MU2KG = swifter_param.pop("MU2KG", 1.0) + DU2M = swifter_param.pop("DU2M", 1.0) + TU2S = swifter_param.pop("TU2S", 1.0) + GR = swifter_param.pop("GR", None) + if GR is not None: + if GR == 'YES': + swifter_param['C'] = swiftest.einsteinC * np.longdouble(TU2S) / np.longdouble(DU2M) + for key in newfeaturelist: + tmp = swifter_param.pop(key, None) + swifter_param['J2'] = J2 + swifter_param['J4'] = J4 + swifter_param['CHK_CLOSE'] = "YES" + if swifter_param['OUT_STAT'] == "REPLACE": + swifter_param['OUT_STAT'] = "UNKNOWN" + swifter_param['! VERSION'] = "Swifter parameter file converted from Swiftest" + + return swifter_param \ No newline at end of file diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py new file mode 100644 index 000000000..670b72a60 --- /dev/null +++ b/python/swiftest/swiftest/simulation_class.py @@ -0,0 +1,186 @@ +from swiftest import io +from swiftest import init_cond +from swiftest import tool +from swiftest import constants +from datetime import date +import xarray as xr + +class Simulation: + """ + This is a class that define the basic Swift/Swifter/Swiftest simulation object + """ + def __init__(self, codename="Swiftest", param_file=""): + self.ds = xr.Dataset() + self.param = { + '! VERSION': f"Swiftest parameter input", + 'T0': "0.0", + 'TSTOP': "0.0", + 'DT': "0.0", + 'PL_IN': "pl.in", + 'TP_IN': "tp.in", + 'CB_IN': "cb.in", + 'IN_TYPE': "ASCII", + 'ISTEP_OUT': "1", + 'ISTEP_DUMP': "1", + 'BIN_OUT': "bin.dat", + 'OUT_TYPE': 'REAL8', + 'OUT_FORM': "EL", + 'OUT_STAT': "REPLACE", + 'CHK_RMAX': "1000.0", + 'CHK_EJECT': "1000.0", + 'CHK_RMIN': constants.RSun / constants.AU2M, + 'CHK_QMIN': constants.RSun / constants.AU2M, + 'CHK_QMIN_COORD': "HELIO", + 'CHK_QMIN_RANGE': f"{constants.RSun / constants.AU2M} 1000.0", + 'ENC_OUT': "enc.dat", + 'MU2KG': constants.MSun, + 'TU2S': constants.JD2S, + 'DU2M': constants.AU2M, + 'EXTRA_FORCE': "NO", + 'BIG_DISCARD': "NO", + 'CHK_CLOSE': "YES", + 'RHILL_PRESENT': "YES", + 'FRAGMENTATION': "NO", + 'ROTATION': "NO", + 'TIDES': "NO", + 'ENERGY': "NO", + 'GR': "NO", + 'YARKOVSKY': "NO", + 'YORP': "NO", + 'MTINY' : "0.0" + } + self.codename = codename + if param_file != "" : + self.read_param(param_file, codename) + return + + def add(self, plname, date=date.today().isoformat(), idval=None): + """ + Adds a solar system body to an existing simulation DataSet. + + Parameters + ---------- + plname : string + Name of planet to add (e.g. "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune" + date : string + Date to use when obtaining the ephemerides in the format YYYY-MM-DD. Defaults to "today" + Returns + ------- + self.ds : xarray dataset + """ + self.ds = init_cond.solar_system_horizons(plname, idval, self.param, date, self.ds) + return + + def read_param(self, param_file, codename="Swiftest"): + if codename == "Swiftest": + self.param = io.read_swiftest_param(param_file, self.param) + self.codename = "Swiftest" + elif codename == "Swifter": + self.param = io.read_swifter_param(param_file) + self.codename = "Swifter" + elif codename == "Swift": + self.param = io.read_swift_param(param_file) + self.codename = "Swift" + else: + print(f'{codename} is not a recognized code name. Valid options are "Swiftest", "Swifter", or "Swift".') + self.codename = "Unknown" + return + + def write_param(self, param_file, param=None): + if param is None: + param = self.param + # Check to see if the parameter type matches the output type. If not, we need to convert + codename = param['! VERSION'].split()[0] + if codename == "Swifter" or codename == "Swiftest": + io.write_labeled_param(param, param_file) + elif codename == "Swift": + io.write_swift_param(param, param_file) + else: + print('Cannot process unknown code type. Call the read_param method with a valid code name. Valid options are "Swiftest", "Swifter", or "Swift".') + return + + def convert(self, param_file, newcodename="Swiftest", plname="pl.swiftest.in", tpname="tp.swiftest.in", cbname="cb.swiftest.in", conversion_questions={}): + """ + Converts simulation input files from one code type to another (Swift, Swifter, or Swiftest). Returns the old parameter configuration. + """ + oldparam = self.param + if self.codename == newcodename: + print(f"This parameter configuration is already in {newcodename} format") + return oldparam + if newcodename != "Swift" and newcodename != "Swifter" and newcodename != "Swiftest": + print(f'{newcodename} is an invalid code type. Valid options are "Swiftest", "Swifter", or "Swift".') + return oldparam + goodconversion = True + if self.codename == "Swifter": + if newcodename == "Swiftest": + self.param = io.swifter2swiftest(self.param, plname, tpname, cbname, conversion_questions) + else: + goodconversion = False + elif self.codename == "Swift": + if newcodename == "Swifter": + self.param = io.swift2swifter(self.param, plname, tpname, conversion_questions) + elif newcodename == "Swiftest": + self.param = io.swift2swiftest(self.param, plname, tpname, cbname, conversion_questions) + else: + goodconversion = False + else: + goodconversion = False + + if goodconversion: + self.write_param(param_file) + else: + print(f"Conversion from {self.codename} to {newcodename} is not supported.") + return oldparam + + def bin2xr(self): + if self.codename == "Swiftest": + self.ds = io.swiftest2xr(self.param) + print('Swiftest simulation data stored as xarray DataSet .ds') + elif self.codename == "Swifter": + self.ds = io.swifter2xr(self.param) + print('Swifter simulation data stored as xarray DataSet .ds') + elif self.codename == "Swift": + print("Reading Swift simulation data is not implemented yet") + else: + print('Cannot process unknown code type. Call the read_param method with a valid code name. Valid options are "Swiftest", "Swifter", or "Swift".') + return + + def follow(self, codestyle="Swifter"): + if self.ds is None: + self.bin2xr() + if codestyle == "Swift": + try: + with open('follow.in', 'r') as f: + line = f.readline() # Parameter file (ignored because bin2xr already takes care of it + line = f.readline() # PL file (ignored) + line = f.readline() # TP file (ignored) + line = f.readline() # ifol + i_list = [i for i in line.split(" ") if i.strip()] + ifol = int(i_list[0]) + line = f.readline() # nskp + i_list = [i for i in line.split(" ") if i.strip()] + nskp = int(i_list[0]) + except IOError: + print('No follow.in file found') + ifol = None + nskp = None + fol = tool.follow_swift(self.ds, ifol=ifol, nskp=nskp) + + print('follow.out written') + return fol + + def save(self, param_file, framenum=-1, codename="Swiftest"): + if codename == "Swiftest": + io.swiftest_xr2infile(self.ds, self.param, framenum) + self.write_param(param_file) + elif codename == "Swifter": + if self.codename == "Swiftest": + swifter_param = io.swiftest2swifter_param(self.param) + else: + swifter_param = self.param + io.swifter_xr2infile(self.ds, swifter_param, framenum) + self.write_param(param_file, param=swifter_param) + else: + print(f'Saving to {codename} not supported') + + return \ No newline at end of file diff --git a/python/swiftest/swiftest/tool.py b/python/swiftest/swiftest/tool.py new file mode 100644 index 000000000..741dc0f1b --- /dev/null +++ b/python/swiftest/swiftest/tool.py @@ -0,0 +1,84 @@ +import swiftest +import numpy as np +import os +import glob +from pyslalib import slalib +import xarray as xr +""" +Functions that recreate the Swift/Swifter tool programs +""" + +def sla_dranrm(angle): + func = np.vectorize(slalib.sla_dranrm) + return xr.apply_ufunc(func, angle) + +def follow_swift(ds, ifol=None, nskp=None): + """ + Emulates the Swift version of tool_follow.f + + + Parameters + ---------- + ds : Dataset containing orbital elements + + Returns + ------- + fol : Dataset containing only the followed body with angles converted to degrees + + Generates a file called follow.out containing 10 columns (angles are all in degrees): + 1 2 3 4 5 6 7 8 9 10 + t,a,e,inc,capom,omega,capm,peri,apo,obar + + """ + fol = None + if ifol is None: + intxt = input(' Input the particle number to follow \n') + ifol = int(intxt) + print(f"Following particle {ifol}") + if ifol < 0: # Negative numbers are planets + fol = ds.where(np.invert(np.isnan(ds['Mass'])), drop=True) + fol = fol.where(np.invert(np.isnan(fol['a'])), drop=True) # Remove times where this body doesn't exist (but this also gets rid of the central body) + fol = fol.isel(id = -ifol - 2) # Take 1 off for 0-indexed arrays in Python, and take 1 more off because the central body is gone + elif ifol > 0: # Positive numbers are test particles + fol = ds.where(np.isnan(ds['Mass']), drop=True).drop_vars(['Mass', 'Radius']) + fol = fol.where(np.invert(np.isnan(fol['a'])), drop=True) + fol = fol.isel(id = ifol - 1) # Take 1 off for 0-indexed arrays in Python + + if nskp is None: + intxt = input('Input the print frequency\n') + nskp = int(intxt) + + dr = 180.0 / np.pi + fol['obar'] = fol['capom'] + fol['omega'] + fol['obar'] = fol['obar'].fillna(0) + fol['obar'] = sla_dranrm(fol['obar']) + fol['obar'] = fol['obar'] * dr + fol['inc'] = fol['inc'] * dr + fol['capom'] = fol['capom'] * dr + fol['omega'] = fol['omega'] * dr + fol['capm'] = fol['capm'] * dr + fol['peri'] = fol['a'] * (1.0 - fol['e']) + fol['apo'] = fol['a'] * (1.0 + fol['e']) + + + tslice = slice(None, None, nskp) + try: + with open('follow.out', 'w') as f: + print('# 1 2 3 4 5 6 7 8 9 10', file=f) + print('# t,a,e,inc,capom,omega,capm,peri,apo,obar', file=f) + for t in fol.isel(time=tslice).time: + a = fol['a'].sel(time=t).values + e = fol['e'].sel(time=t).values + inc = fol['inc'].sel(time=t).values + capom = fol['capom'].sel(time=t).values + omega = fol['omega'].sel(time=t).values + capm = fol['capm'].sel(time=t).values + peri = fol['peri'].sel(time=t).values + apo = fol['apo'].sel(time=t).values + obar = fol['obar'].sel(time=t).values + print(f"{t.values:15.7e} {a:22.16f} {e:22.16f} {inc:22.16f} {capom:22.16f} {omega:22.16f} {capm:22.16f} {peri:22.16f} {apo:22.16f} {obar:22.16f}", file=f) + + except IOError: + print(f"Error writing to follow.out") + + return fol \ No newline at end of file diff --git a/python/swiftest/tests/bin2xr/swiftest/bin2xr_swiftest.py b/python/swiftest/tests/bin2xr/swiftest/bin2xr_swiftest.py new file mode 100644 index 000000000..0a430c654 --- /dev/null +++ b/python/swiftest/tests/bin2xr/swiftest/bin2xr_swiftest.py @@ -0,0 +1,4 @@ +import swiftest +sim = swiftest.Simulation(param_file="param.swiftest.in") +sim.bin2xr() +sim.ds \ No newline at end of file diff --git a/python/swiftest/tests/bin2xr/swiftest/cb.swiftest.in b/python/swiftest/tests/bin2xr/swiftest/cb.swiftest.in new file mode 100644 index 000000000..e50255f4a --- /dev/null +++ b/python/swiftest/tests/bin2xr/swiftest/cb.swiftest.in @@ -0,0 +1,4 @@ +0.000295923385935 +0.00468 +0.0 +0.0 diff --git a/python/swiftest/tests/bin2xr/swiftest/param.swiftest.in b/python/swiftest/tests/bin2xr/swiftest/param.swiftest.in new file mode 100644 index 000000000..a7f91ba33 --- /dev/null +++ b/python/swiftest/tests/bin2xr/swiftest/param.swiftest.in @@ -0,0 +1,31 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 0.15 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 +RHILL_PRESENT yes +MTINY 1e-12 diff --git a/python/swiftest/tests/bin2xr/swiftest/pl.swiftest.in b/python/swiftest/tests/bin2xr/swiftest/pl.swiftest.in new file mode 100644 index 000000000..d8da7a92a Binary files /dev/null and b/python/swiftest/tests/bin2xr/swiftest/pl.swiftest.in differ diff --git a/python/swiftest/tests/bin2xr/swiftest/tp.swiftest.in b/python/swiftest/tests/bin2xr/swiftest/tp.swiftest.in new file mode 100644 index 000000000..64bf92f74 Binary files /dev/null and b/python/swiftest/tests/bin2xr/swiftest/tp.swiftest.in differ diff --git a/python/swiftest/tests/convert_code_type/swift2swifter/param.swift.in b/python/swiftest/tests/convert_code_type/swift2swifter/param.swift.in new file mode 100644 index 000000000..3f9822a58 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swifter/param.swift.in @@ -0,0 +1,6 @@ +.0d0 365.25d9 5.0d0 +365.25d5 365.25d5 +F T F F T F +4.68d-03 100.0 -1.0 4.68d-03 T +bin.dat +unknown diff --git a/python/swiftest/tests/convert_code_type/swift2swifter/pl.swift.in b/python/swiftest/tests/convert_code_type/swift2swifter/pl.swift.in new file mode 100644 index 000000000..4d479d3cf --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swifter/pl.swift.in @@ -0,0 +1,28 @@ + 8 + 2.9592338592955439E-004 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 4.9127330156310911E-011 1.6308387199999999E-005 + -0.15273942296363005 -0.44077188683118762 -2.1987973899201478E-002 + 2.0924205227543746E-002 -7.6522013575130771E-003 -2.5455577585009612E-003 + 7.2437260968171072E-010 4.0454452799999999E-005 + -0.68052645343902751 -0.21255610959625498 3.6375571604128076E-002 + 5.7676478402592110E-003 -1.9654618148759011E-002 -6.0150804827979417E-004 + 8.9973512337453730E-010 4.2635232500000000E-005 + 0.21153912017632401 0.96910814953928759 -1.5976841060778844E-006 + -1.6944135164995145E-002 3.6911953785631699E-003 1.4525071481945407E-008 + 9.5498958252779674E-011 2.2707542499999999E-005 + 1.4232971230754801 0.21815483859431103 -3.0416153305576600E-002 + -1.9274688569975952E-003 1.4590108763912674E-002 3.5304139123317309E-004 + 2.8254526327676804E-007 4.7789450300000003E-004 + 4.0036874054921974 2.9350393270474617 -0.10182563723380476 + -4.5629876169643530E-003 6.4471059617920590E-003 7.5448856044019538E-005 + 8.4600347388504292E-008 4.0286669700000002E-004 + 6.4083018390909805 6.5682871940009111 -0.36911425745370574 + -4.2912688970106801E-003 3.8914184987695602E-003 1.0289743699759401E-004 + 1.2920737211033427E-008 1.7085136200000001E-004 + 14.430329793174279 -13.735823636348456 -0.23812543891764848 + 2.6784223946886604E-003 2.6724061291222238E-003 -2.4777620883141212E-005 + 1.5244164811971947E-008 1.6553711599999999E-004 + 16.808300160620913 -24.994308693440338 0.12729909149223279 + 2.5795430409598025E-003 1.7765162604947151E-003 -9.5908529499802122E-005 diff --git a/python/swiftest/tests/convert_code_type/swift2swifter/swift.in b/python/swiftest/tests/convert_code_type/swift2swifter/swift.in new file mode 100644 index 000000000..fd99232cf --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swifter/swift.in @@ -0,0 +1,3 @@ +param.swift.in +pl.swift.in +tp.swift.in diff --git a/python/swiftest/tests/convert_code_type/swift2swifter/swift2swifter.py b/python/swiftest/tests/convert_code_type/swift2swifter/swift2swifter.py new file mode 100644 index 000000000..b43dbd77b --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swifter/swift2swifter.py @@ -0,0 +1,14 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs an equivalent + parameter file in another code type. + + Input files are param.swift[er|est].in and output files are param.[src]2[dest].new, where [src] is the original file type + and [dest] is the new one. The user may be prompted to answer questions regarding how to convert between the different + simulation types. + """ +inparam = "param.swift.in" +outparam = "param.swift2swifter.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam, codename="Swift") +oldparam = sim.convert(outparam, newcodename="Swifter", plname="pl.swift2swifter.in", tpname="tp.swift2swifter.in") \ No newline at end of file diff --git a/python/swiftest/tests/convert_code_type/swift2swifter/tp.swift.in b/python/swiftest/tests/convert_code_type/swift2swifter/tp.swift.in new file mode 100644 index 000000000..c63ce7f13 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swifter/tp.swift.in @@ -0,0 +1,201 @@ + 50 + 1.75536839836414 -0.397301559901775 -2.886320950191011E-002 + 2.828957660824792E-003 1.250539366801959E-002 -8.833159624221525E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75462547108338 -0.397439253344038 -5.771762699017597E-002 + 2.826684041441025E-003 1.250497227754510E-002 -1.766362858232247E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75338751027446 -0.397668695834012 -8.655446554537932E-002 + 2.822895444946565E-003 1.250427010264027E-002 -2.648871776719500E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75165489340570 -0.397989817412071 -0.115364933939178 + 2.817593026527604E-003 1.250328735740620E-002 -3.530573675304868E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74942814808290 -0.398402520292259 -0.144140261060723 + 2.810778400843813E-003 1.250202434110241E-002 -4.411200127075503E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74670795159950 -0.398906678945642 -0.172871691292285 + 2.802453640651961E-003 1.250048143789167E-002 -5.290483179262686E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74349513437761 -0.399502139462572 -0.201550453497502 + 2.792621287336390E-003 1.249865911879178E-002 -6.168154404172742E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73979067424302 -0.400188720613739 -0.230167821489439 + 2.781284333388745E-003 1.249655793842830E-002 -7.043946749723006E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73559569961003 -0.400966213259897 -0.258715078141622 + 2.768446232154610E-003 1.249417853684106E-002 -7.917593441112837E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73091148830840 -0.401834380569283 -0.287183527684168 + 2.754110894243519E-003 1.249152163881874E-002 -8.788828357128555E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.72026103118157 -0.389355528881347 -2.828594532477477E-002 + 2.886114093303328E-003 1.275805340156797E-002 -9.011625318008804E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71953296244609 -0.389490468454826 -5.656327447617424E-002 + 2.883794537575375E-003 1.275762349729473E-002 -1.802050560751523E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71831976085279 -0.389715322095103 -8.482337627316461E-002 + 2.879929396047131E-003 1.275690713560546E-002 -2.702389743052803E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71662179632064 -0.390030021241745 -0.113057635311967 + 2.874519847244236E-003 1.275590453492696E-002 -3.601905600373064E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71443958590329 -0.390434470064514 -0.141257455903944 + 2.867567538449044E-003 1.275461600056502E-002 -4.500324282485798E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71177379334835 -0.390928545545054 -0.169414257543719 + 2.859074584296430E-003 1.275304192444406E-002 -5.397372422888266E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70862523246946 -0.391512096851912 -0.197519444517652 + 2.849043577517016E-003 1.275118278709834E-002 -6.292776170557357E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70499486153590 -0.392184946380362 -0.225564465162543 + 2.837477571062932E-003 1.274903915435912E-002 -7.186263077873903E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70088378639370 -0.392946889173945 -0.253540776694444 + 2.824380088051367E-003 1.274661167919763E-002 -8.077560980102980E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.69629325931601 -0.393797693137531 -0.281439857258866 + 2.809755118102047E-003 1.274390110104623E-002 -8.966398379301735E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68515366399900 -0.381409497860919 -2.770868114763943E-002 + 2.944472485597326E-003 1.301602639267184E-002 -9.193844020566386E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68444045380880 -0.381541683565614 -5.540892196217252E-002 + 2.942106027515987E-003 1.301558779556061E-002 -1.838488750704571E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68325201143113 -0.381761948356195 -8.309228700094988E-002 + 2.938162731265411E-003 1.301485694874873E-002 -2.757033154802284E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68158869923558 -0.382070225071419 -0.110750336684755 + 2.932643799201507E-003 1.301383407507970E-002 -3.674737585955427E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67945102372369 -0.382466419836768 -0.138374650747165 + 2.925550911915339E-003 1.301251948603269E-002 -4.591322656575339E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67683963509720 -0.382950412144466 -0.165956823795153 + 2.916886226800555E-003 1.301091358145700E-002 -5.506509472578220E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67375533056131 -0.383522054241252 -0.193488435537802 + 2.906652389013839E-003 1.300901685160348E-002 -6.420018645562698E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67019904882879 -0.384181172146986 -0.220961108835647 + 2.894852513239243E-003 1.300682987374474E-002 -7.331572218908740E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.66617187317737 -0.384927565087993 -0.248366475247266 + 2.881490193832806E-003 1.300435331405534E-002 -8.240892524600587E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.66167503032362 -0.385761005705779 -0.275696186833564 + 2.866569501085982E-003 1.300158792691927E-002 -9.147702574897361E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.65004629681643 -0.373463466840492 -2.713141697050409E-002 + 3.004107385165185E-003 1.327964217801076E-002 -9.380048499464011E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64934794517152 -0.373592898676403 -5.425456944817078E-002 + 3.001692998807830E-003 1.327919469791802E-002 -1.875723974515014E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64818426200946 -0.373808574617286 -8.136119772873515E-002 + 2.997669838310936E-003 1.327844904914197E-002 -2.812871813881668E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64655560215051 -0.374110428901093 -0.108443038057544 + 2.992039130381927E-003 1.327740545903941E-002 -3.749162668189549E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64446246154409 -0.374498369609023 -0.135491845590387 + 2.984802589649166E-003 1.327606424539795E-002 -4.684311491365882E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64190547684605 -0.374972278743879 -0.162499390046587 + 2.975962417200357E-003 1.327442581616511E-002 -5.618033740837786E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63888542865316 -0.375532011630592 -0.189457426557952 + 2.965521311764990E-003 1.327249067152087E-002 -6.550044369703316E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63540323612168 -0.376177397913609 -0.216357752508752 + 2.953482451109342E-003 1.327025940042943E-002 -7.480059791839970E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63145995996104 -0.376908241002040 -0.243192173800089 + 2.939849502386553E-003 1.326773268255752E-002 -8.407796715574675E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.62705680133123 -0.377724318274027 -0.269952516408261 + 2.924626618324377E-003 1.326491128756776E-002 -9.332972543286958E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61493892963385 -0.365517435820064 -2.655415279336874E-002 + 3.065098326561108E-003 1.354925233969722E-002 -9.570487094018532E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61425543653423 -0.365644113787191 -5.310021693416905E-002 + 3.062634922083575E-003 1.354879577463227E-002 -1.913805892481565E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61311651258780 -0.365855200878378 -7.963010845652042E-002 + 3.058530081302113E-003 1.354803498730923E-002 -2.869980191831766E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61152250506545 -0.366150632730767 -0.106135739430332 + 3.052785055829394E-003 1.354697020970083E-002 -3.825280107169432E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60947389936449 -0.366530319381278 -0.132609040433608 + 3.045401595105050E-003 1.354560176604655E-002 -4.779414805269034E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60697131859490 -0.366994145343291 -0.159041956298021 + 3.036381944904408E-003 1.354393007257628E-002 -5.732093966627254E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60401552674501 -0.367541969019932 -0.185426417578102 + 3.025728858747958E-003 1.354195563962491E-002 -6.683026757172563E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60060742341456 -0.368173623680233 -0.211754396181856 + 3.013445578918633E-003 1.353967906811411E-002 -7.631923833270372E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.59674804674471 -0.368888916916088 -0.238017872352911 + 2.999535847022010E-003 1.353710105150953E-002 -8.578496151713587E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.59243857233884 -0.369687630842276 -0.264208845982959 + 2.984003900096668E-003 1.353422237509990E-002 -9.522455377438729E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 diff --git a/python/swiftest/tests/convert_code_type/swift2swiftest/param.swift.in b/python/swiftest/tests/convert_code_type/swift2swiftest/param.swift.in new file mode 100644 index 000000000..3f9822a58 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swiftest/param.swift.in @@ -0,0 +1,6 @@ +.0d0 365.25d9 5.0d0 +365.25d5 365.25d5 +F T F F T F +4.68d-03 100.0 -1.0 4.68d-03 T +bin.dat +unknown diff --git a/python/swiftest/tests/convert_code_type/swift2swiftest/pl.swift.in b/python/swiftest/tests/convert_code_type/swift2swiftest/pl.swift.in new file mode 100644 index 000000000..4d479d3cf --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swiftest/pl.swift.in @@ -0,0 +1,28 @@ + 8 + 2.9592338592955439E-004 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 0.0000000000000000 0.0000000000000000 0.0000000000000000 + 4.9127330156310911E-011 1.6308387199999999E-005 + -0.15273942296363005 -0.44077188683118762 -2.1987973899201478E-002 + 2.0924205227543746E-002 -7.6522013575130771E-003 -2.5455577585009612E-003 + 7.2437260968171072E-010 4.0454452799999999E-005 + -0.68052645343902751 -0.21255610959625498 3.6375571604128076E-002 + 5.7676478402592110E-003 -1.9654618148759011E-002 -6.0150804827979417E-004 + 8.9973512337453730E-010 4.2635232500000000E-005 + 0.21153912017632401 0.96910814953928759 -1.5976841060778844E-006 + -1.6944135164995145E-002 3.6911953785631699E-003 1.4525071481945407E-008 + 9.5498958252779674E-011 2.2707542499999999E-005 + 1.4232971230754801 0.21815483859431103 -3.0416153305576600E-002 + -1.9274688569975952E-003 1.4590108763912674E-002 3.5304139123317309E-004 + 2.8254526327676804E-007 4.7789450300000003E-004 + 4.0036874054921974 2.9350393270474617 -0.10182563723380476 + -4.5629876169643530E-003 6.4471059617920590E-003 7.5448856044019538E-005 + 8.4600347388504292E-008 4.0286669700000002E-004 + 6.4083018390909805 6.5682871940009111 -0.36911425745370574 + -4.2912688970106801E-003 3.8914184987695602E-003 1.0289743699759401E-004 + 1.2920737211033427E-008 1.7085136200000001E-004 + 14.430329793174279 -13.735823636348456 -0.23812543891764848 + 2.6784223946886604E-003 2.6724061291222238E-003 -2.4777620883141212E-005 + 1.5244164811971947E-008 1.6553711599999999E-004 + 16.808300160620913 -24.994308693440338 0.12729909149223279 + 2.5795430409598025E-003 1.7765162604947151E-003 -9.5908529499802122E-005 diff --git a/python/swiftest/tests/convert_code_type/swift2swiftest/swift.in b/python/swiftest/tests/convert_code_type/swift2swiftest/swift.in new file mode 100644 index 000000000..fd99232cf --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swiftest/swift.in @@ -0,0 +1,3 @@ +param.swift.in +pl.swift.in +tp.swift.in diff --git a/python/swiftest/tests/convert_code_type/swift2swiftest/swift2swiftest.py b/python/swiftest/tests/convert_code_type/swift2swiftest/swift2swiftest.py new file mode 100644 index 000000000..581f318ea --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swiftest/swift2swiftest.py @@ -0,0 +1,14 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs an equivalent + parameter file in another code type. + + Input files are param.swift[er|est].in and output files are param.[src]2[dest].new, where [src] is the original file type + and [dest] is the new one. The user may be prompted to answer questions regarding how to convert between the different + simulation types. + """ +inparam = "param.swift.in" +outparam = "param.swift2swiftest.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam, codename="Swift") +oldparam = sim.convert(outparam, newcodename="Swiftest", plname="pl.swift2swiftest.in", tpname="tp.swift2swiftest.in", cbname="cb.swift2swiftest.in") \ No newline at end of file diff --git a/python/swiftest/tests/convert_code_type/swift2swiftest/tp.swift.in b/python/swiftest/tests/convert_code_type/swift2swiftest/tp.swift.in new file mode 100644 index 000000000..c63ce7f13 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swift2swiftest/tp.swift.in @@ -0,0 +1,201 @@ + 50 + 1.75536839836414 -0.397301559901775 -2.886320950191011E-002 + 2.828957660824792E-003 1.250539366801959E-002 -8.833159624221525E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75462547108338 -0.397439253344038 -5.771762699017597E-002 + 2.826684041441025E-003 1.250497227754510E-002 -1.766362858232247E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75338751027446 -0.397668695834012 -8.655446554537932E-002 + 2.822895444946565E-003 1.250427010264027E-002 -2.648871776719500E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.75165489340570 -0.397989817412071 -0.115364933939178 + 2.817593026527604E-003 1.250328735740620E-002 -3.530573675304868E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74942814808290 -0.398402520292259 -0.144140261060723 + 2.810778400843813E-003 1.250202434110241E-002 -4.411200127075503E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74670795159950 -0.398906678945642 -0.172871691292285 + 2.802453640651961E-003 1.250048143789167E-002 -5.290483179262686E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.74349513437761 -0.399502139462572 -0.201550453497502 + 2.792621287336390E-003 1.249865911879178E-002 -6.168154404172742E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73979067424302 -0.400188720613739 -0.230167821489439 + 2.781284333388745E-003 1.249655793842830E-002 -7.043946749723006E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73559569961003 -0.400966213259897 -0.258715078141622 + 2.768446232154610E-003 1.249417853684106E-002 -7.917593441112837E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.73091148830840 -0.401834380569283 -0.287183527684168 + 2.754110894243519E-003 1.249152163881874E-002 -8.788828357128555E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.72026103118157 -0.389355528881347 -2.828594532477477E-002 + 2.886114093303328E-003 1.275805340156797E-002 -9.011625318008804E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71953296244609 -0.389490468454826 -5.656327447617424E-002 + 2.883794537575375E-003 1.275762349729473E-002 -1.802050560751523E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71831976085279 -0.389715322095103 -8.482337627316461E-002 + 2.879929396047131E-003 1.275690713560546E-002 -2.702389743052803E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71662179632064 -0.390030021241745 -0.113057635311967 + 2.874519847244236E-003 1.275590453492696E-002 -3.601905600373064E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71443958590329 -0.390434470064514 -0.141257455903944 + 2.867567538449044E-003 1.275461600056502E-002 -4.500324282485798E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.71177379334835 -0.390928545545054 -0.169414257543719 + 2.859074584296430E-003 1.275304192444406E-002 -5.397372422888266E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70862523246946 -0.391512096851912 -0.197519444517652 + 2.849043577517016E-003 1.275118278709834E-002 -6.292776170557357E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70499486153590 -0.392184946380362 -0.225564465162543 + 2.837477571062932E-003 1.274903915435912E-002 -7.186263077873903E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.70088378639370 -0.392946889173945 -0.253540776694444 + 2.824380088051367E-003 1.274661167919763E-002 -8.077560980102980E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.69629325931601 -0.393797693137531 -0.281439857258866 + 2.809755118102047E-003 1.274390110104623E-002 -8.966398379301735E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68515366399900 -0.381409497860919 -2.770868114763943E-002 + 2.944472485597326E-003 1.301602639267184E-002 -9.193844020566386E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68444045380880 -0.381541683565614 -5.540892196217252E-002 + 2.942106027515987E-003 1.301558779556061E-002 -1.838488750704571E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68325201143113 -0.381761948356195 -8.309228700094988E-002 + 2.938162731265411E-003 1.301485694874873E-002 -2.757033154802284E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.68158869923558 -0.382070225071419 -0.110750336684755 + 2.932643799201507E-003 1.301383407507970E-002 -3.674737585955427E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67945102372369 -0.382466419836768 -0.138374650747165 + 2.925550911915339E-003 1.301251948603269E-002 -4.591322656575339E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67683963509720 -0.382950412144466 -0.165956823795153 + 2.916886226800555E-003 1.301091358145700E-002 -5.506509472578220E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67375533056131 -0.383522054241252 -0.193488435537802 + 2.906652389013839E-003 1.300901685160348E-002 -6.420018645562698E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.67019904882879 -0.384181172146986 -0.220961108835647 + 2.894852513239243E-003 1.300682987374474E-002 -7.331572218908740E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.66617187317737 -0.384927565087993 -0.248366475247266 + 2.881490193832806E-003 1.300435331405534E-002 -8.240892524600587E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.66167503032362 -0.385761005705779 -0.275696186833564 + 2.866569501085982E-003 1.300158792691927E-002 -9.147702574897361E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.65004629681643 -0.373463466840492 -2.713141697050409E-002 + 3.004107385165185E-003 1.327964217801076E-002 -9.380048499464011E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64934794517152 -0.373592898676403 -5.425456944817078E-002 + 3.001692998807830E-003 1.327919469791802E-002 -1.875723974515014E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64818426200946 -0.373808574617286 -8.136119772873515E-002 + 2.997669838310936E-003 1.327844904914197E-002 -2.812871813881668E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64655560215051 -0.374110428901093 -0.108443038057544 + 2.992039130381927E-003 1.327740545903941E-002 -3.749162668189549E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64446246154409 -0.374498369609023 -0.135491845590387 + 2.984802589649166E-003 1.327606424539795E-002 -4.684311491365882E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.64190547684605 -0.374972278743879 -0.162499390046587 + 2.975962417200357E-003 1.327442581616511E-002 -5.618033740837786E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63888542865316 -0.375532011630592 -0.189457426557952 + 2.965521311764990E-003 1.327249067152087E-002 -6.550044369703316E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63540323612168 -0.376177397913609 -0.216357752508752 + 2.953482451109342E-003 1.327025940042943E-002 -7.480059791839970E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.63145995996104 -0.376908241002040 -0.243192173800089 + 2.939849502386553E-003 1.326773268255752E-002 -8.407796715574675E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.62705680133123 -0.377724318274027 -0.269952516408261 + 2.924626618324377E-003 1.326491128756776E-002 -9.332972543286958E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61493892963385 -0.365517435820064 -2.655415279336874E-002 + 3.065098326561108E-003 1.354925233969722E-002 -9.570487094018532E-005 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61425543653423 -0.365644113787191 -5.310021693416905E-002 + 3.062634922083575E-003 1.354879577463227E-002 -1.913805892481565E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61311651258780 -0.365855200878378 -7.963010845652042E-002 + 3.058530081302113E-003 1.354803498730923E-002 -2.869980191831766E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.61152250506545 -0.366150632730767 -0.106135739430332 + 3.052785055829394E-003 1.354697020970083E-002 -3.825280107169432E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60947389936449 -0.366530319381278 -0.132609040433608 + 3.045401595105050E-003 1.354560176604655E-002 -4.779414805269034E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60697131859490 -0.366994145343291 -0.159041956298021 + 3.036381944904408E-003 1.354393007257628E-002 -5.732093966627254E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60401552674501 -0.367541969019932 -0.185426417578102 + 3.025728858747958E-003 1.354195563962491E-002 -6.683026757172563E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.60060742341456 -0.368173623680233 -0.211754396181856 + 3.013445578918633E-003 1.353967906811411E-002 -7.631923833270372E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.59674804674471 -0.368888916916088 -0.238017872352911 + 2.999535847022010E-003 1.353710105150953E-002 -8.578496151713587E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 + 1.59243857233884 -0.369687630842276 -0.264208845982959 + 2.984003900096668E-003 1.353422237509990E-002 -9.522455377438729E-004 + 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 diff --git a/python/swiftest/tests/convert_code_type/swifter2swiftest/param.swifter.in b/python/swiftest/tests/convert_code_type/swifter2swiftest/param.swifter.in new file mode 100644 index 000000000..5d250c0b1 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swifter2swiftest/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 80.0 +DT 1.0 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.dat +OUT_TYPE REAL8 +OUT_FORM XV +OUT_STAT NEW +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/python/swiftest/tests/convert_code_type/swifter2swiftest/pl.swifter.in b/python/swiftest/tests/convert_code_type/swifter2swiftest/pl.swifter.in new file mode 100644 index 000000000..b98db89c9 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swifter2swiftest/pl.swifter.in @@ -0,0 +1,40 @@ +10 +1 0.00029591220819207775568 +0.0 0.0 0.0 +0.0 0.0 0.0 +2 4.9125474498983625e-11 0.0014751258227142052 ! mercury +1.6306381826061646e-05 +0.008059842448018334 -0.4616051037329109 -0.03846017738329229 +0.02248719132054853 0.001934639213990692 -0.001904656977422976 +3 7.243452483873647e-10 0.006759134232034942 ! venus +4.0453784346544176e-05 +-0.5115875215389065 0.5030818749037324 0.03642547299277956 +-0.01425515725454357 -0.01452868630179309 0.0006232072038298823 +4 8.997011382166019e-10 0.010044625087011913 ! earthmoon +4.25875607065041e-05 +-0.1090020607540907 -1.009893805009766 4.823302918632528e-05 +0.01682491922568941 -0.001910549762056979 3.992660742687128e-08 +5 9.549535102761465e-11 0.007246789790242477 ! mars +2.2657408050928896e-05 +-1.342897929331636 0.9778655112682739 0.05343398538723887 +-0.007712315645393206 -0.01011917844182223 -2.287744801261131e-05 +6 2.8253459086313547e-07 0.3552720805286442 ! jupiter +0.0004673261703049093 +3.923184193414315 -3.168419770483168 -0.0746147877972047 +0.004655552638985802 0.006232623300954468 -0.0001300429201057457 +7 8.459715183006416e-08 0.4376460836930155 ! saturn +0.00038925687730393614 +6.185794462795267 -7.804174837804826 -0.110498432926239 +0.004066833203985018 0.003458637040736611 -0.0002219310939327014 +8 1.2920249163736674e-08 0.46946272948265794 ! uranus +0.00016953449859497232 +14.9290976575471 12.92949673572929 -0.1454099139559955 +-0.002599557960646664 0.002795888198858545 4.391864857782088e-05 +9 1.5243589003230834e-08 0.7811947848333599 ! neptune +0.00016458790412449367 +29.54416169025338 -4.716921603714237 -0.5838030174427992 +0.0004792636209523189 0.00312573757291745 -7.53264045199501e-05 +10 2.1919422829042796e-12 0.05379680851617536 ! plutocharon +7.943294877391593e-06 +14.54448346259197 -31.05223519593471 -0.8828000265625595 +0.002923077617691739 0.0006625916902153526 -0.0009142553677224461 diff --git a/python/swiftest/tests/convert_code_type/swifter2swiftest/swifter2swiftest.py b/python/swiftest/tests/convert_code_type/swifter2swiftest/swifter2swiftest.py new file mode 100644 index 000000000..ff53b5113 --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swifter2swiftest/swifter2swiftest.py @@ -0,0 +1,14 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs an equivalent + parameter file in another code type. + + Input files are param.swift[er|est].in and output files are param.[src]2[dest].new, where [src] is the original file type + and [dest] is the new one. The user may be prompted to answer questions regarding how to convert between the different + simulation types. + """ +inparam = "param.swifter.in" +outparam = "param.swifter2swiftest.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam, codename="Swifter") +oldparam = sim.convert(outparam, newcodename="Swiftest", plname="pl.swifter2swiftest.in", tpname="tp.swifter2swiftest.in", cbname="cb.swifter2swiftest.in") \ No newline at end of file diff --git a/python/swiftest/tests/convert_code_type/swifter2swiftest/tp.swifter.in b/python/swiftest/tests/convert_code_type/swifter2swiftest/tp.swifter.in new file mode 100644 index 000000000..9c026369e --- /dev/null +++ b/python/swiftest/tests/convert_code_type/swifter2swiftest/tp.swifter.in @@ -0,0 +1,4 @@ +1 +100 +1.01 0.0 0.0 +0.0 6.252003053624663 0.0 diff --git a/python/swiftest/tests/param_readers/param.swift.in b/python/swiftest/tests/param_readers/param.swift.in new file mode 100644 index 000000000..3f9822a58 --- /dev/null +++ b/python/swiftest/tests/param_readers/param.swift.in @@ -0,0 +1,6 @@ +.0d0 365.25d9 5.0d0 +365.25d5 365.25d5 +F T F F T F +4.68d-03 100.0 -1.0 4.68d-03 T +bin.dat +unknown diff --git a/python/swiftest/tests/param_readers/param.swifter.in b/python/swiftest/tests/param_readers/param.swifter.in new file mode 100644 index 000000000..5834d2dcc --- /dev/null +++ b/python/swiftest/tests/param_readers/param.swifter.in @@ -0,0 +1,26 @@ +! Swifter input file generated using init_cond.py +T0 0 +TSTOP 1.0 +DT 0.0006844626967830253 +PL_IN pl.swifter.in +TP_IN tp.swifter.in +IN_TYPE ASCII +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swifter.dat +OUT_TYPE REAL8 +OUT_FORM EL +OUT_STAT NEW +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swifter.dat +EXTRA_FORCE no +BIG_DISCARD no +RHILL_PRESENT yes diff --git a/python/swiftest/tests/param_readers/param.swiftest.in b/python/swiftest/tests/param_readers/param.swiftest.in new file mode 100644 index 000000000..6e623a5dd --- /dev/null +++ b/python/swiftest/tests/param_readers/param.swiftest.in @@ -0,0 +1,29 @@ +! Swiftest input file generated using init_cond.py +T0 0 +TSTOP 1.0 +DT 0.0006844626967830253 +CB_IN cb.swiftest.in +PL_IN pl.swiftest.in +TP_IN tp.swiftest.in +IN_TYPE REAL8 +ISTEP_OUT 1 +ISTEP_DUMP 1 +BIN_OUT bin.swiftest.dat +OUT_TYPE REAL8 +OUT_FORM EL +OUT_STAT REPLACE +CHK_CLOSE yes +CHK_RMIN 0.004650467260962157 +CHK_RMAX 1000.0 +CHK_EJECT 1000.0 +CHK_QMIN 0.004650467260962157 +CHK_QMIN_COORD HELIO +CHK_QMIN_RANGE 0.004650467260962157 1000.0 +ENC_OUT enc.swiftest.dat +EXTRA_FORCE no +BIG_DISCARD no +ROTATION no +GR no +MU2KG 1.988409870698051e+30 +DU2M 149597870700.0 +TU2S 31557600.0 diff --git a/python/swiftest/tests/param_readers/param_readers.py b/python/swiftest/tests/param_readers/param_readers.py new file mode 100644 index 000000000..d0e67a149 --- /dev/null +++ b/python/swiftest/tests/param_readers/param_readers.py @@ -0,0 +1,24 @@ +import swiftest +""" + Reads in an example parameter file for each of the codes (Swift, Swifter, and Swiftest) and outputs a copy using the + internal parsing system. Input files are param.swift[er|est].in and output files are param.swift[er|est].new. + The contents of the parameter files should be the same, though the new version may be formatted differently and also + contain explicit values for default parameters. + """ +inparam = "param.swift.in" +outparam = "param.swift.new" +print(f"Reading Swift parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam, codename="Swift") +sim.write_param(outparam) + +inparam = "param.swifter.in" +outparam = "param.swifter.new" +print(f"Reading Swifter parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam, codename="Swifter") +sim.write_param(outparam) + +inparam = "param.swiftest.in" +outparam = "param.swiftest.new" +print(f"Reading Swifter parameter {inparam} and saving it to {outparam}") +sim = swiftest.Simulation(param_file=inparam) # The default value of codename is "Swiftest" +sim.write_param(outparam) \ No newline at end of file diff --git a/ra15/ra15_discard.f90 b/ra15/ra15_discard.f90 deleted file mode 100644 index 6d8f1a6bb..000000000 --- a/ra15/ra15_discard.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_discard -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! ra15_tpd1P : pointer to head of discard RA15 test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! ra15_tpd1P : pointer to head of discard RA15 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_discard(t, npl, ntp, nsp, ra15_pl1P, ra15_tp1P, ra15_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE ra15_discard(t, npl, ntp, nsp, ra15_pl1P, ra15_tp1P, ra15_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P, ra15_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(ra15_tp), POINTER :: ra15_tpP, ra15_tpspP - -! Executable code - swifter_pl1P => ra15_pl1P%swifter - swifter_tp1P => ra15_tp1P%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - ra15_tpP => ra15_tp1P - DO i = 1, ntp - ra15_tpspP => ra15_tpP - ra15_tpP => ra15_tpP%nextP - swifter_tpspP => ra15_tpspP%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL ra15_discard_spill(ntp, nsp, ra15_tp1P, ra15_tpd1P, ra15_tpspP) - END DO - - RETURN - -END SUBROUTINE ra15_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_discard_spill.f90 b/ra15/ra15_discard_spill.f90 deleted file mode 100644 index 58d3069e9..000000000 --- a/ra15/ra15_discard_spill.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) RA15 test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! ra15_tpd1P : pointer to head of discard RA15 test particle structure linked-list -! ra15_tpspP : pointer to RA15 test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! ra15_tpd1P : pointer to head of discard RA15 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_discard_spill(ntp, nsp, ra15_tp1P, ra15_tpd1P, ra15_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE ra15_discard_spill(ntp, nsp, ra15_tp1P, ra15_tpd1P, ra15_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(ra15_tp), POINTER :: ra15_tp1P, ra15_tpd1P, ra15_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(ra15_tp), POINTER :: ra15_tpP - -! Executable code - swifter_tpspP => ra15_tpspP%swifter - IF (nsp == 0) THEN - ra15_tpd1P => ra15_tpspP - ELSE - ra15_tpP => ra15_tpd1P - DO i = 1, nsp - 1 - ra15_tpP => ra15_tpP%nextP - END DO - ra15_tpP%nextP => ra15_tpspP - ra15_tpP%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(ra15_tpspP%prevP)) THEN - ra15_tpspP%prevP%nextP => ra15_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - ra15_tp1P => ra15_tpspP%nextP - END IF - IF (ASSOCIATED(ra15_tpspP%nextP)) THEN - ra15_tpspP%nextP%prevP => ra15_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(ra15_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - ra15_tpspP%prevP => ra15_tpP - swifter_tpspP%prevP => ra15_tpP%swifter - END IF - NULLIFY(ra15_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE ra15_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_getaccb.f90 b/ra15/ra15_getaccb.f90 deleted file mode 100644 index 1c1290868..000000000 --- a/ra15/ra15_getaccb.f90 +++ /dev/null @@ -1,127 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of planets -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : ra15_pl1P : pointer to head of RA15 planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_getaccb(lextra_force, t, npl, nplmax, ra15_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb.f -! -!********************************************************************************************************************************** -SUBROUTINE ra15_getaccb(lextra_force, t, npl, nplmax, ra15_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_getaccb - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(ra15_pl), POINTER :: ra15_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: mu, massi, massj, r2, ir3 - REAL(DP), DIMENSION(NDIM) :: dx, acc - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_pliP, swifter_pljP - TYPE(ra15_pl), POINTER :: ra15_pliP, ra15_pljP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => ra15_pl1P%swifter - mu = swifter_pl1P%mass - ra15_pl1P%ab(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - ra15_pliP => ra15_pl1P - DO i = 2, npl - ra15_pliP => ra15_pliP%nextP - swifter_pliP => ra15_pliP%swifter - massi = swifter_pliP%mass - dx(:) = swifter_pl1P%xb(:) - swifter_pliP%xb(:) - xh(:, i) = -dx(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - irh(i) = 1.0_DP/SQRT(r2) - ir3 = irh(i)/r2 - acc(:) = ir3*dx(:) - ra15_pl1P%ab(:) = ra15_pl1P%ab(:) - massi*acc(:) - ra15_pliP%ab(:) = mu*acc(:) - END DO - ra15_pliP => ra15_pl1P - DO i = 2, npl - 1 - ra15_pliP => ra15_pliP%nextP - swifter_pliP => ra15_pliP%swifter - massi = swifter_pliP%mass - ra15_pljP => ra15_pliP - DO j = i + 1, npl - ra15_pljP => ra15_pljP%nextP - swifter_pljP => ra15_pljP%swifter - massj = swifter_pljP%mass - dx(:) = swifter_pliP%xb(:) - swifter_pljP%xb(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - ir3 = 1.0_DP/(r2*SQRT(r2)) - acc(:) = ir3*dx(:) - ra15_pliP%ab(:) = ra15_pliP%ab(:) - massj*acc(:) - ra15_pljP%ab(:) = ra15_pljP%ab(:) + massi*acc(:) - END DO - END DO - IF (j2rp2 /= 0.0_DP) THEN - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - ra15_pliP => ra15_pl1P - DO i = 1, npl - ra15_pliP%ab(:) = ra15_pliP%ab(:) + aobl(:, i) - ra15_pliP => ra15_pliP%nextP - END DO - END IF - IF (lextra_force) CALL ra15_user_getaccb(t, npl, ra15_pl1P) - - RETURN - -END SUBROUTINE ra15_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_getaccb_tp.f90 b/ra15/ra15_getaccb_tp.f90 deleted file mode 100644 index bac3f9edb..000000000 --- a/ra15/ra15_getaccb_tp.f90 +++ /dev/null @@ -1,118 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of test particles -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE ra15_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_getaccb_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(NDIM) :: dx, x1tmp, x2tmp, acc - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(ra15_tp), POINTER :: ra15_tpP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => ra15_pl1P%swifter - x1tmp(:) = swifter_pl1P%xb(:) - ra15_tpP => ra15_tp1P - DO i = 1, ntp - swifter_tpP => ra15_tpP%swifter - acc(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - xht(:, i) = swifter_tpP%xb(:) - x1tmp(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - x2tmp(:) = swifter_tpP%xb(:) - swifter_plP => swifter_pl1P - DO j = 1, npl - dx(:) = x2tmp(:) - swifter_plP%xb(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = swifter_plP%mass/(r2*SQRT(r2)) - acc(:) = acc(:) - fac*dx(:) - swifter_plP => swifter_plP%nextP - END DO - ra15_tpP%ab(:) = acc(:) - ra15_tpP => ra15_tpP%nextP - END DO - IF (j2rp2 /= 0.0_DP) THEN - mu = swifter_pl1P%mass - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - ra15_tpP => ra15_tp1P - DO i = 1, ntp - ra15_tpP%ab(:) = ra15_tpP%ab(:) + aoblt(:, i) - ra15_tpP => ra15_tpP%nextP - END DO - END IF - IF (lextra_force) CALL ra15_user_getaccb_tp(t, ntp, ra15_tp1P) - - RETURN - -END SUBROUTINE ra15_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_sequence.f90 b/ra15/ra15_sequence.f90 deleted file mode 100644 index d38907884..000000000 --- a/ra15/ra15_sequence.f90 +++ /dev/null @@ -1,375 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_sequence -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Propagate the solution of the equations of motion by one time sequence using the 15th order RADAU method -! -! Input -! Arguments : niter : number of iterations to perform to achieve desired accuracy -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! x : independent variable (time) -! htry : time step to try -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! Terminal : none -! File : none -! -! Output -! Arguments : ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! x : independent variable (time) -! hdid : time step actually accomplished -! hnext : recommended next time step -! Terminal : none -! File : none -! -! Invocation : CALL ra15_sequence(niter, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, x, htry, hdid, hnext, j2rp2, j4rp4, -! lextra_force) -! -! Notes : Adapted from Edgar Everhart's RADAU15 routine ra15 (reference given in main program notes) -! -! The length of the time sequence is self-adjusting to maintain the magnitude of the last term in the truncated -! time series at or below the specified tolerance eps -! -!********************************************************************************************************************************** -SUBROUTINE ra15_sequence(niter, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, x, htry, hdid, hnext, j2rp2, j4rp4, lextra_force) - -! Modules - USE module_parameters - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_sequence - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: niter, npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: htry, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: x - REAL(DP), INTENT(OUT) :: hdid, hnext - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - -! Internals - INTEGER(I4B) :: i, j, k, m, jd - REAL(DP) :: tpp, tm, t, t2, tval, s, y, z, a, temp, gk, hv, q - REAL(DP), DIMENSION(7) :: b, g, e, bd - TYPE(ra15_pl), POINTER :: ra15_plP - TYPE(ra15_tp), POINTER :: ra15_tpP - -! Executable code - tpp = htry - tm = x - DO - ra15_plP => ra15_pl1P - DO i = 1, npl - DO j = 1, NDIM - b(:) = ra15_plP%b(:, j) - g(1) = b(1) + d(1)*b(2) + d(2)*b(3) + d(4)*b(4) + d( 7)*b(5) + d(11)*b(6) + d(16)*b(7) - g(2) = b(2) + d(3)*b(3) + d(5)*b(4) + d( 8)*b(5) + d(12)*b(6) + d(17)*b(7) - g(3) = b(3) + d(6)*b(4) + d( 9)*b(5) + d(13)*b(6) + d(18)*b(7) - g(4) = b(4) + d(10)*b(5) + d(14)*b(6) + d(19)*b(7) - g(5) = b(5) + d(15)*b(6) + d(20)*b(7) - g(6) = b(6) + d(21)*b(7) - g(7) = b(7) - ra15_plP%g(:, j) = g(:) - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO j = 1, NDIM - b(:) = ra15_tpP%b(:, j) - g(1) = b(1) + d(1)*b(2) + d(2)*b(3) + d(4)*b(4) + d( 7)*b(5) + d(11)*b(6) + d(16)*b(7) - g(2) = b(2) + d(3)*b(3) + d(5)*b(4) + d( 8)*b(5) + d(12)*b(6) + d(17)*b(7) - g(3) = b(3) + d(6)*b(4) + d( 9)*b(5) + d(13)*b(6) + d(18)*b(7) - g(4) = b(4) + d(10)*b(5) + d(14)*b(6) + d(19)*b(7) - g(5) = b(5) + d(15)*b(6) + d(20)*b(7) - g(6) = b(6) + d(21)*b(7) - g(7) = b(7) - ra15_tpP%g(:, j) = g(:) - END DO - ra15_tpP => ra15_tpP%nextP - END DO - t = tpp - t2 = t*t - tval = ABS(t) - DO m = 1, niter - DO j = 2, 8 - jd = j - 1 - s = H(j) - ra15_plP => ra15_pl1P - DO i = 1, npl - DO k = 1, NDIM - b(:) = ra15_plP%b(:, k) - a = w(3)*b(3) + s*(w(4)*b(4) + s*(w(5)*b(5) + s*(w(6)*b(6) + s*w(7)*b(7)))) - y = ra15_plP%xbsav(k) + & - s*(t*ra15_plP%vbsav(k) + t2*s*(w1*ra15_plP%absav(k) + s*(w(1)*b(1) + s*(w(2)*b(2) + s*a)))) - ra15_plP%swifter%xb(k) = y - a = u(3)*b(3) + s*(u(4)*b(4) + s*(u(5)*b(5) + s*(u(6)*b(6) + s*u(7)*b(7)))) - z = ra15_plP%vbsav(k) + s*t*(ra15_plP%absav(k) + s*(u(1)*b(1) + s*(u(2)*b(2) + s*a))) - ra15_plP%swifter%vb(k) = z - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO k = 1, NDIM - b(:) = ra15_tpP%b(:, k) - a = w(3)*b(3) + s*(w(4)*b(4) + s*(w(5)*b(5) + s*(w(6)*b(6) + s*w(7)*b(7)))) - y = ra15_tpP%xbsav(k) + & - s*(t*ra15_tpP%vbsav(k) + t2*s*(w1*ra15_tpP%absav(k) + s*(w(1)*b(1) + s*(w(2)*b(2) + s*a)))) - ra15_tpP%swifter%xb(k) = y - a = u(3)*b(3) + s*(u(4)*b(4) + s*(u(5)*b(5) + s*(u(6)*b(6) + s*u(7)*b(7)))) - z = ra15_tpP%vbsav(k) + s*t*(ra15_tpP%absav(k) + s*(u(1)*b(1) + s*(u(2)*b(2) + s*a))) - ra15_tpP%swifter%vb(k) = z - END DO - ra15_tpP => ra15_tpP%nextP - END DO - CALL ra15_getaccb(lextra_force, tm+s*t, npl, nplmax, ra15_pl1P, j2rp2, j4rp4) - IF (ntp > 0) CALL ra15_getaccb_tp(lextra_force, tm+s*t, npl, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4) - ra15_plP => ra15_pl1P - DO i = 1, npl - DO k = 1, NDIM - g(:) = ra15_plP%g(:, k) - gk = (ra15_plP%ab(k) - ra15_plP%absav(k))/s - SELECT CASE (j) - CASE(2) - ra15_plP%g(1, k) = gk - CASE(3) - ra15_plP%g(2, k) = (gk - g(1))*r( 1) - CASE(4) - ra15_plP%g(3, k) = ((gk - g(1))*r( 2) - g(2))*r( 3) - CASE(5) - ra15_plP%g(4, k) = (((gk - g(1))*r( 4) - g(2))*r( 5) - g(3))*r( 6) - CASE(6) - ra15_plP%g(5, k) = ((((gk - g(1))*r( 7) - g(2))*r( 8) - g(3))*r( 9) - g(4))*r(10) - CASE(7) - ra15_plP%g(6, k) = (((((gk - g(1))*r(11) - g(2))*r(12) - g(3))*r(13) - g(4))*r(14) - & - g(5))*r(15) - CASE(8) - ra15_plP%g(7, k) = ((((((gk - g(1))*r(16) - g(2))*r(17) - g(3))*r(18) - g(4))*r(19) - & - g(5))*r(20) - g(6))*r(21) - END SELECT - temp = ra15_plP%g(jd, k) - g(jd) - b(:) = ra15_plP%b(:, k) - b(jd) = b(jd) + temp - SELECT CASE (j) - CASE(3) - b(1) = b(1) + c( 1)*temp - CASE(4) - b(1) = b(1) + c( 2)*temp - b(2) = b(2) + c( 3)*temp - CASE(5) - b(1) = b(1) + c( 4)*temp - b(2) = b(2) + c( 5)*temp - b(3) = b(3) + c( 6)*temp - CASE(6) - b(1) = b(1) + c( 7)*temp - b(2) = b(2) + c( 8)*temp - b(3) = b(3) + c( 9)*temp - b(4) = b(4) + c(10)*temp - CASE(7) - b(1) = b(1) + c(11)*temp - b(2) = b(2) + c(12)*temp - b(3) = b(3) + c(13)*temp - b(4) = b(4) + c(14)*temp - b(5) = b(5) + c(15)*temp - CASE(8) - b(1) = b(1) + c(16)*temp - b(2) = b(2) + c(17)*temp - b(3) = b(3) + c(18)*temp - b(4) = b(4) + c(19)*temp - b(5) = b(5) + c(20)*temp - b(6) = b(6) + c(21)*temp - END SELECT - ra15_plP%b(:, k) = b(:) - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO k = 1, NDIM - g(:) = ra15_tpP%g(:, k) - gk = (ra15_tpP%ab(k) - ra15_tpP%absav(k))/s - SELECT CASE (j) - CASE(2) - ra15_tpP%g(1, k) = gk - CASE(3) - ra15_tpP%g(2, k) = (gk - g(1))*r( 1) - CASE(4) - ra15_tpP%g(3, k) = ((gk - g(1))*r( 2) - g(2))*r( 3) - CASE(5) - ra15_tpP%g(4, k) = (((gk - g(1))*r( 4) - g(2))*r( 5) - g(3))*r( 6) - CASE(6) - ra15_tpP%g(5, k) = ((((gk - g(1))*r( 7) - g(2))*r( 8) - g(3))*r( 9) - g(4))*r(10) - CASE(7) - ra15_tpP%g(6, k) = (((((gk - g(1))*r(11) - g(2))*r(12) - g(3))*r(13) - g(4))*r(14) - & - g(5))*r(15) - CASE(8) - ra15_tpP%g(7, k) = ((((((gk - g(1))*r(16) - g(2))*r(17) - g(3))*r(18) - g(4))*r(19) - & - g(5))*r(20) - g(6))*r(21) - END SELECT - temp = ra15_tpP%g(jd, k) - g(jd) - b(:) = ra15_tpP%b(:, k) - b(jd) = b(jd) + temp - SELECT CASE (j) - CASE(3) - b(1) = b(1) + c( 1)*temp - CASE(4) - b(1) = b(1) + c( 2)*temp - b(2) = b(2) + c( 3)*temp - CASE(5) - b(1) = b(1) + c( 4)*temp - b(2) = b(2) + c( 5)*temp - b(3) = b(3) + c( 6)*temp - CASE(6) - b(1) = b(1) + c( 7)*temp - b(2) = b(2) + c( 8)*temp - b(3) = b(3) + c( 9)*temp - b(4) = b(4) + c(10)*temp - CASE(7) - b(1) = b(1) + c(11)*temp - b(2) = b(2) + c(12)*temp - b(3) = b(3) + c(13)*temp - b(4) = b(4) + c(14)*temp - b(5) = b(5) + c(15)*temp - CASE(8) - b(1) = b(1) + c(16)*temp - b(2) = b(2) + c(17)*temp - b(3) = b(3) + c(18)*temp - b(4) = b(4) + c(19)*temp - b(5) = b(5) + c(20)*temp - b(6) = b(6) + c(21)*temp - END SELECT - ra15_tpP%b(:, k) = b(:) - END DO - ra15_tpP => ra15_tpP%nextP - END DO - END DO - END DO - hv = ZERO - ra15_plP => ra15_pl1P - DO i = 1, npl - DO j = 1, NDIM - hv = MAX(hv, ABS(ra15_plP%b(7, j))) - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO j = 1, NDIM - hv = MAX(hv, ABS(ra15_tpP%b(7, j))) - END DO - ra15_tpP => ra15_tpP%nextP - END DO - hv = hv*w(7)/tval**7 - tpp = (eps/hv)**PW - IF ((niter /= 6) .OR. (tpp/t > ONE)) EXIT - tpp = 0.8_DP*t - END DO - ra15_plP => ra15_pl1P - DO i = 1, npl - DO j = 1, NDIM - b(:) = ra15_plP%b(:, j) - ra15_plP%xbsav(j) = ra15_plP%xbsav(j) + t*ra15_plP%vbsav(j) + t2*(w1*ra15_plP%absav(j) + b(1)*w(1) + b(2)*w(2) + & - b(3)*w(3) + b(4)*w(4) + b(5)*w(5) + b(6)*w(6) + b(7)*w(7)) - ra15_plP%vbsav(j) = ra15_plP%vbsav(j) + t*(ra15_plP%absav(j) + b(1)*u(1) + b(2)*u(2) + b(3)*u(3) + b(4)*u(4) + & - b(5)*u(5) + b(6)*u(6) + b(7)*u(7)) - END DO - ra15_plP%swifter%xb(:) = ra15_plP%xbsav(:) - ra15_plP%swifter%vb(:) = ra15_plP%vbsav(:) - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO j = 1, NDIM - b(:) = ra15_tpP%b(:, j) - ra15_tpP%xbsav(j) = ra15_tpP%xbsav(j) + t*ra15_tpP%vbsav(j) + t2*(w1*ra15_tpP%absav(j) + b(1)*w(1) + b(2)*w(2) + & - b(3)*w(3) + b(4)*w(4) + b(5)*w(5) + b(6)*w(6) + b(7)*w(7)) - ra15_tpP%vbsav(j) = ra15_tpP%vbsav(j) + t*(ra15_tpP%absav(j) + b(1)*u(1) + b(2)*u(2) + b(3)*u(3) + b(4)*u(4) + & - b(5)*u(5) + b(6)*u(6) + b(7)*u(7)) - END DO - ra15_tpP%swifter%xb(:) = ra15_tpP%xbsav(:) - ra15_tpP%swifter%vb(:) = ra15_tpP%vbsav(:) - ra15_tpP => ra15_tpP%nextP - END DO - tm = tm + t - x = tm - hdid = t - IF (tpp/t > SR) tpp = t*SR - hnext = tpp - q = tpp/t - ra15_plP => ra15_pl1P - DO i = 1, npl - DO j = 1, NDIM - b(:) = ra15_plP%b(:, j) - bd(:) = ra15_plP%bd(:, j) - e(:) = ra15_plP%e(:, j) - IF (niter /= 6) bd(:) = b(:) - e(:) - e(1) = q*(b(1) + 2.0_DP*b(2) + 3.0_DP*b(3) + 4.0_DP*b(4) + 5.0_DP*b(5) + 6.0_DP*b(6) + 7.0_DP*b(7)) - e(2) = q**2*(b(2) + 3.0_DP*b(3) + 6.0_DP*b(4) + 10.0_DP*b(5) + 15.0_DP*b(6) + 21.0_DP*b(7)) - e(3) = q**3*(b(3) + 4.0_DP*b(4) + 10.0_DP*b(5) + 20.0_DP*b(6) + 35.0_DP*b(7)) - e(4) = q**4*(b(4) + 5.0_DP*b(5) + 15.0_DP*b(6) + 35.0_DP*b(7)) - e(5) = q**5*(b(5) + 6.0_DP*b(6) + 21.0_DP*b(7)) - e(6) = q**6*(b(6) + 7.0_DP*b(7)) - e(7) = q**7*b(7) - b(:) = e(:) + bd(:) - ra15_plP%b(:, j) = b(:) - ra15_plP%bd(:, j) = bd(:) - ra15_plP%e(:, j) = e(:) - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO i = 1, ntp - DO j = 1, NDIM - b(:) = ra15_tpP%b(:, j) - bd(:) = ra15_tpP%bd(:, j) - e(:) = ra15_tpP%e(:, j) - IF (niter /= 6) bd(:) = b(:) - e(:) - e(1) = q*(b(1) + 2.0_DP*b(2) + 3.0_DP*b(3) + 4.0_DP*b(4) + 5.0_DP*b(5) + 6.0_DP*b(6) + 7.0_DP*b(7)) - e(2) = q**2*(b(2) + 3.0_DP*b(3) + 6.0_DP*b(4) + 10.0_DP*b(5) + 15.0_DP*b(6) + 21.0_DP*b(7)) - e(3) = q**3*(b(3) + 4.0_DP*b(4) + 10.0_DP*b(5) + 20.0_DP*b(6) + 35.0_DP*b(7)) - e(4) = q**4*(b(4) + 5.0_DP*b(5) + 15.0_DP*b(6) + 35.0_DP*b(7)) - e(5) = q**5*(b(5) + 6.0_DP*b(6) + 21.0_DP*b(7)) - e(6) = q**6*(b(6) + 7.0_DP*b(7)) - e(7) = q**7*b(7) - b(:) = e(:) + bd(:) - ra15_tpP%b(:, j) = b(:) - ra15_tpP%bd(:, j) = bd(:) - ra15_tpP%e(:, j) = e(:) - END DO - ra15_tpP => ra15_tpP%nextP - END DO - - RETURN - -END SUBROUTINE ra15_sequence -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_setup.f90 b/ra15/ra15_setup.f90 deleted file mode 100644 index efac1a436..000000000 --- a/ra15/ra15_setup.f90 +++ /dev/null @@ -1,133 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_setup -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Set up pointers within RA15 and Swifter planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! ra15_plA : RA15 planet structure array -! ra15_tpA : RA15 test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : ra15_plA : RA15 planet structure array -! ra15_tpA : RA15 test particle structure array -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_setup(npl, ntp, ra15_plA, ra15_tpA, ra15_pl1P, ra15_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE ra15_setup(npl, ntp, ra15_plA, ra15_tpA, ra15_pl1P, ra15_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(ra15_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: ra15_plA - TYPE(ra15_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: ra15_tpA - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(ra15_pl), POINTER :: ra15_plP - TYPE(ra15_tp), POINTER :: ra15_tpP - -! Executable code - ra15_pl1P => ra15_plA(1) - swifter_pl1P => ra15_plA(1)%swifter - NULLIFY(ra15_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(ra15_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - ra15_pl1P%nextP => ra15_plA(2) - swifter_pl1P%nextP => ra15_plA(2)%swifter - DO i = 2, npl - 1 - ra15_plA(i)%prevP => ra15_plA(i-1) - ra15_plA(i)%nextP => ra15_plA(i+1) - swifter_plP => ra15_plA(i)%swifter - swifter_plP%prevP => ra15_plA(i-1)%swifter - swifter_plP%nextP => ra15_plA(i+1)%swifter - END DO - ra15_plA(npl)%prevP => ra15_plA(npl-1) - ra15_plP => ra15_plA(npl) - NULLIFY(ra15_plP%nextP) - swifter_plP => ra15_plA(npl)%swifter - swifter_plP%prevP => ra15_plA(npl-1)%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(ra15_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - ra15_tp1P => ra15_tpA(1) - swifter_tp1P => ra15_tpA(1)%swifter - NULLIFY(ra15_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(ra15_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - ra15_tp1P%nextP => ra15_tpA(2) - swifter_tp1P%nextP => ra15_tpA(2)%swifter - DO i = 2, ntp - 1 - ra15_tpA(i)%prevP => ra15_tpA(i-1) - ra15_tpA(i)%nextP => ra15_tpA(i+1) - swifter_tpP => ra15_tpA(i)%swifter - swifter_tpP%prevP => ra15_tpA(i-1)%swifter - swifter_tpP%nextP => ra15_tpA(i+1)%swifter - END DO - ra15_tpA(ntp)%prevP => ra15_tpA(ntp-1) - ra15_tpP => ra15_tpA(ntp) - NULLIFY(ra15_tpP%nextP) - swifter_tpP => ra15_tpA(ntp)%swifter - swifter_tpP%prevP => ra15_tpA(ntp-1)%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE ra15_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_step.f90 b/ra15/ra15_step.f90 deleted file mode 100644 index 9599288bf..000000000 --- a/ra15/ra15_step.f90 +++ /dev/null @@ -1,176 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_step -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : eps : local truncation error control parameter (maximum size of the last terms in the series expansions -! of the dependent variables) -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL ra15_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Edgar Everhart's RADAU15 routine ra15 (reference given in main program notes) -! -!********************************************************************************************************************************** -SUBROUTINE ra15_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(ra15_pl), POINTER :: ra15_pl1P - TYPE(ra15_tp), POINTER :: ra15_tp1P - -! Internals - INTEGER(I4B) :: k, l, la, lb, lc, ld, le, n - INTEGER(I4B), SAVE :: niter - REAL(DP) :: ww, x, hdid, hnext, msys - REAL(DP), SAVE :: hh - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpP - TYPE(ra15_pl), POINTER :: ra15_plP - TYPE(ra15_tp), POINTER :: ra15_tpP - -! Executable code - swifter_pl1P => ra15_pl1P%swifter - IF (ntp > 0) swifter_tp1P => ra15_tp1P%swifter - IF (lfirst) THEN - WRITE(*, 100, ADVANCE = "NO") "Enter the value of eps: " - 100 FORMAT(A) - READ(*, *) eps - WRITE(*, *) " eps = ", eps - CALL coord_h2b(npl, swifter_pl1P, msys) - IF (ntp > 0) CALL coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - DO n = 2, 8 - ww = n + n*n - w(n-1) = ONE/ww - ww = n - u(n-1) = ONE/ww - END DO - ra15_plP => ra15_pl1P - DO n = 1, npl - DO k = 1, NDIM - ra15_plP%bd(:, k) = (/ 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP /) - ra15_plP%b(:, k) = (/ 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO n = 1, ntp - DO k = 1, NDIM - ra15_tpP%bd(:, k) = (/ 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP /) - ra15_tpP%b(:, k) = (/ 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - ra15_tpP => ra15_tpP%nextP - END DO - w1 = HALF - c(1) = -H(2) - d(1) = H(2) - r(1) = ONE/(H(3) - H(2)) - la = 1 - lc = 1 - DO k = 3, 7 - lb = la - la = lc + 1 - lc = NW(k+1) - c(la) = -H(k)*c(lb) - c(lc) = c(la-1) - H(k) - d(la) = H(2)*d(lb) - d(lc) = -c(lc) - r(la) = ONE/(H(k+1) - H(2)) - r(lc) = ONE/(H(k+1) - H(k)) - IF (k == 3) CYCLE - DO l = 4, k - ld = la + l - 3 - le = lb + l - 4 - c(ld) = c(le) - H(k)*c(le+1) - d(ld) = d(le) + H(l-1)*d(le+1) - r(ld) = ONE/(H(k+1) - H(l-1)) - END DO - END DO - hh = dt - niter = 6 - lfirst = .FALSE. - END IF - x = t - DO WHILE ((ABS(x - t - dt)/dt) > DELTARA15) - CALL ra15_getaccb(lextra_force, t, npl, nplmax, ra15_pl1P, j2rp2, j4rp4) - IF (ntp > 0) CALL ra15_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, ra15_pl1P, ra15_tp1P, j2rp2, j4rp4) - ra15_plP => ra15_pl1P - DO n = 1, npl - swifter_plP => ra15_plP%swifter - ra15_plP%xbsav(:) = swifter_plP%xb(:) - ra15_plP%vbsav(:) = swifter_plP%vb(:) - ra15_plP%absav(:) = ra15_plP%ab(:) - ra15_plP => ra15_plP%nextP - END DO - ra15_tpP => ra15_tp1P - DO n = 1, ntp - swifter_tpP => ra15_tpP%swifter - ra15_tpP%xbsav(:) = swifter_tpP%xb(:) - ra15_tpP%vbsav(:) = swifter_tpP%vb(:) - ra15_tpP%absav(:) = ra15_tpP%ab(:) - ra15_tpP => ra15_tpP%nextP - END DO - IF ((x + hh - t - dt)*(x + hh - t) > 0.0_DP) hh = t + dt - x - CALL ra15_sequence(niter, npl, nplmax, ntp, ntpmax, ra15_pl1P, ra15_tp1P, x, hh, hdid, hnext, j2rp2, j4rp4, lextra_force) - hh = hnext - niter = 2 - END DO - CALL coord_b2h(npl, swifter_pl1P) - CALL coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) - - RETURN - -END SUBROUTINE ra15_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_user_getaccb.f90 b/ra15/ra15_user_getaccb.f90 deleted file mode 100644 index cd1b3c614..000000000 --- a/ra15/ra15_user_getaccb.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_user_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! ra15_pl1P : pointer to head of RA15 planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : ra15_pl1P : pointer to head of RA15 planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL ra15_user_getaccb(t, npl, ra15_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE ra15_user_getaccb(t, npl, ra15_pl1P) - -! Modules - USE module_parameters - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_user_getaccb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(ra15_pl), POINTER :: ra15_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE ra15_user_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/ra15/ra15_user_getaccb_tp.f90 b/ra15/ra15_user_getaccb_tp.f90 deleted file mode 100644 index f78ab871c..000000000 --- a/ra15/ra15_user_getaccb_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : ra15_user_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : ra15 -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : ra15_tp1P : pointer to head of active RA15 test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL ra15_user_getaccb_tp(t, ntp, ra15_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE ra15_user_getaccb_tp(t, ntp, ra15_tp1P) - -! Modules - USE module_parameters - USE module_ra15 - USE module_interfaces, EXCEPT_THIS_ONE => ra15_user_getaccb_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(ra15_tp), POINTER :: ra15_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE ra15_user_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_chk.f90 b/rmvs/rmvs_chk.f90 deleted file mode 100644 index 7e6d06baf..000000000 --- a/rmvs/rmvs_chk.f90 +++ /dev/null @@ -1,122 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_chk -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Check to see if there are any encounters between planets and test particles -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! xh : planet positions at beginning of time step -! vh : planet velocities at beginning of time step -! dt : time step -! rts : fraction of Hill's sphere radius to use as radius of encounter region -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! lencounter : logical flag indicating whether there are any encounters at all -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_chk(npl, ntp, rmvs_pl1P, rmvs_tp1P, xh, vh, dt, rts, lencounter) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_chk.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_chk(npl, ntp, rmvs_pl1P, rmvs_tp1P, xh, vh, dt, rts, lencounter) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_chk - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(OUT) :: lencounter - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt, rts - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh, vh - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - INTEGER(I4B) :: i, j, k, iflag, nenc - REAL(DP) :: r2crit - REAL(DP), DIMENSION(NDIM) :: xht, vht, xr, vr - TYPE(rmvs_pl), POINTER :: rmvs_plP - TYPE(rmvs_tp), POINTER :: rmvs_tpP, rmvs_tpencP - -! Executable code - lencounter = .FALSE. - rmvs_plP => rmvs_pl1P - DO i = 1, npl - rmvs_plP%nenc = 0 - NULLIFY(rmvs_plP%tpenc1P) - rmvs_plP => rmvs_plP%nextP - END DO - rmvs_tpP => rmvs_tp1P - DO i = 1, ntp - IF (rmvs_tpP%whm%swifter%status == ACTIVE) THEN - NULLIFY(rmvs_tpP%plencP) - NULLIFY(rmvs_tpP%tpencP) - iflag = 0 - xht(:) = rmvs_tpP%whm%swifter%xh(:) - vht(:) = rmvs_tpP%whm%swifter%vh(:) - rmvs_plP => rmvs_pl1P - DO j = 2, npl - rmvs_plP => rmvs_plP%nextP - r2crit = (rts*rmvs_plP%whm%swifter%rhill)**2 - xr(:) = xht(:) - xh(:, j) - vr(:) = vht(:) - vh(:, j) - CALL rmvs_chk_ind(xr(:), vr(:), dt, r2crit, iflag) - IF (iflag /= 0) THEN - lencounter = .TRUE. - rmvs_plP%nenc = rmvs_plP%nenc + 1 - nenc = rmvs_plP%nenc - IF (nenc == 1) THEN - rmvs_plP%tpenc1P => rmvs_tpP - ELSE - rmvs_tpencP => rmvs_plP%tpenc1P - DO k = 2, nenc - 1 - rmvs_tpencP => rmvs_tpencP%tpencP - END DO - rmvs_tpencP%tpencP => rmvs_tpP - END IF - rmvs_tpP%plencP => rmvs_plP - EXIT - END IF - END DO - END IF - rmvs_tpP => rmvs_tpP%nextP - END DO - - RETURN - -END SUBROUTINE rmvs_chk -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_chk_ind.f90 b/rmvs/rmvs_chk_ind.f90 deleted file mode 100644 index 9312e6ba4..000000000 --- a/rmvs/rmvs_chk_ind.f90 +++ /dev/null @@ -1,84 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_chk_ind -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Determine whether a test particle and planet are having or will have an encounter within the next time step -! -! Input -! Arguments : xr : relative position -! vr : relative velocity -! dt : time step -! r2crit : square of the radius of the encounter region -! Terminal : none -! File : none -! -! Output -! Arguments : iflag : flag indicating encounter ( 1 ) or no encounter ( 0 ) -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_chk_ind(xr, vr, dt, r2crit, iflag) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs_chk_ind.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_chk_ind(xr, vr, dt, r2crit, iflag) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_chk_ind - IMPLICIT NONE - -! Arguments - REAL(DP), INTENT(IN) :: dt, r2crit - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: xr, vr - INTEGER(I4B), INTENT(OUT) :: iflag - -! Internals - REAL(DP) :: r2, v2, vdotr, tmin, r2min - -! Executable code - iflag = 0 - r2 = DOT_PRODUCT(xr(:), xr(:)) - IF (r2 < r2crit) THEN - iflag = 1 - ELSE - vdotr = DOT_PRODUCT(vr(:), xr(:)) - IF (vdotr < 0.0_DP) THEN - v2 = DOT_PRODUCT(vr(:), vr(:)) - tmin = -vdotr/v2 - IF (tmin < dt) THEN - r2min = r2 - vdotr*vdotr/v2 - ELSE - r2min = r2 + 2.0_DP*vdotr*dt + v2*dt*dt - END IF - r2min = MIN(r2min, r2) - IF (r2min <= r2crit) iflag = 1 - END IF - END IF - - RETURN - -END SUBROUTINE rmvs_chk_ind -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_discard.f90 b/rmvs/rmvs_discard.f90 deleted file mode 100644 index f9cdceb95..000000000 --- a/rmvs/rmvs_discard.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_discard -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Call discard routines to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! rmvs_tpd1P : pointer to head of discard RMVS test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! rmvs_tpd1P : pointer to head of discard RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_discard(t, npl, ntp, nsp, rmvs_pl1P, rmvs_tp1P, rmvs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_discard(t, npl, ntp, nsp, rmvs_pl1P, rmvs_tp1P, rmvs_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P, rmvs_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(rmvs_tp), POINTER :: rmvs_tpP, rmvs_tpspP - -! Executable code - IF (lclose) CALL rmvs_discard_pl(t, ntp, rmvs_tp1P) - swifter_pl1P => rmvs_pl1P%whm%swifter - swifter_tp1P => rmvs_tp1P%whm%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - rmvs_tpP => rmvs_tp1P - DO i = 1, ntp - rmvs_tpspP => rmvs_tpP - rmvs_tpP => rmvs_tpP%nextP - swifter_tpspP => rmvs_tpspP%whm%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL rmvs_discard_spill(ntp, nsp, rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP) - END DO - - RETURN - -END SUBROUTINE rmvs_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_discard_pl.f90 b/rmvs/rmvs_discard_pl.f90 deleted file mode 100644 index afbdc9666..000000000 --- a/rmvs/rmvs_discard_pl.f90 +++ /dev/null @@ -1,81 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_discard_pl -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Check to see if test particles should be discarded based on pericenter passage distances with respect to -! planets encountered -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : status message -! File : none -! -! Invocation : CALL rmvs_discard_pl(t, ntp, rmvs_tp1P) -! -! Notes : Adapted from Hal Levison's Swift routine discard_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_discard_pl(t, ntp, rmvs_tp1P) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_discard_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rmvs_tpP => rmvs_tp1P - DO i = 1, ntp - IF (rmvs_tpP%whm%swifter%status == ACTIVE) THEN - IF (rmvs_tpP%lperi) THEN - IF (rmvs_tpP%peri < rmvs_tpP%plperP%whm%swifter%radius) THEN - rmvs_tpP%whm%swifter%status = DISCARDED_PLQ - WRITE(*, *) "Particle ", rmvs_tpP%whm%swifter%id, " q with respect to Planet ", & - rmvs_tpP%plperP%whm%swifter%id, " is too small at t = ", t - END IF - END IF - END IF - rmvs_tpP => rmvs_tpP%nextP - END DO - - RETURN - -END SUBROUTINE rmvs_discard_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_discard_spill.f90 b/rmvs/rmvs_discard_spill.f90 deleted file mode 100644 index 2f6245b38..000000000 --- a/rmvs/rmvs_discard_spill.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) RMVS test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! rmvs_tpd1P : pointer to head of discard RMVS test particle structure linked-list -! rmvs_tpspP : pointer to RMVS test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! rmvs_tpd1P : pointer to head of discard RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_discard_spill(ntp, nsp, rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_discard_spill(ntp, nsp, rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(rmvs_tp), POINTER :: rmvs_tp1P, rmvs_tpd1P, rmvs_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(whm_tp), POINTER :: whm_tpspP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - whm_tpspP => rmvs_tpspP%whm - swifter_tpspP => whm_tpspP%swifter - IF (nsp == 0) THEN - rmvs_tpd1P => rmvs_tpspP - ELSE - rmvs_tpP => rmvs_tpd1P - DO i = 1, nsp - 1 - rmvs_tpP => rmvs_tpP%nextP - END DO - rmvs_tpP%nextP => rmvs_tpspP - rmvs_tpP%whm%nextP => whm_tpspP - rmvs_tpP%whm%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(rmvs_tpspP%prevP)) THEN - rmvs_tpspP%prevP%nextP => rmvs_tpspP%nextP - whm_tpspP%prevP%nextP => whm_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - rmvs_tp1P => rmvs_tpspP%nextP - END IF - IF (ASSOCIATED(rmvs_tpspP%nextP)) THEN - rmvs_tpspP%nextP%prevP => rmvs_tpspP%prevP - whm_tpspP%nextP%prevP => whm_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(rmvs_tpspP%prevP) - NULLIFY(whm_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - rmvs_tpspP%prevP => rmvs_tpP - whm_tpspP%prevP => rmvs_tpP%whm - swifter_tpspP%prevP => rmvs_tpP%whm%swifter - END IF - NULLIFY(rmvs_tpspP%nextP) - NULLIFY(whm_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE rmvs_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_drift_tp.f90 b/rmvs/rmvs_drift_tp.f90 deleted file mode 100644 index ee93a2608..000000000 --- a/rmvs/rmvs_drift_tp.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_drift_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Loop through test particles closely encountering a planet and call Danby drift routine -! -! Input -! Arguments : nenc : number of test particles encountering current planet -! rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! mu : mass of planet being encountered -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! Terminal : error message -! File : none -! -! Invocation : CALL rmvs_drift_tp(nenc, rmvs_tpenc1P, mu, dt) -! -! Notes : Adapted from Hal Levison's Swift routine drift_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_drift_tp(nenc, rmvs_tpenc1P, mu, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_drift_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: mu, dt - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - -! Internals - INTEGER(I4B) :: i, iflag - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - swifter_tpP => rmvs_tpP%whm%swifter - IF (swifter_tpP%status == ACTIVE) THEN - CALL drift_one(mu, rmvs_tpP%xpc(:), rmvs_tpP%vpc(:), dt, iflag) - IF (iflag /= 0) THEN - swifter_tpP%status = DISCARDED_DRIFTERR - WRITE(*, *) "Particle ", swifter_tpP%id, " lost due to error in Danby drift" - END IF - END IF - rmvs_tpP => rmvs_tpP%tpencP - END DO - - RETURN - -END SUBROUTINE rmvs_drift_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_getaccp_ah3_tp.f90 b/rmvs/rmvs_getaccp_ah3_tp.f90 deleted file mode 100644 index 2916efd1a..000000000 --- a/rmvs/rmvs_getaccp_ah3_tp.f90 +++ /dev/null @@ -1,89 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_getaccp_ah3_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Compute direct cross (third) term planetocentric accelerations of test particles closely encountering a planet -! -! Input -! Arguments : index : inner substep number within current set -! npl : number of planets -! nenc : number of test particles encountering current planet -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_getaccp_ah3_tp(index, npl, nenc, rmvs_pl1P, rmvs_pleP) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_a3_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_getaccp_ah3_tp(index, npl, nenc, rmvs_pl1P, rmvs_pleP) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_getaccp_ah3_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: index, npl, nenc - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, fac - REAL(DP), DIMENSION(NDIM) :: dx, acc, xpct - TYPE(rmvs_pl), POINTER :: rmvs_plP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rmvs_tpP => rmvs_pleP%tpenc1P - DO i = 1, nenc - acc(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - xpct(:) = rmvs_tpP%xpc(:) - rmvs_plP => rmvs_pl1P - DO j = 1, npl - IF (.NOT. ASSOCIATED(rmvs_plP, rmvs_pleP)) THEN - dx(:) = xpct(:) - rmvs_plP%xpc(:, index) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - fac = rmvs_plP%whm%swifter%mass*irij3 - acc(:) = acc(:) - fac*dx(:) - END IF - rmvs_plP => rmvs_plP%nextP - END DO - rmvs_tpP%apc(:) = acc(:) - rmvs_tpP => rmvs_tpP%tpencP - END DO - - RETURN - -END SUBROUTINE rmvs_getaccp_ah3_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_getaccp_tp.f90 b/rmvs/rmvs_getaccp_tp.f90 deleted file mode 100644 index 665cf5f1b..000000000 --- a/rmvs/rmvs_getaccp_tp.f90 +++ /dev/null @@ -1,120 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_getaccp_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Compute planetocentric accelerations of test particles closely encountering a planet -! -! Input -! Arguments : index : inner substep number within current set -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! nenc : number of test particles encountering current planet -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_getaccp_tp(index, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_getaccp_tp(index, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_getaccp_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, nenc, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: ir3p, irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xht, aoblt - TYPE(rmvs_pl), POINTER :: rmvs_plP - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P, rmvs_tpP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(ir3p(nplmax), xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - rmvs_tpenc1P => rmvs_pleP%tpenc1P - ah0(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - rmvs_plP => rmvs_pl1P - DO i = 1, npl - IF (.NOT. ASSOCIATED(rmvs_plP, rmvs_pleP)) THEN - r2 = DOT_PRODUCT(rmvs_plP%xpc(:, index), rmvs_plP%xpc(:, index)) - ir3p(i) = 1.0_DP/(r2*SQRT(r2)) - fac = rmvs_plP%whm%swifter%mass*ir3p(i) - ah0(:) = ah0(:) - fac*rmvs_plP%xpc(:, index) - END IF - rmvs_plP => rmvs_plP%nextP - END DO - CALL rmvs_getaccp_ah3_tp(index, npl, nenc, rmvs_pl1P, rmvs_pleP) - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - rmvs_tpP%apc(:) = rmvs_tpP%apc(:) + ah0(:) - rmvs_tpP => rmvs_tpP%tpencP - END DO - IF (j2rp2 /= 0.0_DP) THEN - mu = rmvs_pl1P%whm%swifter%mass - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - xht(:, i) = rmvs_tpP%whm%swifter%xh(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - rmvs_tpP => rmvs_tpP%tpencP - END DO - CALL obl_acc_tp(nenc, xht, j2rp2, j4rp4, irht, aoblt, mu) - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - rmvs_tpP%apc(:) = rmvs_tpP%apc(:) + aoblt(:, i) - rmvs_pleP%aobl(:, index) - rmvs_tpP => rmvs_tpP%tpencP - END DO - END IF - IF (lextra_force) CALL rmvs_user_getacch_tp(t, nenc, rmvs_tpenc1P) - - RETURN - -END SUBROUTINE rmvs_getaccp_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_interp_in.f90 b/rmvs/rmvs_interp_in.f90 deleted file mode 100644 index eb0594b21..000000000 --- a/rmvs/rmvs_interp_in.f90 +++ /dev/null @@ -1,112 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_interp_in -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Interpolate planet positions between two Keplerian orbits in inner encounter region -! -! Input -! Arguments : npl : number of planets -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL rmvs_interp_in(npl, rmvs_pl1P, dt) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_interp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_interp_in(npl, rmvs_pl1P, dt) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_interp_in - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - -! Internals - INTEGER(I4B) :: i, j, iflag - REAL(DP) :: msun, dti, frac, dntphenc - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(rmvs_pl), POINTER :: rmvs_plP - -! Executable code - dntphenc = REAL(NTPHENC, DP) - msun = rmvs_pl1P%whm%swifter%mass - dti = dt/dntphenc - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - xtmp(:) = rmvs_plP%xin(:, 0) - vtmp(:) = rmvs_plP%vin(:, 0) - DO j = 1, NTPHENC - 1 - CALL drift_one(msun, xtmp(:), vtmp(:), dti, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", rmvs_plP%whm%swifter%id, " is lost!!!!!!!!!!" - WRITE(*, *) msun, dti - WRITE(*, *) xtmp(:) - WRITE(*, *) vtmp(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - frac = 1.0_DP - j/dntphenc - rmvs_plP%xin(:, j) = frac*xtmp(:) - rmvs_plP%vin(:, j) = frac*vtmp(:) - END DO - xtmp(:) = rmvs_plP%xin(:, NTPHENC) - vtmp(:) = rmvs_plP%vin(:, NTPHENC) - DO j = NTPHENC - 1, 1, -1 - CALL drift_one(msun, xtmp(:), vtmp(:), -dti, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", rmvs_plP%whm%swifter%id, " is lost!!!!!!!!!!" - WRITE(*, *) msun, -dti - WRITE(*, *) xtmp(:) - WRITE(*, *) vtmp(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - frac = j/dntphenc - rmvs_plP%xin(:, j) = rmvs_plP%xin(:, j) + frac*xtmp(:) - rmvs_plP%vin(:, j) = rmvs_plP%vin(:, j) + frac*vtmp(:) - END DO - END DO - DO j = 0, NTPHENC - rmvs_pl1P%xin(:, j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - rmvs_pl1P%vin(:, j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - - RETURN - -END SUBROUTINE rmvs_interp_in -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_interp_out.f90 b/rmvs/rmvs_interp_out.f90 deleted file mode 100644 index 78b659c78..000000000 --- a/rmvs/rmvs_interp_out.f90 +++ /dev/null @@ -1,112 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_interp_out -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Interpolate planet positions between two Keplerian orbits in outer encounter region -! -! Input -! Arguments : npl : number of planets -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL rmvs_interp_out(npl, rmvs_pl1P, dt) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_interp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_interp_out(npl, rmvs_pl1P, dt) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_interp_out - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - -! Internals - INTEGER(I4B) :: i, j, iflag - REAL(DP) :: msun, dto, frac, dntenc - REAL(DP), DIMENSION(NDIM) :: xtmp, vtmp - TYPE(rmvs_pl), POINTER :: rmvs_plP - -! Executable code - dntenc = REAL(NTENC, DP) - msun = rmvs_pl1P%whm%swifter%mass - dto = dt/dntenc - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - xtmp(:) = rmvs_plP%xout(:, 0) - vtmp(:) = rmvs_plP%vout(:, 0) - DO j = 1, NTENC - 1 - CALL drift_one(msun, xtmp(:), vtmp(:), dto, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", rmvs_plP%whm%swifter%id, " is lost!!!!!!!!!!" - WRITE(*, *) msun, dto - WRITE(*, *) xtmp(:) - WRITE(*, *) vtmp(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - frac = 1.0_DP - j/dntenc - rmvs_plP%xout(:, j) = frac*xtmp(:) - rmvs_plP%vout(:, j) = frac*vtmp(:) - END DO - xtmp(:) = rmvs_plP%xout(:, NTENC) - vtmp(:) = rmvs_plP%vout(:, NTENC) - DO j = NTENC - 1, 1, -1 - CALL drift_one(msun, xtmp(:), vtmp(:), -dto, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", rmvs_plP%whm%swifter%id, " is lost!!!!!!!!!!" - WRITE(*, *) msun, -dto - WRITE(*, *) xtmp(:) - WRITE(*, *) vtmp(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - frac = j/dntenc - rmvs_plP%xout(:, j) = rmvs_plP%xout(:, j) + frac*xtmp(:) - rmvs_plP%vout(:, j) = rmvs_plP%vout(:, j) + frac*vtmp(:) - END DO - END DO - DO j = 0, NTENC - rmvs_pl1P%xout(:, j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - rmvs_pl1P%vout(:, j) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - - RETURN - -END SUBROUTINE rmvs_interp_out -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_kickvp_tp.f90 b/rmvs/rmvs_kickvp_tp.f90 deleted file mode 100644 index a0419e4cf..000000000 --- a/rmvs/rmvs_kickvp_tp.f90 +++ /dev/null @@ -1,75 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_kickvp_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Kick planetocentric velocities of active test particles in inner encounter -! -! Input -! Arguments : nenc : number of test particles encountering current planet -! rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_kickvp_tp(nenc, rmvs_tpenc1P, dt) -! -! Notes : Adapted from Martin Duncan's Swift routine kickvh_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_kickvp_tp(nenc, rmvs_tpenc1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_kickvp_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: dt - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - swifter_tpP => rmvs_tpP%whm%swifter - IF (swifter_tpP%status == ACTIVE) rmvs_tpP%vpc(:) = rmvs_tpP%vpc(:) + rmvs_tpP%apc(:)*dt - rmvs_tpP => rmvs_tpP%tpencP - END DO - - RETURN - -END SUBROUTINE rmvs_kickvp_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_peri.f90 b/rmvs/rmvs_peri.f90 deleted file mode 100644 index cdb7892b6..000000000 --- a/rmvs/rmvs_peri.f90 +++ /dev/null @@ -1,137 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_peri -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Determine planetocentric pericenter passages for test particles in close encounters with a planet -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! index : inner substep number within current set -! nenc : number of test particles encountering current planet -! rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! mu : mass of planet being encountered -! rhill : Hill sphere radius of planet being encountered -! t : time -! dt : time step -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_tpenc1P : pointer to RMVS test particle structure of first test particle encountering planet -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_peri(lfirst, index, nenc, rmvs_pleP, rmvs_tpenc1P, mu, rhill, t, dt, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine util_peri.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_peri(lfirst, index, nenc, rmvs_pleP, rmvs_tpenc1P, mu, rhill, t, dt, encounter_file, out_type) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_peri - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: index, nenc - REAL(DP), INTENT(IN) :: mu, rhill, t, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pleP - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - -! Internals - INTEGER(I4B) :: i, id1, id2 - REAL(DP) :: r2, rhill2, vdotr, a, peri, capm, tperi, rpl - REAL(DP), DIMENSION(NDIM) :: xh1, xh2, vh1, vh2 - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rhill2 = rhill*rhill - rmvs_tpP => rmvs_tpenc1P - IF (lfirst) THEN - DO i = 1, nenc - IF (rmvs_tpP%whm%swifter%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(rmvs_tpP%xpc(:), rmvs_tpP%vpc(:)) - IF (vdotr > 0.0_DP) THEN - rmvs_tpP%isperi = 1 - ELSE - rmvs_tpP%isperi = -1 - END IF - END IF - rmvs_tpP => rmvs_tpP%tpencP - END DO - ELSE - DO i = 1, nenc - IF (rmvs_tpP%whm%swifter%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(rmvs_tpP%xpc(:), rmvs_tpP%vpc(:)) - IF (rmvs_tpP%isperi == -1) THEN - IF (vdotr >= 0.0_DP) THEN - rmvs_tpP%isperi = 0 - CALL orbel_xv2aqt(rmvs_tpP%xpc(:), rmvs_tpP%vpc(:), mu, a, peri, capm, tperi) - r2 = DOT_PRODUCT(rmvs_tpP%xpc(:), rmvs_tpP%xpc(:)) - IF ((ABS(tperi) > FACQDT*dt) .OR. (r2 > rhill2)) peri = SQRT(r2) - IF (encounter_file /= "") THEN - id1 = rmvs_pleP%whm%swifter%id - rpl = rmvs_pleP%whm%swifter%radius - xh1(:) = rmvs_pleP%xin(:, index) - vh1(:) = rmvs_pleP%vin(:, index) - id2 = rmvs_tpP%whm%swifter%id - xh2(:) = rmvs_tpP%whm%swifter%xh(:) - vh2(:) = rmvs_tpP%whm%swifter%vh(:) - CALL io_write_encounter(t, id1, id2, mu, 0.0_DP, rpl, 0.0_DP, xh1(:), xh2(:), vh1(:), vh2(:), & - encounter_file, out_type) - END IF - IF (rmvs_tpP%lperi) THEN - IF (peri < rmvs_tpP%peri) THEN - rmvs_tpP%peri = peri - rmvs_tpP%plperP => rmvs_pleP - END IF - ELSE - rmvs_tpP%lperi = .TRUE. - rmvs_tpP%peri = peri - rmvs_tpP%plperP => rmvs_pleP - END IF - END IF - ELSE - IF (vdotr > 0.0_DP) THEN - rmvs_tpP%isperi = 1 - ELSE - rmvs_tpP%isperi = -1 - END IF - END IF - END IF - rmvs_tpP => rmvs_tpP%tpencP - END DO - END IF - - RETURN - -END SUBROUTINE rmvs_peri -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_setup.f90 b/rmvs/rmvs_setup.f90 deleted file mode 100644 index e8585724b..000000000 --- a/rmvs/rmvs_setup.f90 +++ /dev/null @@ -1,157 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_setup -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Set up pointers within RMVS, WHM and Swifter planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! rmvs_plA : RMVS planet structure array -! rmvs_tpA : RMVS test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_plA : RMVS planet structure array -! rmvs_tpA : RMVS test particle structure array -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_setup(npl, ntp, rmvs_plA, rmvs_tpA, rmvs_pl1P, rmvs_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_setup(npl, ntp, rmvs_plA, rmvs_tpA, rmvs_pl1P, rmvs_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(rmvs_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: rmvs_plA - TYPE(rmvs_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: rmvs_tpA - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(whm_pl), POINTER :: whm_pl1P, whm_plP - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpP - TYPE(rmvs_pl), POINTER :: rmvs_plP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - rmvs_pl1P => rmvs_plA(1) - whm_pl1P => rmvs_plA(1)%whm - swifter_pl1P => rmvs_plA(1)%whm%swifter - NULLIFY(rmvs_pl1P%prevP) - NULLIFY(whm_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(rmvs_pl1P%nextP) - NULLIFY(whm_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - rmvs_pl1P%nextP => rmvs_plA(2) - whm_pl1P%nextP => rmvs_plA(2)%whm - swifter_pl1P%nextP => rmvs_plA(2)%whm%swifter - DO i = 2, npl - 1 - rmvs_plA(i)%prevP => rmvs_plA(i-1) - rmvs_plA(i)%nextP => rmvs_plA(i+1) - whm_plP => rmvs_plA(i)%whm - whm_plP%prevP => rmvs_plA(i-1)%whm - whm_plP%nextP => rmvs_plA(i+1)%whm - swifter_plP => rmvs_plA(i)%whm%swifter - swifter_plP%prevP => rmvs_plA(i-1)%whm%swifter - swifter_plP%nextP => rmvs_plA(i+1)%whm%swifter - END DO - rmvs_plA(npl)%prevP => rmvs_plA(npl-1) - rmvs_plP => rmvs_plA(npl) - NULLIFY(rmvs_plP%nextP) - whm_plP => rmvs_plA(npl)%whm - whm_plP%prevP => rmvs_plA(npl-1)%whm - NULLIFY(whm_plP%nextP) - swifter_plP => rmvs_plA(npl)%whm%swifter - swifter_plP%prevP => rmvs_plA(npl-1)%whm%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(rmvs_tp1P) - NULLIFY(whm_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - rmvs_tp1P => rmvs_tpA(1) - whm_tp1P => rmvs_tpA(1)%whm - swifter_tp1P => rmvs_tpA(1)%whm%swifter - NULLIFY(rmvs_tp1P%prevP) - NULLIFY(whm_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(rmvs_tp1P%nextP) - NULLIFY(whm_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - rmvs_tp1P%nextP => rmvs_tpA(2) - whm_tp1P%nextP => rmvs_tpA(2)%whm - swifter_tp1P%nextP => rmvs_tpA(2)%whm%swifter - DO i = 2, ntp - 1 - rmvs_tpA(i)%prevP => rmvs_tpA(i-1) - rmvs_tpA(i)%nextP => rmvs_tpA(i+1) - whm_tpP => rmvs_tpA(i)%whm - whm_tpP%prevP => rmvs_tpA(i-1)%whm - whm_tpP%nextP => rmvs_tpA(i+1)%whm - swifter_tpP => rmvs_tpA(i)%whm%swifter - swifter_tpP%prevP => rmvs_tpA(i-1)%whm%swifter - swifter_tpP%nextP => rmvs_tpA(i+1)%whm%swifter - END DO - rmvs_tpA(ntp)%prevP => rmvs_tpA(ntp-1) - rmvs_tpP => rmvs_tpA(ntp) - NULLIFY(rmvs_tpP%nextP) - whm_tpP => rmvs_tpA(ntp)%whm - whm_tpP%prevP => rmvs_tpA(ntp-1)%whm - NULLIFY(whm_tpP%nextP) - swifter_tpP => rmvs_tpA(ntp)%whm%swifter - swifter_tpP%prevP => rmvs_tpA(ntp-1)%whm%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE rmvs_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_step.f90 b/rmvs/rmvs_step.f90 deleted file mode 100644 index d7a627ff8..000000000 --- a/rmvs/rmvs_step.f90 +++ /dev/null @@ -1,149 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_step -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, -! encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_step.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, encounter_file, & - out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - LOGICAL(LGT) :: lfirstpl, lfirsttp, lencounter - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: rts - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, vbeg, xend - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(whm_pl), POINTER :: whm_pl1P, whm_plP - TYPE(whm_tp), POINTER :: whm_tp1P - TYPE(rmvs_pl), POINTER :: rmvs_plP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), vbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - whm_pl1P => rmvs_pl1P%whm - whm_tp1P => rmvs_tp1P%whm - swifter_plP => whm_pl1P%swifter - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xbeg(:, i) = swifter_plP%xh(:) - vbeg(:, i) = swifter_plP%vh(:) - END DO - rts = RHSCALE - CALL rmvs_chk(npl, ntp, rmvs_pl1P, rmvs_tp1P, xbeg, vbeg, dt, rts, lencounter) - IF (lencounter) THEN - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - rmvs_plP%xout(:, 0) = xbeg(:, i) - rmvs_plP%vout(:, 0) = vbeg(:, i) - END DO - lfirstpl = lfirst - CALL whm_step_pl(lfirstpl, lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4, dt) - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - swifter_plP => rmvs_plP%whm%swifter - rmvs_plP%xout(:, NTENC) = swifter_plP%xh(:) - rmvs_plP%vout(:, NTENC) = swifter_plP%vh(:) - xend(:, i) = swifter_plP%xh(:) - END DO - CALL rmvs_interp_out(npl, rmvs_pl1P, dt) - CALL rmvs_step_out(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - swifter_tpP => whm_tp1P%swifter - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - swifter_tpP%status = INACTIVE - ELSE IF (swifter_tpP%status == INACTIVE) THEN - swifter_tpP%status = ACTIVE - END IF - swifter_tpP => swifter_tpP%nextP - END DO - lfirsttp = .TRUE. - CALL whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, j4rp4, dt) - swifter_tpP => whm_tp1P%swifter - DO i = 1, ntp - IF (swifter_tpP%status == INACTIVE) swifter_tpP%status = ACTIVE - swifter_tpP => swifter_tpP%nextP - END DO - ELSE - CALL whm_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, j2rp2, j4rp4, dt) - END IF - - RETURN - -END SUBROUTINE rmvs_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_step_in.f90 b/rmvs/rmvs_step_in.f90 deleted file mode 100644 index 3680a33c2..000000000 --- a/rmvs/rmvs_step_in.f90 +++ /dev/null @@ -1,150 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_step_in -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Step active test particles ahead in the inner encounter region -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_step_in(lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, -! encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_step_in.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_step_in(lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, encounter_file, & - out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_step_in - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j, k, nenc - REAL(DP) :: mu, rhill, dti, time - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(rmvs_pl), POINTER :: rmvs_plP, rmvs_pleP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(irh(nplmax), xh(NDIM, nplmax), aobl(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - dti = dt/NTPHENC - IF (j2rp2 /= 0.0_DP) THEN - swifter_pl1P => rmvs_pl1P%whm%swifter - DO i = 0, NTPHENC - rmvs_plP => rmvs_pl1P - DO j = 2, npl - rmvs_plP => rmvs_plP%nextP - xh(:, j) = rmvs_plP%xin(:, i) - irh(j) = 1.0_DP/SQRT(DOT_PRODUCT(xh(:, j), xh(:, j))) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - rmvs_plP => rmvs_pl1P - DO j = 1, npl - rmvs_plP%aobl(:, i) = aobl(:, j) - rmvs_plP => rmvs_plP%nextP - END DO - END DO - END IF - rmvs_pleP => rmvs_pl1P - DO i = 2, npl - rmvs_pleP => rmvs_pleP%nextP - nenc = rmvs_pleP%nenc - IF (nenc > 0) THEN -! There are inner encounters with this planet...switch to planetocentric coordinates to proceed -! Determine initial planetocentric positions and velocities for those test particles encountering this planet - rmvs_tpP => rmvs_pleP%tpenc1P - DO j = 1, nenc - rmvs_tpP%xpc(:) = rmvs_tpP%whm%swifter%xh(:) - rmvs_pleP%xin(:, 0) - rmvs_tpP%vpc(:) = rmvs_tpP%whm%swifter%vh(:) - rmvs_pleP%vin(:, 0) - rmvs_tpP => rmvs_tpP%tpencP - END DO -! Determine planetocentric positions for planets and sun at all interpolated points in inner encounter - rmvs_plP => rmvs_pl1P - DO j = 1, npl - rmvs_plP%xpc(:, :) = rmvs_plP%xin(:, :) - rmvs_pleP%xin(:, :) - rmvs_plP => rmvs_plP%nextP - END DO - time = t - mu = rmvs_pleP%whm%swifter%mass - rhill = rmvs_pleP%whm%swifter%rhill - CALL rmvs_peri(.TRUE., 0, nenc, rmvs_pleP, rmvs_pleP%tpenc1P, mu, rhill, time, dti, encounter_file, out_type) -! Now step the encountering test particles fully through the inner encounter - lfirsttp = .TRUE. - DO j = 1, NTPHENC - CALL rmvs_step_in_tp(j, lfirsttp, lextra_force, time, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, & - j4rp4, dti) - time = t + j*dti - CALL rmvs_peri(.FALSE., j, nenc, rmvs_pleP, rmvs_pleP%tpenc1P, mu, rhill, time, dti, encounter_file, out_type) - END DO - rmvs_tpP => rmvs_pleP%tpenc1P - DO j = 1, nenc - IF (rmvs_tpP%whm%swifter%status == ACTIVE) rmvs_tpP%whm%swifter%status = INACTIVE - rmvs_tpP => rmvs_tpP%tpencP - END DO - END IF - END DO - - RETURN - -END SUBROUTINE rmvs_step_in -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_step_in_tp.f90 b/rmvs/rmvs_step_in_tp.f90 deleted file mode 100644 index f36f61d4d..000000000 --- a/rmvs/rmvs_step_in_tp.f90 +++ /dev/null @@ -1,103 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_step_in_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Step all active test particles closely encountering a given planet ahead one substep in inner integration region -! -! Input -! Arguments : index : inner substep number within current set -! lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! nenc : number of test particles encountering current planet -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! rmvs_pleP : pointer to RMVS planet structure of planet being closely encountered -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_step_in_tp(index, lfirst, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, -! j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs_step_in_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_step_in_tp(index, lfirst, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_step_in_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, nenc, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(rmvs_pl), POINTER :: rmvs_pl1P, rmvs_pleP - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: dth, mu - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P, rmvs_tpP - -! Executable code - dth = 0.5_DP*dt - mu = rmvs_pleP%whm%swifter%mass - rmvs_tpenc1P => rmvs_pleP%tpenc1P - IF (lfirst) THEN - CALL rmvs_getaccp_tp(index-1, lextra_force, t, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4) - lfirst = .FALSE. - END IF - CALL rmvs_kickvp_tp(nenc, rmvs_tpenc1P, dth) - CALL rmvs_drift_tp(nenc, rmvs_tpenc1P, mu, dt) - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - rmvs_tpP%whm%swifter%xh(:) = rmvs_pleP%xin(:, index) + rmvs_tpP%xpc(:) - rmvs_tpP => rmvs_tpP%tpencP - END DO - CALL rmvs_getaccp_tp(index, lextra_force, t+dt, npl, nplmax, nenc, ntpmax, rmvs_pl1P, rmvs_pleP, j2rp2, j4rp4) - CALL rmvs_kickvp_tp(nenc, rmvs_tpenc1P, dth) - rmvs_tpP => rmvs_tpenc1P - DO i = 1, nenc - rmvs_tpP%whm%swifter%vh(:) = rmvs_pleP%vin(:, index) + rmvs_tpP%vpc(:) - rmvs_tpP => rmvs_tpP%tpencP - END DO - - RETURN - -END SUBROUTINE rmvs_step_in_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_step_out.f90 b/rmvs/rmvs_step_out.f90 deleted file mode 100644 index 40c7b7d3b..000000000 --- a/rmvs/rmvs_step_out.f90 +++ /dev/null @@ -1,115 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_step_out -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Step active test particles ahead in the outer encounter region -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_step_out(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, -! encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_step_out.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_step_out(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_step_out - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirst, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp - INTEGER(I4B) :: i, j, k, nenc - REAL(DP) :: dto, time - TYPE(rmvs_pl), POINTER :: rmvs_pleP - TYPE(rmvs_tp), POINTER :: rmvs_tpP - -! Executable code - lfirsttp = lfirst - dto = dt/NTENC - rmvs_tpP => rmvs_tp1P - DO i = 1, ntp - IF (.NOT. ASSOCIATED(rmvs_tpP%plencP)) THEN - rmvs_tpP%whm%swifter%status = INACTIVE - ELSE - rmvs_tpP%lperi = .FALSE. - END IF - rmvs_tpP => rmvs_tpP%nextP - END DO - DO i = 1, NTENC - time = t + (i - 1)*dto - CALL rmvs_step_out2(i, lfirsttp, lextra_force, time, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dto, & - encounter_file, out_type) - rmvs_pleP => rmvs_pl1P - DO j = 2, npl - rmvs_pleP => rmvs_pleP%nextP - nenc = rmvs_pleP%nenc - IF (nenc > 0) THEN - rmvs_tpP => rmvs_pleP%tpenc1P - DO k = 1, nenc - IF (rmvs_tpP%whm%swifter%status == INACTIVE) rmvs_tpP%whm%swifter%status = ACTIVE - rmvs_tpP => rmvs_tpP%tpencP - END DO - END IF - END DO - END DO - - RETURN - -END SUBROUTINE rmvs_step_out -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_step_out2.f90 b/rmvs/rmvs_step_out2.f90 deleted file mode 100644 index 73b14573d..000000000 --- a/rmvs/rmvs_step_out2.f90 +++ /dev/null @@ -1,126 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_step_out2 -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Step active test particles ahead in the outer encounter region, setting up and calling the inner region -! integration if necessary -! -! Input -! Arguments : index : outer substep number within current set -! lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : rmvs_pl1P : pointer to head of RMVS planet structure linked-list -! rmvs_tp1P : pointer to head of active RMVS test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL rmvs_step_out2(index, lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, -! dt, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine rmvs3_step_out2.f -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_step_out2(index, lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, & - encounter_file, out_type) - -! Modules - USE module_parameters - USE module_whm - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_step_out2 - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirst, lextra_force - INTEGER(I4B), INTENT(IN) :: index, npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(rmvs_pl), POINTER :: rmvs_pl1P - TYPE(rmvs_tp), POINTER :: rmvs_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp, lencounter - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: rts - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, vbeg, xend - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpP - TYPE(rmvs_pl), POINTER :: rmvs_plP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), vbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - lfirsttp = lfirst - whm_pl1P => rmvs_pl1P%whm - whm_tp1P => rmvs_tp1P%whm - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - xbeg(:, i) = rmvs_plP%xout(:, index-1) - vbeg(:, i) = rmvs_plP%vout(:, index-1) - xend(:, i) = rmvs_plP%xout(:, index) - END DO - rts = RHPSCALE - CALL rmvs_chk(npl, ntp, rmvs_pl1P, rmvs_tp1P, xbeg, vbeg, dt, rts, lencounter) - IF (lencounter) THEN - rmvs_plP => rmvs_pl1P - DO i = 2, npl - rmvs_plP => rmvs_plP%nextP - rmvs_plP%xin(:, 0) = xbeg(:, i) - rmvs_plP%vin(:, 0) = vbeg(:, i) - rmvs_plP%xin(:, NTPHENC) = xend(:, i) - rmvs_plP%vin(:, NTPHENC) = rmvs_plP%vout(:, index) - END DO - CALL rmvs_interp_in(npl, rmvs_pl1P, dt) - CALL rmvs_step_in(lextra_force, t, npl, nplmax, ntp, ntpmax, rmvs_pl1P, rmvs_tp1P, j2rp2, j4rp4, dt, encounter_file, & - out_type) - lfirsttp = .TRUE. - CALL whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, j4rp4, dt) - ELSE - CALL whm_step_tp(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, j4rp4, dt) - END IF - - RETURN - -END SUBROUTINE rmvs_step_out2 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/rmvs/rmvs_user_getacch_tp.f90 b/rmvs/rmvs_user_getacch_tp.f90 deleted file mode 100644 index a8780bf00..000000000 --- a/rmvs/rmvs_user_getacch_tp.f90 +++ /dev/null @@ -1,74 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : rmvs_user_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : rmvs -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to test particles encountering a planet -! -! Input -! Arguments : t : time -! nenc : number of test particles encountering planet -! rmvs_tpenc1P : pointer to head of encountering RMVS test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : rmvs_tpenc1P : pointer to head of encountering RMVS test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL rmvs_user_getacch_tp(t, nenc, rmvs_tpenc1P) -! -! Notes : In this routine only loop over test particles interacting with the current planet -! -! Proceed from the first test particle to the next on the interaction list by setting rmvs_tpP=>rmvs_tpenc1P to -! begin (outside the loop), then rmvs_tpP=>rmvs_tpP%tpencP inside the loop -! -! Use the current heliocentric position rmvs_tpP%whm%swifter%xh(:) to compute the acceleration components to add -! -! Add the accelerations to rmvs_tpP%apc(:), the planetocentric acceleration -! -! To add extra accelerations in RMVS to non-interacting test particles use whm_user_getacch_tp() -! -!********************************************************************************************************************************** -SUBROUTINE rmvs_user_getacch_tp(t, nenc, rmvs_tpenc1P) - -! Modules - USE module_parameters - USE module_rmvs - USE module_interfaces, EXCEPT_THIS_ONE => rmvs_user_getacch_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: nenc - REAL(DP), INTENT(IN) :: t - TYPE(rmvs_tp), POINTER :: rmvs_tpenc1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE rmvs_user_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/src/discard/discard.f90 b/src/discard/discard.f90 new file mode 100644 index 000000000..be377e49e --- /dev/null +++ b/src/discard/discard.f90 @@ -0,0 +1,266 @@ +submodule (swiftest_classes) s_discard + use swiftest +contains + + module subroutine discard_system(self, param) + !! author: David A. Minton + !! + !! Calls the discard methods for each body class and then the write method if any discards were detected + !! + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + logical :: lany_discards + + associate(system => self, tp => self%tp, pl => self%pl) + lany_discards = .false. + call pl%discard(system, param) + call tp%discard(system, param) + if (tp%nbody > 0) lany_discards = lany_discards .or. any(tp%ldiscard(:)) + if (pl%nbody > 0) lany_discards = lany_discards .or. any(pl%ldiscard(:)) + if (lany_discards) call system%write_discard(param) + end associate + + return + end subroutine discard_system + + + module subroutine discard_pl(self, system, param) + !! author: David A. Minton + !! + !! Placeholder method for discarding massive bodies. This method does nothing except to ensure that the discard flag is set to false. + !! This method is intended to be overridden by more advanced integrators. + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameter + + if (self%nbody == 0) return + self%ldiscard(:) = .false. + + return + end subroutine discard_pl + + + module subroutine discard_tp(self, system, param) + !! author: David A. Minton + !! + !! Check to see if particles should be discarded based on their positions relative to the massive bodies + !! + !! Adapted from David E. Kaufmann's Swifter routine: discard.f90 + !! Adapted from Hal Levison's Swift routine discard. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameter + + associate(tp => self, ntp => self%nbody, cb => system%cb, pl => system%pl, npl => system%pl%nbody) + if ((ntp == 0) .or. (npl ==0)) return + + if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. & + (param%rmaxu >= 0.0_DP) .or. ((param%qmin >= 0.0_DP) .and. (param%qmin_coord == "BARY"))) then + call pl%h2b(cb) + call tp%h2b(cb) + end if + + if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. (param%rmaxu >= 0.0_DP)) call discard_cb_tp(tp, system, param) + if (param%qmin >= 0.0_DP) call discard_peri_tp(tp, system, param) + if (param%lclose) call discard_pl_tp(tp, system, param) + if (any(tp%ldiscard)) call tp%spill(system%tp_discards, tp%ldiscard, ldestructive=.true.) + end associate + + return + end subroutine discard_tp + + + subroutine discard_cb_tp(tp, system, param) + !! author: David A. Minton + !! + !! Check to see if test particles should be discarded based on their positions relative to the Sun + !! or because they are unbound from the system + !! + !! Adapted from David E. Kaufmann's Swifter routine: discard_sun.f90 + !! Adapted from Hal Levison's Swift routine discard_sun.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: tp !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, rmaxu2 + + associate(ntp => tp%nbody, cb => system%cb, t => param%t, Gmtot => system%Gmtot) + rmin2 = max(param%rmin * param%rmin, cb%radius * cb%radius) + rmax2 = param%rmax**2 + rmaxu2 = param%rmaxu**2 + do i = 1, ntp + if (tp%status(i) == ACTIVE) then + rh2 = dot_product(tp%xh(:, i), tp%xh(:, i)) + if ((param%rmax >= 0.0_DP) .and. (rh2 > rmax2)) then + tp%status(i) = DISCARDED_RMAX + write(*, *) "Particle ", tp%id(i), " too far from sun at t = ", t + tp%ldiscard(i) = .true. + tp%lmask(i) = .false. + else if ((param%rmin >= 0.0_DP) .and. (rh2 < rmin2)) then + tp%status(i) = DISCARDED_RMIN + write(*, *) "Particle ", tp%id(i), " too close to sun at t = ", t + tp%ldiscard(i) = .true. + tp%lmask(i) = .false. + else if (param%rmaxu >= 0.0_DP) then + rb2 = dot_product(tp%xb(:, i), tp%xb(:, i)) + vb2 = dot_product(tp%vb(:, i), tp%vb(:, i)) + energy = 0.5_DP * vb2 - Gmtot / sqrt(rb2) + if ((energy > 0.0_DP) .and. (rb2 > rmaxu2)) then + tp%status(i) = DISCARDED_RMAXU + write(*, *) "Particle ", tp%id(i), " is unbound and too far from barycenter at t = ", t + tp%ldiscard(i) = .true. + tp%lmask(i) = .false. + end if + end if + end if + end do + end associate + + return + end subroutine discard_cb_tp + + + subroutine discard_peri_tp(tp, system, param) + !! author: David A. Minton + !! + !! Check to see if a test particle should be discarded because its perihelion distance becomes too small + !! + !! Adapted from David E. Kaufmann's Swifter routine: discard_peri.f90 + !! Adapted from Hal Levison's Swift routine discard_peri.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: tp !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameterss + ! Internals + logical, save :: lfirst = .true. + integer(I4B) :: i, j, ih + real(DP) :: r2 + real(DP), dimension(NDIM) :: dx + + associate(cb => system%cb, ntp => tp%nbody, pl => system%pl, npl => system%pl%nbody, t => param%t) + call tp%get_peri(system, param) + do i = 1, ntp + if (tp%status(i) == ACTIVE) then + if (tp%isperi(i) == 0) then + ih = 1 + do j = 1, npl + dx(:) = tp%xh(:, i) - pl%xh(:, j) + r2 = dot_product(dx(:), dx(:)) + if (r2 <= (pl%rhill(j))**2) ih = 0 + end do + if (ih == 1) then + if ((tp%atp(i) >= param%qmin_alo) .and. & + (tp%atp(i) <= param%qmin_ahi) .and. & + (tp%peri(i) <= param%qmin)) then + tp%status(i) = DISCARDED_PERI + write(*, *) "Particle ", tp%id(i), " perihelion distance too small at t = ", t + tp%ldiscard(i) = .true. + end if + end if + end if + end if + end do + end associate + + return + end subroutine discard_peri_tp + + + subroutine discard_pl_tp(tp, system, param) + !! author: David A. Minton + !! + !! Check to see if test particles should be discarded based on their positions relative to the massive bodies + !! + !! Adapted from David E. Kaufmann's Swifter routine: discard_pl.f90 + !! Adapted from Hal Levison's Swift routine discard_pl.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: tp !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, j, isp + real(DP) :: r2min, radius + real(DP), dimension(NDIM) :: dx, dv + + associate(ntp => tp%nbody, pl => system%pl, npl => system%pl%nbody, t => param%t, dt => param%dt) + do i = 1, ntp + if (tp%status(i) == ACTIVE) then + do j = 1, npl + dx(:) = tp%xh(:, i) - pl%xh(:, j) + dv(:) = tp%vh(:, i) - pl%vh(:, j) + radius = pl%radius(j) + call discard_pl_close(dx(:), dv(:), dt, radius**2, isp, r2min) + if (isp /= 0) then + tp%status(i) = DISCARDED_PLR + tp%lmask(i) = .false. + pl%ldiscard(j) = .true. + write(*, *) "Particle ", tp%id(i), " too close to massive body ", pl%id(j), " at t = ", t + tp%ldiscard(i) = .true. + exit + end if + end do + end if + end do + end associate + + return + end subroutine discard_pl_tp + + + subroutine discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) + !! author: David A. Minton + !! + !! Check to see if a test particle and massive body are having, or will have within the next time step, an encounter such + !! that the separation distance r is less than some critical radius rcrit (or r**2 < rcrit**2 = r2crit) + !! + !! Adapted from David E. Kaufmann's Swifter routine: discard_pl_close.f90 + !! Adapted from Hal Levison's Swift routine discard_pl_close.f + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: dx, dv + real(DP), intent(in) :: dt, r2crit + integer(I4B), intent(out) :: iflag + real(DP), intent(out) :: r2min + ! Internals + real(DP) :: r2, v2, vdotr, tmin + + r2 = dot_product(dx(:), dx(:)) + if (r2 <= r2crit) then + iflag = 1 + else + vdotr = dot_product(dx(:), dv(:)) + if (vdotr > 0.0_DP) then + iflag = 0 + else + v2 = dot_product(dv(:), dv(:)) + tmin = -vdotr / v2 + if (tmin < dt) then + r2min = r2 - vdotr * vdotr / v2 + else + r2min = r2 + 2 * vdotr * dt + v2 * dt**2 + end if + r2min = min(r2min, r2) + if (r2min <= r2crit) then + iflag = 1 + else + iflag = 0 + end if + end if + end if + + return + end subroutine discard_pl_close + +end submodule s_discard diff --git a/src/drift/drift.f90 b/src/drift/drift.f90 new file mode 100644 index 000000000..79744c0f3 --- /dev/null +++ b/src/drift/drift.f90 @@ -0,0 +1,496 @@ +submodule (swiftest_classes) drift_implementation + use swiftest + !> Integration control parameters: + real(DP), parameter :: E2MAX = 0.36_DP + real(DP), parameter :: DM2MAX = 0.16_DP + real(DP), parameter :: E2DM2MAX = 0.0016_DP + real(DP), parameter :: DANBYB = 1.0E-13_DP + integer(I2B), parameter :: NLAG1 = 50 + integer(I2B), parameter :: NLAG2 = 40 + +contains + + module subroutine drift_body(self, system, param, dt) + !! author: David A. Minton + !! + !! Loop bodies and call Danby drift routine on the heliocentric position and velocities. + !! + !! Adapted from Hal Levison's Swift routine drift_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_drift_tp.f90 + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + ! Internals + integer(I4B) :: i + integer(I4B), dimension(:), allocatable :: iflag + + associate(n => self%nbody) + allocate(iflag(n)) + iflag(:) = 0 + call drift_all(self%mu, self%xh, self%vh, self%nbody, param, dt, self%lmask, iflag) + if (any(iflag(1:n) /= 0)) then + where(iflag(1:n) /= 0) self%status(1:n) = DISCARDED_DRIFTERR + do i = 1, n + if (iflag(i) /= 0) write(*, *) " Body ", self%id(i), " lost due to error in Danby drift" + end do + end if + end associate + + return + end subroutine drift_body + + + module pure subroutine drift_all(mu, x, v, n, param, dt, mask, iflag) + !! author: David A. Minton + !! + !! Loop bodies and call Danby drift routine on all bodies for the given position and velocity vector. + !! + !! Adapted from Hal Levison's Swift routine drift_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_drift_tp.f9 + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: mu !! Vector of gravitational constants + real(DP), dimension(:,:), intent(inout) :: x, v !! Position and velocity vectors + integer(I4B), intent(in) :: n !! number of bodies + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + integer(I4B), dimension(:), intent(out) :: iflag !! Vector of error flags. 0 means no problem + ! Internals + integer(I4B) :: i + real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation + real(DP), dimension(:), allocatable :: dtp + + if (n == 0) return + + allocate(dtp(n)) + if (param%lgr) then + do concurrent(i = 1:n, mask(i)) + rmag = norm2(x(:, i)) + vmag2 = dot_product(v(:, i), v(:, i)) + energy = 0.5_DP * vmag2 - mu(i) / rmag + dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) + end do + else + where(mask(1:n)) dtp(1:n) = dt + end if + do concurrent(i = 1:n, mask(i)) + call drift_one(mu(i), x(1,i), x(2,i), x(3,i), v(1,i), v(2,i), v(3,i), dtp(i), iflag(i)) + end do + + return + end subroutine drift_all + + + module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Perform Danby drift for one body, redoing drift with smaller substeps if original accuracy is insufficient + !! + !! Adapted from David E. Kaufmann's Swifter routine routine drift_one.f90 + !! Adapted from Hal Levison and Martin Duncan's Swift routine drift_one.f + implicit none + ! Arguments + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body to drift + real(DP), intent(inout) :: px, py, pz, vx, vy, vz !! Position and velocity of body to drift + real(DP), intent(in) :: dt !! Step size + integer(I4B), intent(out) :: iflag !! iflag : error status flag for Danby drift (0 = OK, nonzero = ERROR) + ! Internals + integer(I4B) :: i + real(DP) :: dttmp + real(DP), dimension(NDIM) :: x, v + + x = [px, py, pz] + v = [vx, vy, vz] + + call drift_dan(mu, x(:), v(:), dt, iflag) + if (iflag /= 0) then + dttmp = 0.1_DP * dt + do i = 1, 10 + call drift_dan(mu, x(:), v(:), dttmp, iflag) + if (iflag /= 0) exit + end do + end if + px = x(1); py = x(2); pz = x(3) + vx = v(1); vy = v(2); vz = v(3) + + return + end subroutine drift_one + + + pure subroutine drift_dan(mu, x0, v0, dt0, iflag) + !! author: David A. Minton + !! + !! Perform Kepler drift, solving Kepler's equation in appropriate variables + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_dan.f90 + !! Adapted from Hal Levison and Martin Duncan's Swift routine drift_dan.f + implicit none + integer(I4B), intent(out) :: iflag + real(DP), intent(in) :: mu, dt0 + real(DP), dimension(:), intent(inout) :: x0, v0 + real(DP) :: dt, f, g, fdot, gdot, c1, c2, c3, u, alpha, fp, r0 + real(DP) :: v0s, a, asq, en, dm, ec, es, esq, xkep, fchk, s, c + real(DP), dimension(NDIM) :: x, v + + ! Executable code + iflag = 0 + dt = dt0 + r0 = sqrt(dot_product(x0(:), x0(:))) + v0s = dot_product(v0(:), v0(:)) + u = dot_product(x0(:), v0(:)) + alpha = 2 * mu / r0 - v0s + if (alpha > 0.0_DP) then + a = mu / alpha + asq = a**2 + en = sqrt(mu / (a * asq)) + ec = 1.0_DP - r0 / a + es = u / (en * asq) + esq = ec**2 + es**2 + dm = dt * en - int(dt * en / TWOPI, kind = I4B) * TWOPI + dt = dm / en + if ((esq < E2MAX) .and. (dm**2 < DM2MAX) .and. (esq * dm**2 < E2DM2MAX)) then + call drift_kepmd(dm, es, ec, xkep, s, c) + fchk = (xkep - ec * s + es * (1.0_DP - c) - dm) + ! DEK - original code compared fchk*fchk with DANBYB, but i think it should + ! DEK - be compared with DANBYB*DANBYB, and i changed it accordingly - please + ! DEK - check with hal and/or martin about this + if (fchk**2 > DANBYB**2) then + iflag = 1 + return + end if + fp = 1.0_DP - ec * c + es * s + f = a / r0 * (c - 1.0_DP) + 1.0_DP + g = dt + (s - xkep) / en + fdot = -(a / (r0 * fp)) * en * s + gdot = (c - 1.0_DP) / fp + 1.0_DP + x(:) = x0(:) * f + v0(:) * g + v(:) = x0(:) * fdot + v0(:) * gdot + x0(:) = x(:) + v0(:) = v(:) + iflag = 0 + return + end if + end if + + call drift_kepu(dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) + if (iflag == 0) then + f = 1.0_DP - mu / r0 * c2 + g = dt - mu * c3 + fdot = -mu / (fp * r0) * c1 + gdot = 1.0_DP - mu / fp * c2 + x(:) = x0(:) * f + v0(:) * g + v(:) = x0(:) * fdot + v0(:) * gdot + x0(:) = x(:) + v0(:) = v(:) + end if + + return + end subroutine drift_dan + + + pure subroutine drift_kepmd(dm, es, ec, x, s, c) + !! author: David A. Minton + !! + !! Solve Kepler's equation in difference form for an ellipse for small input dm and eccentricity + !! Original disclaimer: built for speed, does not check how well the original equation is solved + !! Can do that in calling routine by checking how close (x - ec*s + es*(1.0 - c) - dm) is to zero + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepmd.f90 + !! Adapted from Martin Duncan's Swift routine drift_kepmd.f + implicit none + real(DP), intent(in) :: dm, es, ec + real(DP), intent(out) :: x, s, c + real(DP), parameter :: a0 = 39916800.0_DP, a1 = 6652800.0_DP, a2 = 332640.0_DP, a3 = 7920.0_DP, a4 = 110.0_DP + real(DP) :: dx, fac1, fac2, q, y, f, fp, fpp, fppp + + ! executable code + fac1 = 1.0_DP / (1.0_DP - ec) + q = fac1 * dm + fac2 = es**2 * fac1 - ec / 3.0_DP + x = q * (1.0_DP - 0.5_DP * fac1 * q * (es - q * fac2)) + y = x**2 + s = x * (a0 - y * (a1 - y * (a2 - y * (a3 - y * (a4 - y))))) / a0 + c = sqrt(1.0_DP - s**2) + f = x - ec * s + es * (1.0_DP - c) - dm + fp = 1.0_DP - ec * c + es * s + fpp = ec * s + es * c + fppp = ec * c - es * s + dx = -f / fp + dx = -f / (fp + dx * fpp / 2.0_DP) + dx = -f / (fp + dx * fpp / 2.0_DP + dx**2* fppp / 6.0_DP) + x = x + dx + y = x**2 + s = x * (a0 - y * (a1 - y * (a2 - y * (a3 - y * (a4 - y))))) / a0 + c = sqrt(1.0_DP - s**2) + + return + end subroutine drift_kepmd + + + pure subroutine drift_kepu(dt,r0,mu,alpha,u,fp,c1,c2,c3,iflag) + !! author: David A. Minton + !! + !! Solve Kepler's equation in universal variables + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu.f90 + !! Adapted from Hal Levison's Swift routine drift_kepu.f + implicit none + integer(I4B), intent(out) :: iflag + real(DP), intent(in) :: dt, r0, mu, alpha, u + real(DP), intent(out) :: fp, c1, c2, c3 + real(DP) :: s, st, fo, fn + + ! executable code + call drift_kepu_guess(dt, r0, mu, alpha, u, s) + st = s + call drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) + if (iflag /= 0) then + call drift_kepu_fchk(dt, r0, mu, alpha, u, st, fo) + call drift_kepu_fchk(dt, r0, mu, alpha, u, s, fn) + if (abs(fo) < abs(fn)) s = st + call drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) + end if + + return + end subroutine drift_kepu + + + pure subroutine drift_kepu_fchk(dt, r0, mu, alpha, u, s, f) + !! author: David A. Minton + !! + !! Computes the value of f, the function whose root we are trying to find in universal variables + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_fchk.f90 + !! Adapted from Martin Duncan's Swift routine drift_kepu_fchk.f + implicit none + real(DP), intent(in) :: dt, r0, mu, alpha, u, s + real(DP), intent(out) :: f + real(DP) :: x, c0, c1, c2, c3 + + x = s**2 * alpha + call drift_kepu_stumpff(x, c0, c1, c2, c3) + c1 = c1 * s + c2 = c2 * s**2 + c3 = c3 * s**3 + f = r0 * c1 + u * c2 + mu * c3 - dt + + return + end subroutine drift_kepu_fchk + + + pure subroutine drift_kepu_guess(dt, r0, mu, alpha, u, s) + !! author: David A. Minton + !! + !! Compute initial guess for solving Kepler's equation using universal variables + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_guess.f90 + !! Adapted from Hal Levison and Martin Duncan's Swift routine drift_kepu_guess.f + implicit none + real(DP), intent(in) :: dt, r0, mu, alpha, u + real(DP), intent(out) :: s + integer(I4B) :: iflag + real(DP), parameter :: thresh = 0.4_DP, danbyk = 0.85_DP + real(DP) :: y, sy, cy, sigma, es, x, a, en, ec, e + + if (alpha > 0.0_DP) then + if (dt / r0 <= thresh) then + s = dt / r0 - (dt**2 * u) / (2 * r0**3) + else + a = mu / alpha + en = sqrt(mu / a**3) + ec = 1.0_DP - r0 / a + es = u / (en * a**2) + e = sqrt(ec**2 + es**2) + y = en * dt - es + call orbel_scget(y, sy, cy) + sigma = sign(1.0_DP, es * cy + ec * sy) + x = y + sigma * danbyk * e + s = x / sqrt(alpha) + end if + else + call drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) + if (iflag /= 0) s = dt / r0 + end if + + return + end subroutine drift_kepu_guess + + + pure subroutine drift_kepu_lag(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) + !! author: David A. Minton + !! + !! Solve Kepler's equation in universal variables using Laguerre's method + !! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 178 - 180. + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_lag.f90 + !! Adapted from Hal Levison's Swift routine drift_kepu_lag.f + implicit none + integer(I4B), intent(out) :: iflag + real(DP), intent(in) :: dt, r0, mu, alpha, u + real(DP), intent(inout) :: s + real(DP), intent(out) :: fp, c1, c2, c3 + integer( I4B) :: nc, ncmax + real(DP) :: ln, x, fpp, ds, c0, f, fdt + + if (alpha < 0.0_DP) then + ncmax = NLAG2 + else + ncmax = NLAG1 + end if + ln = 5.0_DP + do nc = 0, ncmax + x = s * s * alpha + call drift_kepu_stumpff(x, c0, c1, c2, c3) + c1 = c1 * s + c2 = c2 * s**2 + c3 = c3 * s**3 + f = r0 * c1 + u * c2 + mu * c3 - dt + fp = r0 * c0 + u * c1 + mu * c2 + fpp = (-r0 * alpha + mu) * c1 + u * c0 + ds = -ln * f / (fp + sign(1.0_DP, fp) * sqrt(abs((ln - 1.0_DP)**2 * fp**2 - (ln - 1.0_DP) * ln * f * fpp))) + s = s + ds + fdt = f / dt + if (fdt**2 < DANBYB**2) then + iflag = 0 + return + end if + end do + iflag = 2 + + return + end subroutine drift_kepu_lag + + + pure subroutine drift_kepu_new(s, dt, r0, mu, alpha, u, fp, c1, c2, c3, iflag) + !! author: David A. Minton + !! + !! Solve Kepler's equation in universal variables using Newton's method + !! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 174 - 175. + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_new.f90 + !! Adapted from Hal Levison's Swift routine drift_kepu_new.f + implicit none + integer(I4B), intent(out) :: iflag + real(DP), intent(in) :: dt, r0, mu, alpha, u + real(DP), intent(inout) :: s + real(DP), intent(out) :: fp, c1, c2, c3 + integer( I4B) :: nc + real(DP) :: x, c0, ds, f, fpp, fppp, fdt + + do nc = 0, 6 + x = s**2 * alpha + call drift_kepu_stumpff(x, c0, c1, c2, c3) + c1 = c1 * s + c2 = c2 * s**2 + c3 = c3 * s**3 + f = r0 * c1 + u * c2 + mu * c3 - dt + fp = r0 * c0 + u * c1 + mu * c2 + fpp = (-r0 * alpha + mu) * c1 + u * c0 + fppp = (-r0 * alpha + mu) * c0 - u * alpha * c1 + ds = -f / fp + ds = -f / (fp + ds * fpp / 2.0_DP) + ds = -f / (fp + ds * fpp / 2.0_DP + ds**2 * fppp / 6.0_DP) + s = s + ds + fdt = f / dt + if (fdt**2 < DANBYB**2) then + iflag = 0 + return + end if + end do + iflag = 1 + + return + end subroutine drift_kepu_new + + + pure subroutine drift_kepu_p3solve(dt, r0, mu, alpha, u, s, iflag) + !! author: David A. Minton + !! + !! Computes real root of cubic involved in setting initial guess for solving Kepler's equation in universal variables + !! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 177 - 178. + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_p3solve.f90 + !! Adapted from Martin Duncan's Swift routine drift_kepu_p3solve.f + implicit none + integer(I4B), intent(out) :: iflag + real(DP), intent(in) :: dt, r0, mu, alpha, u + real(DP), intent(out) :: s + real(DP) :: denom, a0, a1, a2, q, r, sq2, sq, p1, p2 + + denom = (mu - alpha * r0) / 6.0_DP + a2 = 0.5_DP * u / denom + a1 = r0 / denom + a0 = -dt / denom + q = (a1 - a2**2 / 3.0_DP) / 3.0_DP + r = (a1 * a2 - 3 * a0) / 6.0_DP - a2**3 / 27.0_DP + sq2 = q**3 + r**2 + if (sq2 >= 0.0_DP) then + sq = sqrt(sq2) + if ((r + sq) <= 0.0_DP) then + p1 = -(-(r + sq))**(1.0_DP / 3.0_DP) + else + p1 = (r + sq)**(1.0_DP / 3.0_DP) + end if + if ((r - sq) <= 0.0_DP) then + p2 = -(-(r - sq))**(1.0_DP / 3.0_DP) + else + p2 = (r - sq)**(1.0_DP / 3.0_DP) + end if + iflag = 0 + s = p1 + p2 - a2 / 3.0_DP + else + iflag = 1 + s = 0.0_DP + end if + + return + end subroutine drift_kepu_p3solve + + + pure subroutine drift_kepu_stumpff(x, c0, c1, c2, c3) + !! author: David A. Minton + !! + !! Compute Stumpff functions needed for Kepler drift in universal variables + !! Reference: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 171 - 172. + !! + !! Adapted from David E. Kaufmann's Swifter routine: drift_kepu_stumpff.f90 + !! Adapted from Hal Levison's Swift routine drift_kepu_stumpff.f + implicit none + real(DP), intent(inout) :: x + real(DP), intent(out) :: c0, c1, c2, c3 + integer(I4B) :: i, n + real(DP) :: xm + + n = 0 + xm = 0.1_DP + do while (abs(x) >= xm) + n = n + 1 + x = x / 4.0_DP + end do + c2 = (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * & + (1.0_DP - x / 182.0_DP) / 132.0_DP) / 90.0_DP) / 56.0_DP) / & + 30.0_DP) / 12.0_DP) / 2.0_DP + c3 = (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * (1.0_DP - x * & + (1.0_DP - x / 210.0_DP) / 156.0_DP) / 110.0_DP) / 72.0_DP) / & + 42.0_DP) / 20.0_DP ) / 6.0_DP + c1 = 1.0_DP - x * c3 + c0 = 1.0_DP - x * c2 + if (n /= 0) then + do i = n, 1, -1 + c3 = (c2 + c0 * c3) / 4.0_DP + c2 = c1**2 / 2.0_DP + c1 = c0 * c1 + c0 = 2 * c0**2 - 1.0_DP + x = x * 4 + end do + end if + + return + end subroutine drift_kepu_stumpff + + +end submodule drift_implementation diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 new file mode 100644 index 000000000..af1646e4c --- /dev/null +++ b/src/eucl/eucl.f90 @@ -0,0 +1,38 @@ +submodule (swiftest_classes) s_eucl + use swiftest +contains + + module subroutine eucl_dist_index_plpl(self) + !! author: Jacob R. Elliott and David A. Minton + !! + !! Turns i,j indices into k index for use in the Euclidean distance matrix + !! + !! Reference: + !! + !! Mélodie Angeletti, Jean-Marie Bonny, Jonas Koko. Parallel Euclidean distance matrix computation on big datasets *. + !! 2019. hal-0204751 + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body objec + ! Internals + integer(I8B) :: i, j, counter, npl + + npl = int(self%nbody, kind=I8B) + associate(nplpl => self%nplpl) + nplpl = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column + if (allocated(self%k_plpl)) deallocate(self%k_plpl) ! Reset the index array if it's been set previously + allocate(self%k_plpl(2, nplpl)) + do i = 1, npl + counter = (i - 1_I8B) * npl - i * (i - 1_I8B) / 2_I8B + 1_I8B + do j = i + 1_I8B, npl + self%k_plpl(1, counter) = i + self%k_plpl(2, counter) = j + counter = counter + 1_I8B + end do + end do + end associate + + return + end subroutine eucl_dist_index_plpl + + end submodule s_eucl diff --git a/src/fragmentation/fragmentation.f90 b/src/fragmentation/fragmentation.f90 new file mode 100644 index 000000000..460060183 --- /dev/null +++ b/src/fragmentation/fragmentation.f90 @@ -0,0 +1,1114 @@ +submodule(swiftest_classes) s_fragmentation + use swiftest +contains + + module subroutine fragmentation_initialize(system, param, family, x, v, L_spin, Ip, mass, radius, & + nfrag, Ip_frag, m_frag, rad_frag, xb_frag, vb_frag, rot_frag, Qloss, lfailure) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Initialize the position and velocity of fragments to conserve energy and momentum. + use, intrinsic :: ieee_exceptions + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: system + class(swiftest_parameters), intent(in) :: param + integer(I4B), dimension(:), intent(in) :: family + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip + real(DP), dimension(:), intent(inout) :: mass, radius + integer(I4B), intent(inout) :: nfrag + real(DP), dimension(:), allocatable, intent(inout) :: m_frag, rad_frag + real(DP), dimension(:,:), allocatable, intent(inout) :: Ip_frag + real(DP), dimension(:,:), allocatable, intent(inout) :: xb_frag, vb_frag, rot_frag + logical, intent(out) :: lfailure ! Answers the question: Should this have been a merger instead? + real(DP), intent(inout) :: Qloss + ! Internals + real(DP) :: mscale, rscale, vscale, tscale, Lscale, Escale ! Scale factors that reduce quantities to O(~1) in the collisional system + real(DP) :: mtot + real(DP), dimension(NDIM) :: xcom, vcom + integer(I4B) :: ii + logical, dimension(:), allocatable :: lexclude + real(DP), dimension(NDIM, 2) :: rot, L_orb + real(DP), dimension(:,:), allocatable :: x_frag, v_frag, v_r_unit, v_t_unit, v_h_unit + real(DP), dimension(:), allocatable :: rmag, rotmag, v_r_mag, v_t_mag + real(DP), dimension(NDIM) :: Ltot_before + real(DP), dimension(NDIM) :: Ltot_after + real(DP) :: Etot_before, ke_orbit_before, ke_spin_before, pe_before, Lmag_before + real(DP) :: Etot_after, ke_orbit_after, ke_spin_after, pe_after, Lmag_after, dEtot, dLmag + real(DP), dimension(NDIM) :: L_frag_tot, L_frag_orb + real(DP) :: ke_frag_budget, ke_frag_orbit, ke_radial, ke_frag_spin, ke_avg_deficit, ke_avg_deficit_old + real(DP), dimension(NDIM) :: x_col_unit, y_col_unit, z_col_unit + character(len=*), parameter :: fmtlabel = "(A14,10(ES11.4,1X,:))" + integer(I4B) :: try, subtry + integer(I4B), parameter :: NFRAG_MIN = 7 !! The minimum allowable number of fragments (set to 6 because that's how many unknowns are needed in the tangential velocity calculation) + real(DP) :: r_max_start, r_max_start_old, r_max, f_spin + real(DP), parameter :: Ltol = 10 * epsilon(1.0_DP) + real(DP), parameter :: Etol = 1e-10_DP + integer(I4B), parameter :: MAXTRY = 3000 + integer(I4B), parameter :: TANTRY = 3 + logical, dimension(size(IEEE_ALL)) :: fpe_halting_modes, fpe_quiet_modes + + if (nfrag < NFRAG_MIN) then + write(*,*) "symba_frag_pos needs at least ",NFRAG_MIN," fragments, but only ",nfrag," were given." + lfailure = .true. + return + end if + + call ieee_get_halting_mode(IEEE_ALL,fpe_halting_modes) ! Save the current halting modes so we can turn them off temporarily + fpe_quiet_modes(:) = .false. + call ieee_set_halting_mode(IEEE_ALL,fpe_quiet_modes) + + f_spin = 0.05_DP + mscale = 1.0_DP + rscale = 1.0_DP + vscale = 1.0_DP + tscale = 1.0_DP + Lscale = 1.0_DP + Escale = 1.0_DP + + associate(npl => system%pl%nbody, status => system%pl%status) + allocate(lexclude(npl)) + where (status(1:npl) == INACTIVE) ! Safety check in case one of the included bodies has been previously deactivated + lexclude(1:npl) = .true. + elsewhere + lexclude(1:npl) = .false. + end where + end associate + + allocate(x_frag, source=xb_frag) + allocate(v_frag, source=vb_frag) + + call set_scale_factors() + call define_coordinate_system() + call calculate_system_energy(linclude_fragments=.false.) + + r_max_start = norm2(x(:,2) - x(:,1)) + try = 1 + lfailure = .false. + ke_avg_deficit = 0.0_DP + do while (try < MAXTRY) + lfailure = .false. + ke_avg_deficit_old = ke_avg_deficit + ke_avg_deficit = 0.0_DP + subtry = 1 + do + call set_fragment_position_vectors() + call set_fragment_tan_vel(lfailure) + ke_avg_deficit = ke_avg_deficit - ke_radial + subtry = subtry + 1 + if (.not.lfailure .or. subtry == TANTRY) exit + !write(*,*) 'Trying new arrangement' + end do + ke_avg_deficit = ke_avg_deficit / subtry + if (lfailure) write(*,*) 'Failed to find tangential velocities' + + if (.not.lfailure) then + call set_fragment_radial_velocities(lfailure) + if (lfailure) write(*,*) 'Failed to find radial velocities' + if (.not.lfailure) then + call calculate_system_energy(linclude_fragments=.true.) + !write(*,*) 'Qloss : ',Qloss + !write(*,*) '-dEtot: ',-dEtot + !write(*,*) 'delta : ',abs((dEtot + Qloss)) + if ((abs(dEtot + Qloss) > Etol) .or. (dEtot > 0.0_DP)) then + write(*,*) 'Failed due to high energy error: ',dEtot, abs(dEtot + Qloss) / Etol + lfailure = .true. + else if (abs(dLmag) / Lmag_before > Ltol) then + write(*,*) 'Failed due to high angular momentum error: ', dLmag / Lmag_before + lfailure = .true. + end if + end if + end if + + if (.not.lfailure) exit + call restructure_failed_fragments() + try = try + 1 + end do + write(*, "(' -------------------------------------------------------------------------------------')") + write(*, "(' Final diagnostic')") + write(*, "(' -------------------------------------------------------------------------------------')") + if (lfailure) then + write(*,*) "symba_frag_pos failed after: ",try," tries" + do ii = 1, nfrag + vb_frag(:, ii) = vcom(:) + end do + else + write(*,*) "symba_frag_pos succeeded after: ",try," tries" + write(*, "(' dL_tot should be very small' )") + write(*,fmtlabel) ' dL_tot |', dLmag / Lmag_before + write(*, "(' dE_tot should be negative and equal to Qloss' )") + write(*,fmtlabel) ' dE_tot |', dEtot / abs(Etot_before) + write(*,fmtlabel) ' Qloss |', -Qloss / abs(Etot_before) + write(*,fmtlabel) ' dE - Qloss |', (Etot_after - Etot_before + Qloss) / abs(Etot_before) + end if + write(*, "(' -------------------------------------------------------------------------------------')") + + call restore_scale_factors() + call ieee_set_halting_mode(IEEE_ALL,fpe_halting_modes) ! Save the current halting modes so we can turn them off temporarily + + return + + contains + + ! Because of the complexity of this procedure, we have chosen to break it up into a series of nested subroutines. + + subroutine set_scale_factors() + !! author: David A. Minton + !! + !! Scales dimenional quantities to ~O(1) with respect to the collisional system. This scaling makes it easier for the non-linear minimization + !! to converge on a solution + implicit none + integer(I4B) :: i + + ! Find the center of mass of the collisional system + mtot = sum(mass(:)) + xcom(:) = (mass(1) * x(:,1) + mass(2) * x(:,2)) / mtot + vcom(:) = (mass(1) * v(:,1) + mass(2) * v(:,2)) / mtot + + ! Set scale factors + !! Because of the implied G, mass is actually G*mass with units of distance**3 / time**2 + Escale = 0.5_DP * (mass(1) * dot_product(v(:,1), v(:,1)) + mass(2) * dot_product(v(:,2), v(:,2))) + rscale = sum(radius(:)) + mscale = sqrt(Escale * rscale) + vscale = sqrt(Escale / mscale) + tscale = rscale / vscale + Lscale = mscale * rscale * vscale + + xcom(:) = xcom(:) / rscale + vcom(:) = vcom(:) / vscale + + mtot = mtot / mscale + mass = mass / mscale + radius = radius / rscale + x = x / rscale + v = v / vscale + L_spin = L_spin / Lscale + do i = 1, 2 + rot(:,i) = L_spin(:,i) / (mass(i) * radius(i)**2 * Ip(3, i)) + end do + + m_frag = m_frag / mscale + rad_frag = rad_frag / rscale + Qloss = Qloss / Escale + + return + end subroutine set_scale_factors + + subroutine restore_scale_factors() + !! author: David A. Minton + !! + !! Restores dimenional quantities back to the system units + implicit none + integer(I4B) :: i + + call ieee_set_halting_mode(IEEE_ALL,.false.) + ! Restore scale factors + xcom(:) = xcom(:) * rscale + vcom(:) = vcom(:) * vscale + + mtot = mtot * mscale + mass = mass * mscale + radius = radius * rscale + x = x * rscale + v = v * vscale + L_spin = L_spin * Lscale + do i = 1, 2 + rot(:,i) = L_spin(:,i) * (mass(i) * radius(i)**2 * Ip(3, i)) + end do + + m_frag = m_frag * mscale + rad_frag = rad_frag * rscale + rot_frag = rot_frag / tscale + x_frag = x_frag * rscale + v_frag = v_frag * vscale + Qloss = Qloss * Escale + + do i = 1, nfrag + xb_frag(:, i) = x_frag(:, i) + xcom(:) + vb_frag(:, i) = v_frag(:, i) + vcom(:) + end do + + Etot_before = Etot_before * Escale + pe_before = pe_before * Escale + ke_spin_before = ke_spin_before * Escale + ke_orbit_before = ke_orbit_before * Escale + Ltot_before = Ltot_before * Lscale + Lmag_before = Lmag_before * Lscale + Etot_after = Etot_after * Escale + pe_after = pe_after * Escale + ke_spin_after = ke_spin_after * Escale + ke_orbit_after = ke_orbit_after * Escale + Ltot_after = Ltot_after * Lscale + Lmag_after = Lmag_after * Lscale + + mscale = 1.0_DP + rscale = 1.0_DP + vscale = 1.0_DP + tscale = 1.0_DP + Lscale = 1.0_DP + Escale = 1.0_DP + + return + end subroutine restore_scale_factors + + subroutine define_coordinate_system() + !! author: David A. Minton + !! + !! Defines the collisional coordinate system, including the unit vectors of both the system and individual fragments. + implicit none + integer(I4B) :: i + real(DP), dimension(NDIM) :: x_cross_v, xc, vc, delta_r, delta_v + real(DP) :: r_col_norm, v_col_norm + + allocate(rmag(nfrag)) + allocate(rotmag(nfrag)) + allocate(v_r_mag(nfrag)) + allocate(v_t_mag(nfrag)) + allocate(v_r_unit(NDIM,nfrag)) + allocate(v_t_unit(NDIM,nfrag)) + allocate(v_h_unit(NDIM,nfrag)) + + rmag(:) = 0.0_DP + rotmag(:) = 0.0_DP + v_r_mag(:) = 0.0_DP + v_t_mag(:) = 0.0_DP + v_r_unit(:,:) = 0.0_DP + v_t_unit(:,:) = 0.0_DP + v_h_unit(:,:) = 0.0_DP + + L_orb(:, :) = 0.0_DP + ! Compute orbital angular momentum of pre-impact system + do i = 1, 2 + xc(:) = x(:, i) - xcom(:) + vc(:) = v(:, i) - vcom(:) + x_cross_v(:) = xc(:) .cross. vc(:) + L_orb(:, i) = mass(i) * x_cross_v(:) + end do + + ! Compute orbital angular momentum of pre-impact system. This will be the normal vector to the collision fragment plane + L_frag_tot(:) = L_spin(:, 1) + L_spin(:, 2) + L_orb(:, 1) + L_orb(:, 2) + + delta_v(:) = v(:, 2) - v(:, 1) + v_col_norm = norm2(delta_v(:)) + delta_r(:) = x(:, 2) - x(:, 1) + r_col_norm = norm2(delta_r(:)) + + ! We will initialize fragments on a plane defined by the pre-impact system, with the z-axis aligned with the angular momentum vector + ! and the y-axis aligned with the pre-impact distance vector. + y_col_unit(:) = delta_r(:) / r_col_norm + z_col_unit(:) = L_frag_tot(:) / norm2(L_frag_tot) + ! The cross product of the y- by z-axis will give us the x-axis + x_col_unit(:) = y_col_unit(:) .cross. z_col_unit(:) + + return + end subroutine define_coordinate_system + + subroutine calculate_system_energy(linclude_fragments) + !! Author: David A. Minton + !! + !! Calculates total system energy, including all bodies in the pl list that do not have a corresponding value of the lexclude array that is true + !! and optionally including fragments. + implicit none + ! Arguments + logical, intent(in) :: linclude_fragments + ! Internals + integer(I4B) :: i, npl_new, nplm + logical, dimension(:), allocatable :: ltmp + logical :: lk_plpl + class(swiftest_nbody_system), allocatable :: tmpsys + + ! Because we're making a copy of symba_pl with the excludes/fragments appended, we need to deallocate the + ! big k_plpl array and recreate it when we're done, otherwise we run the risk of blowing up the memory by + ! allocating two of these ginormous arrays simulteouously. This is not particularly efficient, but as this + ! subroutine should be called relatively infrequently, it shouldn't matter too much. + !if (allocated(pl%k_plpl)) deallocate(pl%k_plpl) + + ! Build the internal planet list out of the non-excluded bodies and optionally with fragments appended. This + ! will get passed to the energy calculation subroutine so that energy is computed exactly the same way is it + ! is in the main program. + associate(pl => system%pl, npl => system%pl%nbody, cb => system%cb) + lk_plpl = allocated(pl%k_plpl) + if (lk_plpl) deallocate(pl%k_plpl) + if (linclude_fragments) then ! Temporarily expand the planet list to feed it into symba_energy + lexclude(family(:)) = .true. + npl_new = npl + nfrag + else + npl_new = npl + end if + call setup_construct_system(tmpsys, param) + deallocate(tmpsys%cb) + allocate(tmpsys%cb, source=cb) + allocate(ltmp(npl)) + ltmp(:) = .true. + call tmpsys%pl%setup(npl_new, param) + call tmpsys%pl%fill(pl, ltmp) + deallocate(ltmp) + + if (linclude_fragments) then ! Append the fragments if they are included + ! Energy calculation requires the fragments to be in the system barcyentric frame, s + tmpsys%pl%mass(npl+1:npl_new) = m_frag(1:nfrag) + tmpsys%pl%radius(npl+1:npl_new) = rad_frag(1:nfrag) + tmpsys%pl%xb(:,npl+1:npl_new) = xb_frag(:,1:nfrag) + tmpsys%pl%vb(:,npl+1:npl_new) = vb_frag(:,1:nfrag) + tmpsys%pl%status(npl+1:npl_new) = COLLISION + if (param%lrotation) then + tmpsys%pl%Ip(:,npl+1:npl_new) = Ip_frag(:,1:nfrag) + tmpsys%pl%rot(:,npl+1:npl_new) = rot_frag(:,1:nfrag) + end if + call tmpsys%pl%b2h(tmpsys%cb) + allocate(ltmp(npl_new)) + ltmp(1:npl) = lexclude(1:npl) + ltmp(npl+1:npl_new) = .false. + call move_alloc(ltmp, lexclude) + end if + + where (lexclude(1:npl_new)) + tmpsys%pl%status(1:npl_new) = INACTIVE + end where + + select type(plwksp => tmpsys%pl) + class is (symba_pl) + select type(param) + class is (symba_parameters) + plwksp%nplm = count(plwksp%Gmass > param%mtiny / mscale) + end select + end select + call tmpsys%pl%eucl_index() + call tmpsys%get_energy_and_momentum(param) + + ! Restore the big array + deallocate(tmpsys%pl%k_plpl) + select type(pl) + class is (symba_pl) + select type(param) + class is (symba_parameters) + nplm = count(pl%mass > param%mtiny) + end select + end select + if (lk_plpl) call pl%eucl_index() + + ! Calculate the current fragment energy and momentum balances + if (linclude_fragments) then + Ltot_after(:) = tmpsys%Lorbit(:) + tmpsys%Lspin(:) + Lmag_after = norm2(Ltot_after(:)) + ke_orbit_after = tmpsys%ke_orbit + ke_spin_after = tmpsys%ke_spin + pe_after = tmpsys%pe + Etot_after = ke_orbit_after + ke_spin_after + pe_after + dEtot = Etot_after - Etot_before + dLmag = norm2(Ltot_after(:) - Ltot_before(:)) + else + Ltot_before(:) = tmpsys%Lorbit(:) + tmpsys%Lspin(:) + Lmag_before = norm2(Ltot_before(:)) + ke_orbit_before = tmpsys%ke_orbit + ke_spin_before = tmpsys%ke_spin + pe_before = tmpsys%pe + Etot_before = ke_orbit_before + ke_spin_before + pe_before + end if + end associate + return + end subroutine calculate_system_energy + + subroutine shift_vector_to_origin(m_frag, vec_frag) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Adjusts the position or velocity of the fragments as needed to align them with the origin + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: m_frag !! Fragment masses + real(DP), dimension(:,:), intent(inout) :: vec_frag !! Fragment positions or velocities in the center of mass frame + + ! Internals + real(DP), dimension(NDIM) :: mvec_frag, COM_offset + integer(I4B) :: i + + mvec_frag(:) = 0.0_DP + + do i = 1, nfrag + mvec_frag = mvec_frag(:) + vec_frag(:,i) * m_frag(i) + end do + COM_offset(:) = -mvec_frag(:) / mtot + do i = 1, nfrag + vec_frag(:, i) = vec_frag(:, i) + COM_offset(:) + end do + + return + end subroutine shift_vector_to_origin + + subroutine set_fragment_position_vectors() + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Initializes the orbits of the fragments around the center of mass. The fragments are initially placed on a plane defined by the + !! pre-impact angular momentum. They are distributed on an ellipse surrounding the center of mass. + !! The initial positions do not conserve energy or momentum, so these need to be adjusted later. + + implicit none + real(DP) :: dis, rad + real(DP), dimension(NDIM) :: L_sigma + logical, dimension(:), allocatable :: loverlap + integer(I4B) :: i, j + + allocate(loverlap(nfrag)) + + ! Place the fragments into a region that is big enough that we should usually not have overlapping bodies + ! An overlapping bodies will collide in the next time step, so it's not a major problem if they do (it just slows the run down) + r_max = r_max_start + rad = sum(radius(:)) + + ! We will treat the first two fragments of the list as special cases. They get initialized the maximum distances apart along the original impactor distance vector. + ! This is done because in a regular disruption, the first body is the largest, the second the second largest, and the rest are smaller equal-mass fragments. + + call random_number(x_frag(:,3:nfrag)) + loverlap(:) = .true. + do while (any(loverlap(3:nfrag))) + x_frag(:, 1) = x(:, 1) - xcom(:) + x_frag(:, 2) = x(:, 2) - xcom(:) + r_max = r_max + 0.1_DP * rad + do i = 3, nfrag + if (loverlap(i)) then + call random_number(x_frag(:,i)) + x_frag(:, i) = 2 * (x_frag(:, i) - 0.5_DP) * r_max + end if + end do + loverlap(:) = .false. + do j = 1, nfrag + do i = j + 1, nfrag + dis = norm2(x_frag(:,j) - x_frag(:,i)) + loverlap(i) = loverlap(i) .or. (dis <= (rad_frag(i) + rad_frag(j))) + end do + end do + end do + call shift_vector_to_origin(m_frag, x_frag) + + do i = 1, nfrag + rmag(i) = norm2(x_frag(:, i)) + v_r_unit(:, i) = x_frag(:, i) / rmag(i) + call random_number(L_sigma(:)) ! Randomize the tangential velocity direction. This helps to ensure that the tangential velocity doesn't completely line up with the angular momentum vector, + ! otherwise we can get an ill-conditioned system + v_h_unit(:, i) = z_col_unit(:) + 2e-1_DP * (L_sigma(:) - 0.5_DP) + v_h_unit(:, i) = v_h_unit(:, i) / norm2(v_h_unit(:, i)) + v_t_unit(:, i) = v_h_unit(:, i) .cross. v_r_unit(:, i) + xb_frag(:,i) = x_frag(:,i) + xcom(:) + end do + + return + end subroutine set_fragment_position_vectors + + subroutine set_fragment_tan_vel(lerr) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Adjusts the tangential velocities and spins of a collection of fragments such that they conserve angular momentum without blowing the fragment kinetic energy budget. + !! This procedure works in several stages, with a goal to solve the angular and linear momentum constraints on the fragments, while still leaving a positive balance of + !! our fragment kinetic energy (ke_frag_budget) that we can put into the radial velocity distribution. + !! + !! The first thing we'll try to do is solve for the tangential velocities of the first 6 fragments, using angular and linear momentum as constraints and an initial + !! tangential velocity distribution for the remaining bodies (if there are any) that distributes their angular momentum equally between them. + !! If that doesn't work and we blow our kinetic energy budget, we will attempt to find a tangential velocity distribution that minimizes the kinetic energy while + !! conserving momentum. + !! + !! A failure will trigger a restructuring of the fragments so we will try new values of the radial position distribution. + implicit none + ! Arguments + logical, intent(out) :: lerr + ! Internals + integer(I4B) :: i + real(DP), parameter :: TOL = 1e-4_DP + real(DP), dimension(:), allocatable :: v_t_initial + type(lambda_obj) :: spinfunc + type(lambda_obj_err) :: objective_function + real(DP), dimension(NDIM) :: L_frag_spin, L_remainder, Li, rot_L, rot_ke + + ! Initialize the fragments with 0 velocity and spin so we can divide up the balance between the tangential, radial, and spin components while conserving momentum + lerr = .false. + vb_frag(:,:) = 0.0_DP + rot_frag(:,:) = 0.0_DP + v_t_mag(:) = 0.0_DP + v_r_mag(:) = 0.0_DP + + call calculate_system_energy(linclude_fragments=.true.) + ke_frag_budget = -dEtot - Qloss + !write(*,*) '***************************************************' + !write(*,*) 'Original dis : ',norm2(x(:,2) - x(:,1)) + !write(*,*) 'r_max : ',r_max + !write(*,*) 'f_spin : ',f_spin + !write(*,*) '***************************************************' + !write(*,*) 'Energy balance so far: ' + !write(*,*) 'ke_frag_budget : ',ke_frag_budget + !write(*,*) 'ke_orbit_before: ',ke_orbit_before + !write(*,*) 'ke_orbit_after : ',ke_orbit_after + !write(*,*) 'ke_spin_before : ',ke_spin_before + !write(*,*) 'ke_spin_after : ',ke_spin_after + !write(*,*) 'pe_before : ',pe_before + !write(*,*) 'pe_after : ',pe_after + !write(*,*) 'Qloss : ',Qloss + !write(*,*) '***************************************************' + if (ke_frag_budget < 0.0_DP) then + write(*,*) 'Negative ke_frag_budget: ',ke_frag_budget + r_max_start = r_max_start / 2 + lerr = .true. + return + end if + + allocate(v_t_initial, mold=v_t_mag) + + L_frag_spin(:) = 0.0_DP + ke_frag_spin = 0.0_DP + ! Start the first two bodies with the same rotation as the original two impactors, then distribute the remaining angular momentum among the rest + do i = 1, 2 + rot_frag(:, i) = rot(:, i) + L_frag_spin(:) = L_frag_spin(:) + m_frag(i) * rad_frag(i)**2 * Ip_frag(3, i) * rot_frag(:, i) + end do + L_frag_orb(:) = L_frag_tot(:) - L_frag_spin(:) + L_frag_spin(:) = 0.0_DP + do i = 1, nfrag + ! Convert a fraction (f_spin) of either the remaining angular momentum or kinetic energy budget into spin, whichever gives the smaller rotation so as not to blow any budgets + rot_ke(:) = sqrt(2 * f_spin * ke_frag_budget / (nfrag * m_frag(i) * rad_frag(i)**2 * Ip_frag(3, i))) * L_frag_orb(:) / norm2(L_frag_orb(:)) + rot_L(:) = f_spin * L_frag_orb(:) / (nfrag * m_frag(i) * rad_frag(i)**2 * Ip_frag(3, i)) + if (norm2(rot_ke) < norm2(rot_L)) then + rot_frag(:,i) = rot_frag(:, i) + rot_ke(:) + else + rot_frag(:, i) = rot_frag(:, i) + rot_L(:) + end if + L_frag_spin(:) = L_frag_spin(:) + m_frag(i) * rad_frag(i)**2 * Ip_frag(3, i) * rot_frag(:, i) + ke_frag_spin = ke_frag_spin + m_frag(i) * Ip_frag(3, i) * rad_frag(i)**2 * dot_product(rot_frag(:, i), rot_frag(:, i)) + end do + ke_frag_spin = 0.5_DP * ke_frag_spin + ! Convert a fraction of the pre-impact angular momentum into fragment spin angular momentum + L_frag_orb(:) = L_frag_tot(:) - L_frag_spin(:) + L_remainder(:) = L_frag_orb(:) + ! Next we will solve for the tangential component of the velocities that both conserves linear momentum and uses the remaining angular momentum not used in spin. + ! This will be done using a linear solver that solves for the tangential velocities of the first 6 fragments, constrained by the linear and angular momentum vectors, + ! which is embedded in a non-linear minimizer that will adjust the tangential velocities of the remaining i>6 fragments to minimize kinetic energy for a given momentum solution + ! The initial conditions fed to the minimizer for the fragments will be the remaining angular momentum distributed between the fragments. + do i = 1, nfrag + v_t_initial(i) = norm2(L_remainder(:)) / ((nfrag - i + 1) * m_frag(i) * norm2(x_frag(:,i))) + Li(:) = m_frag(i) * x_frag(:,i) .cross. v_t_initial(i) * v_t_unit(:, i) + L_remainder(:) = L_remainder(:) - Li(:) + end do + + ! Find the local kinetic energy minimum for the system that conserves linear and angular momentum + objective_function = lambda_obj(tangential_objective_function, lerr) + v_t_mag(7:nfrag) = util_minimize_bfgs(objective_function, nfrag-6, v_t_initial(7:nfrag), TOL, lerr) + ! Now that the KE-minimized values of the i>6 fragments are found, calculate the momentum-conserving solution for tangential velociteis + v_t_initial(7:nfrag) = v_t_mag(7:nfrag) + v_t_mag(1:nfrag) = solve_fragment_tan_vel(v_t_mag_input=v_t_initial(7:nfrag), lerr=lerr) + + ! Perform one final shift of the radial velocity vectors to align with the center of mass of the collisional system (the origin) + vb_frag(:,1:nfrag) = vmag_to_vb(v_r_mag(1:nfrag), v_r_unit(:,1:nfrag), v_t_mag(1:nfrag), v_t_unit(:,1:nfrag), m_frag(1:nfrag), vcom(:)) + ! Now do a kinetic energy budget check to make sure we are still within the budget. + ke_frag_orbit = 0.0_DP + do i = 1, nfrag + v_frag(:, i) = vb_frag(:, i) - vcom(:) + ke_frag_orbit = ke_frag_orbit + m_frag(i) * dot_product(vb_frag(:, i), vb_frag(:, i)) + end do + ke_frag_orbit = 0.5_DP * ke_frag_orbit + ke_radial = ke_frag_budget - ke_frag_orbit - ke_frag_spin + + ! If we are over the energy budget, flag this as a failure so we can try again + lerr = (ke_radial < 0.0_DP) + !write(*,*) 'Tangential' + !write(*,*) 'ke_frag_budget: ',ke_frag_budget + !write(*,*) 'ke_frag_orbit : ',ke_frag_orbit + !write(*,*) 'ke_frag_spin : ',ke_frag_spin + !write(*,*) 'ke_radial : ',ke_radial + + return + + end subroutine set_fragment_tan_vel + + function tangential_objective_function(v_t_mag_input, lerr) result(fval) + !! Author: David A. Minton + !! + !! Objective function for evaluating how close our fragment velocities get to minimizing KE error from our required value + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: v_t_mag_input !! Unknown tangential component of velocity vector set previously by angular momentum constraint + logical, intent(out) :: lerr !! Error flag + ! Result + real(DP) :: fval + ! Internals + integer(I4B) :: i + real(DP), dimension(:,:), allocatable :: v_shift + real(DP), dimension(:), allocatable :: v_t_new + real(DP) :: keo + + lerr = .false. + + allocate(v_shift(NDIM, nfrag)) + allocate(v_t_new(nfrag)) + + v_t_new(:) = solve_fragment_tan_vel(v_t_mag_input=v_t_mag_input(:), lerr=lerr) + v_shift(:,:) = vmag_to_vb(v_r_mag, v_r_unit, v_t_new, v_t_unit, m_frag, vcom) + + keo = 0.0_DP + do i = 1, nfrag + keo = keo + m_frag(i) * dot_product(v_shift(:, i), v_shift(:, i)) + end do + keo = 0.5_DP * keo + fval = keo + lerr = .false. + return + end function tangential_objective_function + + function solve_fragment_tan_vel(lerr, v_t_mag_input) result(v_t_mag_output) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Adjusts the positions, velocities, and spins of a collection of fragments such that they conserve angular momentum + implicit none + ! Arguments + logical, intent(out) :: lerr !! Error flag + real(DP), dimension(:), optional, intent(in) :: v_t_mag_input !! Unknown tangential velocities for fragments 7:nfrag + ! Internals + integer(I4B) :: i + ! Result + real(DP), dimension(:), allocatable :: v_t_mag_output + + real(DP), dimension(2 * NDIM, 2 * NDIM) :: A ! LHS of linear equation used to solve for momentum constraint in Gauss elimination code + real(DP), dimension(2 * NDIM) :: b ! RHS of linear equation used to solve for momentum constraint in Gauss elimination code + real(DP), dimension(NDIM) :: L_lin_others, L_orb_others, L, vtmp + + v_frag(:,:) = 0.0_DP + lerr = .false. + + ! We have 6 constraint equations (2 vector constraints in 3 dimensions each) + ! The first 3 are that the linear momentum of the fragments is zero with respect to the collisional barycenter + ! The second 3 are that the sum of the angular momentum of the fragments is conserved from the pre-impact state + L_lin_others(:) = 0.0_DP + L_orb_others(:) = 0.0_DP + do i = 1, nfrag + if (i <= 2 * NDIM) then ! The tangential velocities of the first set of bodies will be the unknowns we will solve for to satisfy the constraints + A(1:3, i) = m_frag(i) * v_t_unit(:, i) + L(:) = v_r_unit(:, i) .cross. v_t_unit(:, i) + A(4:6, i) = m_frag(i) * rmag(i) * L(:) + else if (present(v_t_mag_input)) then + vtmp(:) = v_t_mag_input(i - 6) * v_t_unit(:, i) + L_lin_others(:) = L_lin_others(:) + m_frag(i) * vtmp(:) + L(:) = x_frag(:, i) .cross. vtmp(:) + L_orb_others(:) = L_orb_others(:) + m_frag(i) * L(:) + end if + end do + b(1:3) = -L_lin_others(:) + b(4:6) = L_frag_orb(:) - L_orb_others(:) + allocate(v_t_mag_output(nfrag)) + v_t_mag_output(1:6) = util_solve_linear_system(A, b, 6, lerr) + if (present(v_t_mag_input)) v_t_mag_output(7:nfrag) = v_t_mag_input(:) + + return + end function solve_fragment_tan_vel + + subroutine set_fragment_radial_velocities(lerr) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! + !! Adjust the fragment velocities to set the fragment orbital kinetic energy. This will minimize the difference between the fragment kinetic energy and the energy budget + implicit none + ! Arguments + logical, intent(out) :: lerr + ! Internals + real(DP), parameter :: TOL = 1e-10_DP + integer(I4B) :: i, j + real(DP), dimension(:), allocatable :: v_r_initial, v_r_sigma + real(DP), dimension(:,:), allocatable :: v_r + type(lambda_obj) :: objective_function + + ! Set the "target" ke_orbit_after (the value of the orbital kinetic energy that the fragments ought to have) + + allocate(v_r_initial, source=v_r_mag) + ! Initialize radial velocity magnitudes with a random value that is approximately 10% of that found by distributing the kinetic energy equally + allocate(v_r_sigma, source=v_r_mag) + call random_number(v_r_sigma(1:nfrag)) + v_r_sigma(1:nfrag) = sqrt(1.0_DP + 2 * (v_r_sigma(1:nfrag) - 0.5_DP) * 1e-4_DP) + v_r_initial(1:nfrag) = v_r_sigma(1:nfrag) * sqrt(abs(ke_radial) / (2 * m_frag(1:nfrag) * nfrag)) + + ! Initialize the lambda function using a structure constructor that calls the init method + ! Minimize the ke objective function using the BFGS optimizer + objective_function = lambda_obj(radial_objective_function) + v_r_mag = util_minimize_bfgs(objective_function, nfrag, v_r_initial, TOL, lerr) + ! Shift the radial velocity vectors to align with the center of mass of the collisional system (the origin) + vb_frag(:,1:nfrag) = vmag_to_vb(v_r_mag(1:nfrag), v_r_unit(:,1:nfrag), v_t_mag(1:nfrag), v_t_unit(:,1:nfrag), m_frag(1:nfrag), vcom(:)) + do i = 1, nfrag + v_frag(:, i) = vb_frag(:, i) - vcom(:) + end do + ke_frag_orbit = 0.0_DP + do i = 1, nfrag + ke_frag_orbit = ke_frag_orbit + m_frag(i) * dot_product(vb_frag(:, i), vb_frag(:, i)) + end do + ke_frag_orbit = 0.5_DP * ke_frag_orbit + !write(*,*) 'Radial' + !write(*,*) 'Failure? ',lerr + !write(*,*) 'ke_frag_budget: ',ke_frag_budget + !write(*,*) 'ke_frag_orbit : ',ke_frag_orbit + !write(*,*) 'ke_frag_spin : ',ke_frag_spin + !write(*,*) 'ke_remainder : ',ke_frag_budget - (ke_frag_orbit + ke_frag_spin) + lerr = .false. + + return + end subroutine set_fragment_radial_velocities + + function radial_objective_function(v_r_mag_input) result(fval) + !! Author: David A. Minton + !! + !! Objective function for evaluating how close our fragment velocities get to minimizing KE error from our required value + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: v_r_mag_input !! Unknown radial component of fragment velocity vector + ! Result + real(DP) :: fval !! The objective function result, which is the square of the difference between the calculated fragment kinetic energy and our target + !! Minimizing this brings us closer to our objective + ! Internals + integer(I4B) :: i + real(DP), dimension(:,:), allocatable :: v_shift + + allocate(v_shift, mold=vb_frag) + v_shift(:,:) = vmag_to_vb(v_r_mag_input, v_r_unit, v_t_mag, v_t_unit, m_frag, vcom) + fval = 2 * ke_frag_budget + do i = 1, nfrag + fval = fval - m_frag(i) * (Ip_frag(3, i) * rad_frag(i)**2 * dot_product(rot_frag(:, i), rot_frag(:, i)) + dot_product(v_shift(:, i), v_shift(:, i))) + end do + ! The following ensures that fval = 0 is a local minimum, which is what the BFGS method is searching for + fval = (fval / (2 * ke_radial))**2 + + return + + end function radial_objective_function + + function vmag_to_vb(v_r_mag, v_r_unit, v_t_mag, v_t_unit, m_frag, vcom) result(vb) + !! Author: David A. Minton + !! + !! Converts radial and tangential velocity magnitudes into barycentric velocity + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: v_r_mag !! Unknown radial component of fragment velocity vector + real(DP), dimension(:), intent(in) :: v_t_mag !! Tangential component of velocity vector set previously by angular momentum constraint + real(DP), dimension(:,:), intent(in) :: v_r_unit, v_t_unit !! Radial and tangential unit vectors for each fragment + real(DP), dimension(:), intent(in) :: m_frag !! Fragment masses + real(DP), dimension(:), intent(in) :: vcom !! Barycentric velocity of collisional system center of mass + ! Result + real(DP), dimension(:,:), allocatable :: vb + ! Internals + integer(I4B) :: i + + allocate(vb, mold=v_r_unit) + ! Make sure the velocity magnitude stays positive + do i = 1, nfrag + vb(:,i) = abs(v_r_mag(i)) * v_r_unit(:, i) + end do + ! In order to keep satisfying the kinetic energy constraint, we must shift the origin of the radial component of the velocities to the center of mass + call shift_vector_to_origin(m_frag, vb) + + do i = 1, nfrag + vb(:, i) = vb(:, i) + v_t_mag(i) * v_t_unit(:, i) + vcom(:) + end do + + end function vmag_to_vb + + subroutine restructure_failed_fragments() + !! Author: David A. Minton + !! + !! We failed to find a set of positions and velocities that satisfy all the constraints, and so we will alter the fragments and try again. + implicit none + integer(I4B) :: i + real(DP), dimension(:), allocatable :: m_frag_new, rad_frag_new + real(DP), dimension(:,:), allocatable :: xb_frag_new, vb_frag_new, Ip_frag_new, rot_frag_new + real(DP) :: delta_r, delta_r_max + real(DP), parameter :: ke_avg_deficit_target = 0.0_DP + + ! Introduce a bit of noise in the radius determination so we don't just flip flop between similar failed positions + call random_number(delta_r_max) + delta_r_max = sum(radius(:)) * (1.0_DP + 2e-1_DP * (delta_r_max - 0.5_DP)) + if (try > 2) then + ! Linearly interpolate the last two failed solution ke deficits to find a new distance value to try + delta_r = (r_max_start - r_max_start_old) * (ke_avg_deficit_target - ke_avg_deficit_old) / (ke_avg_deficit - ke_avg_deficit_old) + if (abs(delta_r) > delta_r_max) delta_r = sign(delta_r_max, delta_r) + else + delta_r = delta_r_max + end if + r_max_start_old = r_max_start + r_max_start = r_max_start + delta_r ! The larger lever arm can help if the problem is in the angular momentum step + if (f_spin > epsilon(1.0_DP)) then + f_spin = f_spin / 2 + else + f_spin = 0.0_DP + end if + end subroutine restructure_failed_fragments + + + end subroutine fragmentation_initialize + + + + module subroutine fragmentation_regime(Mcb, m1, m2, rad1, rad2, xh1, xh2, vb1, vb2, den1, den2, regime, Mlr, Mslr, mtiny, Qloss) + !! Author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Determine the collisional regime of two colliding bodies. + !! Current version requires all values to be converted to SI units prior to calling the function + !! References: + !! Kokubo, E., Genda, H., 2010. Formation of Terrestrial Planets from Protoplanets Under a Realistic Accretion + !! Condition. ApJL 714, L21. https://doi.org/10.1088/2041-8205/714/1/L21 + !! Leinhardt, Z.M., Stewart, S.T., 2012. Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling + !! Laws 745, 79. https://doi.org/10.1088/0004-637X/745/1/79 + !! Mustill, A.J., Davies, M.B., Johansen, A., 2018. The dynamical evolution of transiting planetary systems including + !! a realistic collision prescription. Mon Not R Astron Soc 478, 2896–2908. https://doi.org/10.1093/mnras/sty1273 + !! Rufu, R., Aharonson, O., 2019. Impact Dynamics of Moons Within a Planetary Potential. J. Geophys. Res. Planets 124, + !! 1008–1019. https://doi.org/10.1029/2018JE005798 + !! Stewart, S.T., Leinhardt, Z.M., 2012. Collisions between Gravity-dominated Bodies. II. The Diversity of Impact + !! Outcomes during the End Stage of Planet Formation. ApJ 751, 32. https://doi.org/10.1088/0004-637X/751/1/32 + !! + implicit none + ! Arguments + integer(I4B), intent(out) :: regime + real(DP), intent(out) :: Mlr, Mslr + real(DP), intent(in) :: Mcb, m1, m2, rad1, rad2, den1, den2, mtiny + real(DP), dimension(:), intent(in) :: xh1, xh2, vb1, vb2 + real(DP), intent(out) :: Qloss !! The residual energy after the collision + ! Constants + integer(I4B), parameter :: N1 = 1 !number of objects with mass equal to the largest remnant from LS12 + integer(I4B), parameter :: N2 = 2 !number of objects with mass larger than second largest remnant from LS12 + real(DP), parameter :: DENSITY1 = 1000.0_DP !standard density parameter from LS12 [kg/m3] + real(DP), parameter :: MU_BAR = 0.37_DP !0.385#0.37#0.3333# 3.978 # 1/3 material parameter for hydrodynamic planet-size bodies (LS12) + real(DP), parameter :: BETA = 2.85_DP !slope of sfd for remnants from LS12 2.85 + real(DP), parameter :: C1 = 2.43_DP !! Kokubo & Genda (2010) eq. (3) + real(DP), parameter :: C2 = -0.0408_DP !! Kokubo & Genda (2010) eq. (3) + real(DP), parameter :: C3 = 1.86_DP !! Kokubo & Genda (2010) eq. (3) + real(DP), parameter :: C4 = 1.08_DP !! Kokubo & Genda (2010) eq. (3) + real(DP), parameter :: CRUFU = 2.0_DP - 3 * MU_BAR ! central potential variable from Rufu and Aharonson (2019) + real(DP), parameter :: SUPERCAT_QRATIO = 1.8_DP ! See Section 4.1 of LS12 + ! Internals + real(DP) :: a1, alpha, aint, b, bcrit, c_star, egy, zeta, l, lint, mu, phi, theta + real(DP) :: Qr, Qrd_pstar, Qr_erosion, Qr_supercat + real(DP) :: Vhr, Verosion, Vescp, Vhill, Vimp, Vsupercat + real(DP) :: Mint, Mtot + real(DP) :: Rp, rhill + real(DP) :: Mresidual + real(DP) :: U_binding + + Vimp = norm2(vb2(:) - vb1(:)) + b = calc_b(xh2, vb2, xh1, vb1) + l = (rad1 + rad2) * (1 - b) + egy = 0.5_DP * dot_product(vb1, vb1) - GC * Mcb / norm2(xh1) + a1 = - GC * Mcb / 2.0_DP / egy + Mtot = m1 + m2 + mu = (m1 * m2) / Mtot + if (l < 2 * rad2) then + !calculate Mint + phi = 2 * acos((l - rad2) / rad2) + aint = rad2**2 * (PI - (phi - sin(phi)) / 2.0_DP) + lint = 2 * sqrt(rad2**2 - (rad2 - l / 2.0_DP) ** 2) + Mint = aint * lint ![kg] + alpha = (l**2) * (3 * rad2 - l) / (4 * (rad2**3)) + else + alpha = 1.0_DP + Mint = m2 + end if + Rp = (3 * (m1 / den1 + alpha * m2 / den2) / (4 * PI))**(1.0_DP/3.0_DP) ! (Mustill et al. 2018) + c_star = calc_c_star(Rp) + !calculate Vescp + Vescp = sqrt(2 * GC * Mtot / Rp) !Mustill et al. 2018 eq 6 + !calculate rhill + rhill = a1 * (m1 / 3.0_DP / (Mcb + m1))**(1.0_DP/3.0_DP) + !calculate Vhill + if ((rad2 + rad1) < rhill) then + Vhill = sqrt(2 * GC * m1 * ((rhill**2 - rhill * (rad1 + rad2)) / & + (rhill**2 - 0.5_DP * (rad1 + rad2)**2)) / (rad1 + rad2)) + else + Vhill = Vescp + end if + !calculate Qr_pstar + Qrd_pstar = calc_Qrd_pstar(m1, m2, alpha, c_star) * (Vhill / Vescp)**CRUFU !Rufu and Aharaonson eq (3) + !calculate Verosion + Qr_erosion = 2 * (1.0_DP - m1 / Mtot) * Qrd_pstar + Verosion = (2 * Qr_erosion * Mtot / mu)** (1.0_DP / 2.0_DP) + Qr = mu*(Vimp**2) / Mtot / 2.0_DP + !calculate mass largest remnant Mlr + Mlr = (1.0_DP - Qr / Qrd_pstar / 2.0_DP) * Mtot ! [kg] # LS12 eq (5) + !calculate Vsupercat + Qr_supercat = SUPERCAT_QRATIO * Qrd_pstar ! See LS12 Section 4.1 + Vsupercat = sqrt(2 * Qr_supercat * Mtot / mu) + !calculate Vhr + zeta = (m1 - m2) / Mtot + theta = 1.0_DP - b + Vhr = Vescp * (C1 * zeta**2 * theta**(2.5_DP) + C2 * zeta**2 + C3 * theta**(2.5_DP) + C4) ! Kokubo & Genda (2010) eq. (3) + bcrit = rad1 / (rad1 + rad2) + Qloss = 0.0_DP + U_binding = (3.0_DP * Mtot) / (5.0_DP * Rp) ! LS12 eq. 27 + + if ((m1 < mtiny).or.(m2 < mtiny)) then + regime = COLLRESOLVE_REGIME_MERGE !perfect merging regime + Mlr = Mtot + Mslr = 0.0_DP + Qloss = 0.0_DP + write(*,*) "FORCE MERGE" + else + if( Vimp < Vescp) then + regime = COLLRESOLVE_REGIME_MERGE !perfect merging regime + Mlr = Mtot + Mslr = 0.0_DP + Qloss = 0.0_DP + else if (Vimp < Verosion) then + if (b < bcrit) then + regime = COLLRESOLVE_REGIME_MERGE !partial accretion regime" + Mlr = Mtot + Mslr = 0.0_DP + Qloss = 0.0_DP + else if ((b > bcrit) .and. (Vimp < Vhr)) then + regime = COLLRESOLVE_REGIME_MERGE ! graze and merge + Mlr = Mtot + Mslr = 0.0_DP + Qloss = 0.0_DP + else + Mlr = m1 + Mslr = calc_Qrd_rev(m2, m1, Mint, den1, den2, Vimp, c_star) + regime = COLLRESOLVE_REGIME_HIT_AND_RUN !hit and run + Qloss = (c_star + 1.0_DP) * U_binding ! Qr + end if + else if (Vimp > Verosion .and. Vimp < Vsupercat) then + if (m2 < 0.001_DP * m1) then + regime = COLLRESOLVE_REGIME_MERGE !cratering regime" + Mlr = Mtot + Mslr = 0.0_DP + Qloss = 0.0_DP + else + Mslr = Mtot * (3.0_DP - BETA) * (1.0_DP - N1 * Mlr / Mtot) / (N2 * BETA) ! LS12 eq (37) + regime = COLLRESOLVE_REGIME_DISRUPTION !disruption + Qloss = (c_star + 1.0_DP) * U_binding ! Qr - Qr_erosion + end if + else if (Vimp > Vsupercat) then + Mlr = Mtot * 0.1_DP * (Qr / (Qrd_pstar * SUPERCAT_QRATIO))**(-1.5_DP) !LS12 eq (44) + Mslr = Mtot * (3.0_DP - BETA) * (1.0_DP - N1 * Mlr / Mtot) / (N2 * BETA) !LS12 eq (37) + regime = COLLRESOLVE_REGIME_SUPERCATASTROPHIC ! supercatastrophic + Qloss = (c_star + 1.0_DP) * U_binding ! Qr - Qr_supercat + else + write(*,*) "Error no regime found in symba_regime" + end if + end if + Mresidual = Mtot - Mlr - Mslr + if (Mresidual < 0.0_DP) then ! prevents final masses from going negative + Mlr = Mlr + Mresidual + end if + + return + + ! Internal functions + contains + function calc_Qrd_pstar(Mtarg, Mp, alpha, c_star) result(Qrd_pstar) + !! author: Jennifer L.L. Pouplin and Carlisle A. Wishard + !! + !! Calculates the corrected Q* for oblique impacts. See Eq. (15) of LS12. + !! Reference: + !! Leinhardt, Z.M., Stewart, S.T., 2012. Collisions between Gravity-dominated Bodies. I. Outcome Regimes and Scaling + !! Laws 745, 79. https://doi.org/10.1088/0004-637X/745/1/79 + !! + implicit none + ! Arguments + real(DP),intent(in) :: Mtarg, Mp, alpha, c_star + ! Result + real(DP) :: Qrd_pstar + ! Internals + real(DP) :: Qrd_star1, mu_alpha, mu, Qrd_star + + ! calc mu, mu_alpha + mu = (Mtarg * Mp) / (Mtarg + Mp) ! [kg] + mu_alpha = (Mtarg * alpha * Mp) / (Mtarg + alpha * Mp) ! [kg] + ! calc Qrd_star1 + Qrd_star1 = (c_star * 4 * PI * DENSITY1 * GC * Rp**2) / 5.0_DP + ! calc Qrd_star + Qrd_star = Qrd_star1 * (((Mp / Mtarg + 1.0_DP)**2) / (4 * Mp / Mtarg))**(2.0_DP / (3.0_DP * MU_BAR) - 1.0_DP) !(eq 23) + ! calc Qrd_pstar, v_pstar + Qrd_pstar = ((mu / mu_alpha)**(2.0_DP - 3.0_DP * MU_BAR / 2.0_DP)) * Qrd_star ! (eq 15) + + return + end function calc_Qrd_pstar + + function calc_Qrd_rev(Mp, Mtarg, Mint, den1, den2, Vimp, c_star) result(Mslr) + !! author: Jennifer L.L. Pouplin and Carlisle A. Wishard + !! + !! Calculates mass of second largest fragment. + !! + implicit none + ! Arguments + real(DP),intent(in) :: Mp, Mtarg, Mint, den1, den2, Vimp, c_star + ! Result + real(DP) :: Mslr + ! Internals + real(DP) :: mtot_rev, mu_rev, gamma_rev, Qrd_star1, Qrd_star, mu_alpha_rev + real(DP) :: Qrd_pstar, Rc1, Qr_rev, Qrd_pstar_rev, Qr_supercat_rev + + ! calc Mslr, Rc1, mu, gammalr + mtot_rev = Mint + Mp + Rc1 = (3 * (Mint / den1 + Mp / den2) / (4 * PI))**(1.0_DP/3.0_DP) ! [m] Mustill et al 2018 + mu_rev = (Mint * Mp) / mtot_rev ! [kg] eq 49 LS12 + mu_alpha_rev = (Mtarg * alpha * Mp) / (Mtarg + alpha * Mp) + gamma_rev = Mint / Mp ! eq 50 LS12 + !calc Qr_rev + Qr_rev = mu_rev * (Vimp**2) / (2 * mtot_rev) + ! calc Qrd_star1, v_star1 + Qrd_star1 = (c_star * 4 * PI * mtot_rev * GC ) / Rc1 / 5.0_DP + ! calc Qrd_pstar_rev + Qrd_star = Qrd_star1 * (((gamma_rev + 1.0_DP)**2) / (4 * gamma_rev)) ** (2.0_DP / (3.0_DP * MU_BAR) - 1.0_DP) !(eq 52) + Qrd_pstar = Qrd_star * ((mu_rev / mu_alpha_rev)**(2.0_DP - 3.0_DP * MU_BAR / 2.0_DP)) + Qrd_pstar_rev = Qrd_pstar * (Vhill / Vescp)**CRUFU !Rufu and Aharaonson eq (3) + !calc Qr_supercat_rev + Qr_supercat_rev = 1.8_DP * Qrd_pstar_rev + if (Qr_rev > Qr_supercat_rev ) then + Mslr = mtot_rev * (0.1_DP * ((Qr_rev / (Qrd_pstar_rev * 1.8_DP))**(-1.5_DP))) !eq (44) + else if ( Qr_rev < Qrd_pstar_rev ) then + Mslr = Mp + else + Mslr = (1.0_DP - Qr_rev / Qrd_pstar_rev / 2.0_DP) * (mtot_rev) ! [kg] #(eq 5) + end if + + if ( Mslr > Mp ) Mslr = Mp !check conservation of mass + + return + end function calc_Qrd_rev + + function calc_b(proj_pos, proj_vel, targ_pos, targ_vel) result(sintheta) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Calculates the impact factor b = sin(theta), where theta is the angle between the relative velocity + !! and distance vectors of the target and projectile bodies. See Fig. 2 of Leinhardt and Stewart (2012) + !! + implicit none + !! Arguments + real(DP), dimension(:), intent(in) :: proj_pos, proj_vel, targ_pos, targ_vel + !! Result + real(DP) :: sintheta + !! Internals + real(DP), dimension(NDIM) :: imp_vel, distance, x_cross_v + + imp_vel(:) = proj_vel(:) - targ_vel(:) + distance(:) = proj_pos(:) - targ_pos(:) + x_cross_v(:) = distance(:) .cross. imp_vel(:) + sintheta = norm2(x_cross_v(:)) / norm2(distance(:)) / norm2(imp_vel(:)) + return + end function calc_b + + function calc_c_star(Rc1) result(c_star) + !! author: David A. Minton + !! + !! Calculates c_star as a function of impact equivalent radius. It inteRpolates between 5 for ~1 km sized bodies to + !! 1.8 for ~10000 km sized bodies. See LS12 Fig. 4 for details. + !! + implicit none + !! Arguments + real(DP), intent(in) :: Rc1 + !! Result + real(DP) :: c_star + !! Internals + real(DP), parameter :: loR = 1.0e3_DP ! Lower bound of inteRpolation size (m) + real(DP), parameter :: hiR = 1.0e7_DP ! Upper bound of inteRpolation size (m) + real(DP), parameter :: loval = 5.0_DP ! Value of C* at lower bound + real(DP), parameter :: hival = 1.9_DP ! Value of C* at upper bound + + if (Rc1 < loR) then + c_star = loval + else if (Rc1 < hiR) then + c_star = loval + (hival - loval) * log(Rc1 / loR) / log(hiR /loR) + else + c_star = hival + end if + return + end function calc_c_star + + end subroutine fragmentation_regime + +end submodule s_fragmentation \ No newline at end of file diff --git a/src/gr/gr.f90 b/src/gr/gr.f90 new file mode 100644 index 000000000..0c0333907 --- /dev/null +++ b/src/gr/gr.f90 @@ -0,0 +1,263 @@ +submodule(swiftest_classes) s_gr + use swiftest +contains + + module pure subroutine gr_kick_getaccb_ns_body(self, system, param) + !! author: David A. Minton + !! + !! Add relativistic correction acceleration for non-symplectic integrators. + !! Based on Quinn et al. (1991) eq. 5 + !! + !! Reference: + !! Quinn, T.R., Tremaine, S., Duncan, M., 1991. A three million year integration of the earth’s orbit. + !! AJ 101, 2287–2305. https://doi.org/10.1086/115850 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_kick_getaccb_ns.f90 + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + real(DP) :: rmag, rdotv, vmag2 + integer(I4B) :: i + + associate(n => self%nbody, cb => system%cb, inv_c2 => param%inv_c2) + if (n == 0) return + do i = 1, n + rmag = norm2(self%xh(:,i)) + vmag2 = dot_product(self%vh(:,i), self%vh(:,i)) + rdotv = dot_product(self%xh(:,i), self%vh(:,i)) + self%agr(:, i) = self%mu * inv_c2 / rmag**3 * ((4 * self%mu(i) / rmag - vmag2) * self%xh(:,i) + 4 * rdotv * self%vh(:,i)) + end do + + select type(self) + class is (swiftest_pl) + do i = 1, NDIM + cb%agr(i) = -sum(self%Gmass(1:n) * self%agr(1:n, i) / cb%Gmass) + end do + end select + end associate + + return + end subroutine gr_kick_getaccb_ns_body + + + module subroutine gr_kick_getacch(mu, x, lmask, n, inv_c2, agr) + !! author: David A. Minton + !! + !! Compute relativisitic accelerations of massive bodies + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_kick_getacch.f90 + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: mu !! Gravitational constant + real(DP), dimension(:,:), intent(in) :: x !! Position vectors + logical, dimension(:), intent(in) :: lmask !! Logical mask indicating which bodies to compute + integer(I4B), intent(in) :: n !! Total number of bodies + real(DP), intent(in) :: inv_c2 !! Inverse speed of light squared: 1 / c**2 + real(DP), dimension(:,:), intent(out) :: agr !! Accelerations + ! Internals + integer(I4B) :: i + real(DP) :: beta, rjmag4 + + agr(:,:) = 0.0_DP + do concurrent (i = 1:n, lmask(i)) + rjmag4 = (dot_product(x(:, i), x(:, i)))**2 + beta = -mu(i)**2 * inv_c2 + agr(:, i) = 2 * beta * x(:, i) / rjmag4 + end do + + return + end subroutine gr_kick_getacch + + + module pure subroutine gr_p4_pos_kick(param, x, v, dt) + !! author: David A. Minton + !! + !! Position kick due to p**4 term in the post-Newtonian correction + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Reference: + !! Saha, P., Tremaine, S., 1994. Long-term planetary integration with individual time steps. + !! AJ 108, 1962–1969. https://doi.org/10.1086/117210 + !! + !! Adapted from David A. Minton's Swifter routine gr_whm_p4.f90 + implicit none + ! Arguments + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), dimension(:), intent(inout) :: x !! Position vector + real(DP), dimension(:), intent(in) :: v !! Velocity vector + real(DP), intent(in) :: dt !! Step size + ! Internals + real(DP), dimension(NDIM) :: dr + real(DP) :: vmag2 + + vmag2 = dot_product(v(:), v(:)) + dr(:) = -2 * param%inv_c2 * vmag2 * v(:) + x(:) = x(:) + dr(:) * dt + + return + end subroutine gr_p4_pos_kick + + + module pure subroutine gr_pseudovel2vel(param, mu, xh, pv, vh) + !! author: David A. Minton + !! + !! Converts the relativistic pseudovelocity back into a veliocentric velocity + !! Based on Saha & Tremaine (1994) Eq. 32 + !! + !! Reference: + !! Saha, P., Tremaine, S., 1994. Long-term planetary integration with individual time steps. + !! AJ 108, 1962–1969. https://doi.org/10.1086/117210 + !! + !! Adapted from David A. Minton's Swifter routine gr_pseudovel2vel.f90 + implicit none + ! Arguments + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body + real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector + real(DP), dimension(:), intent(in) :: pv !! Pseudovelocity velocity vector - see Saha & Tremain (1994), eq. (32) + real(DP), dimension(:), intent(out) :: vh !! Heliocentric velocity vector + ! Internals + real(DP) :: vmag2, rmag, grterm + + associate(inv_c2 => param%inv_c2) + vmag2 = dot_product(pv(:), pv(:)) + rmag = norm2(xh(:)) + grterm = 1.0_DP - inv_c2 * (0.5_DP * vmag2 + 3 * mu / rmag) + vh(:) = pv(:) * grterm + end associate + + return + end subroutine gr_pseudovel2vel + + + module pure subroutine gr_pv2vh_body(self, param) + !! author: David A. Minton + !! + !! Wrapper function that converts from pseudovelocity to heliocentric velocity for swiftest bodies + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion + + associate(n => self%nbody) + if (n == 0) return + allocate(vh, mold = self%vh) + do i = 1, n + call gr_pseudovel2vel(param, self%mu(i), self%xh(:, i), self%vh(:, i), vh(:, i)) + end do + call move_alloc(vh, self%vh) + end associate + + return + end subroutine gr_pv2vh_body + + + module pure subroutine gr_vel2pseudovel(param, mu, xh, vh, pv) + !! author: David A. Minton + !! + !! Converts the heliocentric velocity into a pseudovelocity with relativistic corrections. + !! Uses Newton-Raphson method with direct inversion of the Jacobian (yeah, it's slow, but + !! this is only done once per run). + !! + !! Reference: + !! Saha, P., Tremaine, S., 1994. Long-term planetary integration with individual time steps. + !! AJ 108, 1962–1969. https://doi.org/10.1086/117210 + !! + !! Adapted from David A. Minton's Swifter routine gr_vel2pseudovel.f90 + implicit none + ! Arguments + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body + real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector + real(DP), dimension(:), intent(in) :: vh !! Heliocentric velocity vector + real(DP), dimension(:), intent(out) :: pv !! Pseudovelocity vector - see Saha & Tremain (1994), eq. (32) + ! Internals + real(DP) :: v2, G, pv2, rterm, det + real(DP), dimension(NDIM,NDIM) :: J,Jinv + real(DP), dimension(NDIM) :: F + integer(I4B) :: n,i,k + integer(I4B), parameter :: MAXITER = 50 + real(DP),parameter :: TOL = 1.0e-12_DP + + associate(inv_c2 => param%inv_c2) + pv(1:NDIM) = vh(1:NDIM) ! Initial guess + rterm = 3 * mu / norm2(xh(:)) + v2 = dot_product(vh(:), vh(:)) + do n = 1, MAXITER + pv2 = dot_product(pv(:), pv(:)) + G = 1.0_DP - inv_c2 * (0.5_DP * pv2 + rterm) + F(:) = pv(:) * G - vh(:) + if (abs(sum(F) / v2 ) < TOL) exit ! Root found + + ! Calculate the Jacobian + do k = 1, NDIM + do i = 1, NDIM + if (i == k) then + J(i,k) = G - inv_c2 * pv(k) + else + J(i,k) = -inv_c2 * pv(k) + end if + end do + end do + + ! Inverse of the Jacobian + det = J(1,1) * (J(3,3) * J(2,2) - J(3,2) * J(2,3)) + det = det - J(2,1) * (J(3,3) * J(1,2)-J(3,2) * J(1,3)) + det = det + J(3,1) * (J(2,3) * J(1,2)-J(2,2) * J(1,3)) + + Jinv(1,1) = J(3,3) * J(2,2) - J(3,2) * J(2,3) + Jinv(1,2) = -(J(3,3) * J(1,2) - J(3,2) * J(1,3)) + Jinv(1,3) = J(2,3) * J(1,2) - J(2,2) * J(1,3) + + Jinv(2,1) = -(J(3,3) * J(2,1) - J(3,1) * J(2,3)) + Jinv(2,2) = J(3,3) * J(1,1) - J(3,1) * J(1,3) + Jinv(2,3) = -(J(2,3) * J(1,1) - J(2,1) * J(1,3)) + + Jinv(3,1) = J(3,2) * J(2,1) - J(3,1) * J(2,2) + Jinv(3,2) = -(J(3,2) * J(1,1) - J(3,1) * J(1,2)) + Jinv(3,3) = J(2,2) * J(1,1) - J(2,1) * J(1,2) + + Jinv = Jinv * det + + do i = 1, NDIM + pv(i) = pv(i) - dot_product(Jinv(i,:), F(:)) + end do + end do + end associate + + return + end subroutine gr_vel2pseudovel + + + module pure subroutine gr_vh2pv_body(self, param) + !! author: David A. Minton + !! + !! Wrapper function that converts from heliocentric velocity to pseudovelocity for Swiftest bodies + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion + + associate(n => self%nbody) + if (n == 0) return + allocate(pv, mold = self%vh) + do i = 1, n + call gr_vel2pseudovel(param, self%mu(i), self%xh(:, i), self%vh(:, i), pv(:, i)) + end do + call move_alloc(pv, self%vh) + end associate + + return + end subroutine gr_vh2pv_body + +end submodule s_gr \ No newline at end of file diff --git a/src/helio/helio_coord.f90 b/src/helio/helio_coord.f90 new file mode 100644 index 000000000..f40781810 --- /dev/null +++ b/src/helio/helio_coord.f90 @@ -0,0 +1,113 @@ +submodule (helio_classes) s_helio_coord + use swiftest +contains + + module subroutine helio_coord_vb2vh_pl(self, cb) + !! author: David A. Minton + !! + !! Convert massive bodies from barycentric to heliocentric coordinates (velocity only) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_vb2vh.f90 + !! Adapted from Hal Levison's Swift routine coord_vb2vh.f + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + do i = 1, NDIM + cb%vb(i) = -sum(pl%Gmass(1:npl) * pl%vb(i, 1:npl)) / cb%Gmass + pl%vh(i, 1:npl) = pl%vb(i, 1:npl) - cb%vb(i) + end do + end associate + + return + end subroutine helio_coord_vb2vh_pl + + + module subroutine helio_coord_vb2vh_tp(self, vbcb) + !! author: David A. Minton + !! + !! Convert test particles from barycentric to heliocentric coordinates (velocity only) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_vb2vh_tp.f90 + !! Adapted from Hal Levison's Swift routine coord_vb2h_tp.f + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio massive body object + real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + where (tp%lmask(1:ntp)) + tp%vh(1, 1:ntp) = tp%vb(1, 1:ntp) - vbcb(1) + tp%vh(2, 1:ntp) = tp%vb(2, 1:ntp) - vbcb(2) + tp%vh(3, 1:ntp) = tp%vb(3, 1:ntp) - vbcb(3) + end where + end associate + + return + end subroutine helio_coord_vb2vh_tp + + + module subroutine helio_coord_vh2vb_pl(self, cb) + !! author: David A. Minton + !! + !! Convert massive bodies from heliocentric to barycentric coordinates (velocity only) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_vh2vb.f90 + !! Adapted from Hal Levison's Swift routine coord_vh2b.f + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + integer(I4B) :: i + real(DP) :: Gmtot + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + Gmtot = cb%Gmass + sum(pl%Gmass(1:npl)) + do i = 1, NDIM + cb%vb(i) = -sum(pl%Gmass(1:npl) * pl%vh(i, 1:npl)) / Gmtot + pl%vb(i, 1:npl) = pl%vh(i, 1:npl) + cb%vb(i) + end do + end associate + + return + end subroutine helio_coord_vh2vb_pl + + + module subroutine helio_coord_vh2vb_tp(self, vbcb) + !! author: David A. Minton + !! + !! Convert test particles from heliocentric to barycentric coordinates (velocity only) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_vh2vb_tp.f90 + !! Adapted from Hal Levison's Swift routine coord_vh2b_tp.f + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio massive body object + real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + where (tp%lmask(1:ntp)) + tp%vb(1, 1:ntp) = tp%vh(1, 1:ntp) + vbcb(1) + tp%vb(2, 1:ntp) = tp%vh(2, 1:ntp) + vbcb(2) + tp%vb(3, 1:ntp) = tp%vh(3, 1:ntp) + vbcb(3) + end where + end associate + + return + end subroutine helio_coord_vh2vb_tp + +end submodule s_helio_coord + diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 new file mode 100644 index 000000000..e2a55e458 --- /dev/null +++ b/src/helio/helio_drift.f90 @@ -0,0 +1,154 @@ +submodule (helio_classes) s_helio_drift + use swiftest +contains + + module subroutine helio_drift_body(self, system, param, dt) + !! author: David A. Minton + !! + !! Loop through bodies and call Danby drift routine on democratic heliocentric coordinates + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_drift.f90 + !! Adapted from Hal Levison's Swift routine drift.f + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + ! Internals + integer(I4B) :: i !! Loop counter + real(DP) :: rmag, vmag2, energy + integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag + real(DP), dimension(:), allocatable :: dtp, mu + + if (self%nbody == 0) return + + associate(n => self%nbody) + allocate(iflag(n)) + iflag(:) = 0 + allocate(mu(n)) + mu(:) = system%cb%Gmass + call drift_all(mu, self%xh, self%vb, self%nbody, param, dt, self%lmask, iflag) + if (any(iflag(1:n) /= 0)) then + where(iflag(1:n) /= 0) self%status(1:n) = DISCARDED_DRIFTERR + do i = 1, n + if (iflag(i) /= 0) write(*, *) " Body ", self%id(i), " lost due to error in Danby drift" + end do + end if + end associate + + return + end subroutine helio_drift_body + + + module subroutine helio_drift_pl(self, system, param, dt) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a helio_pl structure + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + + call helio_drift_body(self, system, param, dt) + + return + end subroutine helio_drift_pl + + + module subroutine helio_drift_tp(self, system, param, dt) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a helio_pl structure + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + + call helio_drift_body(self, system, param, dt) + + return + end subroutine helio_drift_tp + + + module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) + !! author: David A. Minton + !! + !! Perform linear drift of massive bodies due to barycentric momentum of Sun + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_lindrift.f90 + !! Adapted from Hal Levison's Swift routine helio_lindrift.f + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(helio_cb), intent(inout) :: cb !! Helio central body + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Argument that determines whether or not this is the beginning or end of the step + ! Internals + real(DP), dimension(NDIM) :: pt !! negative barycentric velocity of the central body + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + if (npl == 0) return + pt(1) = sum(pl%Gmass(1:npl) * pl%vb(1,1:npl), self%lmask(1:npl)) + pt(2) = sum(pl%Gmass(1:npl) * pl%vb(2,1:npl), self%lmask(1:npl)) + pt(3) = sum(pl%Gmass(1:npl) * pl%vb(3,1:npl), self%lmask(1:npl)) + pt(:) = pt(:) / cb%Gmass + do concurrent(i = 1:npl, self%lmask(i)) + pl%xh(:,i) = pl%xh(:,i) + pt(:) * dt + end do + + if (lbeg) then + cb%ptbeg = pt(:) + else + cb%ptend = pt(:) + end if + end associate + + return + end subroutine helio_drift_linear_pl + + + module subroutine helio_drift_linear_tp(self, cb, dt, lbeg) + !! author: David A. Minton + !! + !! Perform linear drift of test particles due to barycentric momentum of Sun + !! New vectorized version included + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_lindrift_tp.f90 + !! Adapted from Hal Levison's Swift routine helio_lindrift_tp.f + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio test particleb object + class(helio_cb), intent(in) :: cb !! Helio central body + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Argument that determines whether or not this is the beginning or end of the step + ! Internals + real(DP), dimension(NDIM) :: pt !! negative barycentric velocity of the central body + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + if (ntp == 0) return + if (lbeg) then + pt(:) = cb%ptbeg + else + pt(:) = cb%ptend + end if + where (self%lmask(1:ntp)) + tp%xh(1, 1:ntp) = tp%xh(1, 1:ntp) + pt(1) * dt + tp%xh(2, 1:ntp) = tp%xh(2, 1:ntp) + pt(2) * dt + tp%xh(3, 1:ntp) = tp%xh(3, 1:ntp) + pt(3) * dt + end where + end associate + + return + end subroutine helio_drift_linear_tp + +end submodule s_helio_drift diff --git a/src/helio/helio_gr.f90 b/src/helio/helio_gr.f90 new file mode 100644 index 000000000..4902c45b8 --- /dev/null +++ b/src/helio/helio_gr.f90 @@ -0,0 +1,111 @@ +submodule(helio_classes) s_helio_gr + use swiftest +contains + + module subroutine helio_gr_kick_getacch_pl(self, param) + !! author: David A. Minton + !! + !! Compute relativisitic accelerations of massive bodies + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_kick_getacch.f90 + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: suma + real(DP), dimension(:, :), allocatable :: aj + real(DP) :: beta, rjmag4 + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + call gr_kick_getacch(pl%mu, pl%xh, pl%lmask, npl, param%inv_c2, pl%agr) + pl%ah(:,1:npl) = pl%ah(:,1:npl) + pl%agr(:,1:npl) + end associate + + return + end subroutine helio_gr_kick_getacch_pl + + + module subroutine helio_gr_kick_getacch_tp(self, param) + !! author: David A. Minton + !! + !! Compute relativisitic accelerations of test particles + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_helio_kick_getacch.f90 + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP) :: rjmag4, beta + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + call gr_kick_getacch(tp%mu, tp%xh, tp%lmask, ntp, param%inv_c2, tp%agr) + tp%ah(:,1:ntp) = tp%ah(:,1:ntp) + tp%agr(:,1:ntp) + end associate + + return + end subroutine helio_gr_kick_getacch_tp + + + module pure subroutine helio_gr_p4_pl(self, param, dt) + !! author: David A. Minton + !! + !! Position kick to massive bodies due to p**4 term in the post-Newtonian correction + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_helio_p4.f90 + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + do concurrent(i = 1:npl, pl%lmask(i)) + call gr_p4_pos_kick(param, pl%xh(:, i), pl%vb(:, i), dt) + end do + end associate + + return + end subroutine helio_gr_p4_pl + + module pure subroutine helio_gr_p4_tp(self, param, dt) + !! author: David A. Minton + !! + !! Position kick to test particles due to p**4 term in the post-Newtonian correction + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_helio_p4.f90 + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + do concurrent(i = 1:ntp, tp%lmask(i)) + call gr_p4_pos_kick(param, tp%xh(:, i), tp%vb(:, i), dt) + end do + end associate + + return + end subroutine helio_gr_p4_tp + +end submodule s_helio_gr \ No newline at end of file diff --git a/src/helio/helio_kick.f90 b/src/helio/helio_kick.f90 new file mode 100644 index 000000000..eebd17f53 --- /dev/null +++ b/src/helio/helio_kick.f90 @@ -0,0 +1,149 @@ +submodule(helio_classes) s_helio_kick + use swiftest +contains + + module subroutine helio_kick_getacch_pl(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of massive bodies + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_kick_getacch.f90 + !! Adapted from Hal Levison's Swift routine helio_kick_getacch.f + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + + if (self%nbody == 0) return + + associate(cb => system%cb, pl => self, npl => self%nbody) + call pl%accel_int() + if (param%loblatecb) then + call pl%accel_obl(system) + if (lbeg) then + cb%aoblbeg = cb%aobl + else + cb%aoblend = cb%aobl + end if + if (param%ltides) then + call pl%accel_tides(system) + if (lbeg) then + cb%atidebeg = cb%atide + else + cb%atideend = cb%atide + end if + end if + end if + if (param%lextra_force) call pl%accel_user(system, param, t, lbeg) + if (param%lgr) call pl%accel_gr(param) + end associate + + return + end subroutine helio_kick_getacch_pl + + + module subroutine helio_kick_getacch_tp(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of test particles + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_kick_getacch_tp.f90 + !! Adapted from Hal Levison's Swift routine helio_kick_getacch_tp.f + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + + if (self%nbody == 0) return + + associate(tp => self, cb => system%cb, pl => system%pl, npl => system%pl%nbody) + system%lbeg = lbeg + if (system%lbeg) then + call tp%accel_int(pl%Gmass(:), pl%xbeg(:,:), npl) + else + call tp%accel_int(pl%Gmass(:), pl%xend(:,:), npl) + end if + if (param%loblatecb) call tp%accel_obl(system) + if (param%lextra_force) call tp%accel_user(system, param, t, lbeg) + if (param%lgr) call tp%accel_gr(param) + end associate + + return + end subroutine helio_kick_getacch_tp + + + module subroutine helio_kick_vb_pl(self, system, param, t, dt, lbeg) + !! author: David A. Minton + !! + !! Kick barycentric velocities of bodies + !! + !! Adapted from Martin Duncan and Hal Levison's Swift routine kickvh.f + !! Adapted from David E. Kaufmann's Swifter routine helio_kick_vb.f90 + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Swiftest generic body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + pl%ah(:,:) = 0.0_DP + call pl%accel(system, param, t, lbeg) + if (lbeg) then + call pl%set_beg_end(xbeg = pl%xh) + else + call pl%set_beg_end(xend = pl%xh) + end if + do concurrent(i = 1:npl, pl%lmask(i)) + pl%vb(:, i) = pl%vb(:, i) + pl%ah(:, i) * dt + end do + end associate + + return + end subroutine helio_kick_vb_pl + + + module subroutine helio_kick_vb_tp(self, system, param, t, dt, lbeg) + !! author: David A. Minton + !! + !! Kick barycentric velocities of bodies + !! + !! Adapted from Martin Duncan and Hal Levison's Swift routine kickvh_tp.f + !! Adapted from David E. Kaufmann's Swifter routine helio_kick_vb_tp.f90 + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Swiftest generic body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + tp%ah(:,:) = 0.0_DP + call tp%accel(system, param, t, lbeg) + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%vb(:, i) = tp%vb(:, i) + tp%ah(:, i) * dt + end do + end associate + + return + end subroutine helio_kick_vb_tp + +end submodule s_helio_kick \ No newline at end of file diff --git a/src/helio/helio_step.f90 b/src/helio/helio_step.f90 new file mode 100644 index 000000000..039884596 --- /dev/null +++ b/src/helio/helio_step.f90 @@ -0,0 +1,112 @@ +submodule(helio_classes) s_helio_step + use swiftest +contains + + module subroutine helio_step_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step massive bodies and and active test particles ahead in heliocentric coordinates. + !! + !! Currently there's no difference between this and the WHM system stepper, so this is just + !! a wrapper function to keep the method calls consistent for inherited types. + !! + !! Adapted from Hal Levison's Swift routine step_kdk.f + !! Adapted from David E. Kaufmann's Swifter routine helio_step.f90 + implicit none + ! Arguments + class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + + call whm_step_system(self, param, t, dt) + + return + end subroutine helio_step_system + + + module subroutine helio_step_pl(self, system, param, t, dt) + !! author: David A. Minton + !! + !! Step massive bodies ahead Democratic Heliocentric method + !! + !! Adapted from David E. Kaufmann's Swifter helio_step_pl.f90 + !! Adapted from Hal Levison's Swift routine helio_step_pl.f + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize + ! Internals + real(DP) :: dth !! Half step size + + if (self%nbody == 0) return + + associate(pl => self) + select type(cb => system%cb) + class is (helio_cb) + dth = 0.5_DP * dt + if (pl%lfirst) then + call pl%vh2vb(cb) + pl%lfirst = .false. + end if + call pl%lindrift(cb, dth, lbeg=.true.) + call pl%kick(system, param, t, dth, lbeg=.true.) + if (param%lgr) call pl%gr_pos_kick(param, dth) + call pl%drift(system, param, dt) + call pl%kick(system, param, t + dt, dth, lbeg=.false.) + if (param%lgr) call pl%gr_pos_kick(param, dth) + call pl%lindrift(cb, dth, lbeg=.false.) + call pl%vb2vh(cb) + end select + end associate + + return + end subroutine helio_step_pl + + + module subroutine helio_step_tp(self, system, param, t, dt) + + !! author: David A. Minton + !! + !! Step active test particles ahead using Democratic Heliocentric method + !! + !! Adapted from David E. Kaufmann's Swifter routine helio_step_tp.f90 + !! Adapted from Hal Levison's Swift routine helio_step_tp.f + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize + ! Internals + real(DP) :: dth !! Half step size + + if (self%nbody == 0) return + + associate(tp => self) + select type(cb => system%cb) + class is (helio_cb) + dth = 0.5_DP * dt + if (tp%lfirst) then + call tp%vh2vb(vbcb = -cb%ptbeg) + tp%lfirst = .false. + end if + call tp%lindrift(cb, dth, lbeg=.true.) + call tp%kick(system, param, t, dth, lbeg=.true.) + if (param%lgr) call tp%gr_pos_kick(param, dth) + call tp%drift(system, param, dt) + call tp%kick(system, param, t + dt, dth, lbeg=.false.) + if (param%lgr) call tp%gr_pos_kick(param, dth) + call tp%lindrift(cb, dth, lbeg=.false.) + call tp%vb2vh(vbcb = -cb%ptend) + end select + end associate + + return + end subroutine helio_step_tp + +end submodule s_helio_step diff --git a/src/io/io.f90 b/src/io/io.f90 new file mode 100644 index 000000000..42cc8ddd9 --- /dev/null +++ b/src/io/io.f90 @@ -0,0 +1,1520 @@ +submodule (swiftest_classes) s_io + use swiftest +contains + + module subroutine io_conservation_report(self, param, lterminal) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Reports the current state of energy, mass, and angular momentum conservation in a run + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Input colleciton of user-defined parameters + logical, intent(in) :: lterminal !! Indicates whether to output information to the terminal screen + ! Internals + real(DP), dimension(NDIM) :: Ltot_now, Lorbit_now, Lspin_now + real(DP), dimension(NDIM), save :: Ltot_last, Lorbit_last, Lspin_last + real(DP), save :: ke_orbit_last, ke_spin_last, pe_last, Eorbit_last + real(DP) :: ke_orbit_now, ke_spin_now, pe_now, Eorbit_now + real(DP) :: Eorbit_error, Etotal_error, Ecoll_error + real(DP) :: Mtot_now, Merror + real(DP) :: Lmag_now, Lerror + character(len=*), parameter :: EGYFMT = '(ES23.16,10(",",ES23.16,:))' ! Format code for all simulation output + character(len=*), parameter :: EGYHEADER = '("t,Eorbit,Ecollisions,Lx,Ly,Lz,Mtot")' + integer(I4B), parameter :: EGYIU = 72 + character(len=*), parameter :: EGYTERMFMT = '(" DL/L0 = ", ES12.5 & + "; DEcollisions/|E0| = ", ES12.5, & + "; D(Eorbit+Ecollisions)/|E0| = ", ES12.5, & + "; DM/M0 = ", ES12.5)' + + associate(system => self, pl => self%pl, cb => self%cb, npl => self%pl%nbody, Ecollisions => self%Ecollisions, Lescape => self%Lescape, Mescape => self%Mescape, & + Euntracked => self%Euntracked, Eorbit_orig => param%Eorbit_orig, Mtot_orig => param%Mtot_orig, & + Ltot_orig => param%Ltot_orig(:), Lmag_orig => param%Lmag_orig, Lorbit_orig => param%Lorbit_orig(:), Lspin_orig => param%Lspin_orig(:), & + lfirst => param%lfirstenergy) + if (lfirst) then + if (param%out_stat == "OLD") then + open(unit = EGYIU, file = ENERGY_FILE, form = "formatted", status = "old", action = "write", position = "append") + else + open(unit = EGYIU, file = ENERGY_FILE, form = "formatted", status = "replace", action = "write") + write(EGYIU,EGYHEADER) + end if + end if + call system%get_energy_and_momentum(param) + ke_orbit_now = system%ke_orbit + ke_spin_now = system%ke_spin + pe_now = system%pe + Lorbit_now = system%Lorbit + Lspin_now = system%Lspin + Eorbit_now = ke_orbit_now + ke_spin_now + pe_now + Ltot_now(:) = Lorbit_now(:) + Lspin_now(:) + Lescape(:) + Mtot_now = cb%mass + sum(pl%mass(1:npl)) + system%Mescape + if (lfirst) then + Eorbit_orig = Eorbit_now + Mtot_orig = Mtot_now + Lorbit_orig(:) = Lorbit_now(:) + Lspin_orig(:) = Lspin_now(:) + Ltot_orig(:) = Ltot_now(:) + Lmag_orig = norm2(Ltot_orig(:)) + lfirst = .false. + end if + + write(EGYIU,EGYFMT) param%t, Eorbit_now, Ecollisions, Ltot_now, Mtot_now + flush(EGYIU) + if (.not.lfirst .and. lterminal) then + Lmag_now = norm2(Ltot_now) + Lerror = norm2(Ltot_now - Ltot_orig) / Lmag_orig + Eorbit_error = (Eorbit_now - Eorbit_orig) / abs(Eorbit_orig) + Ecoll_error = Ecollisions / abs(Eorbit_orig) + Etotal_error = (Eorbit_now - Ecollisions - Eorbit_orig - Euntracked) / abs(Eorbit_orig) + Merror = (Mtot_now - Mtot_orig) / Mtot_orig + write(*, egytermfmt) Lerror, Ecoll_error, Etotal_error, Merror + if (Ecoll_error > 0.0_DP) then + write(*,*) 'Something has gone wrong! Collisional energy should not be positive!' + write(*,*) 'dke_orbit: ',(ke_orbit_now - ke_orbit_last) / abs(Eorbit_orig) + write(*,*) 'dke_spin : ',(ke_spin_now - ke_spin_last) / abs(Eorbit_orig) + write(*,*) 'dpe : ',(pe_now - pe_last) / abs(Eorbit_orig) + write(*,*) + end if + end if + ke_orbit_last = ke_orbit_now + ke_spin_last = ke_spin_now + pe_last = pe_now + Eorbit_last = Eorbit_now + Lorbit_last(:) = Lorbit_now(:) + Lspin_last(:) = Lspin_now(:) + Ltot_last(:) = Ltot_now(:) + end associate + return + + end subroutine io_conservation_report + + + module subroutine io_dump_param(self, param_file_name) + !! author: David A. Minton + !! + !! Dump integration parameters to file + !! + !! Adapted from David E. Kaufmann's Swifter routine io_dump_param.f90 + !! Adapted from Martin Duncan's Swift routine io_dump_param.f + implicit none + ! Arguments + class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + ! Internals + integer(I4B), parameter :: LUN = 7 !! Unit number of output file + integer(I4B) :: ierr !! Error code + character(STRMAX) :: error_message !! Error message in UDIO procedure + + open(unit = LUN, file = param_file_name, status='replace', form = 'FORMATTED', iostat =ierr) + if (ierr /=0) then + write(*,*) 'Swiftest error.' + write(*,*) ' Could not open dump file: ',trim(adjustl(param_file_name)) + call util_exit(FAILURE) + end if + + !! todo: Currently this procedure does not work in user-defined derived-type input mode + !! due to compiler incompatabilities + !write(LUN,'(DT)') param + call self%writer(LUN, iotype = "none", v_list = [0], iostat = ierr, iomsg = error_message) + if (ierr /= 0) then + write(*,*) trim(adjustl(error_message)) + call util_exit(FAILURE) + end if + close(LUN) + + return + end subroutine io_dump_param + + + module subroutine io_dump_swiftest(self, param, msg) + !! author: David A. Minton + !! + !! Dump massive body data to files + !! + !! Adapted from David E. Kaufmann's Swifter routine: io_dump_pl.f90 and io_dump_tp.f90 + !! Adapted from Hal Levison's Swift routine io_dump_pl.f and io_dump_tp.f + implicit none + ! Arguments + class(swiftest_base), intent(inout) :: self !! Swiftest base object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + ! Internals + integer(I4B) :: ierr !! Error code + integer(I4B),parameter :: LUN = 7 !! Unit number for dump file + integer(I4B) :: iu = LUN + character(len=:), allocatable :: dump_file_name + + select type(self) + class is(swiftest_cb) + dump_file_name = trim(adjustl(param%incbfile)) + class is (swiftest_pl) + dump_file_name = trim(adjustl(param%inplfile)) + class is (swiftest_tp) + dump_file_name = trim(adjustl(param%intpfile)) + end select + open(unit = iu, file = dump_file_name, form = "UNFORMATTED", status = 'replace', iostat = ierr) + if (ierr /= 0) then + write(*, *) "Swiftest error:" + write(*, *) " Unable to open binary dump file " // dump_file_name + call util_exit(FAILURE) + end if + call self%write_frame(iu, param) + close(LUN) + + return + end subroutine io_dump_swiftest + + + module subroutine io_dump_system(self, param, msg) + !! author: David A. Minton + !! + !! Dumps the state of the system to files in case the simulation is interrupted. + !! As a safety mechanism, there are two dump files that are written in alternating order + !! so that if a dump file gets corrupted during writing, the user can restart from the older one. + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + ! Internals + class(swiftest_parameters), allocatable :: dump_param !! Local parameters variable used to parameters change input file names + !! to dump file-specific values without changing the user-defined values + integer(I4B), save :: idx = 1 !! Index of current dump file. Output flips between 2 files for extra security + !! in case the program halts during writing + character(len=:), allocatable :: param_file_name + real(DP) :: tfrac + + allocate(dump_param, source=param) + param_file_name = trim(adjustl(DUMP_PARAM_FILE(idx))) + dump_param%incbfile = trim(adjustl(DUMP_CB_FILE(idx))) + dump_param%inplfile = trim(adjustl(DUMP_PL_FILE(idx))) + dump_param%intpfile = trim(adjustl(DUMP_TP_FILE(idx))) + dump_param%out_form = XV + dump_param%out_stat = 'APPEND' + dump_param%T0 = param%t + call dump_param%dump(param_file_name) + + call self%cb%dump(dump_param) + if (self%pl%nbody > 0) call self%pl%dump(dump_param) + if (self%tp%nbody > 0) call self%tp%dump(dump_param) + + idx = idx + 1 + if (idx > NDUMPFILES) idx = 1 + + ! Print the status message (format code passed in from main driver) + tfrac = (param%t - param%t0) / (param%tstop - param%t0) + write(*,msg) param%t, tfrac, self%pl%nbody, self%tp%nbody + if (param%lenergy) call self%conservation_report(param, lterminal=.true.) + + return + end subroutine io_dump_system + + + module function io_get_args(integrator, param_file_name) result(ierr) + !! author: David A. Minton + !! + !! Reads in the name of the parameter file from command line arguments. + implicit none + ! Arguments + integer(I4B) :: integrator !! Symbolic code of the requested integrator + character(len=:), allocatable :: param_file_name !! Name of the input parameters file + ! Result + integer(I4B) :: ierr !! I/O error code + ! Internals + character(len=STRMAX) :: arg1, arg2 + integer :: narg,ierr_arg1, ierr_arg2 + character(len=*),parameter :: linefmt = '(A)' + + ierr = -1 ! Default is to fail + narg = command_argument_count() ! + if (narg == 2) then + call get_command_argument(1, arg1, status = ierr_arg1) + call get_command_argument(2, arg2, status = ierr_arg2) + if ((ierr_arg1 == 0) .and. (ierr_arg2 == 0)) then + ierr = 0 + call io_toupper(arg1) + select case(arg1) + case('BS') + integrator = BS + case('HELIO') + integrator = HELIO + case('RA15') + integrator = RA15 + case('TU4') + integrator = TU4 + case('WHM') + integrator = WHM + case('RMVS') + integrator = RMVS + case('SYMBA') + integrator = SYMBA + case('RINGMOONS') + integrator = RINGMOONS + case default + integrator = UNKNOWN_INTEGRATOR + write(*,*) trim(adjustl(arg1)) // ' is not a valid integrator.' + ierr = -1 + end select + param_file_name = trim(adjustl(arg2)) + end if + else + call get_command_argument(1, arg1, status = ierr_arg1) + if (ierr_arg1 == 0) then + if (arg1 == '-v' .or. arg1 == '--version') then + call util_version() + else if (arg1 == '-h' .or. arg1 == '--help') then + call util_exit(HELP) + end if + end if + end if + if (ierr /= 0) call util_exit(USAGE) + + return + end function io_get_args + + + module function io_get_token(buffer, ifirst, ilast, ierr) result(token) + !! author: David A. Minton + !! + !! Retrieves a character token from an input string. Here a token is defined as any set of contiguous non-blank characters not + !! beginning with or containing "!". If "!" is present, any remaining part of the buffer including the "!" is ignored + !! + !! Adapted from David E. Kaufmann's Swifter routine io_get_token.f90 + implicit none + ! Arguments + character(len=*), intent(in) :: buffer !! Input string buffer + integer(I4B), intent(inout) :: ifirst !! Index of the buffer at which to start the search for a token + integer(I4B), intent(out) :: ilast !! Index of the buffer at the end of the returned token + integer(I4B), intent(out) :: ierr !! Error code + ! Result + character(len=:), allocatable :: token !! Returned token string + ! Internals + integer(I4B) :: i,ilength + + ilength = len(buffer) + + if (ifirst > ilength) then + ilast = ifirst + ierr = -1 !! Bad input + token = '' + return + end if + do i = ifirst, ilength + if (buffer(i:i) /= ' ') exit + end do + if ((i > ilength) .or. (buffer(i:i) == '!')) then + ifirst = i + ilast = i + ierr = -2 !! No valid token + token = '' + return + end if + ifirst = i + do i = ifirst, ilength + if ((buffer(i:i) == ' ') .or. (buffer(i:i) == '!')) exit + end do + ilast = i - 1 + ierr = 0 + + token = buffer(ifirst:ilast) + + return + end function io_get_token + + + module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Read in parameters for the integration + !! Currently this procedure does not work in user-defined derived-type input mode + !! e.g. read(unit,'(DT)') param + !! as the newline characters are ignored in the input file when compiled in ifort. + !! + !! Adapted from David E. Kaufmann's Swifter routine io_init_param.f90 + !! Adapted from Martin Duncan's Swift routine io_init_param.f + implicit none + ! Arguments + class(swiftest_parameters), intent(inout) :: self !! Collection of parameters + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + ! Internals + logical :: t0_set = .false. !! Is the initial time set in the input file? + logical :: tstop_set = .false. !! Is the final time set in the input file? + logical :: dt_set = .false. !! Is the step size set in the input file? + integer(I4B) :: ilength, ifirst, ilast, i !! Variables used to parse input file + character(STRMAX) :: line !! Line of the input file + character (len=:), allocatable :: line_trim,param_name, param_value !! Strings used to parse the param file + character(*),parameter :: linefmt = '(A)' !! Format code for simple text string + + ! Parse the file line by line, extracting tokens then matching them up with known parameters if possible + associate(param => self) + do + read(unit = unit, fmt = linefmt, iostat = iostat, end = 1) line + line_trim = trim(adjustl(line)) + ilength = len(line_trim) + if ((ilength /= 0)) then + ifirst = 1 + ! Read the pair of tokens. The first one is the parameter name, the second is the value. + param_name = io_get_token(line_trim, ifirst, ilast, iostat) + if (param_name == '') cycle ! No parameter name (usually because this line is commented out) + call io_toupper(param_name) + ifirst = ilast + 1 + param_value = io_get_token(line_trim, ifirst, ilast, iostat) + select case (param_name) + case ("T0") + read(param_value, *) param%t0 + t0_set = .true. + case ("TSTOP") + read(param_value, *) param%tstop + tstop_set = .true. + case ("DT") + read(param_value, *) param%dt + dt_set = .true. + case ("CB_IN") + param%incbfile = param_value + case ("PL_IN") + param%inplfile = param_value + case ("TP_IN") + param%intpfile = param_value + case ("IN_TYPE") + call io_toupper(param_value) + param%in_type = param_value + case ("ISTEP_OUT") + read(param_value, *) param%istep_out + case ("BIN_OUT") + param%outfile = param_value + case ("OUT_TYPE") + call io_toupper(param_value) + param%out_type = param_value + case ("OUT_FORM") + call io_toupper(param_value) + param%out_form = param_value + case ("OUT_STAT") + call io_toupper(param_value) + param%out_stat = param_value + case ("ISTEP_DUMP") + read(param_value, *) param%istep_dump + case ("CHK_CLOSE") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%lclose = .true. + case ("CHK_RMIN") + read(param_value, *) param%rmin + case ("CHK_RMAX") + read(param_value, *) param%rmax + case ("CHK_EJECT") + read(param_value, *) param%rmaxu + case ("CHK_QMIN") + read(param_value, *) param%qmin + case ("CHK_QMIN_COORD") + call io_toupper(param_value) + param%qmin_coord = param_value + case ("CHK_QMIN_RANGE") + read(param_value, *) param%qmin_alo + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%qmin_ahi + case ("ENC_OUT") + param%enc_out = param_value + case ("DISCARD_OUT") + param%discard_out = param_value + case ("EXTRA_FORCE") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%lextra_force = .true. + case ("BIG_DISCARD") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T' ) param%lbig_discard = .true. + case ("RHILL_PRESENT") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T' ) param%lrhill_present = .true. + case ("MU2KG") + read(param_value, *) param%MU2KG + case ("TU2S") + read(param_value, *) param%TU2S + case ("DU2M") + read(param_value, *) param%DU2M + case ("ENERGY") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%lenergy = .true. + case ("GR") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%lgr = .true. + case ("ROTATION") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%lrotation = .true. + case ("TIDES") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == 'T') param%ltides = .true. + case ("FIRSTKICK") + call io_toupper(param_value) + if (param_value == "NO" .or. param_value == 'F') param%lfirstkick = .false. + case ("FIRSTENERGY") + call io_toupper(param_value) + if (param_value == "NO" .or. param_value == 'F') param%lfirstenergy = .false. + case("EORBIT_ORIG") + read(param_value, *) param%Eorbit_orig + case("MTOT_ORIG") + read(param_value, *) param%Mtot_orig + case("LTOT_ORIG") + read(param_value, *) param%Ltot_orig(1) + do i = 2, NDIM + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%Ltot_orig(i) + end do + param%Lmag_orig = norm2(param%Ltot_orig(:)) + case("LORBIT_ORIG") + read(param_value, *) param%Lorbit_orig(1) + do i = 2, NDIM + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%Lorbit_orig(i) + end do + case("LSPIN_ORIG") + read(param_value, *) param%Lspin_orig(1) + do i = 2, NDIM + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%Lspin_orig(i) + end do + case("LESCAPE") + read(param_value, *) param%Lescape(1) + do i = 2, NDIM + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%Lescape(i) + end do + case("MESCAPE") + read(param_value, *) param%Mescape + case("ECOLLISIONS") + read(param_value, *) param%Ecollisions + case("EUNTRACKED") + read(param_value, *) param%Euntracked + case ("NPLMAX", "NTPMAX", "MTINY", "PARTICLE_FILE", "FRAGMENTATION", "SEED", "YARKOVSKY", "YORP") ! Ignore SyMBA-specific, not-yet-implemented, or obsolete input parameters + case default + write(iomsg,*) "Unknown parameter -> ",param_name + iostat = -1 + return + end select + end if + end do + 1 continue + iostat = 0 + + !! Do basic sanity checks on the input values + if ((.not. t0_set) .or. (.not. tstop_set) .or. (.not. dt_set)) then + write(iomsg,*) 'Valid simulation time not set' + iostat = -1 + return + end if + if (param%dt <= 0.0_DP) then + write(iomsg,*) 'Invalid timestep: ' + iostat = -1 + return + end if + if (param%inplfile == "") then + write(iomsg,*) 'No valid massive body file in input file' + iostat = -1 + return + end if + if ((param%in_type /= REAL8_TYPE) .and. (param%in_type /= "ASCII")) then + write(iomsg,*) 'Invalid input file type:',trim(adjustl(param%in_type)) + iostat = -1 + return + end if + if ((param%istep_out <= 0) .and. (param%istep_dump <= 0)) then + write(iomsg,*) 'Invalid istep' + iostat = -1 + return + end if + if ((param%istep_out > 0) .and. (param%outfile == "")) then + write(iomsg,*) 'Invalid outfile' + iostat = -1 + return + end if + if (param%outfile /= "") then + if ((param%out_type /= REAL4_TYPE) .and. (param%out_type /= REAL8_TYPE) .and. & + (param%out_type /= SWIFTER_REAL4_TYPE) .and. (param%out_type /= SWIFTER_REAL8_TYPE)) then + write(iomsg,*) 'Invalid out_type: ',trim(adjustl(param%out_type)) + iostat = -1 + return + end if + if ((param%out_form /= "EL") .and. (param%out_form /= "XV")) then + write(iomsg,*) 'Invalid out_form: ',trim(adjustl(param%out_form)) + iostat = -1 + return + end if + if ((param%out_stat /= "NEW") .and. (param%out_stat /= "REPLACE") .and. (param%out_stat /= "APPEND") .and. (param%out_stat /= "UNKNOWN")) then + write(iomsg,*) 'Invalid out_stat: ',trim(adjustl(param%out_stat)) + iostat = -1 + return + end if + end if + if (param%qmin > 0.0_DP) then + if ((param%qmin_coord /= "HELIO") .and. (param%qmin_coord /= "BARY")) then + write(iomsg,*) 'Invalid qmin_coord: ',trim(adjustl(param%qmin_coord)) + iostat = -1 + return + end if + if ((param%qmin_alo <= 0.0_DP) .or. (param%qmin_ahi <= 0.0_DP)) then + write(iomsg,*) 'Invalid qmin vals' + iostat = -1 + return + end if + end if + if (param%ltides .and. .not. param%lrotation) then + write(iomsg,*) 'Tides require rotation to be turned on' + iostat = -1 + return + end if + + write(*,*) "T0 = ",param%t0 + write(*,*) "TSTOP = ",param%tstop + write(*,*) "DT = ",param%dt + write(*,*) "CB_IN = ",trim(adjustl(param%incbfile)) + write(*,*) "PL_IN = ",trim(adjustl(param%inplfile)) + write(*,*) "TP_IN = ",trim(adjustl(param%intpfile)) + write(*,*) "IN_TYPE = ",trim(adjustl(param%in_type)) + write(*,*) "ISTEP_OUT = ",param%istep_out + write(*,*) "BIN_OUT = ",trim(adjustl(param%outfile)) + write(*,*) "OUT_TYPE = ",trim(adjustl(param%out_type)) + write(*,*) "OUT_FORM = ",trim(adjustl(param%out_form)) + write(*,*) "OUT_STAT = ",trim(adjustl(param%out_stat)) + write(*,*) "ISTEP_DUMP = ",param%istep_dump + write(*,*) "CHK_CLOSE = ",param%lclose + write(*,*) "CHK_RMIN = ",param%rmin + write(*,*) "CHK_RMAX = ",param%rmax + write(*,*) "CHK_EJECT = ",param%rmaxu + write(*,*) "CHK_QMIN = ",param%qmin + write(*,*) "CHK_QMIN_COORD = ",trim(adjustl(param%qmin_coord)) + write(*,*) "CHK_QMIN_RANGE = ",param%qmin_alo, param%qmin_ahi + write(*,*) "EXTRA_FORCE = ",param%lextra_force + write(*,*) "RHILL_PRESENT = ",param%lrhill_present + write(*,*) "ROTATION = ", param%lrotation + write(*,*) "TIDES = ", param%ltides + write(*,*) "ENERGY = ",param%lenergy + write(*,*) "MU2KG = ",param%MU2KG + write(*,*) "TU2S = ",param%TU2S + write(*,*) "DU2M = ",param%DU2M + if (trim(adjustl(param%enc_out)) /= "") then + write(*,*) "ENC_OUT = ",trim(adjustl(param%enc_out)) + else + write(*,*) "! ENC_OUT not set: Encounters will not be recorded to file" + end if + if (trim(adjustl(param%discard_out)) /= "") then + write(*,*) "DISCARD_OUT = ",trim(adjustl(param%discard_out)) + write(*,*) "BIG_DISCARD = ",param%lbig_discard + else + write(*,*) "! DISCARD_OUT not set: Discards will not be recorded to file" + write(*,*) "! BIG_DISCARD = ",param%lbig_discard + end if + + if ((param%MU2KG < 0.0_DP) .or. (param%TU2S < 0.0_DP) .or. (param%DU2M < 0.0_DP)) then + write(iomsg,*) 'Invalid unit conversion factor' + iostat = -1 + return + end if + + ! Calculate the G for the system units + param%GU = GC / (param%DU2M**3 / (param%MU2KG * param%TU2S**2)) + + ! Calculate the inverse speed of light in the system units + param%inv_c2 = einsteinC * param%TU2S / param%DU2M + param%inv_c2 = (param%inv_c2)**(-2) + + associate(integrator => v_list(1)) + if (integrator == RMVS) then + if (.not.param%lclose) then + write(iomsg,*) 'This integrator requires CHK_CLOSE to be enabled.' + iostat = -1 + return + end if + end if + + ! Determine if the GR flag is set correctly for this integrator + select case(integrator) + case(WHM, RMVS, HELIO, SYMBA) + write(*,*) "GR = ", param%lgr + case default + if (param%lgr) write(iomsg, *) 'GR is not yet implemented for this integrator. This parameter will be ignored.' + param%lgr = .false. + end select + end associate + + iostat = 0 + end associate + + return + end subroutine io_param_reader + + + module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) + !! author: David A. Minton + !! + !! Dump integration parameters to file + !! + !! Adapted from David E. Kaufmann's Swifter routine io_dump_param.f90 + !! Adapted from Martin Duncan's Swift routine io_dump_param.f + implicit none + ! Arguments + class(swiftest_parameters),intent(in) :: self !! Collection of parameters + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! Not used in this procedure + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + ! Internals + character(*),parameter :: Ifmt = '(I0)' !! Format label for integer values + character(*),parameter :: Rfmt = '(ES25.17)' !! Format label for real values + character(*),parameter :: Rarrfmt = '(3(ES25.17,1X))' !! Format label for real values + character(*),parameter :: Lfmt = '(L1)' !! Format label for logical values + character(len=*), parameter :: Afmt = '(A25,1X,64(:,A25,1X))' + character(256) :: param_name, param_value + type character_array + character(25) :: value + end type character_array + type(character_array), dimension(:), allocatable :: param_array + integer(I4B) :: i + + associate(param => self) + write(param_name, Afmt) "T0"; write(param_value,Rfmt) param%t0; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "TSTOP"; write(param_value, Rfmt) param%tstop; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "DT"; write(param_value, Rfmt) param%dt; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "PL_IN"; write(param_value, Afmt) trim(adjustl(param%inplfile)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "TP_in"; write(param_value, Afmt) trim(adjustl(param%intpfile)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "IN_TYPE"; write(param_value, Afmt) trim(adjustl(param%in_type)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + if (param%istep_out > 0) then + write(param_name, Afmt) "ISTEP_OUT"; write(param_value, Ifmt) param%istep_out; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "BIN_OUT"; write(param_value, Afmt) trim(adjustl(param%outfile)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "OUT_TYPE"; write(param_value, Afmt) trim(adjustl(param%out_type)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "OUT_FORM"; write(param_value, Afmt) trim(adjustl(param%out_form)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "OUT_STAT"; write(param_value, Afmt) "APPEND"; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + end if + write(param_name, Afmt) "ENC_OUT"; write(param_value, Afmt) trim(adjustl(param%enc_out)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + if (param%istep_dump > 0) then + write(param_name, Afmt) "ISTEP_DUMP"; write(param_value, Ifmt) param%istep_dump; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + end if + write(param_name, Afmt) "CHK_RMIN"; write(param_value, Rfmt) param%rmin; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "CHK_RMAX"; write(param_value, Rfmt) param%rmax; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "CHK_EJECT"; write(param_value, Rfmt) param%rmaxu; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "CHK_QMIN"; write(param_value, Rfmt) param%qmin; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + if (param%qmin >= 0.0_DP) then + write(param_name, Afmt) "CHK_QMIN_COORD"; write(param_value, Afmt) trim(adjustl(param%qmin_coord)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + allocate(param_array(2)) + write(param_array(1)%value, Rfmt) param%qmin_alo + write(param_array(2)%value, Rfmt) param%qmin_ahi + write(param_name, Afmt) "CHK_QMIN_RANGE"; write(unit, Afmt) adjustl(param_name), adjustl(param_array(1)%value), adjustl(param_array(2)%value) + end if + write(param_name, Afmt) "MU2KG"; write(param_value, Rfmt) param%MU2KG; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "TU2S"; write(param_value, Rfmt) param%TU2S ; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "DU2M"; write(param_value, Rfmt) param%DU2M; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "RHILL_PRESENT"; write(param_value, Lfmt) param%lrhill_present; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "EXTRA_FORCE"; write(param_value, Lfmt) param%lextra_force; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "BIG_DISCARD"; write(param_value, Lfmt) param%lbig_discard; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "CHK_CLOSE"; write(param_value, Lfmt) param%lclose; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "ENERGY"; write(param_value, Lfmt) param%lenergy; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "GR"; write(param_value, Lfmt) param%lgr; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "ROTATION"; write(param_value, Lfmt) param%lrotation; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "TIDES"; write(param_value, Lfmt) param%ltides; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + + if (param%lenergy) then + write(param_name, Afmt) "FIRSTENERGY"; write(param_value, Lfmt) param%lfirstenergy; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "EORBIT_ORIG"; write(param_value, Rfmt) param%Eorbit_orig; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "MTOT_ORIG"; write(param_value, Rfmt) param%Mtot_orig; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(unit, '("LTOT_ORIG ",3(1X,ES25.17))') param%Ltot_orig(:) + write(unit, '("LORBIT_ORIG",3(1X,ES25.17))') param%Lorbit_orig(:) + write(unit, '("LSPIN_ORIG ",3(1X,ES25.17))') param%Lspin_orig(:) + write(unit, '("LESCAPE ",3(1X,ES25.17))') param%Lescape(:) + + write(param_name, Afmt) "MESCAPE"; write(param_value, Rfmt) param%Mescape; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "ECOLLISIONS"; write(param_value, Rfmt) param%Ecollisions; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "EUNTRACKED"; write(param_value, Rfmt) param%Euntracked; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + end if + write(param_name, Afmt) "FIRSTKICK"; write(param_value, Lfmt) param%lfirstkick; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + + + + iostat = 0 + iomsg = "UDIO not implemented" + end associate + + return + end subroutine io_param_writer + + + module subroutine io_read_body_in(self, param) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Read in either test particle or massive body data + !! + !! Adapted from David E. Kaufmann's Swifter routine swiftest_init_pl.f90 and swiftest_init_tp.f90 + !! Adapted from Martin Duncan's Swift routine swiftest_init_pl.f and swiftest_init_tp.f + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + integer(I4B), parameter :: LUN = 7 !! Unit number of input file + integer(I4B) :: iu = LUN + integer(I4B) :: i, ierr, nbody + logical :: is_ascii, is_pl + character(len=:), allocatable :: infile + real(DP) :: t + real(QP) :: val + + ! Select the appropriate polymorphic class (test particle or massive body) + select type(self) + class is (swiftest_pl) + infile = param%inplfile + is_pl = .true. + class is (swiftest_tp) + infile = param%intpfile + is_pl = .false. + end select + + ierr = 0 + is_ascii = (param%in_type == 'ASCII') + select case(param%in_type) + case(ASCII_TYPE) + open(unit = iu, file = infile, status = 'old', form = 'FORMATTED', iostat = ierr) + read(iu, *, iostat = ierr) nbody + call self%setup(nbody, param) + if (nbody > 0) then + do i = 1, nbody + select type(self) + class is (swiftest_pl) + if (param%lrhill_present) then + read(iu, *, iostat=ierr, err=100) self%id(i), val, self%rhill(i) + else + read(iu, *, iostat=ierr, err=100) self%id(i), val + end if + self%Gmass(i) = real(val, kind=DP) + self%mass(i) = real(val / param%GU, kind=DP) + if (param%lclose) read(iu, *, iostat=ierr, err=100) self%radius(i) + if (param%lrotation) then + read(iu, iostat=ierr, err=100) self%Ip(:, i) + read(iu, iostat=ierr, err=100) self%rot(:, i) + end if + if (param%ltides) then + read(iu, iostat=ierr, err=100) self%k2(i) + read(iu, iostat=ierr, err=100) self%Q(i) + end if + class is (swiftest_tp) + read(iu, *, iostat=ierr, err=100) self%id(i) + end select + read(iu, *, iostat=ierr, err=100) self%xh(1, i), self%xh(2, i), self%xh(3, i) + read(iu, *, iostat=ierr, err=100) self%vh(1, i), self%vh(2, i), self%vh(3, i) + self%status(i) = ACTIVE + self%lmask(i) = .true. + end do + end if + case (REAL4_TYPE, REAL8_TYPE) !, SWIFTER_REAL4_TYPE, SWIFTER_REAL8_TYPE) + open(unit=iu, file=infile, status='old', form='UNFORMATTED', iostat=ierr) + read(iu, iostat=ierr, err=100) nbody + call self%setup(nbody, param) + if (nbody > 0) then + call self%read_frame(iu, param, XV, ierr) + self%status(:) = ACTIVE + self%lmask(:) = .true. + end if + case default + write(*,*) trim(adjustl(param%in_type)) // ' is an unrecognized file type' + ierr = -1 + end select + close(iu) + + 100 if (ierr /= 0 ) then + write(*,*) 'Error reading in initial conditions from ',trim(adjustl(infile)) + call util_exit(FAILURE) + end if + + return + end subroutine io_read_body_in + + + module subroutine io_read_cb_in(self, param) + !! author: David A. Minton + !! + !! Reads in central body data + !! + !! Adapted from David E. Kaufmann's Swifter routine swiftest_init_pl.f90 + !! Adapted from Martin Duncan's Swift routine swiftest_init_pl.f + implicit none + ! Arguments + class(swiftest_cb), intent(inout) :: self + class(swiftest_parameters), intent(inout) :: param + ! Internals + integer(I4B), parameter :: LUN = 7 !! Unit number of input file + integer(I4B) :: iu = LUN + integer(I4B) :: ierr + logical :: is_ascii + real(DP) :: t + real(QP) :: val + + ierr = 0 + is_ascii = (param%in_type == 'ASCII') + if (is_ascii) then + open(unit = iu, file = param%incbfile, status = 'old', form = 'FORMATTED', iostat = ierr) + !read(iu, *, iostat = ierr) self%id + read(iu, *, iostat = ierr) val + self%Gmass = real(val, kind=DP) + self%mass = real(val / param%GU, kind=DP) + read(iu, *, iostat = ierr) self%radius + read(iu, *, iostat = ierr) self%j2rp2 + read(iu, *, iostat = ierr) self%j4rp4 + else + open(unit = iu, file = param%incbfile, status = 'old', form = 'UNFORMATTED', iostat = ierr) + call self%read_frame(iu, param, XV, ierr) + end if + close(iu) + if (ierr /= 0) then + write(*,*) 'Error opening massive body initial conditions file ',trim(adjustl(param%incbfile)) + call util_exit(FAILURE) + end if + if (self%j2rp2 /= 0.0_DP) param%loblatecb = .true. + + return + end subroutine io_read_cb_in + + + + function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + xh1, xh2, vh1, vh2, enc_out, out_type) result(ierr) + !! author: David A. Minton + !! + !! Read close encounter data from input binary files + !! Other than time t, there is no direct file input from this function + !! Function returns read error status (0 = OK, nonzero = ERROR) + !! Adapted from David E. Kaufmann's Swifter routine: io_read_encounter.f90 + implicit none + ! Arguments + integer(I4B), intent(out) :: name1, name2 + real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(out) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: enc_out, out_type + ! Result + integer(I4B) :: ierr + ! Internals + logical , save :: lfirst = .true. + integer(I4B), parameter :: lun = 30 + integer(I4B), save :: iu = lun + + if (lfirst) then + open(unit = iu, file = enc_out, status = 'OLD', form = 'UNFORMATTED', iostat = ierr) + if (ierr /= 0) then + write(*, *) "Swiftest Error:" + write(*, *) " unable to open binary encounter file" + call util_exit(FAILURE) + end if + lfirst = .false. + end if + read(iu, iostat = ierr) t + if (ierr /= 0) then + close(unit = iu, iostat = ierr) + return + end if + + read(iu, iostat = ierr) name1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), vh1(3), mass1, radius1 + if (ierr /= 0) then + close(unit = iu, iostat = ierr) + return + end if + read(iu, iostat = ierr) name2, xh2(2), xh2(2), xh2(3), vh2(2), vh2(2), vh2(3), mass2, radius2 + if (ierr /= 0) then + close(unit = iu, iostat = ierr) + return + end if + + return + end function io_read_encounter + + + module subroutine io_read_frame_body(self, iu, param, form, ierr) + !! author: David A. Minton + !! + !! Reads a frame of output of either test particle or massive body data from a binary output file + !! + !! Adapted from David E. Kaufmann's Swifter routine io_read_frame.f90 + !! Adapted from Hal Levison's Swift routine io_read_frame.F + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + + associate(n => self%nbody) + read(iu, iostat=ierr, err=100) self%id(:) + !read(iu, iostat=ierr, err=100) self%name(1:n) + select case (form) + case (EL) + if (.not.allocated(self%a)) allocate(self%a(n)) + if (.not.allocated(self%e)) allocate(self%e(n)) + if (.not.allocated(self%inc)) allocate(self%inc(n)) + if (.not.allocated(self%capom)) allocate(self%capom(n)) + if (.not.allocated(self%omega)) allocate(self%omega(n)) + if (.not.allocated(self%capm)) allocate(self%capm(n)) + read(iu, iostat=ierr, err=100) self%a(:) + read(iu, iostat=ierr, err=100) self%e(:) + read(iu, iostat=ierr, err=100) self%inc(:) + read(iu, iostat=ierr, err=100) self%capom(:) + read(iu, iostat=ierr, err=100) self%omega(:) + read(iu, iostat=ierr, err=100) self%capm(:) + case (XV) + read(iu, iostat=ierr, err=100) self%xh(1, :) + read(iu, iostat=ierr, err=100) self%xh(2, :) + read(iu, iostat=ierr, err=100) self%xh(3, :) + read(iu, iostat=ierr, err=100) self%vh(1, :) + read(iu, iostat=ierr, err=100) self%vh(2, :) + read(iu, iostat=ierr, err=100) self%vh(3, :) + end select + select type(pl => self) + class is (swiftest_pl) ! Additional output if the passed polymorphic object is a massive body + read(iu, iostat=ierr, err=100) pl%Gmass(:) + pl%mass(:) = pl%Gmass(:) / param%GU + if (param%lrhill_present) read(iu, iostat=ierr, err=100) pl%rhill(:) + read(iu, iostat=ierr, err=100) pl%radius(:) + if (param%lrotation) then + read(iu, iostat=ierr, err=100) pl%rot(1, :) + read(iu, iostat=ierr, err=100) pl%rot(2, :) + read(iu, iostat=ierr, err=100) pl%rot(3, :) + read(iu, iostat=ierr, err=100) pl%Ip(1, :) + read(iu, iostat=ierr, err=100) pl%Ip(2, :) + read(iu, iostat=ierr, err=100) pl%Ip(3, :) + end if + if (param%ltides) then + read(iu, iostat=ierr, err=100) pl%k2(1:n) + read(iu, iostat=ierr, err=100) pl%Q(1:n) + end if + end select + end associate + + 100 if (ierr /=0) then + write(*,*) 'Error reading Swiftest body data' + call util_exit(FAILURE) + end if + + return + end subroutine io_read_frame_body + + + module subroutine io_read_frame_cb(self, iu, param, form, ierr) + !! author: David A. Minton + !! + !! Reads a frame of output of central body data to the binary output file + !! + !! Adapted from David E. Kaufmann's Swifter routine io_read_frame.f90 + !! Adapted from Hal Levison's Swift routine io_read_frame.F + implicit none + ! Arguments + class(swiftest_cb), intent(inout) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error cod + + read(iu, iostat=ierr, err=100) self%id + !read(iu, iostat=ierr, err=100) self%name + read(iu, iostat=ierr, err=100) self%Gmass + self%mass = self%Gmass / param%GU + read(iu, iostat=ierr, err=100) self%radius + read(iu, iostat=ierr, err=100) self%j2rp2 + read(iu, iostat=ierr, err=100) self%j4rp4 + if (param%lrotation) then + read(iu, iostat=ierr, err=100) self%Ip(:) + read(iu, iostat=ierr, err=100) self%rot(:) + end if + if (param%ltides) then + read(iu, iostat=ierr, err=100) self%k2 + read(iu, iostat=ierr, err=100) self%Q + end if + 100 if (ierr /=0) then + write(*,*) 'Error reading central body data' + call util_exit(FAILURE) + end if + + return + end subroutine io_read_frame_cb + + + module subroutine io_read_frame_system(self, iu, param, form, ierr) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Read a frame (header plus records for each massive body and active test particle) from a output binary file + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + ! Internals + logical, save :: lfirst = .true. + + iu = BINUNIT + if (lfirst) then + open(unit = iu, file = param%outfile, status = 'OLD', form = 'UNFORMATTED', iostat = ierr) + lfirst = .false. + if (ierr /= 0) then + write(*, *) "Swiftest error:" + write(*, *) " Binary output file already exists or cannot be accessed" + return + end if + end if + ierr = io_read_hdr(iu, param%t, self%pl%nbody, self%tp%nbody, param%out_form, param%out_type) + if (ierr /= 0) then + write(*, *) "Swiftest error:" + write(*, *) " Binary output file already exists or cannot be accessed" + return + end if + call self%cb%read_frame(iu, param, form, ierr) + if (ierr /= 0) return + call self%pl%read_frame(iu, param, form, ierr) + if (ierr /= 0) return + call self%tp%read_frame(iu, param, form, ierr) + + return + end subroutine io_read_frame_system + + + function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) + !! author: David A. Minton + !! + !! Read frame header from input binary files + !! Function returns read error status (0 = OK, nonzero = ERROR) + !! Adapted from David E. Kaufmann's Swifter routine: io_read_hdr.f90 + !! Adapted from Hal Levison's Swift routine io_read_hdr.f + implicit none + ! Arguments + integer(I4B), intent(in) :: iu + integer(I4B), intent(out) :: npl, ntp + character(*), intent(out) :: out_form + real(DP), intent(out) :: t + character(*), intent(in) :: out_type + ! Result + integer(I4B) :: ierr + ! Internals + real(SP) :: ttmp + + select case (out_type) + case (REAL4_TYPE, SWIFTER_REAL4_TYPE) + read(iu, iostat = ierr) ttmp, npl, ntp, out_form + if (ierr /= 0) return + t = ttmp + case (REAL8_TYPE, SWIFTER_REAL8_TYPE) + read(iu, iostat = ierr) t + read(iu, iostat = ierr) npl + read(iu, iostat = ierr) ntp + read(iu, iostat = ierr) out_form + case default + write(*,*) trim(adjustl(out_type)) // ' is an unrecognized file type' + ierr = -1 + end select + + return + end function io_read_hdr + + module subroutine io_read_param_in(self, param_file_name) + !! author: David A. Minton + !! + !! Read in parameters for the integration + !! + !! Adapted from David E. Kaufmann's Swifter routine io_init_param.f90 + !! Adapted from Martin Duncan's Swift routine io_init_param.f + implicit none + ! Arguments + class(swiftest_parameters),intent(inout) :: self !! Current run configuration parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + ! Internals + integer(I4B), parameter :: LUN = 7 !! Unit number of input file + integer(I4B) :: ierr = 0 !! Input error code + character(STRMAX) :: error_message !! Error message in UDIO procedure + + ! Read in name of parameter file + write(*, *) 'Parameter input file is ', trim(adjustl(param_file_name)) + write(*, *) ' ' + 100 format(A) + open(unit = LUN, file = param_file_name, status = 'old', iostat = ierr) + if (ierr /= 0) then + write(*,*) 'Swiftest error: ', ierr + write(*,*) ' Unable to open file ',trim(adjustl(param_file_name)) + call util_exit(FAILURE) + end if + + !! todo: Currently this procedure does not work in user-defined derived-type input mode + !! as the newline characters are ignored in the input file when compiled in ifort. + + !read(LUN,'(DT)', iostat= ierr, iomsg = error_message) param + call self%reader(LUN, iotype= "none", v_list = [self%integrator], iostat = ierr, iomsg = error_message) + if (ierr /= 0) then + write(*,*) 'Swiftest error reading ', trim(adjustl(param_file_name)) + write(*,*) ierr,trim(adjustl(error_message)) + call util_exit(FAILURE) + end if + + return + end subroutine io_read_param_in + + + module subroutine io_toupper(string) + !! author: David A. Minton + !! + !! Convert string to uppercase + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_toupper.f90 + implicit none + ! Arguments + character(*), intent(inout) :: string !! String to make upper case + ! Internals + integer(I4B) :: i, length, idx + + length = len(string) + do i = 1, length + idx = iachar(string(i:i)) + if ((idx >= lowercase_begin) .and. (idx <= lowercase_end)) then + idx = idx + uppercase_offset + string(i:i) = achar(idx) + end if + end do + + return + end subroutine io_toupper + + + module subroutine io_write_discard(self, param) + !! author: David A. Minton + !! + !! Write out information about discarded test particle + !! + !! Adapted from David E. Kaufmann's Swifter routine io_discard_write.f90 + !! Adapted from Hal Levison's Swift routine io_discard_write.f + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B), parameter :: LUN = 40 + integer(I4B) :: i, ierr + logical, save :: lfirst = .true. + real(DP), dimension(:,:), allocatable :: vh + character(*), parameter :: HDRFMT = '(E23.16, 1X, I8, 1X, L1)' + character(*), parameter :: NAMEFMT = '(A, 2(1X, I8))' + character(*), parameter :: VECFMT = '(3(E23.16, 1X))' + character(*), parameter :: NPLFMT = '(I8)' + character(*), parameter :: PLNAMEFMT = '(I8, 2(1X, E23.16))' + class(swiftest_body), allocatable :: pltemp + + associate(tp_discards => self%tp_discards, nsp => self%tp_discards%nbody, pl => self%pl, npl => self%pl%nbody) + if (nsp == 0) return + select case(param%out_stat) + case('APPEND') + open(unit = LUN, file = param%discard_out, status = 'OLD', position = 'APPEND', form = 'FORMATTED', iostat = ierr) + case('NEW', 'REPLACE', 'UNKNOWN') + open(unit = LUN, file = param%discard_out, status = param%out_stat, form = 'FORMATTED', iostat = ierr) + case default + write(*,*) 'Invalid status code for OUT_STAT: ',trim(adjustl(param%out_stat)) + call util_exit(FAILURE) + end select + lfirst = .false. + if (param%lgr) call tp_discards%pv2v(param) + + write(LUN, HDRFMT) param%t, nsp, param%lbig_discard + do i = 1, nsp + write(LUN, NAMEFMT) SUB, tp_discards%id(i), tp_discards%status(i) + write(LUN, VECFMT) tp_discards%xh(1, i), tp_discards%xh(2, i), tp_discards%xh(3, i) + write(LUN, VECFMT) tp_discards%vh(1, i), tp_discards%vh(2, i), tp_discards%vh(3, i) + end do + if (param%lbig_discard) then + if (param%lgr) then + allocate(pltemp, source = pl) + call pltemp%pv2v(param) + allocate(vh, source = pltemp%vh) + deallocate(pltemp) + else + allocate(vh, source = pl%vh) + end if + + write(LUN, NPLFMT) npl + do i = 1, npl + write(LUN, PLNAMEFMT) pl%id(i), pl%Gmass(i), pl%radius(i) + write(LUN, VECFMT) pl%xh(1, i), pl%xh(2, i), pl%xh(3, i) + write(LUN, VECFMT) vh(1, i), vh(2, i), vh(3, i) + end do + deallocate(vh) + end if + close(LUN) + end associate + + return + end subroutine io_write_discard + + + module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + xh1, xh2, vh1, vh2, enc_out, out_type) + !! author: David A. Minton + !! + !! Write close encounter data to output binary files + !! There is no direct file output from this subroutine + !! + !! Adapted from David E. Kaufmann's Swifter routine: io_write_encounter.f90 + !! Adapted from Hal Levison's Swift routine io_write_encounter.f + implicit none + ! Arguments + integer(I4B), intent(in) :: name1, name2 + real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(in) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: enc_out, out_type + ! Internals + logical , save :: lfirst = .true. + integer(I4B), parameter :: lun = 30 + integer(I4B) :: ierr + integer(I4B), save :: iu = lun + + open(unit = iu, file = enc_out, status = 'OLD', position = 'APPEND', form = 'UNFORMATTED', iostat = ierr) + if ((ierr /= 0) .and. lfirst) then + open(unit = iu, file = enc_out, status = 'NEW', form = 'UNFORMATTED', iostat = ierr) + end if + if (ierr /= 0) then + write(*, *) "Swiftest Error:" + write(*, *) " Unable to open binary encounter file" + call util_exit(FAILURE) + end if + lfirst = .false. + write(iu, iostat = ierr) t + if (ierr < 0) then + write(*, *) "Swiftest Error:" + write(*, *) " Unable to write binary file record" + call util_exit(FAILURE) + end if + write(iu) name1, xh1(1), xh1(2), xh1(3), vh1(1), vh1(2), mass1, radius1 + write(iu) name2, xh2(1), xh2(2), xh2(3), vh2(1), vh2(2), mass2, radius2 + close(unit = iu, iostat = ierr) + if (ierr /= 0) then + write(*, *) "Swiftest Error:" + write(*, *) " Unable to close binary encounter file" + call util_exit(FAILURE) + end if + + return + end subroutine io_write_encounter + + + module subroutine io_write_frame_body(self, iu, param) + !! author: David A. Minton + !! + !! Write a frame of output of either test particle or massive body data to the binary output file + !! Note: If outputting to orbital elements, but sure that the conversion is done prior to calling this method + !! + !! Adapted from David E. Kaufmann's Swifter routine io_write_frame.f90 + !! Adapted from Hal Levison's Swift routine io_write_frame.F + implicit none + ! Arguments + class(swiftest_body), intent(in) :: self !! Swiftest particle object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + + associate(n => self%nbody) + if (n == 0) return + write(iu) self%id(1:n) + !write(iu) self%name(1:n) + select case (param%out_form) + case (EL) + write(iu) self%a(1:n) + write(iu) self%e(1:n) + write(iu) self%inc(1:n) + write(iu) self%capom(1:n) + write(iu) self%omega(1:n) + write(iu) self%capm(1:n) + case (XV) + write(iu) self%xh(1, 1:n) + write(iu) self%xh(2, 1:n) + write(iu) self%xh(3, 1:n) + write(iu) self%vh(1, 1:n) + write(iu) self%vh(2, 1:n) + write(iu) self%vh(3, 1:n) + end select + select type(pl => self) + class is (swiftest_pl) ! Additional output if the passed polymorphic object is a massive body + write(iu) pl%Gmass(1:n) + write(iu) pl%rhill(1:n) + write(iu) pl%radius(1:n) + if (param%lrotation) then + write(iu) pl%rot(1, 1:n) + write(iu) pl%rot(2, 1:n) + write(iu) pl%rot(3, 1:n) + write(iu) pl%Ip(1, 1:n) + write(iu) pl%Ip(2, 1:n) + write(iu) pl%Ip(3, 1:n) + end if + if (param%ltides) then + write(iu) pl%k2(1:n) + write(iu) pl%Q(1:n) + end if + end select + end associate + + return + end subroutine io_write_frame_body + + + module subroutine io_write_frame_cb(self, iu, param) + !! author: David A. Minton + !! + !! Write a frame of output of central body data to the binary output file + !! + !! Adapted from David E. Kaufmann's Swifter routine io_write_frame.f90 + !! Adapted from Hal Levison's Swift routine io_write_frame.F + implicit none + ! Arguments + class(swiftest_cb), intent(in) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + + associate(cb => self) + !write(iu) cb%name + write(iu) cb%id + write(iu) cb%Gmass + write(iu) cb%radius + write(iu) cb%j2rp2 + write(iu) cb%j4rp4 + if (param%lrotation) then + write(iu) cb%rot(1) + write(iu) cb%rot(2) + write(iu) cb%rot(3) + write(iu) cb%Ip(1) + write(iu) cb%Ip(2) + write(iu) cb%Ip(3) + end if + if (param%ltides) then + write(iu) cb%k2 + write(iu) cb%Q + end if + end associate + + return + end subroutine io_write_frame_cb + + + module subroutine io_write_frame_system(self, iu, param) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Write a frame (header plus records for each massive body and active test particle) to output binary file + !! There is no direct file output from this subroutine + !! + !! Adapted from David E. Kaufmann's Swifter routine io_write_frame.f90 + !! Adapted from Hal Levison's Swift routine io_write_frame.F + implicit none + ! Arguments + class(swiftest_nbody_system), intent(in) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + logical, save :: lfirst = .true. !! Flag to determine if this is the first call of this method + integer(I4B) :: ierr !! I/O error code + + class(swiftest_cb), allocatable :: cb !! Temporary local version of pl structure used for non-destructive conversions + class(swiftest_pl), allocatable :: pl !! Temporary local version of pl structure used for non-destructive conversions + class(swiftest_tp), allocatable :: tp !! Temporary local version of pl structure used for non-destructive conversions + + allocate(cb, source = self%cb) + allocate(pl, source = self%pl) + allocate(tp, source = self%tp) + iu = BINUNIT + + if (lfirst) then + select case(param%out_stat) + case('APPEND') + open(unit = iu, file = param%outfile, status = 'OLD', position = 'APPEND', form = 'UNFORMATTED', iostat = ierr) + case('NEW', 'REPLACE', 'UNKNOWN') + open(unit = iu, file = param%outfile, status = param%out_stat, form = 'UNFORMATTED', iostat = ierr) + case default + write(*,*) 'Invalid status code for OUT_STAT: ',trim(adjustl(param%out_stat)) + call util_exit(FAILURE) + end select + if (ierr /= 0) then + write(*, *) "Swiftest error: io_write_frame_system - first", ierr + write(*, *) " Binary output file " // trim(adjustl(param%outfile)) // " already exists or cannot be accessed" + write(*, *) " OUT_STAT: " // trim(adjustl(param%out_stat)) + call util_exit(FAILURE) + end if + lfirst = .false. + else + open(unit = iu, file = param%outfile, status = 'OLD', position = 'APPEND', form = 'UNFORMATTED', iostat = ierr) + if (ierr /= 0) then + write(*, *) "Swiftest error: io_write_frame_system" + write(*, *) " Unable to open binary output file for APPEND" + call util_exit(FAILURE) + end if + end if + call io_write_hdr(iu, param%t, pl%nbody, tp%nbody, param%out_form, param%out_type) + + if (param%lgr) then + call pl%pv2v(param) + call tp%pv2v(param) + end if + + if (param%out_form == EL) then ! Do an orbital element conversion prior to writing out the frame, as we have access to the central body here + call pl%xv2el(cb) + call tp%xv2el(cb) + end if + + ! Write out each data type frame + call cb%write_frame(iu, param) + call pl%write_frame(iu, param) + call tp%write_frame(iu, param) + + deallocate(cb, pl, tp) + + close(iu) + + return + end subroutine io_write_frame_system + + + subroutine io_write_hdr(iu, t, npl, ntp, out_form, out_type) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Write frame header to output binary file + !! + !! Adapted from David Adapted from David E. Kaufmann's Swifter routine io_write_hdr.f90 + !! Adapted from Hal Levison's Swift routine io_write_hdr.F + implicit none + ! Arguments + integer(I4B), intent(in) :: iu !! Output file unit number + real(DP), intent(in) :: t !! Current time of simulation + integer(I4B), intent(in) :: npl !! Number of massive bodies + integer(I4B), intent(in) :: ntp !! Number of test particles + character(*), intent(in) :: out_form !! Output format type ("EL" or "XV") + character(*), intent(in) :: out_type !! Output file format type (REAL4, REAL8 - see swiftest module for symbolic name definitions) + ! Internals + integer(I4B) :: ierr !! Error code + + select case (out_type) + case (REAL4_TYPE,SWIFTER_REAL4_TYPE) + write(iu, iostat = ierr) real(t, kind=SP) + if (ierr /= 0) then + write(*, *) "Swiftest error:" + write(*, *) " Unable to write binary file header" + call util_exit(FAILURE) + end if + case (REAL8_TYPE,SWIFTER_REAL8_TYPE) + write(iu, iostat = ierr) t + if (ierr /= 0) then + write(*, *) "Swiftest error:" + write(*, *) " Unable to write binary file header" + call util_exit(FAILURE) + end if + end select + write(iu, iostat = ierr) npl + write(iu, iostat = ierr) ntp + write(iu, iostat = ierr) out_form + + return + end subroutine io_write_hdr + +end submodule s_io diff --git a/src/kick/kick.f90 b/src/kick/kick.f90 new file mode 100644 index 000000000..3945a91d0 --- /dev/null +++ b/src/kick/kick.f90 @@ -0,0 +1,72 @@ +submodule(swiftest_classes) s_kick + use swiftest +contains + + module pure subroutine kick_getacch_int_pl(self) + !! author: David A. Minton + !! + !! Compute direct cross (third) term heliocentric accelerations of massive bodies + !! + !! Adapted from Hal Levison's Swift routine getacch_ah3.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch_ah3.f90 and helio_kick_getacch_int.f90 + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self + ! Internals + integer(I4B) :: k + real(DP) :: rji2, irij3, faci, facj + real(DP), dimension(NDIM) :: dx + + associate(pl => self, npl => self%nbody, nplpl => self%nplpl) + do k = 1, nplpl + associate(i => pl%k_plpl(1, k), j => pl%k_plpl(2, k)) + if (pl%lmask(i) .and. pl%lmask(j)) then + dx(:) = pl%xh(:, j) - pl%xh(:, i) + rji2 = dot_product(dx(:), dx(:)) + irij3 = 1.0_DP / (rji2 * sqrt(rji2)) + faci = pl%Gmass(i) * irij3 + facj = pl%Gmass(j) * irij3 + pl%ah(:, i) = pl%ah(:, i) + facj * dx(:) + pl%ah(:, j) = pl%ah(:, j) - faci * dx(:) + end if + end associate + end do + end associate + + return + end subroutine kick_getacch_int_pl + + + module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) + !! author: David A. Minton + !! + !! Compute direct cross (third) term heliocentric accelerations of test particles by massive bodies + !! + !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch_ah3.f90 and helio_kick_getacch_int_tp.f90 + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle + real(DP), dimension(:), intent(in) :: GMpl !! Massive body masses + real(DP), dimension(:,:), intent(in) :: xhp !! Massive body position vectors + integer(I4B), intent(in) :: npl !! Number of active massive bodies + ! Internals + integer(I4B) :: i, j + real(DP) :: rji2, irij3, fac, r2 + real(DP), dimension(NDIM) :: dx + + associate(tp => self, ntp => self%nbody) + do concurrent(i = 1:ntp, tp%lmask(i)) + do j = 1, npl + dx(:) = tp%xh(:,i) - xhp(:, j) + r2 = dot_product(dx(:), dx(:)) + fac = GMpl(j) / (r2 * sqrt(r2)) + tp%ah(:, i) = tp%ah(:, i) - fac * dx(:) + end do + end do + end associate + + return + end subroutine kick_getacch_int_tp + +end submodule s_kick diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 new file mode 100644 index 000000000..55eb1bc89 --- /dev/null +++ b/src/main/swiftest_driver.f90 @@ -0,0 +1,101 @@ +program swiftest_driver + !! author: David A. Minton + !! + !! Driver program for the Swiftest integrators. Unlike the earlier Swift and Swifter drivers, in Swiftest all integrators + !! are run from this single program. + !! + !! Adapted from Swifter by David E. Kaufmann's Swifter driver programs swifter_[bs,helio,ra15,rmvs,symba,tu4,whm].f90 + !! Adapted from Hal Levison and Martin Duncan's Swift driver programs + use swiftest + implicit none + + class(swiftest_nbody_system), allocatable :: nbody_system !! Polymorphic object containing the nbody system to be integrated + class(swiftest_parameters), allocatable :: param !! Run configuration parameters + integer(I4B) :: integrator !! Integrator type code (see swiftest_globals for symbolic names) + character(len=:),allocatable :: param_file_name !! Name of the file containing user-defined parameters + integer(I4B) :: ierr !! I/O error code + integer(I8B) :: iloop !! Loop counter + integer(I8B) :: idump !! Dump cadence counter + integer(I8B) :: iout !! Output cadence counter + !integer(I8B), parameter :: LOOPMAX = huge(iloop) !! Maximum loop value before resetting + integer(I8B) :: nloops !! Number of steps to take in the simulation + real(DP) :: start_wall_time !! Wall clock time at start of execution + real(DP) :: finish_wall_time !! Wall clock time when execution has finished + integer(I4B) :: iu !! Unit number of binary file + character(*),parameter :: statusfmt = '("Time = ", ES12.5, "; fraction done = ", F6.3, "; ' // & + 'Number of active pl, tp = ", I5, ", ", I5)' + + ierr = io_get_args(integrator, param_file_name) + if (ierr /= 0) then + write(*,*) 'Error reading in arguments from the command line' + call util_exit(FAILURE) + end if + !$ start_wall_time = omp_get_wtime() + !> Read in the user-defined parameters file and the initial conditions of the system + select case(integrator) + case(symba) + allocate(symba_parameters :: param) + case default + allocate(swiftest_parameters :: param) + end select + param%integrator = integrator + call setup_construct_system(nbody_system, param) + call param%read_from_file(param_file_name) + associate(t => param%t, & + t0 => param%t0, & + dt => param%dt, & + tstop => param%tstop, & + istep_out => param%istep_out, & + istep_dump => param%istep_dump) + call nbody_system%initialize(param) + t = t0 + iloop = 0 + iout = istep_out + idump = istep_dump + nloops = ceiling(tstop / dt) + if (istep_out > 0) call nbody_system%write_frame(iu, param) + !> Define the maximum number of threads + nthreads = 1 ! In the *serial* case + !$ nthreads = omp_get_max_threads() ! In the *parallel* case + !$ write(*,'(a)') ' OpenMP parameters:' + !$ write(*,'(a)') ' ------------------' + !$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads + write(*, *) " *************** Main Loop *************** " + do iloop = 1, nloops + !> Step the system forward in time + call nbody_system%step(param, t, dt) + + t = t0 + iloop * dt + + !> Evaluate any discards or collisional outcomes + call nbody_system%discard(param) + + !> If the loop counter is at the output cadence value, append the data file with a single frame + if (istep_out > 0) then + iout = iout - 1 + if (iout == 0) then + call nbody_system%write_frame(iu, param) + iout = istep_out + end if + end if + + !> If the loop counter is at the dump cadence value, dump the state of the system to a file in case it needs to be restarted + if (istep_dump > 0) then + idump = idump - 1 + if (idump == 0) then + call nbody_system%dump(param, statusfmt) + idump = istep_dump + end if + end if + !if (t >= tstop) exit + end do + + !> Dump the final state of the system to file + !call nbody_system%dump(param, t, dt, statusfmt) + !$ finish_wall_time = omp_get_wtime() + !$ write(*,*) 'Time: ', finish_wall_time - start_wall_time + end associate + call util_exit(SUCCESS) + + stop +end program swiftest_driver diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 new file mode 100644 index 000000000..89f4aa055 --- /dev/null +++ b/src/modules/helio_classes.f90 @@ -0,0 +1,239 @@ +module helio_classes + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Definition of classes and methods specific to the Democratic Heliocentric Method + !! Adapted from David E. Kaufmann's Swifter routine: helio.f90 + use swiftest_globals + use swiftest_classes, only : swiftest_cb, swiftest_pl, swiftest_tp, swiftest_nbody_system + use whm_classes, only : whm_nbody_system + implicit none + public + + + !******************************************************************************************************************************** + ! helio_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + type, extends(whm_nbody_system) :: helio_nbody_system + contains + procedure :: step => helio_step_system !! Advance the Helio nbody system forward in time by one step + end type helio_nbody_system + + !******************************************************************************************************************************** + ! helio_cb class definitions and method interfaces + !******************************************************************************************************************************* + !> Helio central body particle class + type, extends(swiftest_cb) :: helio_cb + real(DP), dimension(NDIM) :: ptbeg !! negative barycentric velocity of the central body at the beginning of time step + real(DP), dimension(NDIM) :: ptend !! negative barycentric velocity of the central body at the end of time step + contains + end type helio_cb + + !******************************************************************************************************************************** + ! helio_pl class definitions and method interfaces + !******************************************************************************************************************************* + + !! Helio massive body particle class + type, extends(swiftest_pl) :: helio_pl + contains + procedure :: vh2vb => helio_coord_vh2vb_pl !! Convert massive bodies from heliocentric to barycentric coordinates (velocity only) + procedure :: vb2vh => helio_coord_vb2vh_pl !! Convert massive bodies from barycentric to heliocentric coordinates (velocity only) + procedure :: drift => helio_drift_pl !! Method for Danby drift in Democratic Heliocentric coordinates + procedure :: lindrift => helio_drift_linear_pl !! Method for linear drift of massive bodies due to barycentric momentum of Sun + procedure :: accel_gr => helio_gr_kick_getacch_pl !! Acceleration term arising from the post-Newtonian correction + procedure :: gr_pos_kick => helio_gr_p4_pl !! Position kick due to p**4 term in the post-Newtonian correction + procedure :: accel => helio_kick_getacch_pl !! Compute heliocentric accelerations of massive bodies + procedure :: kick => helio_kick_vb_pl !! Kicks the barycentric velocities + procedure :: step => helio_step_pl !! Steps the body forward one stepsize + end type helio_pl + + !******************************************************************************************************************************** + ! helio_tp class definitions and method interfaces + !******************************************************************************************************************************* + + !! Helio test particle class + type, extends(swiftest_tp) :: helio_tp + contains + procedure :: vh2vb => helio_coord_vh2vb_tp !! Convert test particles from heliocentric to barycentric coordinates (velocity only) + procedure :: vb2vh => helio_coord_vb2vh_tp !! Convert test particles from barycentric to heliocentric coordinates (velocity only) + procedure :: lindrift => helio_drift_linear_tp !! Method for linear drift of massive bodies due to barycentric momentum of Sun + procedure :: drift => helio_drift_tp !! Method for Danby drift in Democratic Heliocentric coordinates + procedure :: accel_gr => helio_gr_kick_getacch_tp !! Acceleration term arising from the post-Newtonian correction + procedure :: gr_pos_kick => helio_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction + procedure :: accel => helio_kick_getacch_tp !! Compute heliocentric accelerations of massive bodies + procedure :: kick => helio_kick_vb_tp !! Kicks the barycentric velocities + procedure :: step => helio_step_tp !! Steps the body forward one stepsize + end type helio_tp + + interface + module subroutine helio_coord_vb2vh_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine helio_coord_vb2vh_pl + + module subroutine helio_coord_vb2vh_tp(self, vbcb) + implicit none + class(helio_tp), intent(inout) :: self !! Helio massive body object + real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body + end subroutine helio_coord_vb2vh_tp + + module subroutine helio_coord_vh2vb_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine helio_coord_vh2vb_pl + + module subroutine helio_coord_vh2vb_tp(self, vbcb) + implicit none + class(helio_tp), intent(inout) :: self !! Helio massive body object + real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body + end subroutine helio_coord_vh2vb_tp + + module subroutine helio_drift_body(self, system, param, dt) + use swiftest_classes, only : swiftest_body, swiftest_nbody_system, swiftest_parameters + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine helio_drift_body + + module subroutine helio_drift_pl(self, system, param, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine helio_drift_pl + + module subroutine helio_drift_tp(self, system, param, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine helio_drift_tp + + module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(helio_cb), intent(inout) :: cb !! Helio central body + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Argument that determines whether or not this is the beginning or end of the step + end subroutine helio_drift_linear_pl + + module subroutine helio_drift_linear_tp(self, cb, dt, lbeg) + implicit none + class(helio_tp), intent(inout) :: self !! Helio test particle object + class(helio_cb), intent(in) :: cb !! Helio central body + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Argument that determines whether or not this is the beginning or end of the step + end subroutine helio_drift_linear_tp + + module subroutine helio_gr_kick_getacch_pl(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine helio_gr_kick_getacch_pl + + module subroutine helio_gr_kick_getacch_tp(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine helio_gr_kick_getacch_tp + + module pure subroutine helio_gr_p4_pl(self, param, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + end subroutine helio_gr_p4_pl + + module pure subroutine helio_gr_p4_tp(self, param, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + end subroutine helio_gr_p4_tp + + module subroutine helio_kick_getacch_pl(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_parameters, swiftest_nbody_system + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine helio_kick_getacch_pl + + module subroutine helio_kick_getacch_tp(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Helio test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine helio_kick_getacch_tp + + module subroutine helio_kick_vb_pl(self, system, param, t, dt, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + end subroutine helio_kick_vb_pl + + module subroutine helio_kick_vb_tp(self, system, param, t, dt, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Helio test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + end subroutine helio_kick_vb_tp + + module subroutine helio_step_pl(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! Helio massive body particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize + end subroutine helio_step_pl + + module subroutine helio_step_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine helio_step_system + + module subroutine helio_step_tp(self, system, param, t, dt) + use swiftest_classes, only : swiftest_cb, swiftest_parameters, swiftest_nbody_system + implicit none + class(helio_tp), intent(inout) :: self !! Helio test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsizee + end subroutine helio_step_tp + end interface + +end module helio_classes diff --git a/src/modules/lambda_function.f90 b/src/modules/lambda_function.f90 new file mode 100644 index 000000000..cd7e180cb --- /dev/null +++ b/src/modules/lambda_function.f90 @@ -0,0 +1,273 @@ +module lambda_function + !! author: David A. Minton + !! + !! Defines a class that can enable objects that behave like lambda functions. + !! + !! To use this class, define a type of either lambda_obj or lambda_obj_err, or extend the lambda_obj class as necessary, such that an interface that matches the function you wish to lambdafy. + !! Once defined, the lambda object can evaluate itself by calling the type-bound procedure eval. e.g. f%eval(x) (or f%eval(x, lerr), f%eval(x, [argument list], etc)) + !! + !! ******************************************************************************************************************************************************************************************** + !! Example - Defining a lambda function f(x,rval,ival) where rval and ival are a real and integer argument, respectively. This implementation uses an abstract interface, though this is not + !! strictly necessary unless you want to bind more than one function with the same interface. + !! ******************************************************************************************************************************************************************************************** + !! + !! module lambda_new + !! use swiftest ! This will bring in the lambda_function module + !! ! Define types in a module + !! + !! type, extends(lambda_obj) :: lambda_obj_ri_args + !! procedure(abstract_lambda_ri_args), pointer, nopass :: lambdaptr_ri_args => null() + !! real(DP) :: rval !! Real parameter + !! integer(I4B) :: ival !! Integer paramete + !! contains + !! generic :: init => lambda_ri_args_init + !! procedure :: eval => lambda_ri_args_eval + !! procedure, nopass :: lambda_ri_args_init + !! final :: lambda_ri_args_destroy + !! end type + !! interface lambda_obj + !! module procedure lambda_ri_args_init + !! end interface + !! + !! abstract interface + !! function abstract_lambda_ri_args(x, rval, ival) result(y) + !! !Template for the lambda function + !! import DP, I4B + !! real(DP), dimension(:), intent(in) :: x !! Dependent variable + !! real(DP), intent(in) :: rval !! Real parameter + !! integer(I4B), intent(in) :: ival !! Integer parameter + !! real(DP) :: y !! Real result + !! end function + !! end interface + !! + !! contains + !! type(lambda_obj_ri_args) function lambda_ri_args_init(lambda, rval, ival) + !! !! Initializes the lambda function parameters (can be used as a structure constructor) + !! implicit none + !! procedure(abstract_lambda_ri_args) :: lambda !! The lambda function that will be passed + !! real(DP), intent(in) :: rval !! Real parameter + !! integer(I4B), intent(in) :: ival !! Integer parameter + !! + !! ! Assign the procedure passed to this function to the procedure pointer + !! lambda_ri_args_init%lambdaptr_ri_args => lambda + !! + !! ! Assign the argument values + !! lambda_ri_args_init%rval = rval + !! lambda_ri_args_init%ival = ival + !! return + !! end function lambda_ri_args_init + !! + !! function lambda_ri_args_eval(self, x) result(y) + !! !! Defines the evaluation method, allowing the lambda function to be called with a single argument + !! implicit none + !! class(lambda_obj_ri_args), intent(inout) :: self + !! real(DP), dimension(:), intent(in) :: x + !! real(DP) :: y + !! + !! if (associated(self%lambdaptr_ri_args)) then + !! y = self%lambdaptr_ri_args(x, self%rval, self%ival) + !! self%lastval = y + !! if (allocated(self%lastarg)) deallocate(self%lastarg) + !! allocate(self%lastarg, source=x) + !! else + !! error stop "Lambda function was not initialized" + !! end if + !! end function lambda_ri_args_eval + !! + !! subroutine lambda_ri_args_destroy(self) + !! !! Finalizer method. Use this as a template for cleaning up the object upon destruction, such as nullifying pointers + !! implicit none + !! type(lambda_obj_ri_args) :: self + !! if (associated(self%lambdaptr_ri_args)) nullify(self%lambdaptr_ri_args) + !! end subroutine lambda_ri_args_destroy + !! + !! function example_function(x, rval, ival) result(y) + !! !This is the actual function you are going to use as the lambda function. Its interface must match the abstract interface previously defined + !! implicit none + !! ! Arguments + !! real(DP), dimension(:), intent(in) :: x + !! real(DP), intent(in) :: rval + !! integer(I4B), intent(in) :: ival + !! ! Result + !! real(DP) :: y + !! ! Internals + !! integer(I4B) :: i, n + !! n = size(x) + !! y = 42._DP * ival + !! do i = 1, n + !! y = y + x(i)**2 + !! end do + !! return + !! end function example_function + !! end module lambda_new + !! + !! program usage + !! use swiftest + !! use lambda_new + !! implicit none + !! type(lambda_obj_ri_args) :: f + !! real(DP) :: sigma_par + !! integer(I4B) :: iwonky, i,j + !! real(DP), dimension(12) :: xarr + !! + !! sigma_par = 3.14_DP + !! iwonky = 13 + !! + !! f = lambda_obj(example_function, sigma_par, iwonky) + !! do i = 1, 10 + !! xarr(:) = [(j * 0.25_DP / i, j=1, 12)] + !! write(*,*) i,f%eval(xarr) + !! end do + !! end program usage + !! ******************************************************************************************************************************************************************************************** + + use swiftest_globals + implicit none + public + + type :: lambda_obj + !! Base class for an lambda function object. This object takes no additional arguments other than the dependent variable x, an array of real numbers + procedure(lambda0), pointer, nopass :: lambdaptr => null() + real(DP) :: lastval + real(DP),dimension(:), allocatable :: lastarg + contains + generic :: init => lambda_init_0 + procedure :: eval => lambda_eval_0 + procedure, nopass :: lambda_init_0 + final :: lambda_destroy + end type + + type, extends(lambda_obj) :: lambda_obj_err + !! Extended class for an lambda function object. This object takes allows for the return of a logical error flag during evaluation of the function. + procedure(lambda0err), pointer, nopass :: lambdaptr_err => null() + logical :: lerr + contains + generic :: init => lambda_init_0_err + procedure :: eval => lambda_eval_0_err + procedure, nopass :: lambda_init_0_err + end type + + type, extends(lambda_obj) :: lambda_obj_tvar + !! Base class for an lambda function object. This object takes no additional arguments other than the dependent variable x, an array of real numbers + procedure(lambda0tvar), pointer, nopass :: lambdaptr_tvar => null() + contains + generic :: init => lambda_init_tvar + procedure :: evalt => lambda_eval_tvar + procedure, nopass :: lambda_init_tvar + end type + interface lambda_obj + module procedure lambda_init_0 + module procedure lambda_init_0_err + module procedure lambda_init_tvar + end interface + + abstract interface + function lambda0(x) result(y) + ! Template for a 0 argument function + import DP + real(DP), dimension(:), intent(in) :: x + real(DP) :: y + end function + + function lambda0err(x, lerr) result(y) + ! Template for a 0 argument function that returns an error value + import DP + real(DP), dimension(:), intent(in) :: x + logical, intent(out) :: lerr + real(DP) :: y + end function + + function lambda0tvar(x, t) result(y) + ! Template for a 0 argument function that returns an error value + import DP + real(DP), dimension(:), intent(in) :: x + real(DP), intent(in) :: t + real(DP), dimension(:), allocatable :: y + end function + end interface + + contains + type(lambda_obj) function lambda_init_0(lambda) + implicit none + ! Arguments + procedure(lambda0) :: lambda + lambda_init_0%lambdaptr => lambda + return + end function lambda_init_0 + + type(lambda_obj_err) function lambda_init_0_err(lambda, lerr) + implicit none + ! Arguments + procedure(lambda0err) :: lambda + logical, intent(in) :: lerr + lambda_init_0_err%lambdaptr_err => lambda + lambda_init_0_err%lerr = lerr + return + end function lambda_init_0_err + + type(lambda_obj_tvar) function lambda_init_tvar(lambda, t) + implicit none + ! Arguments + procedure(lambda0tvar) :: lambda + real(DP), intent(in) :: t + lambda_init_tvar%lambdaptr_tvar => lambda + return + end function lambda_init_tvar + + function lambda_eval_0(self, x) result(y) + implicit none + ! Arguments + class(lambda_obj), intent(inout) :: self + real(DP), dimension(:), intent(in) :: x + ! Result + real(DP) :: y + if (associated(self%lambdaptr)) then + y = self%lambdaptr(x) + self%lastval = y + if (allocated(self%lastarg)) deallocate(self%lastarg) + allocate(self%lastarg, source=x) + else + error stop "Lambda function was not initialized" + end if + end function lambda_eval_0 + + function lambda_eval_0_err(self, x) result(y) + implicit none + ! Arguments + class(lambda_obj_err), intent(inout) :: self + real(DP), dimension(:), intent(in) :: x + ! Result + real(DP) :: y + if (associated(self%lambdaptr_err)) then + y = self%lambdaptr_err(x, self%lerr) + self%lastval = y + if (allocated(self%lastarg)) deallocate(self%lastarg) + allocate(self%lastarg, source=x) + else + error stop "Lambda function was not initialized" + end if + end function lambda_eval_0_err + + function lambda_eval_tvar(self, x, t) result(y) + implicit none + ! Arguments + class(lambda_obj_tvar), intent(inout) :: self + real(DP), dimension(:), intent(in) :: x + real(DP), intent(in) :: t + ! Result + real(DP), dimension(:), allocatable :: y + if (associated(self%lambdaptr_tvar)) then + y = self%lambdaptr_tvar(x,t) + else + error stop "Lambda function was not initialized" + end if + end function lambda_eval_tvar + + subroutine lambda_destroy(self) + implicit none + type(lambda_obj) :: self + if (associated(self%lambdaptr)) nullify(self%lambdaptr) + end subroutine lambda_destroy + +end module lambda_function + diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 new file mode 100644 index 000000000..4f7255237 --- /dev/null +++ b/src/modules/rmvs_classes.f90 @@ -0,0 +1,260 @@ +module rmvs_classes + !! author: David A. Minton + !! + !! Definition of classes and methods specific to the Regularized Mixed Variable Symplectic (RMVS) integrator + !! Partially adapted from David E. Kaufmann's Swifter module: module_rmvs.f90 + use swiftest_globals + use whm_classes, only : whm_cb, whm_pl, whm_tp, whm_nbody_system + implicit none + public + + integer(I4B), private, parameter :: NTENC = 10 + integer(I4B), private, parameter :: NTPHENC = 3 + integer(I4B), private, parameter :: NTPENC = NTENC * NTPHENC + real(DP), private, parameter :: RHSCALE = 3.5_DP + real(DP), private, parameter :: RHPSCALE = 1.0_DP + real(DP), private, parameter :: FACQDT = 2.0_DP + + !******************************************************************************************************************************** + ! rmvs_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + type, extends(whm_nbody_system) :: rmvs_nbody_system + !> In the RMVS integrator, only test particles are discarded + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + real(DP) :: rts !! fraction of Hill's sphere radius to use as radius of encounter region + real(DP), dimension(:,:), allocatable :: vbeg !! Planet velocities at beginning ot step + contains + !> Replace the abstract procedures with concrete ones + procedure :: initialize => rmvs_setup_initialize_system !! Performs RMVS-specific initilization steps, including generating the close encounter planetocentric structures + procedure :: step => rmvs_step_system !! Advance the RMVS nbody system forward in time by one step + end type rmvs_nbody_system + + type, private :: rmvs_interp + real(DP), dimension(:, :), allocatable :: x !! interpolated heliocentric planet position for outer encounter + real(DP), dimension(:, :), allocatable :: v !! interpolated heliocentric planet velocity for outer encounter + real(DP), dimension(:, :), allocatable :: aobl !! Encountering planet's oblateness acceleration value + real(DP), dimension(:, :), allocatable :: atide !! Encountering planet's tidal acceleration value + end type rmvs_interp + + !******************************************************************************************************************************** + ! rmvs_cb class definitions and method interfaces + !******************************************************************************************************************************* + !> RMVS central body particle class + type, extends(whm_cb) :: rmvs_cb + type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters + type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + end type rmvs_cb + + !******************************************************************************************************************************** + ! rmvs_tp class definitions and method interfaces + !******************************************************************************************************************************* + + !! RMVS test particle class + type, extends(whm_tp) :: rmvs_tp + !! Note to developers: If you add componenets to this class, be sure to update methods and subroutines that traverse the + !! component list, such as rmvs_setup_tp and rmvs_util_spill_tp + ! encounter steps) + logical, dimension(:), allocatable :: lperi !! planetocentric pericenter passage flag (persistent for a full rmvs time step) over a full RMVS time step) + integer(I4B), dimension(:), allocatable :: plperP !! index of planet associated with pericenter distance peri (persistent over a full RMVS time step) + integer(I4B), dimension(:), allocatable :: plencP !! index of planet that test particle is encountering (not persistent for a full RMVS time step) + + ! The following are used to correctly set the oblateness values of the acceleration during an inner encounter with a planet + type(rmvs_cb) :: cb_heliocentric !! Copy of original central body object passed to close encounter (used for oblateness acceleration during planetocentric encoountters) + real(DP), dimension(:,:), allocatable :: xheliocentric !! original heliocentric position (used for oblateness calculation during close encounters) + integer(I4B) :: index !! inner substep number within current set + integer(I4B) :: ipleP !! index value of encountering planet + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + contains + procedure :: discard => rmvs_discard_tp !! Check to see if test particles should be discarded based on pericenter passage distances with respect to planets encountered + procedure :: encounter_check => rmvs_encounter_check_tp !! Checks if any test particles are undergoing a close encounter with a massive body + procedure :: accel => rmvs_kick_getacch_tp !! Calculates either the standard or modified version of the acceleration depending if the + !! if the test particle is undergoing a close encounter or not + procedure :: setup => rmvs_setup_tp !! Constructor method - Allocates space for the input number of bodiess + procedure :: append => rmvs_util_append_tp !! Appends elements from one structure to another + procedure :: fill => rmvs_util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => rmvs_util_resize_tp !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: sort => rmvs_util_sort_tp !! Sorts body arrays by a sortable componen + procedure :: rearrange => rmvs_util_sort_rearrange_tp !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => rmvs_util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type rmvs_tp + + !******************************************************************************************************************************** + ! rmvs_pl class definitions and method interfaces + !******************************************************************************************************************************* + + !> RMVS massive body particle class + type, extends(whm_pl) :: rmvs_pl + integer(I4B), dimension(:), allocatable :: nenc !! number of test particles encountering planet this full rmvs time step + integer(I4B), dimension(:), allocatable :: tpenc1P !! index of first test particle encountering planet + integer(I4B), dimension(:), allocatable :: plind !! Connects the planetocentric indices back to the heliocentric planet list + type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters + type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + class(rmvs_nbody_system), dimension(:), allocatable :: planetocentric !! Planetocentric version of the massive body objects (one for each massive body) + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + contains + procedure :: setup => rmvs_setup_pl !! Constructor method - Allocates space for the input number of bodiess + procedure :: append => rmvs_util_append_pl !! Appends elements from one structure to another + procedure :: fill => rmvs_util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => rmvs_util_resize_pl !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: sort => rmvs_util_sort_pl !! Sorts body arrays by a sortable componen + procedure :: rearrange => rmvs_util_sort_rearrange_pl !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => rmvs_util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type rmvs_pl + + interface + module elemental function rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) result(lflag) + implicit none + real(DP), intent(in) :: r2, v2, vdotr, dt, r2crit + logical :: lflag + end function rmvs_chk_ind + + module subroutine rmvs_discard_tp(self, system, param) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine rmvs_discard_tp + + module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + real(DP), intent(in) :: dt !! step size + logical :: lencounter !! Returns true if there is at least one close encounter + end function rmvs_encounter_check_tp + + module subroutine rmvs_kick_getacch_tp(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine rmvs_kick_getacch_tp + + module subroutine rmvs_setup_pl(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine rmvs_setup_pl + + module subroutine rmvs_setup_initialize_system(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine rmvs_setup_initialize_system + + module subroutine rmvs_setup_tp(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parametere + end subroutine rmvs_setup_tp + + module subroutine rmvs_util_append_pl(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine rmvs_util_append_pl + + module subroutine rmvs_util_append_tp(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine rmvs_util_append_tp + + module subroutine rmvs_util_fill_pl(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine rmvs_util_fill_pl + + module subroutine rmvs_util_fill_tp(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine rmvs_util_fill_tp + + module subroutine rmvs_util_resize_pl(self, nnew) + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine rmvs_util_resize_pl + + module subroutine rmvs_util_resize_tp(self, nnew) + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine rmvs_util_resize_tp + + module subroutine rmvs_util_sort_pl(self, sortby, ascending) + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine rmvs_util_sort_pl + + module subroutine rmvs_util_sort_tp(self, sortby, ascending) + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine rmvs_util_sort_tp + + module subroutine rmvs_util_sort_rearrange_pl(self, ind) + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine rmvs_util_sort_rearrange_pl + + module subroutine rmvs_util_sort_rearrange_tp(self, ind) + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine rmvs_util_sort_rearrange_tp + + module subroutine rmvs_util_spill_pl(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine rmvs_util_spill_pl + + module subroutine rmvs_util_spill_tp(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_body + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine rmvs_util_spill_tp + + module subroutine rmvs_step_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine rmvs_step_system + + end interface + +end module rmvs_classes diff --git a/src/modules/swiftest.f90 b/src/modules/swiftest.f90 new file mode 100644 index 000000000..61d45163c --- /dev/null +++ b/src/modules/swiftest.f90 @@ -0,0 +1,19 @@ +module swiftest + !! author: David A. Minton + !! graph: false + !! + !! This module serves to combine all of the Swiftest project modules under a single umbrella so that they can be accessed from individual submodule implementations with a simple "use swiftest" line. + use swiftest_globals + use swiftest_operators + use swiftest_classes + use whm_classes + use rmvs_classes + use helio_classes + use symba_classes + use lambda_function + !use advisor_annotate + !$ use omp_lib + implicit none + public + +end module swiftest diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 new file mode 100644 index 000000000..2455e77f2 --- /dev/null +++ b/src/modules/swiftest_classes.f90 @@ -0,0 +1,1305 @@ +module swiftest_classes + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Definition of data and structures generic to all integrators. + !! Adapted from David E. Kaufmann's Swifter routine: module_swifter.f90 + use swiftest_globals + implicit none + public + + !******************************************************************************************************************************** + ! swiftest_parameters class definitions + !******************************************************************************************************************************** + + !> User defined parameters that are read in from the parameters input file. + !> Each paramter is initialized to a default values. + type :: swiftest_parameters + integer(I4B) :: integrator = UNKNOWN_INTEGRATOR !! Symbolic name of the nbody integrator used + integer(I4B) :: nplmax = -1 !! Maximum allowed number of massive bodies + integer(I4B) :: ntpmax = -1 !! Maximum allowed number of test particles + real(DP) :: t0 = -1.0_DP !! Integration start time + real(DP) :: t = -1.0_DP !! Integration current time + real(DP) :: tstop = -1.0_DP !! Integration stop time + real(DP) :: dt = -1.0_DP !! Time step + character(STRMAX) :: incbfile = CB_INFILE !! Name of input file for the central body + character(STRMAX) :: inplfile = PL_INFILE !! Name of input file for massive bodies + character(STRMAX) :: intpfile = TP_INFILE !! Name of input file for test particles + character(STRMAX) :: in_type = ASCII_TYPE !! Format of input data files + integer(I4B) :: istep_out = -1 !! Number of time steps between binary outputs + character(STRMAX) :: outfile = BIN_OUTFILE !! Name of output binary file + character(STRMAX) :: out_type = REAL8_TYPE !! Binary format of output file + character(STRMAX) :: out_form = XV !! Data to write to output file + character(STRMAX) :: out_stat = 'NEW' !! Open status for output binary file + integer(I4B) :: istep_dump = -1 !! Number of time steps between dumps + real(DP) :: rmin = -1.0_DP !! Minimum heliocentric radius for test particle + real(DP) :: rmax = -1.0_DP !! Maximum heliocentric radius for test particle + real(DP) :: rmaxu = -1.0_DP !! Maximum unbound heliocentric radius for test particle + real(DP) :: qmin = -1.0_DP !! Minimum pericenter distance for test particle + character(STRMAX) :: qmin_coord = 'HELIO' !! Coordinate frame to use for qmin + real(DP) :: qmin_alo = -1.0_DP !! Minimum semimajor axis for qmin + real(DP) :: qmin_ahi = -1.0_DP !! Maximum semimajor axis for qmin + character(STRMAX) :: enc_out = "" !! Name of output file for encounters + character(STRMAX) :: discard_out = "" !! Name of output file for discards + real(QP) :: MU2KG = -1.0_QP !! Converts mass units to grams + real(QP) :: TU2S = -1.0_QP !! Converts time units to seconds + real(QP) :: DU2M = -1.0_QP !! Converts distance unit to centimeters + real(DP) :: GU = -1.0_DP !! Universal gravitational constant in the system units + real(DP) :: inv_c2 = -1.0_DP !! Inverse speed of light squared in the system units + character(STRMAX) :: ennergy_out = "" !! Name of output energy and momentum report file + + ! Logical flags to turn on or off various features of the code + logical :: lrhill_present = .false. !! Hill radii are given as an input rather than calculated by the code (can be used to inflate close encounter regions manually) + logical :: lextra_force = .false. !! User defined force function turned on + logical :: lbig_discard = .false. !! Save big bodies on every discard + logical :: lclose = .false. !! Turn on close encounters + logical :: lenergy = .false. !! Track the total energy of the system + logical :: loblatecb = .false. !! Calculate acceleration from oblate central body (automatically turns true if nonzero J2 is input) + logical :: lrotation = .false. !! Include rotation states of big bodies + logical :: ltides = .false. !! Include tidal dissipation + + ! Initial values to pass to the energy report subroutine (usually only used in the case of a restart, otherwise these will be updated with initial conditions values) + real(DP) :: Eorbit_orig = 0.0_DP !! Initial orbital energy + real(DP) :: Mtot_orig = 0.0_DP !! Initial system mass + real(DP) :: Lmag_orig = 0.0_DP !! Initial total angular momentum magnitude + real(DP), dimension(NDIM) :: Ltot_orig = 0.0_DP !! Initial total angular momentum vector + real(DP), dimension(NDIM) :: Lorbit_orig = 0.0_DP !! Initial orbital angular momentum + real(DP), dimension(NDIM) :: Lspin_orig = 0.0_DP !! Initial spin angular momentum vector + real(DP), dimension(NDIM) :: Ltot = 0.0_DP !! System angular momentum vector + real(DP), dimension(NDIM) :: Lescape = 0.0_DP !! Angular momentum of bodies that escaped the system (used for bookeeping) + real(DP) :: Mescape = 0.0_DP !! Mass of bodies that escaped the system (used for bookeeping) + real(DP) :: Ecollisions = 0.0_DP !! Energy lost from system due to collisions + real(DP) :: Euntracked = 0.0_DP !! Energy gained from system due to escaped bodies + logical :: lfirstenergy = .true. !! This is the first time computing energe + logical :: lfirstkick = .true. !! Initiate the first kick in a symplectic step + + ! Future features not implemented or in development + logical :: lgr = .false. !! Turn on GR + logical :: lyarkovsky = .false. !! Turn on Yarkovsky effect + logical :: lyorp = .false. !! Turn on YORP effect + contains + procedure :: reader => io_param_reader + procedure :: writer => io_param_writer + procedure :: dump => io_dump_param + procedure :: read_from_file => io_read_param_in + end type swiftest_parameters + + !******************************************************************************************************************************** + ! swiftest_base class definitions and methods + !******************************************************************************************************************************** + type, abstract :: swiftest_base + !! An superclass for a generic Swiftest object + logical :: lintegrate = .false. !! Flag indicating that this object should be integrated in the current step + contains + !! The minimal methods that all systems must have + procedure :: dump => io_dump_swiftest + procedure(abstract_initialize), deferred :: initialize + procedure(abstract_read_frame), deferred :: read_frame + procedure(abstract_write_frame), deferred :: write_frame + end type swiftest_base + + !******************************************************************************************************************************** + ! swiftest_cb class definitions and methods + !******************************************************************************************************************************** + !> A concrete lass for the central body in a Swiftest simulation + type, abstract, extends(swiftest_base) :: swiftest_cb + character(len=STRMAX) :: name !! Non-unique name + integer(I4B) :: id = 0 !! External identifier (unique) + real(DP) :: mass = 0.0_DP !! Central body mass (units MU) + real(DP) :: Gmass = 0.0_DP !! Central mass gravitational term G * mass (units GU * MU) + real(DP) :: radius = 0.0_DP !! Central body radius (units DU) + real(DP) :: density = 1.0_DP !! Central body mass density - calculated internally (units MU / DU**3) + real(DP) :: j2rp2 = 0.0_DP !! J2*R^2 term for central body + real(DP) :: j4rp4 = 0.0_DP !! J4*R^2 term for central body + real(DP), dimension(NDIM) :: aobl = 0.0_DP !! Barycentric acceleration due to central body oblatenes + real(DP), dimension(NDIM) :: atide = 0.0_DP !! Barycentric acceleration due to central body oblatenes + real(DP), dimension(NDIM) :: aoblbeg = 0.0_DP !! Barycentric acceleration due to central body oblatenes at beginning of step + real(DP), dimension(NDIM) :: aoblend = 0.0_DP !! Barycentric acceleration due to central body oblatenes at end of step + real(DP), dimension(NDIM) :: atidebeg = 0.0_DP !! Barycentric acceleration due to central body oblatenes at beginning of step + real(DP), dimension(NDIM) :: atideend = 0.0_DP !! Barycentric acceleration due to central body oblatenes at end of step + real(DP), dimension(NDIM) :: xb = 0.0_DP !! Barycentric position (units DU) + real(DP), dimension(NDIM) :: vb = 0.0_DP !! Barycentric velocity (units DU / TU) + real(DP), dimension(NDIM) :: agr = 0.0_DP !! Acceleration due to post-Newtonian correction + real(DP), dimension(NDIM) :: Ip = 0.0_DP !! Unitless principal moments of inertia (I1, I2, I3) / (MR**2). Principal axis rotation assumed. + real(DP), dimension(NDIM) :: rot = 0.0_DP !! Body rotation vector in inertial coordinate frame (units rad / TU) + real(DP) :: k2 = 0.0_DP !! Tidal Love number + real(DP) :: Q = 0.0_DP !! Tidal quality factor + real(DP) :: tlag = 0.0_DP !! Tidal phase lag angle + real(DP), dimension(NDIM) :: L0 = 0.0_DP !! Initial angular momentum of the central body + real(DP), dimension(NDIM) :: dL = 0.0_DP !! Change in angular momentum of the central body + contains + procedure :: initialize => io_read_cb_in !! I/O routine for reading in central body data + procedure :: read_frame => io_read_frame_cb !! I/O routine for reading out a single frame of time-series data for the central body + procedure :: write_frame => io_write_frame_cb !! I/O routine for writing out a single frame of time-series data for the central body + end type swiftest_cb + + !******************************************************************************************************************************** + ! swiftest_body definitions and methods + !******************************************************************************************************************************** + !> An abstract class for a generic collection of Swiftest bodies + type, abstract, extends(swiftest_base) :: swiftest_body + !! Superclass that defines the generic elements of a Swiftest particle + logical :: lfirst = .true. !! Run the current step as a first + integer(I4B) :: nbody = 0 !! Number of bodies + character(len=STRMAX), dimension(:), allocatable :: name !! Non-unique name + integer(I4B), dimension(:), allocatable :: id !! External identifier (unique) + integer(I4B), dimension(:), allocatable :: status !! An integrator-specific status indicator + logical, dimension(:), allocatable :: ldiscard !! Body should be discarded + logical, dimension(:), allocatable :: lmask !! Logical mask used to select a subset of bodies when performing certain operations (drift, kick, accel, etc.) + real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) + real(DP), dimension(:,:), allocatable :: xh !! Heliocentric position + real(DP), dimension(:,:), allocatable :: vh !! Heliocentric velocity + real(DP), dimension(:,:), allocatable :: xb !! Barycentric position + real(DP), dimension(:,:), allocatable :: vb !! Barycentric velocity + real(DP), dimension(:,:), allocatable :: ah !! Total heliocentric acceleration + real(DP), dimension(:,:), allocatable :: aobl !! Barycentric accelerations of bodies due to central body oblatenes + real(DP), dimension(:,:), allocatable :: atide !! Tanngential component of acceleration of bodies due to tides + real(DP), dimension(:,:), allocatable :: agr !! Acceleration due to post-Newtonian correction + real(DP), dimension(:), allocatable :: ir3h !! Inverse heliocentric radius term (1/rh**3) + real(DP), dimension(:), allocatable :: a !! Semimajor axis (pericentric distance for a parabolic orbit) + real(DP), dimension(:), allocatable :: e !! Eccentricity + real(DP), dimension(:), allocatable :: inc !! Inclination + real(DP), dimension(:), allocatable :: capom !! Longitude of ascending node + real(DP), dimension(:), allocatable :: omega !! Argument of pericenter + real(DP), dimension(:), allocatable :: capm !! Mean anomaly + !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the + !! component list, such as setup_body and util_spill + contains + procedure(abstract_discard_body), deferred :: discard + procedure(abstract_kick_body), deferred :: kick + procedure(abstract_set_mu), deferred :: set_mu + procedure(abstract_step_body), deferred :: step + procedure(abstract_accel), deferred :: accel + ! These are concrete because the implementation is the same for all types of particles + procedure :: drift => drift_body !! Loop through bodies and call Danby drift routine on heliocentric variables + procedure :: v2pv => gr_vh2pv_body !! Converts from velocity to psudeovelocity for GR calculations using symplectic integrators + procedure :: pv2v => gr_pv2vh_body !! Converts from psudeovelocity to velocity for GR calculations using symplectic integrators + procedure :: initialize => io_read_body_in !! Read in body initial conditions from a file + procedure :: read_frame => io_read_frame_body !! I/O routine for writing out a single frame of time-series data for the central body + procedure :: write_frame => io_write_frame_body !! I/O routine for writing out a single frame of time-series data for the central body + procedure :: accel_obl => obl_acc_body !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + procedure :: el2xv => orbel_el2xv_vec !! Convert orbital elements to position and velocity vectors + procedure :: xv2el => orbel_xv2el_vec !! Convert position and velocity vectors to orbital elements + procedure :: setup => setup_body !! A constructor that sets the number of bodies and allocates all allocatable arrays + procedure :: accel_user => user_kick_getacch_body !! Add user-supplied heliocentric accelerations to planets + procedure :: append => util_append_body !! Appends elements from one structure to another + procedure :: fill => util_fill_body !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => util_resize_body !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: set_ir3 => util_set_ir3h !! Sets the inverse heliocentric radius term (1/rh**3) + procedure :: sort => util_sort_body !! Sorts body arrays by a sortable componen + procedure :: rearrange => util_sort_rearrange_body !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => util_spill_body !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type swiftest_body + + !******************************************************************************************************************************** + ! swiftest_pl definitions and methods + !******************************************************************************************************************************** + !> An abstract class for a generic collection of Swiftest massive bodies + type, abstract, extends(swiftest_body) :: swiftest_pl + !! Superclass that defines the generic elements of a Swiftest particle + real(DP), dimension(:), allocatable :: mass !! Body mass (units MU) + real(DP), dimension(:), allocatable :: Gmass !! Mass gravitational term G * mass (units GU * MU) + real(DP), dimension(:), allocatable :: rhill !! Body mass (units MU) + real(DP), dimension(:), allocatable :: radius !! Body radius (units DU) + real(DP), dimension(:,:), allocatable :: xbeg !! Position at beginning of step + real(DP), dimension(:,:), allocatable :: xend !! Position at end of step + real(DP), dimension(:,:), allocatable :: vbeg !! Velocity at beginning of step + real(DP), dimension(:), allocatable :: density !! Body mass density - calculated internally (units MU / DU**3) + real(DP), dimension(:,:), allocatable :: Ip !! Unitless principal moments of inertia (I1, I2, I3) / (MR**2). Principal axis rotation assumed. + real(DP), dimension(:,:), allocatable :: rot !! Body rotation vector in inertial coordinate frame (units rad / TU) + real(DP), dimension(:), allocatable :: k2 !! Tidal Love number + real(DP), dimension(:), allocatable :: Q !! Tidal quality factor + real(DP), dimension(:), allocatable :: tlag !! Tidal phase lag + integer(I4B), dimension(:,:), allocatable :: k_plpl !! Index array used to convert flattened the body-body comparison upper triangular matrix + integer(I8B) :: nplpl !! Number of body-body comparisons in the flattened upper triangular matrix + !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the + !! component list, such as setup_pl and util_spill_pl + contains + ! Massive body-specific concrete methods + ! These are concrete because they are the same implemenation for all integrators + procedure :: discard => discard_pl !! Placeholder method for discarding massive bodies + procedure :: eucl_index => eucl_dist_index_plpl !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix + procedure :: accel_int => kick_getacch_int_pl !! Compute direct cross (third) term heliocentric accelerations of massive bodies + procedure :: accel_obl => obl_acc_pl !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + procedure :: setup => setup_pl !! A base constructor that sets the number of bodies and allocates and initializes all arrays + procedure :: accel_tides => tides_kick_getacch_pl !! Compute the accelerations of bodies due to tidal interactions with the central body + procedure :: append => util_append_pl !! Appends elements from one structure to another + procedure :: h2b => util_coord_h2b_pl !! Convert massive bodies from heliocentric to barycentric coordinates (position and velocity) + procedure :: b2h => util_coord_b2h_pl !! Convert massive bodies from barycentric to heliocentric coordinates (position and velocity) + procedure :: fill => util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => util_resize_pl !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: set_beg_end => util_set_beg_end_pl !! Sets the beginning and ending positions and velocities of planets. + procedure :: set_mu => util_set_mu_pl !! Method used to construct the vectorized form of the central body mass + procedure :: set_rhill => util_set_rhill !! Calculates the Hill's radii for each body + procedure :: sort => util_sort_pl !! Sorts body arrays by a sortable component + procedure :: rearrange => util_sort_rearrange_pl !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type swiftest_pl + + !******************************************************************************************************************************** + ! swiftest_tp definitions and methods + !******************************************************************************************************************************** + !> An abstract class for a generic collection of Swiftest test particles + type, abstract, extends(swiftest_body) :: swiftest_tp + !! Superclass that defines the generic elements of a Swiftest test particle + integer(I4B), dimension(:), allocatable :: isperi !! Perihelion passage flag + real(DP), dimension(:), allocatable :: peri !! Perihelion distance + real(DP), dimension(:), allocatable :: atp !! Semimajor axis following perihelion passage + !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the + !! component list, such as setup_tp and util_spill_tp + contains + ! Test particle-specific concrete methods + ! These are concrete because they are the same implemenation for all integrators + procedure :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies + procedure :: accel_int => kick_getacch_int_tp !! Compute direct cross (third) term heliocentric accelerations of test particles by massive bodies + procedure :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + procedure :: setup => setup_tp !! A base constructor that sets the number of bodies and + procedure :: append => util_append_tp !! Appends elements from one structure to another + procedure :: h2b => util_coord_h2b_tp !! Convert test particles from heliocentric to barycentric coordinates (position and velocity) + procedure :: b2h => util_coord_b2h_tp !! Convert test particles from barycentric to heliocentric coordinates (position and velocity) + procedure :: fill => util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: get_peri => util_peri_tp !! Determine system pericenter passages for test particles + procedure :: resize => util_resize_tp !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass + procedure :: sort => util_sort_tp !! Sorts body arrays by a sortable component + procedure :: rearrange => util_sort_rearrange_tp !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type swiftest_tp + + !******************************************************************************************************************************** + ! swiftest_nbody_system class definitions and methods + !******************************************************************************************************************************** + !> An abstract class for a basic Swiftest nbody system + type, abstract, extends(swiftest_base) :: swiftest_nbody_system + !! This superclass contains a minimial system of a set of test particles (tp), massive bodies (pl), and a central body (cb) + class(swiftest_cb), allocatable :: cb !! Central body data structure + class(swiftest_pl), allocatable :: pl !! Massive body data structure + class(swiftest_tp), allocatable :: tp !! Test particle data structure + class(swiftest_tp), allocatable :: tp_discards !! Discarded test particle data structure + real(DP) :: Gmtot = 0.0_DP !! Total system mass - used for barycentric coordinate conversion + real(DP) :: ke_orbit = 0.0_DP !! System orbital kinetic energy + real(DP) :: ke_spin = 0.0_DP !! System spin kinetic energy + real(DP) :: pe = 0.0_DP !! System potential energy + real(DP) :: te = 0.0_DP !! System total energy + real(DP), dimension(NDIM) :: Lorbit = 0.0_DP !! System orbital angular momentum vector + real(DP), dimension(NDIM) :: Lspin = 0.0_DP !! System spin angular momentum vector + real(DP), dimension(NDIM) :: Lescape = 0.0_DP !! Angular momentum of bodies that escaped the system (used for bookeeping) + real(DP) :: Mescape = 0.0_DP !! Mass of bodies that escaped the system (used for bookeeping) + real(DP) :: Ecollisions = 0.0_DP !! Energy lost from system due to collisions + real(DP) :: Euntracked = 0.0_DP !! Energy gained from system due to escaped bodies + logical :: lbeg !! True if this is the beginning of a step. This is used so that test particle steps can be calculated + !! separately from massive bodies. Massive body variables are saved at half steps, and passed to + !! the test particles + integer(I4B) :: maxid = -1 !! The current maximum particle id number + contains + !> Each integrator will have its own version of the step + procedure(abstract_step_system), deferred :: step + + ! Concrete classes that are common to the basic integrator (only test particles considered for discard) + procedure :: discard => discard_system !! Perform a discard step on the system + procedure :: conservation_report => io_conservation_report !! Compute energy and momentum and print out the change with time + procedure :: dump => io_dump_system !! Dump the state of the system to a file + procedure :: read_frame => io_read_frame_system !! Read in a frame of input data from file + procedure :: write_discard => io_write_discard !! Write out information about discarded test particles + procedure :: write_frame => io_write_frame_system !! Append a frame of output data to file + procedure :: initialize => setup_initialize_system !! Initialize the system from input files + procedure :: step_spin => tides_step_spin_system !! Steps the spins of the massive & central bodies due to tides. + procedure :: set_msys => util_set_msys !! Sets the value of msys from the masses of system bodies. + procedure :: get_energy_and_momentum => util_get_energy_momentum_system !! Calculates the total system energy and momentum + end type swiftest_nbody_system + + type :: swiftest_encounter + integer(I4B) :: nenc !! Total number of encounters + logical, dimension(:), allocatable :: lvdotr !! relative vdotr flag + integer(I4B), dimension(:), allocatable :: status !! status of the interaction + integer(I4B), dimension(:), allocatable :: index1 !! position of the first body in the encounter + integer(I4B), dimension(:), allocatable :: index2 !! position of the second body in the encounter + real(DP), dimension(:,:), allocatable :: x1 !! the position of body 1 in the encounter + real(DP), dimension(:,:), allocatable :: x2 !! the position of body 2 in the encounter + real(DP), dimension(:,:), allocatable :: v1 !! the velocity of body 1 in the encounter + real(DP), dimension(:,:), allocatable :: v2 !! the velocity of body 2 in the encounter + contains + procedure :: setup => setup_encounter !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure :: copy => util_copy_encounter !! Copies elements from the source encounter list into self. + procedure :: spill => util_spill_encounter !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure :: resize => util_resize_encounter !! Checks the current size of the encounter list against the required size and extends it by a factor of 2 more than requested if it is too small. + end type swiftest_encounter + + abstract interface + subroutine abstract_discard_body(self, system, param) + import swiftest_body, swiftest_nbody_system, swiftest_parameters + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine abstract_discard_body + + subroutine abstract_accel(self, system, param, t, lbeg) + import swiftest_body, swiftest_nbody_system, swiftest_parameters, DP + class(swiftest_body), intent(inout) :: self !! Swiftest body data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step + end subroutine abstract_accel + + subroutine abstract_initialize(self, param) + import swiftest_base, swiftest_parameters + class(swiftest_base), intent(inout) :: self !! Swiftest base object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine abstract_initialize + + subroutine abstract_kick_body(self, system, param, t, dt, lbeg) + import swiftest_body, swiftest_nbody_system, swiftest_parameters, DP + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system objec + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + end subroutine abstract_kick_body + + subroutine abstract_read_frame(self, iu, param, form, ierr) + import DP, I4B, swiftest_base, swiftest_parameters + class(swiftest_base), intent(inout) :: self !! Swiftest base object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + end subroutine abstract_read_frame + + subroutine abstract_set_mu(self, cb) + import swiftest_body, swiftest_cb + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine abstract_set_mu + + subroutine abstract_step_body(self, system, param, t, dt) + import DP, swiftest_body, swiftest_nbody_system, swiftest_parameters + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine abstract_step_body + + subroutine abstract_step_system(self, param, t, dt) + import DP, swiftest_nbody_system, swiftest_parameters + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine abstract_step_system + + subroutine abstract_write_frame(self, iu, param) + import DP, I4B, swiftest_base, swiftest_parameters + class(swiftest_base), intent(in) :: self !! Swiftest base object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine abstract_write_frame + end interface + + interface + module subroutine discard_pl(self, system, param) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameter + end subroutine discard_pl + + module subroutine discard_system(self, param) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine discard_system + + module subroutine discard_tp(self, system, param) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine discard_tp + + module pure subroutine drift_all(mu, x, v, n, param, dt, mask, iflag) + implicit none + real(DP), dimension(:), intent(in) :: mu !! Vector of gravitational constants + real(DP), dimension(:,:), intent(inout) :: x, v !! Position and velocity vectors + integer(I4B), intent(in) :: n !! number of bodies + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + integer(I4B), dimension(:), intent(out) :: iflag !! Vector of error flags. 0 means no problem + end subroutine drift_all + + module subroutine drift_body(self, system, param, dt) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine drift_body + + module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) + implicit none + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body to drift + real(DP), intent(inout) :: px, py, pz, vx, vy, vz !! Position and velocity of body to drift + real(DP), intent(in) :: dt !! Step size + integer(I4B), intent(out) :: iflag !! iflag : error status flag for Danby drift (0 = OK, nonzero = ERROR) + end subroutine drift_one + + module subroutine eucl_dist_index_plpl(self) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + end subroutine + + module subroutine fragmentation_initialize(system, param, family, x, v, L_spin, Ip, mass, radius, & + nfrag, Ip_frag, m_frag, rad_frag, xb_frag, vb_frag, rot_frag, Qloss, lfailure) + implicit none + class(swiftest_nbody_system), intent(inout) :: system + class(swiftest_parameters), intent(in) :: param + integer(I4B), dimension(:), intent(in) :: family + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip + real(DP), dimension(:), intent(inout) :: mass, radius + integer(I4B), intent(inout) :: nfrag + real(DP), dimension(:), allocatable, intent(inout) :: m_frag, rad_frag + real(DP), dimension(:,:), allocatable, intent(inout) :: Ip_frag + real(DP), dimension(:,:), allocatable, intent(inout) :: xb_frag, vb_frag, rot_frag + logical, intent(out) :: lfailure ! Answers the question: Should this have been a merger instead? + real(DP), intent(inout) :: Qloss + end subroutine fragmentation_initialize + + module subroutine fragmentation_regime(Mcb, m1, m2, rad1, rad2, xh1, xh2, vb1, vb2, den1, den2, regime, Mlr, Mslr, mtiny, Qloss) + implicit none + integer(I4B), intent(out) :: regime + real(DP), intent(out) :: Mlr, Mslr + real(DP), intent(in) :: Mcb, m1, m2, rad1, rad2, den1, den2, mtiny + real(DP), dimension(:), intent(in) :: xh1, xh2, vb1, vb2 + real(DP), intent(out) :: Qloss !! The residual energy after the collision + end subroutine fragmentation_regime + + module pure subroutine gr_kick_getaccb_ns_body(self, system, param) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine gr_kick_getaccb_ns_body + + module subroutine gr_kick_getacch(mu, x, lmask, n, inv_c2, agr) + implicit none + real(DP), dimension(:), intent(in) :: mu !! Gravitational constant + real(DP), dimension(:,:), intent(in) :: x !! Position vectors + logical, dimension(:), intent(in) :: lmask !! Logical mask indicating which bodies to compute + integer(I4B), intent(in) :: n !! Total number of bodies + real(DP), intent(in) :: inv_c2 !! Inverse speed of light squared: 1 / c**2 + real(DP), dimension(:,:), intent(out) :: agr !! Accelerations + end subroutine gr_kick_getacch + + module pure subroutine gr_p4_pos_kick(param, x, v, dt) + implicit none + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), dimension(:), intent(inout) :: x !! Position vector + real(DP), dimension(:), intent(in) :: v !! Velocity vector + real(DP), intent(in) :: dt !! Step size + end subroutine gr_p4_pos_kick + + module pure subroutine gr_pseudovel2vel(param, mu, xh, pv, vh) + implicit none + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body + real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector + real(DP), dimension(:), intent(in) :: pv !! Pseudovelocity velocity vector - see Saha & Tremain (1994), eq. (32) + real(DP), dimension(:), intent(out) :: vh !! Heliocentric velocity vector + end subroutine gr_pseudovel2vel + + module pure subroutine gr_pv2vh_body(self, param) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine gr_pv2vh_body + + module pure subroutine gr_vel2pseudovel(param, mu, xh, vh, pv) + implicit none + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body + real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector + real(DP), dimension(:), intent(in) :: vh !! Heliocentric velocity vector + real(DP), dimension(:), intent(out) :: pv !! Pseudovelocity vector - see Saha & Tremain (1994), eq. (32) + end subroutine gr_vel2pseudovel + + module pure subroutine gr_vh2pv_body(self, param) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine gr_vh2pv_body + + module subroutine io_conservation_report(self, param, lterminal) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Input colleciton of user-defined parameters + logical, intent(in) :: lterminal !! Indicates whether to output information to the terminal screen + end subroutine io_conservation_report + + module subroutine io_dump_param(self, param_file_name) + implicit none + class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + end subroutine io_dump_param + + module subroutine io_dump_swiftest(self, param, msg) + implicit none + class(swiftest_base), intent(inout) :: self !! Swiftest base object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + end subroutine io_dump_swiftest + + module subroutine io_dump_system(self, param, msg) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + end subroutine io_dump_system + + module function io_get_args(integrator, param_file_name) result(ierr) + implicit none + integer(I4B) :: integrator !! Symbolic code of the requested integrator + character(len=:), allocatable :: param_file_name !! Name of the input parameters file + integer(I4B) :: ierr !! I/O error code + end function io_get_args + + module function io_get_token(buffer, ifirst, ilast, ierr) result(token) + implicit none + character(len=*), intent(in) :: buffer !! Input string buffer + integer(I4B), intent(inout) :: ifirst !! Index of the buffer at which to start the search for a token + integer(I4B), intent(out) :: ilast !! Index of the buffer at the end of the returned token + integer(I4B), intent(out) :: ierr !! Error code + character(len=:), allocatable :: token !! Returned token string + end function io_get_token + + module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(swiftest_parameters), intent(inout) :: self !! Collection of parameters + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine io_param_reader + + module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(swiftest_parameters), intent(in) :: self !! Collection of parameters + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! Not used in this procedure + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine io_param_writer + + module subroutine io_read_body_in(self, param) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine io_read_body_in + + module subroutine io_read_cb_in(self, param) + implicit none + class(swiftest_cb), intent(inout) :: self !! Swiftest central body object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine io_read_cb_in + + module subroutine io_read_param_in(self, param_file_name) + implicit none + class(swiftest_parameters), intent(inout) :: self !! Current run configuration parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + end subroutine io_read_param_in + + module subroutine io_read_frame_body(self, iu, param, form, ierr) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + end subroutine io_read_frame_body + + module subroutine io_read_frame_cb(self, iu, param, form, ierr) + implicit none + class(swiftest_cb), intent(inout) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + end subroutine io_read_frame_cb + + module subroutine io_read_frame_system(self, iu, param, form, ierr) + implicit none + class(swiftest_nbody_system),intent(inout) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + end subroutine io_read_frame_system + + module subroutine io_write_discard(self, param) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine io_write_discard + + module subroutine io_toupper(string) + implicit none + character(*), intent(inout) :: string !! String to make upper case + end subroutine io_toupper + + module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + xh1, xh2, vh1, vh2, enc_out, out_type) + implicit none + integer(I4B), intent(in) :: name1, name2 + real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(in) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: enc_out, out_type + end subroutine io_write_encounter + + module subroutine io_write_frame_body(self, iu, param) + implicit none + class(swiftest_body), intent(in) :: self !! Swiftest body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine io_write_frame_body + + module subroutine io_write_frame_cb(self, iu, param) + implicit none + class(swiftest_cb), intent(in) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine io_write_frame_cb + + module subroutine io_write_frame_system(self, iu, param) + implicit none + class(swiftest_nbody_system), intent(in) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine io_write_frame_system + + module pure subroutine kick_getacch_int_pl(self) + implicit none + class(swiftest_pl), intent(inout) :: self + end subroutine kick_getacch_int_pl + + module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle + real(DP), dimension(:), intent(in) :: GMpl !! Massive body masses + real(DP), dimension(:,:), intent(in) :: xhp !! Massive body position vectors + integer(I4B), intent(in) :: npl !! Number of active massive bodies + end subroutine kick_getacch_int_tp + + module subroutine obl_acc_body(self, system) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + end subroutine obl_acc_body + + module subroutine obl_acc_pl(self, system) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + end subroutine obl_acc_pl + + module subroutine obl_acc_tp(self, system) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + end subroutine obl_acc_tp + + module subroutine obl_pot(npl, Mcb, Mpl, j2rp2, j4rp4, xh, irh, oblpot) + implicit none + integer(I4B), intent(in) :: npl + real(DP), intent(in) :: Mcb + real(DP), dimension(:), intent(in) :: Mpl + real(DP), intent(in) :: j2rp2, j4rp4 + real(DP), dimension(:), intent(in) :: irh + real(DP), dimension(:, :), intent(in) :: xh + real(DP), intent(out) :: oblpot + end subroutine obl_pot + + module subroutine orbel_el2xv_vec(self, cb) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine orbel_el2xv_vec + + module pure subroutine orbel_scget(angle, sx, cx) + implicit none + real(DP), intent(in) :: angle + real(DP), intent(out) :: sx, cx + end subroutine orbel_scget + + module pure subroutine orbel_xv2aeq(mu, x, v, a, e, q) + implicit none + real(DP), intent(in) :: mu !! Gravitational constant + real(DP), dimension(:), intent(in) :: x !! Position vector + real(DP), dimension(:), intent(in) :: v !! Velocity vector + real(DP), intent(out) :: a !! semimajor axis + real(DP), intent(out) :: e !! eccentricity + real(DP), intent(out) :: q !! periapsis + end subroutine orbel_xv2aeq + + module pure subroutine orbel_xv2aqt(mu, x, v, a, q, capm, tperi) + implicit none + real(DP), intent(in) :: mu !! Gravitational constant + real(DP), dimension(:), intent(in) :: x !! Position vector + real(DP), dimension(:), intent(in) :: v !! Velocity vector + real(DP), intent(out) :: a !! semimajor axis + real(DP), intent(out) :: q !! periapsis + real(DP), intent(out) :: capm !! mean anomaly + real(DP), intent(out) :: tperi !! time of pericenter passage + end subroutine orbel_xv2aqt + + module subroutine orbel_xv2el_vec(self, cb) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine orbel_xv2el_vec + + module subroutine setup_body(self, n, param) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine setup_body + + module subroutine setup_construct_system(system, param) + implicit none + class(swiftest_nbody_system), allocatable, intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine setup_construct_system + + module subroutine setup_encounter(self, n) + implicit none + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter structure + integer(I4B), intent(in) :: n !! Number of encounters to allocate space for + end subroutine setup_encounter + + module subroutine setup_initialize_system(self, param) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine setup_initialize_system + + module subroutine setup_pl(self, n, param) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine setup_pl + + module subroutine setup_tp(self, n, param) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parametersr + end subroutine setup_tp + + module subroutine tides_kick_getacch_pl(self, system) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + end subroutine tides_kick_getacch_pl + + module subroutine tides_step_spin_system(self, param, t, dt) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine tides_step_spin_system + + module subroutine user_kick_getacch_body(self, system, param, t, lbeg) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody_system_object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step + end subroutine user_kick_getacch_body + end interface + + interface util_append + module subroutine util_append_arr_char_string(arr, source, lsource_mask) + implicit none + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: arr !! Destination array + character(len=STRMAX), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_arr_char_string + + module subroutine util_append_arr_DP(arr, source, lsource_mask) + implicit none + real(DP), dimension(:), allocatable, intent(inout) :: arr !! Destination array + real(DP), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_arr_DP + + module subroutine util_append_arr_DPvec(arr, source, lsource_mask) + implicit none + real(DP), dimension(:,:), allocatable, intent(inout) :: arr !! Destination array + real(DP), dimension(:,:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_arr_DPvec + + module subroutine util_append_arr_I4B(arr, source, lsource_mask) + implicit none + integer(I4B), dimension(:), allocatable, intent(inout) :: arr !! Destination array + integer(I4B), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_arr_I4B + + module subroutine util_append_arr_logical(arr, source, lsource_mask) + implicit none + logical, dimension(:), allocatable, intent(inout) :: arr !! Destination array + logical, dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_arr_logical + end interface + + interface + module subroutine util_append_body(self, source, lsource_mask) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_body + + module subroutine util_append_pl(self, source, lsource_mask) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_pl + + module subroutine util_append_tp(self, source, lsource_mask) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine util_append_tp + + module subroutine util_coord_b2h_pl(self, cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_coord_b2h_pl + + module subroutine util_coord_b2h_tp(self, cb) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + end subroutine util_coord_b2h_tp + + module subroutine util_coord_h2b_pl(self, cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_coord_h2b_pl + + module subroutine util_coord_h2b_tp(self, cb) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + end subroutine util_coord_h2b_tp + + module subroutine util_copy_encounter(self, source) + implicit none + class(swiftest_encounter), intent(inout) :: self !! Encounter list + class(swiftest_encounter), intent(in) :: source !! Source object to copy into + end subroutine util_copy_encounter + + module subroutine util_exit(code) + implicit none + integer(I4B), intent(in) :: code !! Failure exit code + end subroutine util_exit + + module subroutine util_fill_body(self, inserts, lfill_list) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_body), intent(in) :: inserts !! Swiftest body object to be inserted + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_body + + module subroutine util_fill_pl(self, inserts, lfill_list) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(in) :: inserts !! Swiftest body object to be inserted + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_pl + + module subroutine util_fill_tp(self, inserts, lfill_list) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(in) :: inserts !! Swiftest body object to be inserted + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_tp + end interface + + interface util_fill + module subroutine util_fill_arr_char_string(keeps, inserts, lfill_list) + implicit none + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + character(len=STRMAX), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_arr_char_string + + module subroutine util_fill_arr_DP(keeps, inserts, lfill_list) + implicit none + real(DP), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_arr_DP + + module subroutine util_fill_arr_DPvec(keeps, inserts, lfill_list) + implicit none + real(DP), dimension(:,:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:,:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_arr_DPvec + + module subroutine util_fill_arr_I4B(keeps, inserts, lfill_list) + implicit none + integer(I4B), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + integer(I4B), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_arr_I4B + + module subroutine util_fill_arr_logical(keeps, inserts, lfill_list) + implicit none + logical, dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + logical, dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine util_fill_arr_logical + end interface + + interface + module function util_minimize_bfgs(f, N, x0, eps, lerr) result(x1) + use lambda_function + implicit none + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0 + real(DP), intent(in) :: eps + logical, intent(out) :: lerr + real(DP), dimension(:), allocatable :: x1 + end function util_minimize_bfgs + + module subroutine util_peri_tp(self, system, param) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine util_peri_tp + end interface + + interface util_solve_linear_system + module function util_solve_linear_system_d(A,b,n,lerr) result(x) + implicit none + integer(I4B), intent(in) :: n + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), intent(in) :: b + logical, intent(out) :: lerr + real(DP), dimension(n) :: x + end function util_solve_linear_system_d + + module function util_solve_linear_system_q(A,b,n,lerr) result(x) + implicit none + integer(I4B), intent(in) :: n + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), intent(in) :: b + logical, intent(out) :: lerr + real(QP), dimension(n) :: x + end function util_solve_linear_system_q + end interface + + interface + module function util_solve_rkf45(f, y0in, t1, dt0, tol) result(y1) + use lambda_function + implicit none + class(lambda_obj), intent(inout) :: f !! lambda function object that has been initialized to be a function of derivatives. The object will return with components lastarg and lasteval set + real(DP), dimension(:), intent(in) :: y0in !! Initial value at t=0 + real(DP), intent(in) :: t1 !! Final time + real(DP), intent(in) :: dt0 !! Initial step size guess + real(DP), intent(in) :: tol !! Tolerance on solution + real(DP), dimension(:), allocatable :: y1 !! Final result + end function util_solve_rkf45 + end interface + + interface util_resize + module subroutine util_resize_arr_char_string(arr, nnew) + implicit none + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine util_resize_arr_char_string + + module subroutine util_resize_arr_DP(arr, nnew) + implicit none + real(DP), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine util_resize_arr_DP + + module subroutine util_resize_arr_DPvec(arr, nnew) + implicit none + real(DP), dimension(:,:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine util_resize_arr_DPvec + + module subroutine util_resize_arr_I4B(arr, nnew) + implicit none + integer(I4B), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine util_resize_arr_I4B + + module subroutine util_resize_arr_logical(arr, nnew) + implicit none + logical, dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine util_resize_arr_logical + end interface + + interface + module subroutine util_resize_body(self, nnew) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine util_resize_body + + module subroutine util_resize_encounter(self, nnew) + implicit none + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter list + integer(I4B), intent(in) :: nnew !! New size of list needed + end subroutine util_resize_encounter + + module subroutine util_resize_pl(self, nnew) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine util_resize_pl + + module subroutine util_resize_tp(self, nnew) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine util_resize_tp + + module subroutine util_get_energy_momentum_system(self, param) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine util_get_energy_momentum_system + + module subroutine util_set_beg_end_pl(self, xbeg, xend, vbeg) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + real(DP), dimension(:,:), intent(in), optional :: xbeg !! Position vectors at beginning of step + real(DP), dimension(:,:), intent(in), optional :: xend !! Positions vectors at end of step + real(DP), dimension(:,:), intent(in), optional :: vbeg !! vbeg is an unused variable to keep this method forward compatible with RMVS + end subroutine util_set_beg_end_pl + + module subroutine util_set_ir3h(self) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + end subroutine util_set_ir3h + + module subroutine util_set_msys(self) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + end subroutine util_set_msys + + module subroutine util_set_mu_pl(self, cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_set_mu_pl + + module subroutine util_set_mu_tp(self, cb) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_set_mu_tp + + module subroutine util_set_rhill(self,cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_set_rhill + + module subroutine util_set_rhill_approximate(self,cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_set_rhill_approximate + end interface + + interface util_sort + module subroutine util_sort_i4b(arr) + implicit none + integer(I4B), dimension(:), intent(inout) :: arr + end subroutine util_sort_i4b + + module subroutine util_sort_index_i4b(arr,ind) + implicit none + integer(I4B), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + end subroutine util_sort_index_i4b + + module subroutine util_sort_sp(arr) + implicit none + real(SP), dimension(:), intent(inout) :: arr + end subroutine util_sort_sp + + module subroutine util_sort_index_sp(arr,ind) + implicit none + real(SP), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + end subroutine util_sort_index_sp + + module subroutine util_sort_dp(arr) + implicit none + real(DP), dimension(:), intent(inout) :: arr + end subroutine util_sort_dp + + module subroutine util_sort_index_dp(arr,ind) + implicit none + real(DP), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + end subroutine util_sort_index_dp + end interface util_sort + + interface + module subroutine util_sort_rearrange_body(self, ind) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine util_sort_rearrange_body + + module subroutine util_sort_rearrange_pl(self, ind) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine util_sort_rearrange_pl + + module subroutine util_sort_rearrange_tp(self, ind) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine util_sort_rearrange_tp + + module subroutine util_sort_body(self, sortby, ascending) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine util_sort_body + + module subroutine util_sort_pl(self, sortby, ascending) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine util_sort_pl + + module subroutine util_sort_tp(self, sortby, ascending) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine util_sort_tp + end interface + + interface util_spill + module subroutine util_spill_arr_char_string(keeps, discards, lspill_list, ldestructive) + implicit none + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_arr_char_string + + module subroutine util_spill_arr_DP(keeps, discards, lspill_list, ldestructive) + implicit none + real(DP), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_arr_DP + + module subroutine util_spill_arr_DPvec(keeps, discards, lspill_list, ldestructive) + implicit none + real(DP), dimension(:,:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:,:), allocatable, intent(inout) :: discards !! Array discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_arr_DPvec + + module subroutine util_spill_arr_I4B(keeps, discards, lspill_list, ldestructive) + implicit none + integer(I4B), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + integer(I4B), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_arr_I4B + + module subroutine util_spill_arr_logical(keeps, discards, lspill_list, ldestructive) + implicit none + logical, dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + logical, dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_arr_logical + end interface + + interface + module subroutine util_spill_body(self, discards, lspill_list, ldestructive) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_body + + module subroutine util_spill_encounter(self, discards, lspill_list, ldestructive) + implicit none + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter list + class(swiftest_encounter), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + end subroutine util_spill_encounter + + module subroutine util_spill_pl(self, discards, lspill_list, ldestructive) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_pl + + module subroutine util_spill_tp(self, discards, lspill_list, ldestructive) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine util_spill_tp + + module subroutine util_valid(pl, tp) + implicit none + class(swiftest_pl), intent(in) :: pl + class(swiftest_tp), intent(in) :: tp + end subroutine util_valid + + module subroutine util_version() + implicit none + end subroutine util_version + end interface + +end module swiftest_classes diff --git a/src/modules/swiftest_globals.f90 b/src/modules/swiftest_globals.f90 new file mode 100644 index 000000000..5ec55f6c6 --- /dev/null +++ b/src/modules/swiftest_globals.f90 @@ -0,0 +1,127 @@ +module swiftest_globals + !! author: David A. Minton + !! graph: false + !! + !! Basic parameters, definitions, and global type definitions used throughout the Swiftest project + !! Adapted from David E. Kaufmann's Swifter routine: swiftest_globals.f90 and module_swifter.f90 + use, intrinsic :: iso_fortran_env ! Use the intrinsic kind definitions + implicit none + public + + integer, parameter :: I8B = int64 !! Symbolic name for kind types of 8-byte integers + integer, parameter :: I4B = int32 !! Symbolic name for kind types of 4-byte integers + integer, parameter :: I2B = int16 !! Symbolic name for kind types of 2-byte integers + integer, parameter :: I1B = int8 !! Symbolic name for kind types of 1-byte integers + + integer, parameter :: SP = real32 !! Symbolic name for kind types of single-precision reals + integer, parameter :: DP = real64 !! Symbolic name for kind types of double-precision reals + integer, parameter :: QP = real128 !! Symbolic name for kind types of quad-precision reals + + real(DP), parameter :: PIBY2 = 1.570796326794896619231321691639751442099_DP !! Definition of /(\pi / 2\) + real(DP), parameter :: PI = 3.141592653589793238462643383279502884197_DP !! Definition of /(\pi\) + real(DP), parameter :: PI3BY2 = 4.712388980384689857693965074919254326296_DP !! Definition of /(3 \pi / 2\) + real(DP), parameter :: TWOPI = 6.283185307179586476925286766559005768394_DP !! Definition of 2 \pi + real(DP), parameter :: THIRD = 0.333333333333333333333333333333333333333_DP !! Definition of 1 / 3 + real(DP), parameter :: DEGRAD = 180.0_DP/PI !! Definition of conversion factor from degrees to radians + + integer(I4B), parameter :: LOWERCASE_BEGIN = iachar('a') !! ASCII character set parameter for lower to upper conversion - start of lowercase + integer(I4B), parameter :: LOWERCASE_END = iachar('z') !! ASCII character set parameter for lower to upper conversion - end of lowercase + integer(I4B), parameter :: UPPERCASE_OFFSET = iachar('A') - iachar('a') !! ASCII character set parameter for lower to upper conversion - offset between upper and lower + + real(SP), parameter :: VERSION_NUMBER = 0.1_SP !! swiftest version + + !> Symbolic name for integrator types + integer(I4B), parameter :: UNKNOWN_INTEGRATOR = 1 + integer(I4B), parameter :: BS = 2 + integer(I4B), parameter :: HELIO = 3 + integer(I4B), parameter :: RA15 = 4 + integer(I4B), parameter :: TU4 = 5 + integer(I4B), parameter :: WHM = 6 + integer(I4B), parameter :: RMVS = 7 + integer(I4B), parameter :: SYMBA = 8 + integer(I4B), parameter :: RINGMOONS = 9 + + integer(I4B), parameter :: STRMAX = 128 !! Maximum size of character strings + + character(*), parameter :: ASCII_TYPE = 'ASCII' !! Symbolic name for ASCII file type + character(*), parameter :: REAL4_TYPE = 'REAL4' !! Symbolic name for binary file type REAL4 + character(*), parameter :: REAL8_TYPE = 'REAL8' !! Symbolic name for binary file type REAL8 + character(*), parameter :: SWIFTER_REAL4_TYPE = 'SWIFTER4' !! Symbolic name for binary file type for the old style Swifter REAL4 + character(*), parameter :: SWIFTER_REAL8_TYPE = 'SWIFTER8' !! Symbolic name for binary file type for the old style Swifter REAL8 + + character(*), parameter :: EL = 'EL' !! Symbolic name for binary output file contents for orbital element type + character(*), parameter :: XV = 'XV' !! Symbolic name for binary output file contents for cartesian position and velocity type + + ! OpenMP Parameters + integer(I4B) :: nthreads = 1 !! Number of OpenMP threads + integer(I4B), parameter :: NTHERSHOLD = 1000 !! Threshold value for OpenMP loop parallelization + + integer(I4B), parameter :: SUCCESS = 0 !! Symbolic name for function return/flag code for success + integer(I4B), parameter :: FAILURE = -1 !! Symbolic name for function return/flag code for failure + integer(I4B), parameter :: USAGE = -2 !! Symbolic name for function return/flag code for printing the usage message + integer(I4B), parameter :: HELP = -3 !! Symbolic name for function return/flag code for printing the usage message + + + character(*), parameter :: SUCCESS_MSG = '(/, "Normal termination of Swiftest (version ", f3.1, ")")' + character(*), parameter :: FAIL_MSG = '(/, "Terminating Swiftest (version ", f3.1, ") due to error!!")' + character(*), parameter :: USAGE_MSG = '("Usage: swiftest [bs|helio|ra15|rmvs|symba|tu4|whm] ")' + character(*), parameter :: HELP_MSG = USAGE_MSG + + integer(I4B), parameter :: ELLIPSE = -1 !! Symbolic names for orbit types - ellipse + integer(I4B), parameter :: PARABOLA = 0 !! Symbolic names for orbit types - parabola + integer(I4B), parameter :: HYPERBOLA = 1 !! Symbolic names for orbit types - hyperbola + + !> Symbolic names for body/particle status codes: + integer(I4B), parameter :: ACTIVE = 0 + integer(I4B), parameter :: INACTIVE = 1 + integer(I4B), parameter :: DISCARDED_RMAX = -1 + integer(I4B), parameter :: DISCARDED_RMIN = -2 + integer(I4B), parameter :: DISCARDED_RMAXU = -3 + integer(I4B), parameter :: DISCARDED_PERI = -4 + integer(I4B), parameter :: DISCARDED_PLR = -5 + integer(I4B), parameter :: DISCARDED_PLQ = -6 + integer(I4B), parameter :: DISCARDED_DRIFTERR = -7 + integer(I4B), parameter :: MERGED = -8 + integer(I4B), parameter :: DISRUPTION = -9 + integer(I4B), parameter :: SUPERCATASTROPHIC = -10 + integer(I4B), parameter :: GRAZE_AND_MERGE = -11 + integer(I4B), parameter :: HIT_AND_RUN = -12 + integer(I4B), parameter :: COLLISION = -13 + + !>Symbolic names for collisional outcomes from collresolve_resolve: + integer(I4B), parameter :: COLLRESOLVE_REGIME_MERGE = 1 + integer(I4B), parameter :: COLLRESOLVE_REGIME_DISRUPTION = 2 + integer(I4B), parameter :: COLLRESOLVE_REGIME_SUPERCATASTROPHIC = 3 + integer(I4B), parameter :: COLLRESOLVE_REGIME_GRAZE_AND_MERGE = 4 + integer(I4B), parameter :: COLLRESOLVE_REGIME_HIT_AND_RUN = 5 + + !> String labels for body/particle addition/subtraction in discard file + character(*), parameter :: ADD = '+1' + character(*), parameter :: SUB = '-1' + + !> Standard file names + integer(I4B), parameter :: NDUMPFILES = 2 + character(*), dimension(2), parameter :: DUMP_CB_FILE = ['dump_cb1.bin', 'dump_cb2.bin' ] + character(*), dimension(2), parameter :: DUMP_PL_FILE = ['dump_pl1.bin', 'dump_pl2.bin' ] + character(*), dimension(2), parameter :: DUMP_TP_FILE = ['dump_tp1.bin', 'dump_tp2.bin' ] + character(*), dimension(2), parameter :: DUMP_PARAM_FILE = ['dump_param1.dat', 'dump_param2.dat'] + + !> Default file names that can be changed by the user in the parameters file + character(*), parameter :: ENC_OUTFILE = 'encounter.out' + character(*), parameter :: DISCARD_FILE = 'discard.out' + character(*), parameter :: ENERGY_FILE = 'energy.out' + character(*), parameter :: CB_INFILE = 'cb.in' + character(*), parameter :: PL_INFILE = 'pl.in' + character(*), parameter :: TP_INFILE = 'tp.in' + character(*), parameter :: BIN_OUTFILE = 'bin.dat' + integer(I4B), parameter :: BINUNIT = 20 !! File unit number for the binary output file + + !> Miscellaneous constants: + integer(I4B), parameter :: NDIM = 3 !! Number of dimensions in our reality + integer(I4B), parameter :: NDIM2 = 2 * NDIM !! 2x the number of dimensions + real(DP), parameter :: VSMALL = 2 * epsilon(1._DP) !! Very small number used to prevent floating underflow + + real(DP), parameter :: GC = 6.6743E-11_DP !! Universal gravitational constant in SI units + real(DP), parameter :: einsteinC = 299792458.0_DP !! Speed of light in SI units + +end module swiftest_globals diff --git a/src/modules/swiftest_operators.f90 b/src/modules/swiftest_operators.f90 new file mode 100644 index 000000000..2c982f09c --- /dev/null +++ b/src/modules/swiftest_operators.f90 @@ -0,0 +1,144 @@ +module swiftest_operators + !! author: David A. Minton + !! + !! Custom operators, including + !! A .cross. B = Cross product of A(1:3) and B(1:3) + !! + !! Each operator can also do element-wise computation on arrays of the form .mag. A(1:3, 1:n) + use swiftest_globals + implicit none + public + + !******************************************************************************************************************************** + ! Interfaces for .cross. operator + !******************************************************************************************************************************** + + interface operator(.cross.) + module pure function operator_cross_sp(A, B) result(C) + implicit none + real(SP), dimension(:), intent(in) :: A, B + real(SP), dimension(3) :: C + end function operator_cross_sp + + module pure function operator_cross_dp(A, B) result(C) + implicit none + real(DP), dimension(:), intent(in) :: A, B + real(DP), dimension(3) :: C + end function operator_cross_dp + + module pure function operator_cross_qp(A, B) result(C) + implicit none + real(QP), dimension(:), intent(in) :: A, B + real(QP), dimension(3) :: C + end function operator_cross_qp + + module pure function operator_cross_i1b(A, B) result(C) + implicit none + integer(I1B), dimension(:), intent(in) :: A, B + integer(I1B), dimension(3) :: C + end function operator_cross_i1b + + module pure function operator_cross_i2b(A, B) result(C) + implicit none + integer(I2B), dimension(:), intent(in) :: A, B + integer(I2B), dimension(3) :: C + end function operator_cross_i2b + + module pure function operator_cross_i4b(A, B) result(C) + implicit none + integer(I4B), dimension(:), intent(in) :: A, B + integer(I4B), dimension(3) :: C + end function operator_cross_i4b + + module pure function operator_cross_i8b(A, B) result(C) + implicit none + integer(I8B), dimension(:), intent(in) :: A, B + integer(I8B), dimension(3) :: C + end function operator_cross_i8b + + module pure function operator_cross_el_sp(A, B) result(C) + implicit none + real(SP), dimension(:,:), intent(in) :: A, B + real(SP), dimension(:,:), allocatable :: C + end function operator_cross_el_sp + + module pure function operator_cross_el_dp(A, B) result(C) + implicit none + real(DP), dimension(:,:), intent(in) :: A, B + real(DP), dimension(:,:), allocatable :: C + end function operator_cross_el_dp + + module pure function operator_cross_el_qp(A, B) result(C) + implicit none + real(QP), dimension(:,:), intent(in) :: A, B + real(QP), dimension(:,:), allocatable :: C + end function operator_cross_el_qp + + module pure function operator_cross_el_i1b(A, B) result(C) + implicit none + integer(I1B), dimension(:,:), intent(in) :: A, B + integer(I1B), dimension(:,:), allocatable :: C + end function operator_cross_el_i1b + + module pure function operator_cross_el_i2b(A, B) result(C) + implicit none + integer(I2B), dimension(:,:), intent(in) :: A, B + integer(I2B), dimension(:,:), allocatable :: C + end function operator_cross_el_i2b + + module pure function operator_cross_el_i4b(A, B) result(C) + implicit none + integer(I4B), dimension(:,:), intent(in) :: A, B + integer(I4B), dimension(:,:), allocatable :: C + end function operator_cross_el_i4b + + module pure function operator_cross_el_i8b(A, B) result(C) + implicit none + integer(I8B), dimension(:,:), intent(in) :: A, B + integer(I8B), dimension(:,:), allocatable :: C + end function operator_cross_el_i8b + end interface + + !******************************************************************************************************************************** + ! Interfaces for .mag. operator + !******************************************************************************************************************************** + + interface operator(.mag.) + module pure function operator_mag_sp(A) result(B) + implicit none + real(SP), dimension(:), intent(in) :: A + real(SP) :: B + end function operator_mag_sp + + module pure function operator_mag_dp(A) result(B) + implicit none + real(DP), dimension(:), intent(in) :: A + real(DP) :: B + end function operator_mag_dp + + module pure function operator_mag_qp(A) result(B) + implicit none + real(QP), dimension(:), intent(in) :: A + real(QP) :: B + end function operator_mag_qp + + module pure function operator_mag_el_sp(A) result(B) + implicit none + real(SP), dimension(:,:), intent(in) :: A + real(SP), dimension(:), allocatable :: B + end function operator_mag_el_sp + + module pure function operator_mag_el_dp(A) result(B) + implicit none + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), allocatable :: B + end function operator_mag_el_dp + + module pure function operator_mag_el_qp(A) result(B) + implicit none + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), allocatable :: B + end function operator_mag_el_qp + end interface + +end module swiftest_operators diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 new file mode 100644 index 000000000..0e66ebf7c --- /dev/null +++ b/src/modules/symba_classes.f90 @@ -0,0 +1,689 @@ +module symba_classes + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Definition of classes and methods specific to the Democratic SyMBAcentric Method + !! Adapted from David E. Kaufmann's Swifter routine: helio.f90 + use swiftest_globals + use swiftest_classes, only : swiftest_parameters, swiftest_base, swiftest_encounter + use helio_classes, only : helio_cb, helio_pl, helio_tp, helio_nbody_system + use rmvs_classes, only : rmvs_chk_ind + implicit none + public + + integer(I4B), private, parameter :: NENMAX = 32767 + integer(I4B), private, parameter :: NTENC = 3 + real(DP), private, parameter :: RHSCALE = 6.5_DP + real(DP), private, parameter :: RSHELL = 0.48075_DP + character(*), parameter :: PARTICLE_OUTFILE = 'particle.dat' + integer(I4B), parameter :: PARTICLEUNIT = 44 !! File unit number for the binary particle info output file + + type, extends(swiftest_parameters) :: symba_parameters + character(STRMAX) :: particle_file = PARTICLE_OUTFILE !! Name of output particle information file + real(DP) :: MTINY = -1.0_DP !! Smallest mass that is fully gravitating + integer(I4B), dimension(:), allocatable :: seed !! Random seeds + logical :: lfragmentation = .false. !! Do fragmentation modeling instead of simple merger. + contains + procedure :: reader => symba_io_param_reader + procedure :: writer => symba_io_param_writer + end type symba_parameters + + !******************************************************************************************************************************** + ! symba_cb class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA central body particle class + type, extends(helio_cb) :: symba_cb + real(DP) :: M0 = 0.0_DP !! Initial mass of the central body + real(DP) :: dM = 0.0_DP !! Change in mass of the central body + real(DP) :: R0 = 0.0_DP !! Initial radius of the central body + real(DP) :: dR = 0.0_DP !! Change in the radius of the central body + contains + end type symba_cb + + !******************************************************************************************************************************** + ! symba_particle_info class definitions and method interfaces + !******************************************************************************************************************************* + !> Class definition for the particle origin information object. This object is used to track time, location, and collisional regime + !> of fragments produced in collisional events. + type, extends(swiftest_base) :: symba_particle_info + character(len=32) :: origin_type !! String containing a description of the origin of the particle (e.g. Initial Conditions, Supercatastrophic, Disruption, etc.) + real(DP) :: origin_time !! The time of the particle's formation + real(DP), dimension(NDIM) :: origin_xh !! The heliocentric distance vector at the time of the particle's formation + real(DP), dimension(NDIM) :: origin_vh !! The heliocentric velocity vector at the time of the particle's formation + contains + procedure :: dump => symba_io_dump_particle_info !! I/O routine for dumping particle info to file + procedure :: initialize => symba_io_initialize_particle_info !! I/O routine for reading in particle info data + procedure :: read_frame => symba_io_read_frame_info !! I/O routine for reading in a single frame of particle info + procedure :: write_frame => symba_io_write_frame_info !! I/O routine for writing out a single frame of particle info + end type symba_particle_info + + !******************************************************************************************************************************** + ! symba_kinship class definitions and method interfaces + !******************************************************************************************************************************* + !> Class definition for the kinship relationships used in bookkeeping multiple collisions bodies in a single time step. + type symba_kinship + integer(I4B) :: parent !! Index of parent particle + integer(I4B) :: nchild !! number of children in merger list + integer(I4B), dimension(:), allocatable :: child !! Index of children particles + end type symba_kinship + + !******************************************************************************************************************************** + ! symba_pl class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA massive body class + type, extends(helio_pl) :: symba_pl + logical, dimension(:), allocatable :: lcollision !! flag indicating whether body has merged with another this time step + logical, dimension(:), allocatable :: lencounter !! flag indicating whether body is part of an encounter this time step + logical, dimension(:), allocatable :: lmtiny !! flag indicating whether this body is below the MTINY cutoff value + integer(I4B) :: nplm !! number of bodies above the MTINY limit + integer(I8B) :: nplplm !! Number of body (all massive)-body (only those above MTINY) comparisons in the flattened upper triangular matrix + integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with other planets this time step + integer(I4B), dimension(:), allocatable :: ntpenc !! number of encounters with test particles this time step + integer(I4B), dimension(:), allocatable :: levelg !! level at which this body should be moved + integer(I4B), dimension(:), allocatable :: levelm !! deepest encounter level achieved this time step + integer(I4B), dimension(:), allocatable :: isperi !! perihelion passage flag + real(DP), dimension(:), allocatable :: peri !! perihelion distance + real(DP), dimension(:), allocatable :: atp !! semimajor axis following perihelion passage + type(symba_kinship), dimension(:), allocatable :: kin !! Array of merger relationship structures that can account for multiple pairwise mergers in a single step + type(symba_particle_info), dimension(:), allocatable :: info + contains + procedure :: make_family => symba_collision_make_family_pl !! When a single body is involved in more than one collision in a single step, it becomes part of a family + procedure :: discard => symba_discard_pl !! Process massive body discards + procedure :: drift => symba_drift_pl !! Method for Danby drift in Democratic Heliocentric coordinates. Sets the mask to the current recursion level + procedure :: encounter_check => symba_encounter_check_pl !! Checks if massive bodies are going through close encounters with each other + procedure :: accel => symba_kick_getacch_pl !! Compute heliocentric accelerations of massive bodies + procedure :: setup => symba_setup_pl !! Constructor method - Allocates space for the input number of bodies + procedure :: append => symba_util_append_pl !! Appends elements from one structure to another + procedure :: fill => symba_util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: get_peri => symba_util_peri_pl !! Determine system pericenter passages for massive bodies + procedure :: rearray => symba_util_rearray_pl !! Clean up the massive body structures to remove discarded bodies and add new bodies + procedure :: resize => symba_util_resize_pl !! Checks the current size of a SyMBA massive body against the requested size and resizes it if it is too small. + procedure :: sort => symba_util_sort_pl !! Sorts body arrays by a sortable componen + procedure :: rearrange => symba_util_sort_rearrange_pl !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => symba_util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type symba_pl + + type, extends(symba_pl) :: symba_merger + integer(I4B), dimension(:), allocatable :: ncomp + contains + procedure :: append => symba_util_append_merger !! Appends elements from one structure to another + procedure :: resize => symba_util_resize_merger !! Checks the current size of a SyMBA merger list against the requested size and resizes it if it is too small. + procedure :: setup => symba_setup_merger !! Constructor method - Allocates space for the input number of bodies + end type symba_merger + + !******************************************************************************************************************************** + ! symba_tp class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA test particle class + type, extends(helio_tp) :: symba_tp + integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with planets this time step + integer(I4B), dimension(:), allocatable :: levelg !! level at which this particle should be moved + integer(I4B), dimension(:), allocatable :: levelm !! deepest encounter level achieved this time step + contains + procedure :: drift => symba_drift_tp !! Method for Danby drift in Democratic Heliocentric coordinates. Sets the mask to the current recursion level + procedure :: encounter_check => symba_encounter_check_tp !! Checks if any test particles are undergoing a close encounter with a massive body + procedure :: accel => symba_kick_getacch_tp !! Compute heliocentric accelerations of test particles + procedure :: setup => symba_setup_tp !! Constructor method - Allocates space for the input number of bodies + procedure :: append => symba_util_append_tp !! Appends elements from one structure to another + procedure :: fill => symba_util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => symba_util_resize_tp !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: sort => symba_util_sort_tp !! Sorts body arrays by a sortable componen + procedure :: rearrange => symba_util_sort_rearrange_tp !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => symba_util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type symba_tp + + !******************************************************************************************************************************** + ! symba_pltpenc class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA class for tracking pl-tp close encounters in a step + type, extends(swiftest_encounter) :: symba_pltpenc + integer(I4B), dimension(:), allocatable :: level !! encounter recursion level + contains + procedure :: collision_check => symba_collision_check_pltpenc !! Checks if a test particle is going to collide with a massive body + procedure :: encounter_check => symba_encounter_check_pltpenc !! Checks if massive bodies are going through close encounters with each other + procedure :: kick => symba_kick_pltpenc !! Kick barycentric velocities of active test particles within SyMBA recursion + procedure :: setup => symba_setup_pltpenc !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure :: spill => symba_util_spill_pltpenc !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + end type symba_pltpenc + + !******************************************************************************************************************************** + ! symba_plplenc class definitions and method interfaces + !******************************************************************************************************************************* + !> SyMBA class for tracking pl-pl close encounters in a step + type, extends(symba_pltpenc) :: symba_plplenc + contains + procedure :: scrub_non_collision => symba_collision_encounter_scrub !! Processes the pl-pl encounter list remove only those encounters that led to a collision + procedure :: resolve_fragmentations => symba_collision_resolve_fragmentations !! Process list of collisions, determine the collisional regime, and then create fragments + procedure :: resolve_mergers => symba_collision_resolve_mergers !! Process list of collisions and merge colliding bodies together + end type symba_plplenc + + !******************************************************************************************************************************** + ! symba_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + type, extends(helio_nbody_system) :: symba_nbody_system + class(symba_merger), allocatable :: mergeadd_list !! List of added bodies in mergers or collisions + class(symba_merger), allocatable :: mergesub_list !! List of subtracted bodies in mergers or collisions + class(symba_pltpenc), allocatable :: pltpenc_list !! List of massive body-test particle encounters in a single step + class(symba_plplenc), allocatable :: plplenc_list !! List of massive body-massive body encounters in a single step + integer(I4B) :: irec !! System recursion level + contains + procedure :: write_discard => symba_io_write_discard !! Write out information about discarded and merged planets and test particles in SyMBA + procedure :: initialize => symba_setup_initialize_system !! Performs SyMBA-specific initilization steps + procedure :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step + procedure :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system + procedure :: set_recur_levels => symba_step_set_recur_levels_system !! Sets recursion levels of bodies and encounter lists to the current system level + procedure :: recursive_step => symba_step_recur_system !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current recursion level, if applicable, and descend to the next deeper level if necessary + procedure :: reset => symba_step_reset_system !! Resets pl, tp,and encounter structures at the start of a new step + end type symba_nbody_system + + interface + module subroutine symba_collision_check_pltpenc(self, system, param, t, dt, irec) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! current time + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + end subroutine symba_collision_check_pltpenc + + module subroutine symba_collision_encounter_scrub(self, system, param) + implicit none + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameterss + end subroutine + + module subroutine symba_collision_make_family_pl(self,idx) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), dimension(2), intent(in) :: idx !! Array holding the indices of the two bodies involved in the collision + end subroutine symba_collision_make_family_pl + + module subroutine symba_collision_resolve_fragmentations(self, system, param) + implicit none + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + end subroutine symba_collision_resolve_fragmentations + + module subroutine symba_collision_resolve_mergers(self, system, param) + implicit none + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + end subroutine symba_collision_resolve_mergers + + module subroutine symba_discard_pl(self, system, param) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine symba_discard_pl + + module subroutine symba_drift_pl(self, system, param, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine symba_drift_pl + + module subroutine symba_drift_tp(self, system, param, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine symba_drift_tp + + module pure elemental subroutine symba_encounter_check_one(xr, yr, zr, vxr, vyr, vzr, rhill1, rhill2, dt, irec, lencounter, lvdotr) + implicit none + real(DP), intent(in) :: xr, yr, zr, vxr, vyr, vzr + real(DP), intent(in) :: rhill1, rhill2, dt + integer(I4B), intent(in) :: irec + logical, intent(out) :: lencounter, lvdotr + end subroutine symba_encounter_check_one + + module function symba_encounter_check_pl(self, system, dt, irec) result(lany_encounter) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + logical :: lany_encounter !! Returns true if there is at least one close encounter + end function symba_encounter_check_pl + + module function symba_encounter_check_pltpenc(self, system, dt, irec) result(lany_encounter) + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-pl encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + logical :: lany_encounter !! Returns true if there is at least one close encounter + end function symba_encounter_check_pltpenc + + module function symba_encounter_check_tp(self, system, dt, irec) result(lany_encounter) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + logical :: lany_encounter !! Returns true if there is at least one close encounter + end function symba_encounter_check_tp + + module function symba_fragmentation_casedisruption(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + implicit none + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collisionn + integer(I4B) :: status !! Status flag assigned to this outcome + end function symba_fragmentation_casedisruption + + module function symba_fragmentation_casehitandrun(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + implicit none + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collision + integer(I4B) :: status !! Status flag assigned to this outcome + end function symba_fragmentation_casehitandrun + + module function symba_fragmentation_casemerge(system, param, family, x, v, mass, radius, L_spin, Ip) result(status) + implicit none + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(in) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(in) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collisio + integer(I4B) :: status !! Status flag assigned to this outcome + end function symba_fragmentation_casemerge + + module function symba_fragmentation_casesupercatastrophic(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + implicit none + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collision + integer(I4B) :: status !! Status flag assigned to this outcome + end function symba_fragmentation_casesupercatastrophic + + module subroutine symba_io_write_discard(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_io_write_discard + + module subroutine symba_io_dump_particle_info(self, param, msg) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_particle_info), intent(inout) :: self !! Swiftest base object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + end subroutine symba_io_dump_particle_info + + module subroutine symba_io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(symba_parameters), intent(inout) :: self !! Current run configuration parameters with SyMBA additionss + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine symba_io_param_reader + + module subroutine symba_io_param_writer(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(symba_parameters),intent(in) :: self !! Current run configuration parameters with SyMBA additions + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! Not used in this procedure + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine symba_io_param_writer + + module subroutine symba_io_initialize_particle_info(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_particle_info), intent(inout) :: self !! SyMBA particle info object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine symba_io_initialize_particle_info + + module subroutine symba_io_read_frame_info(self, iu, param, form, ierr) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_particle_info), intent(inout) :: self !! SyMBA particle info object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + end subroutine symba_io_read_frame_info + + module subroutine symba_kick_getacch_pl(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine symba_kick_getacch_pl + + module subroutine symba_kick_getacch_tp(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine symba_kick_getacch_tp + + module subroutine symba_kick_pltpenc(self, system, dt, irec, sgn) + implicit none + class(symba_pltpenc), intent(in) :: self !! SyMBA pl-tp encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + integer(I4B), intent(in) :: sgn !! sign to be applied to acceleration + end subroutine symba_kick_pltpenc + + module subroutine symba_io_write_frame_info(self, iu, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_particle_info), intent(in) :: self !! SyMBA particle info object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_io_write_frame_info + + module subroutine symba_setup_initialize_system(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine symba_setup_initialize_system + + module subroutine symba_setup_merger(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_merger), intent(inout) :: self !! SyMBA merger list object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_setup_merger + + module subroutine symba_setup_pl(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_setup_pl + + module subroutine symba_setup_pltpenc(self,n) + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter structure + integer(I4B), intent(in) :: n !! Number of encounters to allocate space for + end subroutine symba_setup_pltpenc + + module subroutine symba_setup_tp(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + end subroutine symba_setup_tp + + module subroutine symba_step_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine symba_step_system + + module subroutine symba_step_interp_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine symba_step_interp_system + + module subroutine symba_step_set_recur_levels_system(self, ireci) + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system objec + integer(I4B), intent(in) :: ireci !! Input recursion level + end subroutine symba_step_set_recur_levels_system + + module recursive subroutine symba_step_recur_system(self, param, t, ireci) + use swiftest_classes, only : swiftest_parameters + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), value :: t + integer(I4B), value :: ireci !! input recursion level + end subroutine symba_step_recur_system + + module subroutine symba_step_reset_system(self) + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + end subroutine symba_step_reset_system + end interface + + interface util_append + module subroutine symba_util_append_arr_info(arr, source, lsource_mask) + implicit none + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: arr !! Destination array + type(symba_particle_info), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine symba_util_append_arr_info + + module subroutine symba_util_append_arr_kin(arr, source, lsource_mask) + implicit none + type(symba_kinship), dimension(:), allocatable, intent(inout) :: arr !! Destination array + type(symba_kinship), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine symba_util_append_arr_kin + end interface + + interface + module subroutine symba_util_append_merger(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_merger), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine symba_util_append_merger + + module subroutine symba_util_append_pl(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine symba_util_append_pl + + module subroutine symba_util_append_tp(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine symba_util_append_tp + end interface + + interface util_fill + module subroutine symba_util_fill_arr_info(keeps, inserts, lfill_list) + implicit none + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_particle_info), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine symba_util_fill_arr_info + + module subroutine symba_util_fill_arr_kin(keeps, inserts, lfill_list) + implicit none + type(symba_kinship), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_kinship), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine symba_util_fill_arr_kin + end interface + + interface + module subroutine symba_util_fill_pl(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine symba_util_fill_pl + + module subroutine symba_util_fill_tp(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine symba_util_fill_tp + + module subroutine symba_util_peri_pl(self, system, param) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_util_peri_pl + + module subroutine symba_util_rearray_pl(self, system, param) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + end subroutine symba_util_rearray_pl + end interface + + interface util_resize + module subroutine symba_util_resize_arr_info(arr, nnew) + implicit none + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine symba_util_resize_arr_info + + module subroutine symba_util_resize_arr_kin(arr, nnew) + implicit none + type(symba_kinship), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + end subroutine symba_util_resize_arr_kin + end interface + + interface + module subroutine symba_util_resize_merger(self, nnew) + implicit none + class(symba_merger), intent(inout) :: self !! SyMBA merger list object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine symba_util_resize_merger + + module subroutine symba_util_resize_pl(self, nnew) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine symba_util_resize_pl + + module subroutine symba_util_resize_tp(self, nnew) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine symba_util_resize_tp + + module subroutine symba_util_sort_pl(self, sortby, ascending) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine symba_util_sort_pl + + module subroutine symba_util_sort_tp(self, sortby, ascending) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine symba_util_sort_tp + + module subroutine symba_util_sort_rearrange_pl(self, ind) + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine symba_util_sort_rearrange_pl + + module subroutine symba_util_sort_rearrange_tp(self, ind) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine symba_util_sort_rearrange_tp + end interface + + interface util_spill + module subroutine symba_util_spill_arr_info(keeps, discards, lspill_list, ldestructive) + implicit none + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine symba_util_spill_arr_info + + module subroutine symba_util_spill_arr_kin(keeps, discards, lspill_list, ldestructive) + implicit none + type(symba_kinship), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_kinship), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine symba_util_spill_arr_kin + end interface + + interface + module subroutine symba_util_spill_pl(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine symba_util_spill_pl + + module subroutine symba_util_spill_pltpenc(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_encounter + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + class(swiftest_encounter), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + end subroutine symba_util_spill_pltpenc + + module subroutine symba_util_spill_tp(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_body + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine symba_util_spill_tp + end interface + +end module symba_classes \ No newline at end of file diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 new file mode 100644 index 000000000..a79f52bca --- /dev/null +++ b/src/modules/whm_classes.f90 @@ -0,0 +1,287 @@ +module whm_classes + !! author: David A. Minton + !! + !! Definition of classes and methods specific to the Democratic Heliocentric Method + !! Partially adapted from David E. Kaufmann's Swifter module: module_whm.f90 + use swiftest_globals + use swiftest_classes, only : swiftest_cb, swiftest_pl, swiftest_tp, swiftest_nbody_system + implicit none + public + + !******************************************************************************************************************************** + ! whm_cb class definitions and method interfaces + !******************************************************************************************************************************* + !> Swiftest central body particle class + type, extends(swiftest_cb) :: whm_cb + contains + end type whm_cb + + !******************************************************************************************************************************** + ! whm_pl class definitions and method interfaces + !******************************************************************************************************************************* + + !> WHM massive body particle class + type, extends(swiftest_pl) :: whm_pl + real(DP), dimension(:), allocatable :: eta !! Jacobi mass + real(DP), dimension(:,:), allocatable :: xj !! Jacobi position + real(DP), dimension(:,:), allocatable :: vj !! Jacobi velocity + real(DP), dimension(:), allocatable :: muj !! Jacobi mu: GMcb * eta(i) / eta(i - 1) + real(DP), dimension(:), allocatable :: ir3j !! Third term of heliocentric acceleration + !! Note to developers: If you add componenets to this class, be sure to update methods and subroutines that traverse the + !! component list, such as whm_setup_pl and whm_util_spill_pl + contains + procedure :: h2j => whm_coord_h2j_pl !! Convert position and velcoity vectors from heliocentric to Jacobi coordinates + procedure :: j2h => whm_coord_j2h_pl !! Convert position and velcoity vectors from Jacobi to helliocentric coordinates + procedure :: vh2vj => whm_coord_vh2vj_pl !! Convert velocity vectors from heliocentric to Jacobi coordinates + procedure :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine to jacobi coordinates + procedure :: accel_gr => whm_gr_kick_getacch_pl !! Acceleration term arising from the post-Newtonian correction + procedure :: gr_pos_kick => whm_gr_p4_pl !! Position kick due to p**4 term in the post-Newtonian correction + procedure :: accel => whm_kick_getacch_pl !! Compute heliocentric accelerations of massive bodies + procedure :: kick => whm_kick_vh_pl !! Kick heliocentric velocities of massive bodies + procedure :: append => whm_util_append_pl !! Appends elements from one structure to another + procedure :: fill => whm_util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) + procedure :: resize => whm_util_resize_pl !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + procedure :: set_ir3 => whm_util_set_ir3j !! Sets both the heliocentric and jacobi inverse radius terms (1/rj**3 and 1/rh**3) + procedure :: set_mu => whm_util_set_mu_eta_pl !! Sets the Jacobi mass value for all massive bodies. + procedure :: sort => whm_util_sort_pl !! Sort a WHM massive body object in-place. + procedure :: rearrange => whm_util_sort_rearrange_pl !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods + procedure :: spill => whm_util_spill_pl !!"Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure :: setup => whm_setup_pl !! Constructor method - Allocates space for the input number of bodiess + procedure :: step => whm_step_pl !! Steps the body forward one stepsize + end type whm_pl + + !******************************************************************************************************************************** + ! whm_tp class definitions and method interfaces + !******************************************************************************************************************************* + + !! WHM test particle class + type, extends(swiftest_tp) :: whm_tp + !! Note to developers: If you add componenets to this class, be sure to update methods and subroutines that traverse the + !! component list, such as whm_util_spill_tp + contains + procedure :: accel_gr => whm_gr_kick_getacch_tp !! Acceleration term arising from the post-Newtonian correction + procedure :: gr_pos_kick => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction + procedure :: accel => whm_kick_getacch_tp !! Compute heliocentric accelerations of test particles + procedure :: kick => whm_kick_vh_tp !! Kick heliocentric velocities of test particles + procedure :: step => whm_step_tp !! Steps the particle forward one stepsize + end type whm_tp + + !******************************************************************************************************************************** + ! whm_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + !> An abstract class for the WHM integrator nbody system + type, extends(swiftest_nbody_system) :: whm_nbody_system + contains + !> Replace the abstract procedures with concrete ones + procedure :: initialize => whm_setup_initialize_system !! Performs WHM-specific initilization steps, like calculating the Jacobi masses + procedure :: step => whm_step_system !! Advance the WHM nbody system forward in time by one step + end type whm_nbody_system + + interface + module subroutine whm_coord_h2j_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + end subroutine whm_coord_h2j_pl + + module subroutine whm_coord_j2h_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + end subroutine whm_coord_j2h_pl + + module subroutine whm_coord_vh2vj_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + end subroutine whm_coord_vh2vj_pl + + module subroutine whm_drift_pl(self, system, param, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine whm_drift_pl + + !> Get heliocentric accelration of massive bodies + module subroutine whm_kick_getacch_pl(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_cb, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine whm_kick_getacch_pl + + !> Get heliocentric accelration of the test particle + module subroutine whm_kick_getacch_tp(self, system, param, t, lbeg) + use swiftest_classes, only : swiftest_cb, swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + end subroutine whm_kick_getacch_tp + + module subroutine whm_kick_vh_pl(self, system, param, t, dt, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + end subroutine whm_kick_vh_pl + + module subroutine whm_kick_vh_tp(self, system, param, t, dt, lbeg) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + end subroutine whm_kick_vh_tp + + module subroutine whm_gr_kick_getacch_pl(self, param) + use swiftest_classes, only : swiftest_cb, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine whm_gr_kick_getacch_pl + + module subroutine whm_gr_kick_getacch_tp(self, param) + use swiftest_classes, only : swiftest_cb, swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine whm_gr_kick_getacch_tp + + module pure subroutine whm_gr_p4_pl(self, param, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + end subroutine whm_gr_p4_pl + + module pure subroutine whm_gr_p4_tp(self, param, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + end subroutine whm_gr_p4_tp + + !> Reads WHM massive body object in from file + module subroutine whm_setup_pl(self, n, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body objectobject + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine whm_setup_pl + + module subroutine whm_setup_initialize_system(self, param) + use swiftest_classes, only : swiftest_parameters + implicit none + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine whm_setup_initialize_system + + module subroutine whm_step_pl(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine whm_step_pl + + module subroutine whm_step_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters + implicit none + class(whm_nbody_system), intent(inout) :: self !! WHM system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine whm_step_system + + module subroutine whm_step_tp(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize + end subroutine whm_step_tp + + module subroutine whm_util_append_pl(self, source, lsource_mask) + use swiftest_classes, only : swiftest_body + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + end subroutine whm_util_append_pl + + module subroutine whm_util_spill_pl(self, discards, lspill_list, ldestructive) + use swiftest_classes, only : swiftest_body + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + end subroutine whm_util_spill_pl + + module subroutine whm_util_fill_pl(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(in) :: inserts !! inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + end subroutine whm_util_fill_pl + + module subroutine whm_util_resize_pl(self, nnew) + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + integer(I4B), intent(in) :: nnew !! New size neded + end subroutine whm_util_resize_pl + + module subroutine whm_util_set_ir3j(self) + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + end subroutine whm_util_set_ir3j + + module subroutine whm_util_set_mu_eta_pl(self, cb) + use swiftest_classes, only : swiftest_cb + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine whm_util_set_mu_eta_pl + + module subroutine whm_util_sort_pl(self, sortby, ascending) + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + end subroutine whm_util_sort_pl + + module subroutine whm_util_sort_rearrange_pl(self, ind) + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + end subroutine whm_util_sort_rearrange_pl + end interface + +end module whm_classes diff --git a/src/obl/obl.f90 b/src/obl/obl.f90 new file mode 100644 index 000000000..035a54b18 --- /dev/null +++ b/src/obl/obl.f90 @@ -0,0 +1,150 @@ +submodule (swiftest_classes) s_obl + use swiftest +contains + module subroutine obl_acc_body(self, system) + !! author: David A. Minton + !! + !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + !! Returned values do not include monopole term or terms higher than J4 + !! + !! Adapted from David E. Kaufmann's Swifter routine: obl_acc.f90 and obl_acc_tp.f90 + !! Adapted from Hal Levison's Swift routine obl_acc.f and obl_acc_tp.f + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + ! Internals + integer(I4B) :: i + real(DP) :: r2, irh, rinv2, t0, t1, t2, t3, fac1, fac2 + + if (self%nbody == 0) return + + associate(n => self%nbody, cb => system%cb) + self%aobl(:,:) = 0.0_DP + do concurrent(i = 1:n, self%lmask(i)) + r2 = dot_product(self%xh(:, i), self%xh(:, i)) + irh = 1.0_DP / sqrt(r2) + rinv2 = irh**2 + t0 = -cb%Gmass * rinv2 * rinv2 * irh + t1 = 1.5_DP * cb%j2rp2 + t2 = self%xh(3, i) * self%xh(3, i) * rinv2 + t3 = 1.875_DP * cb%j4rp4 * rinv2 + fac1 = t0 * (t1 - t3 - (5 * t1 - (14.0_DP - 21.0_DP * t2) * t3) * t2) + fac2 = 2 * t0 * (t1 - (2.0_DP - (14.0_DP * t2 / 3.0_DP)) * t3) + self%aobl(:, i) = fac1 * self%xh(:, i) + self%aobl(3, i) = fac2 * self%xh(3, i) + self%aobl(3, i) + end do + end associate + return + + end subroutine obl_acc_body + + + module subroutine obl_acc_pl(self, system) + !! author: David A. Minton + !! + !! Compute the barycentric accelerations of massive bodies due to the oblateness of the central body + !! + !! Adapted from David E. Kaufmann's Swifter routine: obl_acc.f90 and obl_acc_tp.f90 + !! Adapted from Hal Levison's Swift routine obl_acc.f and obl_acc_tp.f + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody, cb => system%cb) + call obl_acc_body(pl, system) + do i = 1, NDIM + cb%aobl(i) = -sum(pl%Gmass(1:npl) * pl%aobl(i, 1:npl), pl%lmask(1:npl)) / cb%Gmass + end do + + do concurrent(i = 1:npl, pl%lmask(i)) + pl%ah(:, i) = pl%ah(:, i) + pl%aobl(:, i) - cb%aobl(:) + end do + end associate + + return + + end subroutine obl_acc_pl + + + module subroutine obl_acc_tp(self, system) + !! author: David A. Minton + !! + !! Compute the barycentric accelerations of massive bodies due to the oblateness of the central body + !! + !! Adapted from David E. Kaufmann's Swifter routine: obl_acc.f90 and obl_acc_tp.f90 + !! Adapted from Hal Levison's Swift routine obl_acc.f and obl_acc_tp.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + ! Internals + real(DP), dimension(NDIM) :: aoblcb + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody, cb => system%cb) + call obl_acc_body(tp, system) + if (system%lbeg) then + aoblcb = cb%aoblbeg + else + aoblcb = cb%aoblend + end if + + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%ah(:, i) = tp%ah(:, i) + tp%aobl(:, i) - aoblcb(:) + end do + + end associate + return + + end subroutine obl_acc_tp + + module subroutine obl_pot(npl, Mcb, Mpl, j2rp2, j4rp4, xh, irh, oblpot) + !! author: David A. Minton + !! + !! Compute the contribution to the total gravitational potential due solely to the oblateness of the central body + !! Returned value does not include monopole term or terms higher than J4 + !! + !! Reference: MacMillan, W. D. 1958. The Theory of the Potential, (Dover Publications), 363. + !! + !! Adapted from David E. Kaufmann's Swifter routine: obl_pot.f90 + !! Adapted from Hal Levison's Swift routine obl_pot.f + implicit none + ! Arguments + integer(I4B), intent(in) :: npl + real(DP), intent(in) :: Mcb + real(DP), dimension(:), intent(in) :: Mpl + real(DP), intent(in) :: j2rp2, j4rp4 + real(DP), dimension(:), intent(in) :: irh + real(DP), dimension(:, :), intent(in) :: xh + real(DP), intent(out) :: oblpot + + ! Internals + integer(I4B) :: i + real(DP) :: rinv2, t0, t1, t2, t3, p2, p4, mu + + oblpot = 0.0_DP + mu = Mcb + do i = 1, npl + rinv2 = irh(i)**2 + t0 = mu * Mpl(i) * rinv2 * irh(i) + t1 = j2rp2 + t2 = xh(3, i) * xh(3, i) * rinv2 + t3 = j4rp4 * rinv2 + p2 = 0.5_DP * (3 * t2 - 1.0_DP) + p4 = 0.125_DP * ((35 * t2 - 30.0_DP) * t2 + 3.0_DP) + oblpot = oblpot + t0 * (t1 * p2 + t3 * p4) + end do + + return + end subroutine obl_pot + + +end submodule s_obl diff --git a/src/operators/operator_cross.f90 b/src/operators/operator_cross.f90 new file mode 100644 index 000000000..736dc2696 --- /dev/null +++ b/src/operators/operator_cross.f90 @@ -0,0 +1,192 @@ +submodule(swiftest_operators) s_operator_cross + use swiftest + !! author: David A. Minton + !! + !! Contains implementations for the .cross. operator for all defined integer and real types + !! Single vector implementations: C(1:3) = A(1:3) .cross. B(1:3) + !! Vector list implementations: C(1:3, :) = A(1:3, :) .cross. B(1:3, :) +contains + + module pure function operator_cross_sp(A, B) result(C) + implicit none + real(SP), dimension(:), intent(in) :: A, B + real(SP), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_sp + + module pure function operator_cross_dp(A, B) result(C) + implicit none + real(DP), dimension(:), intent(in) :: A, B + real(DP), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_dp + + module pure function operator_cross_qp(A, B) result(C) + implicit none + real(QP), dimension(:), intent(in) :: A, B + real(QP), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_qp + + module pure function operator_cross_i1b(A, B) result(C) + implicit none + integer(I1B), dimension(:), intent(in) :: A, B + integer(I1B), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_i1b + + module pure function operator_cross_i2b(A, B) result(C) + implicit none + integer(I2B), dimension(:), intent(in) :: A, B + integer(I2B), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_i2b + + module pure function operator_cross_i4b(A, B) result(C) + implicit none + integer(I4B), dimension(:), intent(in) :: A, B + integer(I4B), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_i4b + + module pure function operator_cross_i8b(A, B) result(C) + implicit none + integer(I8B), dimension(:), intent(in) :: A, B + integer(I8B), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_i8b + + module pure function operator_cross_el_sp(A, B) result(C) + implicit none + real(SP), dimension(:,:), intent(in) :: A, B + real(SP), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_sp + + module pure function operator_cross_el_dp(A, B) result(C) + implicit none + real(DP), dimension(:,:), intent(in) :: A, B + real(DP), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_dp + + module pure function operator_cross_el_qp(A, B) result(C) + implicit none + real(QP), dimension(:,:), intent(in) :: A, B + real(QP), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_qp + + module pure function operator_cross_el_i1b(A, B) result(C) + implicit none + integer(I1B), dimension(:,:), intent(in) :: A, B + integer(I1B), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_i1b + + module pure function operator_cross_el_i2b(A, B) result(C) + implicit none + integer(I2B), dimension(:,:), intent(in) :: A, B + integer(I2B), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_i2b + + module pure function operator_cross_el_i4b(A, B) result(C) + implicit none + integer(I4B), dimension(:,:), intent(in) :: A, B + integer(I4B), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_i4b + + module pure function operator_cross_el_i8b(A, B) result(C) + implicit none + integer(I8B), dimension(:,:), intent(in) :: A, B + integer(I8B), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_i8b + +end submodule s_operator_cross \ No newline at end of file diff --git a/src/operators/operator_mag.f90 b/src/operators/operator_mag.f90 new file mode 100644 index 000000000..5a054d5ce --- /dev/null +++ b/src/operators/operator_mag.f90 @@ -0,0 +1,68 @@ +submodule(swiftest_operators) s_operator_mag + !! author: David A. Minton + !! + !! Contains implementations for the .mag. operator for all defined real types + !! Single vector implementations: B = .mag. A(1:3) + !! Vector list implementations: B(:) = .mag. A(1:3, :) + contains + + module pure function operator_mag_sp(A) result(B) + implicit none + real(SP), dimension(:), intent(in) :: A + real(SP) :: B + B = norm2(A(:)) + return + end function operator_mag_sp + + module pure function operator_mag_dp(A) result(B) + implicit none + real(DP), dimension(:), intent(in) :: A + real(DP) :: B + B = norm2(A(:)) + return + end function operator_mag_dp + + module pure function operator_mag_el_sp(A) result(B) + implicit none + real(SP), dimension(:,:), intent(in) :: A + real(SP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_sp + + module pure function operator_mag_el_dp(A) result(B) + implicit none + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_dp + + module pure function operator_mag_el_qp(A) result(B) + implicit none + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_qp + +end submodule s_operator_mag + diff --git a/src/orbel/orbel.f90 b/src/orbel/orbel.f90 new file mode 100644 index 000000000..f1ab88825 --- /dev/null +++ b/src/orbel/orbel.f90 @@ -0,0 +1,1016 @@ +submodule (swiftest_classes) s_orbel + use swiftest +contains + + module subroutine orbel_el2xv_vec(self, cb) + !! author: David A. Minton + !! + !! A wrapper method that converts all of the cartesian position and velocity vectors of a Swiftest body object to orbital elements. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body objec + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + call self%set_mu(cb) + do i = 1, self%nbody + call orbel_el2xv(self%mu(i), self%a(i), self%e(i), self%inc(i), self%capom(i), & + self%omega(i), self%capm(i), self%xh(:, i), self%vh(:, i)) + end do + end subroutine orbel_el2xv_vec + + + pure subroutine orbel_el2xv(mu, a, ie, inc, capom, omega, capm, x, v) + !! author: David A. Minton + !! + !! Compute osculating orbital elements from relative C)rtesian position and velocity + !! All angular measures are returned in radians + !! If inclination < TINY, longitude of the ascending node is arbitrarily set to 0 + !! + !! If eccentricity < sqrt(TINY), argument of pericenter is arbitrarily set to 0 + !! + !! ALGORITHM: See Fitzpatrick "Principles of Cel. Mech." + !! + !! Adapted from Martin Duncan's el2xv.f + !! DATE WRITTEN: May 11, 1992. + !! REVISIONS: May 26 - now use better Kepler solver for ellipses + !! and hyperbolae called EHYBRID.F and FHYBRID.F + implicit none + real(DP), intent(in) :: mu + real(DP), intent(in) :: a, ie, inc, capom, omega, capm + real(DP), dimension(:), intent(out) :: x, v + + integer(I4B) :: iorbit_type + real(DP) :: e, cape, capf, zpara, em1 + real(DP) :: sip, cip, so, co, si, ci + real(DP) :: d11, d12, d13, d21, d22, d23 + real(DP) :: scap, ccap, shcap, chcap + real(DP) :: sqe, sqgma, xfac1, xfac2, ri, vfac1, vfac2 + + + if(ie < 0.0_DP) then + !write(*,*) ' ERROR in orbel_el2xv: e<0, setting e=0!!1' + e = 0.0_DP + iorbit_type = ELLIPSE + else + e = ie + em1 = e - 1._DP + if (abs(em1) < VSMALL) then + iorbit_type = PARABOLA + else if (e > 1.0_DP) then + iorbit_type = HYPERBOLA + else + iorbit_type = ELLIPSE + end if + endif + + call orbel_scget(omega,sip,cip) + call orbel_scget(capom,so,co) + call orbel_scget(inc,si,ci) + d11 = cip * co - sip * so * ci + d12 = cip * so + sip * co * ci + d13 = sip * si + d21 = -sip * co - cip * so * ci + d22 = -sip * so + cip * co * ci + d23 = cip * si + + !-- + ! Get the other quantities depending on orbit type + ! + if (iorbit_type == ELLIPSE) then + cape = orbel_ehybrid(e,capm) + call orbel_scget(cape,scap,ccap) + sqe = sqrt(1._DP - e**2) + sqgma = sqrt(mu* a) + xfac1 = a * (ccap - e) + xfac2 = a * sqe * scap + ri = 1._DP / (a * (1._DP - e* ccap)) + vfac1 = -ri * sqgma * scap + vfac2 = ri * sqgma * sqe * ccap + endif + !-- + if (iorbit_type == HYPERBOLA) then + capf = orbel_fhybrid(e,capm) + call orbel_schget(capf,shcap,chcap) + sqe = sqrt(e**2 - 1._DP ) + sqgma = sqrt(mu * a) + xfac1 = a * (e - chcap) + xfac2 = a * sqe * shcap + ri = 1._DP / (a * (e * chcap - 1._DP)) + vfac1 = -ri * sqgma * shcap + vfac2 = ri * sqgma * sqe * chcap + endif + !-- + if (iorbit_type == PARABOLA) then + zpara = orbel_zget(capm) + sqgma = sqrt(2 * mu * a) + xfac1 = a * (1._DP - zpara * zpara) + xfac2 = 2 * a * zpara + ri = 1._DP / (a * (1._DP + zpara * zpara)) + vfac1 = -ri * sqgma * zpara + vfac2 = ri * sqgma + endif + !-- + x(1) = d11 * xfac1 + d21 * xfac2 + x(2) = d12 * xfac1 + d22 * xfac2 + x(3) = d13 * xfac1 + d23 * xfac2 + v(1) = d11 * vfac1 + d21 * vfac2 + v(2) = d12 * vfac1 + d22 * vfac2 + v(3) = d13 * vfac1 + d23 * vfac2 + + return + end subroutine orbel_el2xv + + + module pure subroutine orbel_scget(angle, sx, cx) + !! author: David A. Minton + !! + !! Efficiently compute the sine and cosine of an input angle + !! Input angle must be in radians + !! + !! Adapted from David E. Kaufmann's Swifter routine: orbel_scget.f90 + !! Adapted from Hal Levison's Swift routine orbel_scget.f + implicit none + ! Arguments + real(DP), intent(in) :: angle + real(DP), intent(out) :: sx, cx + ! Internals + integer(I4B) :: nper + real(DP) :: x + + nper = angle / TWOPI + x = angle - nper * TWOPI + if (x < 0.0_DP) x = x + TWOPI + sx = sin(x) + cx = sqrt(1.0_DP - sx**2) + if ((x > PIBY2) .and. (x < PI3BY2)) cx = -cx + + return + + end subroutine orbel_scget + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + !********************************************************************** + ! ORBEL_SCHGET.F + !********************************************************************** + ! PURPOSE: Given an angle, efficiently compute sinh and cosh. + ! + ! Input: + ! angle ==> angle in radians (real scalar) + ! + ! Output: + ! shx ==> sinh(angle) (real scalar) + ! chx ==> cosh(angle) (real scalar) + ! + ! ALGORITHM: Obvious from the code + ! REMARKS: Based on the routine SCGET for sine's and cosine's. + ! We use the sqrt rather than cosh (it's faster) + ! BE SURE THE ANGLE IS IN RADIANS AND IT CAN'T BE LARGER THAN 300 + ! OR OVERFLOWS WILL OCCUR! + ! AUTHOR: M. Duncan. + ! DATE WRITTEN: May 6, 1992. + ! REVISIONS: + !********************************************************************** + pure subroutine orbel_schget(angle,shx,chx) + + real(DP), intent(in) :: angle + real(DP), intent(out) :: shx,chx + + shx = sinh(angle) + chx= sqrt(1._DP + shx * shx) + + return + end subroutine orbel_schget + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ! ORBEL_FLON.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. for hyperbola using hybrid approach. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! capn ==> hyperbola mean anomaly. (real scalar) + ! Returns: + ! orbel_flon ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: Uses power series for N in terms of F and Newton,s method + ! REMARKS: ONLY GOOD FOR LOW VALUES OF N (N < 0.636*e -0.6) + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 26, 1992. + ! REVISIONS: + !********************************************************************** + real(DP) pure function orbel_flon(e,icapn) + implicit none + real(DP), intent(in) :: e, icapn + integer(I4B) :: iflag,i + real(DP) :: a,b,sq,biga,bigb, capn + real(DP) :: x,x2 + real(DP) :: f,fp,dx + real(DP) :: diff + real(DP) :: a0,a1 + real(DP) :: b1 + integer(I4B), parameter :: IMAX = 10 + real(DP), parameter :: a11 = 156._DP, a9 = 17160._DP, a7 = 1235520._DP + real(DP), parameter :: a5 = 51891840._DP, a3 = 1037836800._DP + real(DP), parameter :: b11 = 11 * a11, b9 = 9 * a9, b7 = 7 * a7 + real(DP), parameter :: b5 = 5 * a5, b3 = 3 * a3 + real(DP), parameter :: THIRD = 1._DP / 3._DP + + ! Function to solve "Kepler's eqn" for F (here called + ! x) for given e and CAPN. Only good for smallish CAPN + + iflag = 0 + if (icapn < 0._DP) then + iflag = 1 + capn = -icapn + else + capn = icapn + end if + + a1 = 6227020800._DP * (1._DP - 1._DP / e) + a0 = -6227020800._DP * capn / e + b1 = a1 + + ! set iflag nonzero if capn < 0., in which case solve for -capn + ! and change the sign of the final answer for f. + ! Begin with a reasonable guess based on solving the cubic for small F + a = 6 * ( e - 1.d0) / e + b = -6 * capn / e + sq = SQRT(0.25_DP * b**2 + a**3 / 27._DP) + biga = (-0.5_DP * b + sq)**(1.0_DP / 3.0_DP) + bigb = -(+0.5_DP * b + sq)**(1.0_DP / 3.0_DP) + x = biga + bigb + ! write(6,*) 'cubic = ',x**3 +a*x +b + orbel_flon = x + ! If capn is VSMALL (or zero) no need to go further than cubic even for + ! e =1. + if( capn < VSMALL) go to 100 + + do i = 1,IMAX + x2 = x * x + f = a0 + x * (a1 + x2 * (a3 + x2 * (a5 + x2 * (a7 + x2 * (a9 + x2 * (a11 + x2)))))) + fp = b1 + x2 * (b3 + x2 * (b5 + x2 * (b7 + x2 * (b9 + x2 * (b11 + 13 * x2))))) + dx = -f / fp + ! write(6,*) 'i,dx,x,f : ' + ! write(6,432) i,dx,x,f + 432 format(1x,i3,3(2x,1p1e22.15)) + orbel_flon = x + dx + ! if we have converged here there's no point in going on + if(abs(dx) <= VSMALL) go to 100 + x = orbel_flon + end do + + ! abnormal return here - we've gone thru the loop + ! imax times without convergence + if(iflag == 1) then + orbel_flon = -orbel_flon + capn = -capn + end if + !write(*,*) 'flon : returning without complete convergence' + diff = e * sinh(orbel_flon) - orbel_flon - capn + !write(*,*) 'n, f, ecc*sinh(f) - f - n : ' + !write(*,*) capn,orbel_flon,diff + return + + ! normal return here, but check if capn was originally negative + 100 if(iflag == 1) then + orbel_flon = -orbel_flon + capn = -capn + end if + + return + end function orbel_flon + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_FGET.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. for hyperbola using hybrid approach. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! capn ==> hyperbola mean anomaly. (real scalar) + ! Returns: + ! orbel_fget ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: Based on pp. 70-72 of Fitzpatrick's book "Principles of + ! Cel. Mech. ". Quartic convergence from Danby's book. + ! REMARKS: + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 11, 1992. + ! REVISIONS: 2/26/93 hfl + !********************************************************************** + real(DP) pure function orbel_fget(e,capn) + implicit none + + real(DP), intent(in) :: e,capn + + integer :: i + real(DP) :: tmp,x,shx,chx + real(DP) :: esh,ech,f,fp,fpp,fppp,dx + integer(I4B), parameter :: IMAX = 10 + + !---- + !... executable code + + ! function to solve "kepler's eqn" for f (here called + ! x) for given e and capn. + + ! begin with a guess proposed by danby + if( capn < 0.d0) then + tmp = -2 * capn / e + 1.8_DP + x = -log(tmp) + else + tmp = +2 * capn / e + 1.8_DP + x = log(tmp) + end if + + orbel_fget = x + + do i = 1, IMAX + call orbel_schget(x,shx,chx) + esh = e * shx + ech = e * chx + f = esh - x - capn + ! write(6,*) 'i,x,f : ',i,x,f + fp = ech - 1.d0 + fpp = esh + fppp = ech + dx = -f / fp + dx = -f / (fp + dx * fpp / 2._DP) + dx = -f / (fp + dx * fpp / 2._DP + dx**2 * fppp / 6._DP) + orbel_fget = x + dx + ! if we have converged here there's no point in going on + if(abs(dx) <= VSMALL) return + x = orbel_fget + end do + + !write(*,*) 'fget : returning without complete convergence' + return + end function orbel_fget + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_ZGET.F + !********************************************************************** + ! PURPOSE: Solves the equivalent of Kepler's eqn. for a parabola + ! given Q (Fitz. notation.) + ! + ! Input: + ! q ==> parabola mean anomaly. (real scalar) + ! Returns: + ! orbel_zget ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: p. 70-72 of Fitzpatrick's book "Princ. of Cel. Mech." + ! REMARKS: For a parabola we can solve analytically. + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 11, 1992. + ! REVISIONS: May 27 - corrected it for negative Q and use power + ! series for small Q. + !********************************************************************** + real(DP) pure function orbel_zget(iq) + implicit none + + real(DP), intent(in) :: iq + + integer(I4B) :: iflag + real(DP) :: x,tmp,q + + iflag = 0 + if (iq < 0.0_DP) then + iflag = 1 + q = -iq + else + q = iq + end if + + if (q < 1.e-3_DP) then + orbel_zget = q * (1._DP - (q**2 / 3._DP) * (1._DP - q**2)) + else + x = 0.5_DP * (3 * q + sqrt(9 * q**2 + 4._DP)) + tmp = x**(1._DP / 3._DP) + orbel_zget = tmp - 1._DP / tmp + end if + + if(iflag == 1) then + orbel_zget = -orbel_zget + q = -q + end if + + return + end function orbel_zget + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_ESOLMD.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. e is ecc. m is mean anomaly. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! m ==> mean anomaly. (real scalar) + ! Returns: + ! orbel_esolmd ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: Some sort of quartic convergence from Wisdom. + ! REMARKS: ONLY GOOD FOR SMALL ECCENTRICITY SINCE IT ONLY + ! ITERATES ONCE. (GOOD FOR PLANET CALCS.) + ! ALSO DOES NOT PUT M OR E BETWEEN 0. AND 2*PI + ! INCLUDES: needs SCGET.F + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 7, 1992. + ! REVISIONS: 2/26/93 hfl + !********************************************************************** + real(DP) pure function orbel_esolmd(e,m) + implicit none + + real(DP), intent(in) :: e + real(DP), intent(in) :: m + + real(DP) :: x,sm,cm,sx,cx + real(DP) :: es,ec,f,fp,fpp,fppp,dx + + !... function to solve kepler's eqn for e (here called + !... x) for given e and m. returns value of x. + + call orbel_scget(m,sm,cm) + x = m + e * sm * (1._DP + e * ( cm + e * (1._DP - 1.5_DP * sm**2))) + + call orbel_scget(x,sx,cx) + es = e * sx + ec = e * cx + f = x - es - m + fp = 1._DP - ec + fpp = es + fppp = ec + dx = -f / fp + dx = -f / (fp + dx * fpp / 2._DP) + dx = -f / (fp + dx * fpp / 2._DP + dx**2 * fppp / 6._DP) + + orbel_esolmd = x + dx + + return + end function orbel_esolmd + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_EHIE.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. e is ecc. m is mean anomaly. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! m ==> mean anomaly. (real scalar) + ! Returns: + ! orbel_ehybrid ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: Use Danby's quartic for 3 iterations. + ! Eqn. is f(x) = x - e*sin(x+M). Note that + ! E = x + M. First guess is very good for e near 1. + ! Need to first get M between 0. and PI and use + ! symmetry to return right answer if M between PI and 2PI + ! REMARKS: Modifies M so that both E and M are in range (0,TWOPI) + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 25,1992. + ! REVISIONS: + !********************************************************************** + real(DP) pure function orbel_ehie(e,im) + implicit none + + real(DP), intent(in) :: e,im + + integer(I4B) :: iflag,nper,niter + real(DP) :: dx,x,sa,ca,esa,eca,f,fp,m + + integer(I4B), parameter :: NMAX = 3 + + ! in this section, bring m into the range (0,TWOPI) and if + ! the result is greater than pi, solve for (TWOPI - m). + iflag = 0 + nper = im / TWOPI + m = im - nper * TWOPI + if (m < 0._DP) m = m + TWOPI + + if (m > PI) then + m = TWOPI - m + iflag = 1 + end if + + ! make a first guess that works well for e near 1. + x = (6 * m)**(1._DP / 3._DP) - m + niter =0 + + ! iteration loop + do niter =1,NMAX + call orbel_scget(x + m,sa,ca) + esa = e * sa + eca = e * ca + f = x - esa + fp = 1._DP -eca + dx = -f / fp + dx = -f / (fp + 0.5_DP * dx * esa) + dx = -f / (fp + 0.5_DP * dx * (esa + eca * dx / 3.0_DP)) + x = x + dx + end do + + orbel_ehie = m + x + + if (iflag == 1) then + orbel_ehie = TWOPI - orbel_ehie + m = TWOPI - m + end if + + return + end function orbel_ehie + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_EGET.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. e is ecc. m is mean anomaly. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! m ==> mean anomaly. (real scalar) + ! Returns: + ! orbel_eget ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: Quartic convergence from Danby + ! REMARKS: For results very near roundoff, give it M between + ! 0 and 2*pi. One can condition M before calling EGET + ! by calling my double precision function MOD2PI(M). + ! This is not done within the routine to speed it up + ! and because it works fine even for large M. + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 7, 1992. + ! REVISIONS: May 21, 1992. Now have it go through EXACTLY two iterations + ! with the premise that it will only be called if + ! we have an ellipse with e between 0.15 and 0.8 + !********************************************************************** + real(DP) pure function orbel_eget(e,m) + implicit none + + real(DP), intent(in) :: e,m + real(DP) :: x,sm,cm,sx,cx + real(DP) :: es,ec,f,fp,fpp,fppp,dx + + + ! function to solve kepler's eqn for e (here called + ! x) for given e and m. returns value of x. + ! may 21 : for e < 0.18 use esolmd for speed and sufficient accuracy + ! may 21 : for e > 0.8 use ehie - this one may not converge fast enough. + + call orbel_scget(m,sm,cm) + + ! begin with a guess accurate to order ecc**3 + x = m + e * sm * ( 1._DP + e * (cm + e * (1._DP - 1.5_DP * sm * sm))) + + ! go through one iteration for improved estimate + call orbel_scget(x,sx,cx) + es = e * sx + ec = e * cx + f = x - es - m + fp = 1._DP - ec + fpp = es + fppp = ec + dx = -f / fp + dx = -f / (fp + dx * fpp / 2._DP) + dx = -f / (fp + dx * fpp / 2._DP + dx*2 * fppp / 6._DP) + orbel_eget = x + dx + + ! do another iteration. + ! for m between 0 and 2*pi this seems to be enough to + ! get near roundoff error for eccentricities between 0 and 0.8 + + x = orbel_eget + call orbel_scget(x,sx,cx) + es = e * sx + ec = e * cx + f = x - es - m + fp = 1._DP - ec + fpp = es + fppp = ec + dx = -f / fp + dx = -f / (fp + dx * fpp / 2._DP) + dx = -f / (fp + dx * fpp / 2._DP + dx**2 * fppp / 6._DP) + + orbel_eget = x + dx + + return + end function orbel_eget + + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_EHYBRID.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. e is ecc. m is mean anomaly. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! m ==> mean anomaly. (real scalar) + ! Returns: + ! orbel_ehybrid ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: For e < 0.18 uses fast routine ESOLMD + ! For larger e but less than 0.8, uses EGET + ! For e > 0.8 uses EHIE + ! REMARKS: Only EHIE brings M and E into range (0,TWOPI) + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 25,1992. + ! REVISIONS: 2/26/93 hfl + !********************************************************************** + real(DP) pure function orbel_ehybrid(e,m) + implicit none + + real(DP), intent(in) :: e,m + !real(DP) :: orbel_esolmd,orbel_eget,orbel_ehie + + if (e < 0.18_DP) then + orbel_ehybrid = orbel_esolmd(e,m) + else + if( e <= 0.8_DP) then + orbel_ehybrid = orbel_eget(e,m) + else + orbel_ehybrid = orbel_ehie(e,m) + end if + end if + return + end function orbel_ehybrid + + !********************************************************************** + ! Code converted to Modern Fortran by David A. Minton + ! Date: 2020-06-29 + ! ORBEL_FHYBRID.F + !********************************************************************** + ! PURPOSE: Solves Kepler's eqn. for hyperbola using hybrid approach. + ! + ! Input: + ! e ==> eccentricity anomaly. (real scalar) + ! n ==> hyperbola mean anomaly. (real scalar) + ! Returns: + ! orbel_fhybrid ==> eccentric anomaly. (real scalar) + ! + ! ALGORITHM: For abs(N) < 0.636*ecc -0.6 , use FLON + ! For larger N, uses FGET + ! REMARKS: + ! AUTHOR: M. Duncan + ! DATE WRITTEN: May 26,1992. + ! REVISIONS:: + ! REVISIONS: 2/26/93 hfl + !********************************************************************** + real(DP) pure function orbel_fhybrid(e,n) + implicit none + real(DP), intent(in) :: e,n + + real(DP) :: abn + + abn = n + if(n < 0._DP) abn = -abn + + if(abn < 0.636_DP * e -0.6_DP) then + orbel_fhybrid = orbel_flon(e,n) + else + orbel_fhybrid = orbel_fget(e,n) + end if + + return + end function orbel_fhybrid + + + module pure subroutine orbel_xv2aeq(mu, x, v, a, e, q) + !! author: David A. Minton + !! + !! Compute semimajor axis, eccentricity, and pericentric distance from relative Cartesian position and velocity + !! + !! Adapted from David E. Kaufmann's Swifter routine: orbel_xv2aeq.f90 + !! Adapted from Luke Dones' Swift routine orbel_xv2aeq.f + implicit none + !! Arguments + real(DP), intent(in) :: mu + real(DP), dimension(:), intent(in) :: x, v + real(DP), intent(out) :: a, e, q + integer(I4B) :: iorbit_type + real(DP) :: r, v2, h2, energy, fac + real(DP), dimension(NDIM) :: hvec + + a = 0.0_DP + e = 0.0_DP + q = 0.0_DP + r = sqrt(dot_product(x(:), x(:))) + v2 = dot_product(v(:), v(:)) + hvec(:) = x(:) .cross. v(:) + h2 = dot_product(hvec(:), hvec(:)) + if (h2 == 0.0_DP) return + energy = 0.5_DP * v2 - mu / r + if (abs(energy * r / mu) < sqrt(VSMALL)) then + iorbit_type = PARABOLA + else + a = -0.5_DP * mu / energy + if (a < 0.0_DP) then + fac = -h2 / (mu * a) + if (fac > VSMALL) then + iorbit_type = HYPERBOLA + else + iorbit_type = PARABOLA + end if + else + iorbit_type = ELLIPSE + end if + end if + select case (iorbit_type) + case (ELLIPSE) + fac = 1.0_DP - h2 / (mu * a) + if (fac > VSMALL) e = sqrt(fac) + q = a * (1.0_DP - e) + case (PARABOLA) + a = 0.5_DP * h2 / mu + e = 1.0_DP + q = a + case (HYPERBOLA) + e = sqrt(1.0_DP + fac) + q = a * (1.0_DP - e) + end select + + return + + end subroutine orbel_xv2aeq + + + module pure subroutine orbel_xv2aqt(mu, x, v, a, q, capm, tperi) + !! author: David A. Minton + !! + !! Compute semimajor axis, pericentric distance, mean anomaly, and time to nearest pericenter passage from + !! relative Cartesian position and velocity + !! tperi > 0 means nearest pericenter passage is in the future + !! tperi < 0 means nearest pericenter passage is in the past + !! + !! Adapted from David E. Kaufmann's Swifter routine: orbel_xv2aqt.f90 + implicit none + ! Arguments + real(DP), intent(in) :: mu !! Gravitational constant + real(DP), dimension(:), intent(in) :: x !! Position vector + real(DP), dimension(:), intent(in) :: v !! Velocity vector + real(DP), intent(out) :: a !! semimajor axis + real(DP), intent(out) :: q !! periapsis + real(DP), intent(out) :: capm !! mean anomaly + real(DP), intent(out) :: tperi !! time of pericenter passage + ! Internals + integer(I4B) :: iorbit_type + real(DP) :: r, v2, h2, rdotv, energy, fac, w, face, cape, e, tmpf, capf, mm + real(DP), dimension(NDIM) :: hvec + + a = 0.0_DP + q = 0.0_DP + capm = 0.0_DP + tperi = 0.0_DP + r = sqrt(dot_product(x(:), x(:))) + v2 = dot_product(v(:), v(:)) + hvec(:) = x(:) .cross. v(:) + h2 = dot_product(hvec(:), hvec(:)) + if (h2 == 0.0_DP) return + rdotv = dot_product(x(:), v(:)) + energy = 0.5_DP * v2 - mu / r + if (abs(energy * r / mu) < sqrt(VSMALL)) then + iorbit_type = PARABOLA + else + a = -0.5_DP * mu / energy + if (a < 0.0_DP) then + fac = -h2 / (mu * a) + if (fac > VSMALL) then + iorbit_type = HYPERBOLA + else + iorbit_type = PARABOLA + end if + else + iorbit_type = ELLIPSE + end if + end if + select case (iorbit_type) + case (ELLIPSE) + fac = 1.0_DP - h2 / (mu * a) + if (fac > VSMALL) then + e = sqrt(fac) + cape = 0.0_DP + face = (a - r) / (a * e) + if (face < -1.0_DP) then + cape = PI + else if (face < 1.0_DP) then + cape = acos(face) + end if + if (rdotv < 0.0_DP) cape = TWOPI - cape + else + e = 0.0_DP + cape = 0.0_DP + end if + capm = cape - e * sin(cape) + q = a * (1.0_DP - e) + mm = sqrt(mu / a**3) + if (capm < PI) then + tperi = -1.0_DP * capm / mm + else + tperi = -1.0_DP * (capm - TWOPI) / mm + end if + case (PARABOLA) + a = 0.5_DP * h2 / mu + e = 1.0_DP + w = 0.0_DP + fac = 2 * a / r - 1.0_DP + if (fac < -1.0_DP) then + w = PI + else if (fac < 1.0_DP) then + w = acos(fac) + end if + if (rdotv < 0.0_DP) w = TWOPI - w + tmpf = tan(0.5_DP * w) + capm = tmpf*(1.0_DP + tmpf * tmpf / 3.0_DP) + q = a + mm = sqrt(0.5_DP * mu / q**3) + tperi = -1.0_DP * capm / mm + case (HYPERBOLA) + e = sqrt(1.0_DP + fac) + tmpf = (a - r) / (a * e) + if (tmpf < 1.0_DP) tmpf = 1.0_DP + capf = log(tmpf + sqrt(tmpf * tmpf - 1.0_DP)) + if (rdotv < 0.0_DP) capf = -capf + capm = e * sinh(capf) - capf + q = a * (1.0_DP - e) + mm = sqrt(-mu / a**3) + tperi = -1.0_DP * capm / mm + end select + + return + + end subroutine orbel_xv2aqt + + + module subroutine orbel_xv2el_vec(self, cb) + !! author: David A. Minton + !! + !! A wrapper method that converts all of the cartesian position and velocity vectors of a Swiftest body object to orbital elements. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! internals + integer(I4B) :: i + + if (self%nbody == 0) return + + call self%set_mu(cb) + if (.not.allocated(self%a)) allocate(self%a(self%nbody)) + if (.not.allocated(self%e)) allocate(self%e(self%nbody)) + if (.not.allocated(self%inc)) allocate(self%inc(self%nbody)) + if (.not.allocated(self%capom)) allocate(self%capom(self%nbody)) + if (.not.allocated(self%omega)) allocate(self%omega(self%nbody)) + if (.not.allocated(self%capm)) allocate(self%capm(self%nbody)) + do i = 1, self%nbody + call orbel_xv2el(self%mu(i), self%xh(:, i), self%vh(:, i), self%a(i), self%e(i), self%inc(i), & + self%capom(i), self%omega(i), self%capm(i)) + end do + end subroutine orbel_xv2el_vec + + pure subroutine orbel_xv2el(mu, x, v, a, e, inc, capom, omega, capm) + !! author: David A. Minton + !! + !! Compute osculating orbital elements from relative Cartesian position and velocity + !! All angular measures are returned in radians + !! If inclination < TINY, longitude of the ascending node is arbitrarily set to 0 + !! + !! If eccentricity < sqrt(TINY), argument of pericenter is arbitrarily set to 0 + !! + !! References: Danby, J. M. A. 1988. Fundamentals of Celestial Mechanics, (Willmann-Bell, Inc.), 201 - 206. + !! Fitzpatrick, P. M. 1970. Principles of Celestial Mechanics, (Academic Press), 69 - 73. + !! Roy, A. E. 1982. Orbital Motion, (Adam Hilger, Ltd.), 75 - 95 + !! + !! Adapted from David E. Kaufmann's Swifter routine: orbel_xv2el.f90 + !! Adapted from Martin Duncan's Swift routine orbel_xv2el.f + implicit none + real(DP), intent(in) :: mu + real(DP), dimension(:), intent(in) :: x, v + real(DP), intent(out) :: a, e, inc, capom, omega, capm + integer(I4B) :: iorbit_type + real(DP) :: r, v2, h2, h, rdotv, energy, fac, u, w, cw, sw, face, cape, tmpf, capf + real(DP), dimension(NDIM) :: hvec + + a = 0.0_DP + e = 0.0_DP + inc = 0.0_DP + capom = 0.0_DP + omega = 0.0_DP + capm = 0.0_DP + r = sqrt(dot_product(x(:), x(:))) + v2 = dot_product(v(:), v(:)) + hvec = x(:) .cross. v(:) + h2 = dot_product(hvec(:), hvec(:)) + h = sqrt(h2) + if (h2 == 0.0_DP) return + rdotv = dot_product(x(:), v(:)) + energy = 0.5_DP * v2 - mu / r + fac = hvec(3) / h + if (fac < -1.0_DP) then + inc = PI + else if (fac < 1.0_DP) then + inc = acos(fac) + end if + fac = sqrt(hvec(1)**2 + hvec(2)**2) / h + if (fac**2 < VSMALL) then + u = atan2(x(2), x(1)) + if (hvec(3) < 0.0_DP) u = -u + else + capom = atan2(hvec(1), -hvec(2)) + u = atan2(x(3) / sin(inc), x(1) * cos(capom) + x(2) * sin(capom)) + end if + if (capom < 0.0_DP) capom = capom + TWOPI + if (u < 0.0_DP) u = u + TWOPI + if (abs(energy * r / mu) < sqrt(VSMALL)) then + iorbit_type = parabola + else + a = -0.5_DP * mu / energy + if (a < 0.0_DP) then + fac = -h2 / (mu * a) + if (fac > VSMALL) then + iorbit_type = HYPERBOLA + else + iorbit_type = PARABOLA + end if + else + iorbit_type = ELLIPSE + end if + end if + select case (iorbit_type) + case (ELLIPSE) + fac = 1.0_DP - h2 / (mu * a) + if (fac > VSMALL) then + e = sqrt(fac) + cape = 0.0_DP + face = (a - r) / (a * e) + if (face < -1.0_DP) then + cape = PI + else if (face < 1.0_DP) then + cape = acos(face) + end if + if (rdotv < 0.0_DP) cape = TWOPI - cape + fac = 1.0_DP - e * cos(cape) + cw = (cos(cape) - e) / fac + sw = sqrt(1.0_DP - e**2) * sin(cape) / fac + w = atan2(sw, cw) + if (w < 0.0_DP) w = w + TWOPI + else + cape = u + w = u + end if + capm = cape - e * sin(cape) + case (PARABOLA) + a = 0.5_DP * h2 / mu + e = 1.0_DP + w = 0.0_DP + fac = 2 * a / r - 1.0_DP + if (fac < -1.0_DP) then + w = PI + else if (fac < 1.0_DP) then + w = acos(fac) + end if + if (rdotv < 0.0_DP) w = TWOPI - w + tmpf = tan(0.5_DP * w) + capm = tmpf * (1.0_DP + tmpf * tmpf / 3.0_DP) + case (HYPERBOLA) + e = sqrt(1.0_DP + fac) + tmpf = max((a - r) / (a * e), 1.0_DP) + capf = log(tmpf + sqrt(tmpf**2 - 1.0_DP)) + if (rdotv < 0.0_DP) capf = -capf + fac = e * cosh(capf) - 1.0_DP + cw = (e - cosh(capf)) / fac + sw = sqrt(e * e - 1.0_DP) * sinh(capf) / fac + w = atan2(sw, cw) + if (w < 0.0_DP) w = w + TWOPI + capm = e * sinh(capf) - capf + end select + omega = u - w + if (omega < 0.0_DP) omega = omega + TWOPI + + return + end subroutine orbel_xv2el + + +end submodule s_orbel diff --git a/src/rmvs/rmvs_discard.f90 b/src/rmvs/rmvs_discard.f90 new file mode 100644 index 000000000..bcdb9f902 --- /dev/null +++ b/src/rmvs/rmvs_discard.f90 @@ -0,0 +1,41 @@ +submodule(rmvs_classes) s_rmvs_discard + use swiftest +contains + + module subroutine rmvs_discard_tp(self, system, param) + !! author: David A. Minton + !! + !! Check to see if test particles should be discarded based on pericenter passage distances with respect to planets encountered + !! + !! Adapted from Hal Levison's Swift routine discard_pl.f + !! Adapted from Hal Levison's Swift routine rmvs_discard_pl.f90 + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody, pl => system%pl, t => param%t) + do i = 1, ntp + associate(iplperP => tp%plperP(i)) + if ((tp%status(i) == ACTIVE) .and. (tp%lperi(i))) then + if ((tp%peri(i) < pl%radius(iplperP))) then + tp%status(i) = DISCARDED_PLQ + write(*, *) "Particle ",tp%id(i)," q with respect to Planet ",pl%id(iplperP)," is too small at t = ",t + tp%ldiscard(i) = .true. + tp%lmask(i) = .false. + end if + end if + end associate + end do + ! Call the base method that this overrides + call discard_tp(tp, system, param) + end associate + + end subroutine rmvs_discard_tp + +end submodule s_rmvs_discard \ No newline at end of file diff --git a/src/rmvs/rmvs_encounter_check.f90 b/src/rmvs/rmvs_encounter_check.f90 new file mode 100644 index 000000000..e4c441472 --- /dev/null +++ b/src/rmvs/rmvs_encounter_check.f90 @@ -0,0 +1,86 @@ +submodule (rmvs_classes) s_rmvs_chk + use swiftest +contains + + module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) + !! author: David A. Minton + !! + !! Determine whether a test particle and planet are having or will have an encounter within the next time step + !! + !! Adapted from David E. Kaufmann's Swifter routine: rmvs_chk.f90 + !! Adapted from Hal Levison's Swift routine rmvs3_chk.f + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + real(DP), intent(in) :: dt !! step size + ! Result + logical :: lencounter !! Returns true if there is at least one close encounter + ! Internals + integer(I4B) :: i, j + real(DP) :: r2, v2, vdotr + real(DP), dimension(NDIM) :: xr, vr + real(DP), dimension(system%pl%nbody) :: r2crit + logical :: lflag + + if (self%nbody == 0) return + + select type(pl => system%pl) + class is (rmvs_pl) + associate(tp => self, ntp => self%nbody, npl => pl%nbody, rts => system%rts) + r2crit(:) = (rts * pl%rhill(:))**2 + tp%plencP(:) = 0 + do j = 1, npl + do i = 1, ntp + if ((.not.tp%lmask(i)).or.(tp%plencP(i) /= 0)) cycle + xr(:) = tp%xh(:, i) - pl%xbeg(:, j) + vr(:) = tp%vh(:, i) - pl%vbeg(:, j) + r2 = dot_product(xr(:), xr(:)) + v2 = dot_product(vr(:), vr(:)) + vdotr = dot_product(vr(:), xr(:)) + lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit(j)) + if (lflag) tp%plencP(i) = j + end do + pl%nenc(j) = count(tp%plencP(:) == j) + end do + lencounter = any(pl%nenc(:) > 0) + end associate + end select + return + end function rmvs_encounter_check_tp + + + module elemental function rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) result(lflag) + !! author: David A. Minton + !! + !! Determine whether a test particle and planet are having or will have an encounter within the next time step + !! + !! Adapted from David E. Kaufmann's Swifter routine: rmvs_chk_ind.f90 + !! Adapted from Hal Levison's Swift routine rmvs_chk_ind.f + implicit none + ! Arguments + real(DP), intent(in) :: r2, v2, vdotr, dt, r2crit + logical :: lflag + ! Internals + real(DP) :: tmin, r2min + + lflag = .false. + if (r2 < r2crit) then + lflag = .true. + else + if (vdotr < 0.0_DP) then + tmin = -vdotr / v2 + if (tmin < dt) then + r2min = r2 - vdotr**2 / v2 + else + r2min = r2 + 2 * vdotr * dt + v2 * dt**2 + end if + r2min = min(r2min, r2) + lflag = (r2min <= r2crit) + end if + end if + + return + end function rmvs_chk_ind + +end submodule s_rmvs_chk diff --git a/src/rmvs/rmvs_kick.f90 b/src/rmvs/rmvs_kick.f90 new file mode 100644 index 000000000..018ada8f3 --- /dev/null +++ b/src/rmvs/rmvs_kick.f90 @@ -0,0 +1,89 @@ +submodule(rmvs_classes) s_rmvs_kick + use swiftest +contains + + module subroutine rmvs_kick_getacch_tp(self, system, param, t, lbeg) + + !! author: David A. Minton + !! + !! Compute the oblateness acceleration in the inner encounter region with planets + !! + !! Performs a similar task as David E. Kaufmann's Swifter routine rmvs_kick_getacch_tp.f90, but + !! uses object polymorphism, and so is not directly adapted. + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + ! Internals + class(swiftest_parameters), allocatable :: param_planetocen + real(DP), dimension(:, :), allocatable :: xh_original + real(DP) :: GMcb_original + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody, ipleP => self%ipleP, inner_index => self%index) + select type(system) + class is (rmvs_nbody_system) + if (system%lplanetocentric) then ! This is a close encounter step, so any accelerations requiring heliocentric position values + ! must be handeled outside the normal WHM method call + select type(pl => system%pl) + class is (rmvs_pl) + select type (cb => system%cb) + class is (rmvs_cb) + associate(xpc => pl%xh, xpct => self%xh, apct => self%ah, system_planetocen => system) + system_planetocen%lbeg = lbeg + + ! Save the original heliocentric position for later + allocate(xh_original, source=tp%xh) + + ! Temporarily turn off the heliocentric-dependent acceleration terms during an inner encounter using a copy of the parameter list with all of the heliocentric-specific acceleration terms turned off + allocate(param_planetocen, source=param) + param_planetocen%loblatecb = .false. + param_planetocen%lextra_force = .false. + param_planetocen%lgr = .false. + + ! Compute the planetocentric values of acceleration + call whm_kick_getacch_tp(tp, system_planetocen, param_planetocen, t, lbeg) + + ! Now compute any heliocentric values of acceleration + if (tp%lfirst) then + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index - 1)%x(:,1) + end do + else + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index )%x(:,1) + end do + end if + + ! Swap the planetocentric and heliocentric position vectors and central body masses + tp%xh(:,:) = tp%xheliocentric(:,:) + GMcb_original = cb%Gmass + cb%Gmass = tp%cb_heliocentric%Gmass + + ! If the heliocentric-specifc acceleration terms are requested, compute those now + if (param%loblatecb) call tp%accel_obl(system_planetocen) + if (param%lextra_force) call tp%accel_user(system_planetocen, param, t, lbeg) + if (param%lgr) call tp%accel_gr(param) + + ! Put everything back the way we found it + tp%xh(:,:) = xh_original(:,:) + cb%Gmass = GMcb_original + + end associate + end select + end select + else ! Not a close encounter, so just proceded with the standard WHM method + call whm_kick_getacch_tp(tp, system, param, t, lbeg) + end if + end select + end associate + + return + end subroutine rmvs_kick_getacch_tp + +end submodule s_rmvs_kick \ No newline at end of file diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 new file mode 100644 index 000000000..92043e0fe --- /dev/null +++ b/src/rmvs/rmvs_setup.f90 @@ -0,0 +1,168 @@ +submodule(rmvs_classes) s_rmvs_setup + use swiftest +contains + + module subroutine rmvs_setup_pl(self, n, param) + !! author: David A. Minton + !! + !! Allocate RMVS test particle structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine rmvs_setup.f90 + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + ! Internals + integer(I4B) :: i,j + + !> Call allocation method for parent class + associate(pl => self) + call whm_setup_pl(pl, n, param) + if (n <= 0) return + + allocate(pl%outer(0:NTENC)) + allocate(pl%inner(0:NTPHENC)) + if (.not.pl%lplanetocentric) then + allocate(pl%nenc(n)) + pl%nenc(:) = 0 + ! Set up inner and outer planet interpolation vector storage containers + do i = 0, NTENC + allocate(pl%outer(i)%x(NDIM, n)) + allocate(pl%outer(i)%v(NDIM, n)) + pl%outer(i)%x(:,:) = 0.0_DP + pl%outer(i)%v(:,:) = 0.0_DP + end do + do i = 0, NTPHENC + allocate(pl%inner(i)%x(NDIM, n)) + allocate(pl%inner(i)%v(NDIM, n)) + pl%inner(i)%x(:,:) = 0.0_DP + pl%inner(i)%v(:,:) = 0.0_DP + end do + if (param%loblatecb) then + do i = 0, NTPHENC + allocate(pl%inner(i)%aobl(NDIM, n)) + pl%inner(i)%aobl(:,:) = 0.0_DP + end do + end if + if (param%ltides) then + do i = 0, NTPHENC + allocate(pl%inner(i)%atide(NDIM, n)) + pl%inner(i)%atide(:,:) = 0.0_DP + end do + end if + end if + end associate + return + end subroutine rmvs_setup_pl + + + module subroutine rmvs_setup_initialize_system(self, param) + !! author: David A. Minton + !! + !! Initialize an RMVS nbody system from files and sets up the planetocentric structures. + !! + !! We currently rearrange the pl order to keep it consistent with the way Swifter does it + !! In Swifter, the central body occupies the first position in the pl list, and during + !! encounters, the encountering planet is skipped in loops. In Swiftest, we instantiate an + !! RMVS nbody system object attached to each pl to store planetocentric versions of the system + !! to use during close encounters. + implicit none + ! Arguments + class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, j + + ! Call parent method + call whm_setup_initialize_system(self, param) + + ! Set up the pl-tp planetocentric encounter structures for pl and cb. The planetocentric tp structures are + ! generated as necessary during close encounter steps. + select type(pl => self%pl) + class is(rmvs_pl) + select type(cb => self%cb) + class is (rmvs_cb) + select type (tp => self%tp) + class is (rmvs_tp) + tp%cb_heliocentric = cb + pl%lplanetocentric = .false. + tp%lplanetocentric = .false. + cb%lplanetocentric = .false. + associate(npl => pl%nbody) + allocate(pl%planetocentric(npl)) + pl%planetocentric(:)%lplanetocentric = .true. + do i = 1, npl + allocate(pl%planetocentric(i)%cb, source=cb) + allocate(rmvs_pl :: pl%planetocentric(i)%pl) + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + cbenci%lplanetocentric = .true. + plenci%lplanetocentric = .true. + call plenci%setup(npl, param) + plenci%status(:) = ACTIVE + plenci%lmask(:) = .true. + ! plind stores the heliocentric index value of a planetocentric planet + ! e.g. Consider an encounter with planet 3. + ! Then the following will be the values of plind: + ! pl%planetocentric(3)%pl%plind(1) = 0 (central body - never used) + ! pl%planetocentric(3)%pl%plind(2) = 1 + ! pl%planetocentric(3)%pl%plind(3) = 2 + ! pl%planetocentric(3)%pl%plind(4) = 4 + ! pl%planetocentric(3)%pl%plind(5) = 5 + ! etc. + allocate(plenci%plind(npl)) + plenci%plind(1:npl) = [(j,j=1,npl)] + plenci%plind(2:npl) = pack(plenci%plind(1:npl), plenci%plind(1:npl) /= i) + plenci%plind(1) = 0 + plenci%Gmass(1) = cb%Gmass + plenci%Gmass(2:npl) = pl%Gmass(plenci%plind(2:npl)) + cbenci%Gmass = pl%Gmass(i) + end select + end select + end do + end associate + end select + end select + end select + return + end subroutine rmvs_setup_initialize_system + + + module subroutine rmvs_setup_tp(self, n, param) + !! author: David A. Minton + !! + !! Allocate WHM test particle structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine whm_setup.f90 + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + !> Call allocation method for parent class. In this case, whm does not have its own setup method, so we use the base method for swiftest_tp + call setup_tp(self, n, param) + if (n <= 0) return + + if (allocated(self%lperi)) deallocate(self%lperi) + if (allocated(self%plperP)) deallocate(self%plperP) + if (allocated(self%plencP)) deallocate(self%plencP) + + allocate(self%lperi(n)) + allocate(self%plperP(n)) + allocate(self%plencP(n)) + + if (self%lplanetocentric) then + if (allocated(self%xheliocentric)) deallocate(self%xheliocentric) + allocate(self%xheliocentric(NDIM, n)) + end if + + self%lperi(:) = .false. + + return + end subroutine rmvs_setup_tp + +end submodule s_rmvs_setup diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 new file mode 100644 index 000000000..0385aeecc --- /dev/null +++ b/src/rmvs/rmvs_step.f90 @@ -0,0 +1,636 @@ +submodule(rmvs_classes) s_rmvs_step + use swiftest +contains + + module subroutine rmvs_step_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step massive bodies and and active test particles ahead in heliocentric coordinates + !! + !! Adapted from Hal Levison's Swift routine rmvs3_step.f + !! Adapted from David E. Kaufmann's Swifter routine rmvs_step.f90 + implicit none + ! Arguments + class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsiz + ! Internals + logical :: lencounter, lfirstpl, lfirsttp + real(DP) :: rts + real(DP), dimension(:,:), allocatable :: xbeg, xend, vbeg + integer(I4B) :: i + + select type(cb => self%cb) + class is (rmvs_cb) + select type(pl => self%pl) + class is (rmvs_pl) + select type(tp => self%tp) + class is (rmvs_tp) + associate(system => self, ntp => tp%nbody, npl => pl%nbody) + allocate(xbeg, source=pl%xh) + allocate(vbeg, source=pl%vh) + call pl%set_beg_end(xbeg = xbeg, vbeg = vbeg) + ! ****** Check for close encounters ***** ! + system%rts = RHSCALE + lencounter = tp%encounter_check(system, dt) + if (lencounter) then + lfirstpl = pl%lfirst + pl%outer(0)%x(:,:) = xbeg(:,:) + pl%outer(0)%v(:,:) = vbeg(:,:) + call pl%step(system, param, t, dt) + pl%outer(NTENC)%x(:,:) = pl%xh(:,:) + pl%outer(NTENC)%v(:,:) = pl%vh(:,:) + call rmvs_interp_out(cb, pl, dt) + call rmvs_step_out(cb, pl, tp, system, param, t, dt) + tp%lmask(1:ntp) = .not. tp%lmask(1:ntp) + call pl%set_beg_end(xbeg = xbeg, xend = xend) + tp%lfirst = .true. + call tp%step(system, param, t, dt) + tp%lmask(1:ntp) = .true. + pl%lfirst = lfirstpl + tp%lfirst = .true. + if (param%ltides) call system%step_spin(param, t, dt) + else + call whm_step_system(system, param, t, dt) + end if + end associate + end select + end select + end select + return + end subroutine rmvs_step_system + + + subroutine rmvs_interp_out(cb, pl, dt) + !! author: David A. Minton + !! + !! Interpolate planet positions between two Keplerian orbits in outer encounter region + !! + !! Adapted from David E. Kaufmann's Swifter routine rmvs_interp_out.f90 + !! + !! Adapted from Hal Levison's Swift routine rmvs3_interp.f + implicit none + ! Arguments + class(rmvs_cb), intent(inout) :: cb !! RMVS central body object + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + real(DP), intent(in) :: dt !! Step size + ! Internals + integer(I4B) :: i, outer_index + real(DP) :: frac, dntenc + real(DP), dimension(:,:), allocatable :: xtmp, vtmp + real(DP), dimension(:), allocatable :: GMcb, dto + integer(I4B), dimension(:), allocatable :: iflag + + dntenc = real(NTENC, kind=DP) + associate (npl => pl%nbody) + allocate(xtmp, mold = pl%xh) + allocate(vtmp, mold = pl%vh) + allocate(GMcb(npl)) + allocate(dto(npl)) + allocate(iflag(npl)) + dto(:) = dt / dntenc + GMcb(:) = cb%Gmass + xtmp(:,:) = pl%outer(0)%x(:, :) + vtmp(:,:) = pl%outer(0)%v(:, :) + do outer_index = 1, NTENC - 1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + dto(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), dto(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(FAILURE) + end if + end do + end if + frac = 1.0_DP - outer_index / dntenc + pl%outer(outer_index)%x(:, :) = frac * xtmp(:,:) + pl%outer(outer_index)%v(:, :) = frac * vtmp(:,:) + end do + xtmp(:,:) = pl%outer(NTENC)%x(:, :) + vtmp(:,:) = pl%outer(NTENC)%v(:, :) + do outer_index = NTENC - 1, 1, -1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + -dto(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), -dto(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(FAILURE) + end if + end do + end if + frac = outer_index / dntenc + pl%outer(outer_index)%x(:, :) = pl%outer(outer_index)%x(:, :) + frac * xtmp(:,:) + pl%outer(outer_index)%v(:, :) = pl%outer(outer_index)%v(:, :) + frac * vtmp(:,:) + end do + end associate + + return + end subroutine rmvs_interp_out + + + subroutine rmvs_step_out(cb, pl, tp, system, param, t, dt) + !! author: David A. Minton + !! + !! Step ACTIVE test particles ahead in the outer encounter region, setting up and calling the inner region + !! integration if necessar + !! + !! Adapted from Hal Levison's Swift routines rmvs3_step_out.f and rmvs3_step_out2.f + !! Adapted from David E. Kaufmann's Swifter routines rmvs_step_out.f90 and rmvs_step_out2.f90 + implicit none + ! Arguments + class(rmvs_cb), intent(inout) :: cb !! RMVS central body object + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsiz + ! Internals + integer(I4B) :: outer_index, j, k + real(DP) :: dto, outer_time, rts + logical :: lencounter, lfirsttp + + associate(npl => pl%nbody, ntp => tp%nbody) + dto = dt / NTENC + where(tp%plencP(:) == 0) + tp%lmask(:) = .false. + elsewhere + tp%lperi(:) = .false. + end where + do outer_index = 1, NTENC + outer_time = t + (outer_index - 1) * dto + call pl%set_beg_end(xbeg = pl%outer(outer_index - 1)%x(:, :), & + vbeg = pl%outer(outer_index - 1)%v(:, :), & + xend = pl%outer(outer_index )%x(:, :)) + system%rts = RHPSCALE + lencounter = tp%encounter_check(system, dto) + if (lencounter) then + ! Interpolate planets in inner encounter region + call rmvs_interp_in(cb, pl, system, param, dto, outer_index) + ! Step through the inner region + call rmvs_step_in(cb, pl, tp, param, outer_time, dto) + lfirsttp = tp%lfirst + tp%lfirst = .true. + call tp%step(system, param, outer_time, dto) + tp%lfirst = lfirsttp + else + call tp%step(system, param, outer_time, dto) + end if + do j = 1, npl + if (pl%nenc(j) == 0) cycle + tp%lfirst = .true. + where((tp%plencP(:) == j) .and. (.not.tp%lmask(:))) + tp%lmask(:) = .true. + end where + end do + end do + end associate + + return + end subroutine rmvs_step_out + + + subroutine rmvs_interp_in(cb, pl, system, param, dt, outer_index) + !! author: David A. Minton + !! + !! Interpolate planet positions between two Keplerian orbits in inner encounter regio + !! + !! Adapted from David E. Kaufmann's Swifter routine rmvs_interp_in.f90 + !! + !! Adapted from Hal Levison's Swift routine rmvs3_interp.f + implicit none + ! Arguments + class(rmvs_cb), intent(inout) :: cb !! RMVS cenral body object + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + class(swiftest_parameters), intent(in) :: param !! Swiftest parameters file + real(DP), intent(in) :: dt !! Step size + integer(I4B), intent(in) :: outer_index !! Outer substep number within current set + ! Internals + integer(I4B) :: i, inner_index + real(DP) :: frac, dntphenc + real(DP), dimension(:,:), allocatable :: xtmp, vtmp, xh_original + real(DP), dimension(:), allocatable :: GMcb, dti + integer(I4B), dimension(:), allocatable :: iflag + + associate (npl => system%pl%nbody) + dntphenc = real(NTPHENC, kind=DP) + + ! Set the endpoints of the inner region from the outer region values in the current outer step index + pl%inner(0)%x(:,:) = pl%outer(outer_index - 1)%x(:, :) + pl%inner(0)%v(:,:) = pl%outer(outer_index - 1)%v(:, :) + pl%inner(NTPHENC)%x(:,:) = pl%outer(outer_index)%x(:, :) + pl%inner(NTPHENC)%v(:,:) = pl%outer(outer_index)%v(:, :) + + allocate(xtmp,mold=pl%xh) + allocate(vtmp,mold=pl%vh) + allocate(GMcb(npl)) + allocate(dti(npl)) + allocate(iflag(npl)) + dti(:) = dt / dntphenc + GMcb(:) = cb%Gmass + xtmp(:, :) = pl%inner(0)%x(:, :) + vtmp(:, :) = pl%inner(0)%v(:, :) + + if ((param%loblatecb) .or. (param%ltides)) then + allocate(xh_original, source=pl%xh) + pl%xh(:, :) = xtmp(:, :) ! Temporarily replace heliocentric position with inner substep values to calculate the oblateness terms + end if + if (param%loblatecb) then + call pl%accel_obl(system) + pl%inner(0)%aobl(:, :) = pl%aobl(:, :) ! Save the oblateness acceleration on the planet for this substep + end if + if (param%ltides) then + call pl%accel_tides(system) + pl%inner(0)%atide(:, :) = pl%atide(:, :) ! Save the oblateness acceleration on the planet for this substep + end if + + do inner_index = 1, NTPHENC - 1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + dti(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /=0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), dti(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(failure) + end if + end do + end if + frac = 1.0_DP - inner_index / dntphenc + pl%inner(inner_index)%x(:, :) = frac * xtmp(:,:) + pl%inner(inner_index)%v(:, :) = frac * vtmp(:,:) + end do + + xtmp(:,:) = pl%inner(NTPHENC)%x(:, :) + vtmp(:,:) = pl%inner(NTPHENC)%v(:, :) + + do inner_index = NTPHENC - 1, 1, -1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + -dti(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /=0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), -dti(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(failure) + end if + end do + end if + frac = inner_index / dntphenc + pl%inner(inner_index)%x(:, :) = pl%inner(inner_index)%x(:, :) + frac * xtmp(:, :) + pl%inner(inner_index)%v(:, :) = pl%inner(inner_index)%v(:, :) + frac * vtmp(:, :) + + if (param%loblatecb) then + pl%xh(:,:) = pl%inner(inner_index)%x(:, :) + call pl%accel_obl(system) + pl%inner(inner_index)%aobl(:, :) = pl%aobl(:, :) + end if + if (param%ltides) then + call pl%accel_tides(system) + pl%inner(inner_index)%atide(:, :) = pl%atide(:, :) + end if + end do + if (param%loblatecb) then + ! Calculate the final value of oblateness accelerations at the final inner substep + pl%xh(:,:) = pl%inner(NTPHENC)%x(:, :) + call pl%accel_obl(system) + pl%inner(NTPHENC)%aobl(:, :) = pl%aobl(:, :) + end if + if (param%ltides) then + call pl%accel_tides(system) + pl%inner(NTPHENC)%atide(:, :) = pl%atide(:, :) + end if + ! Put the planet positions back into place + if (allocated(xh_original)) call move_alloc(xh_original, pl%xh) + end associate + return + + end subroutine rmvs_interp_in + + + subroutine rmvs_step_in(cb, pl, tp, param, outer_time, dto) + !! author: David A. Minton + !! + !! Step active test particles ahead in the inner encounter region + !! + !! Adapted from Hal Levison's Swift routine rmvs3_step_in.f + !! Adapted from David E. Kaufmann's Swifter routine rmvs_step_in.f90 + implicit none + ! Arguments + class(rmvs_cb), intent(inout) :: cb !! RMVS central body object + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: outer_time !! Current time + real(DP), intent(in) :: dto !! Outer step size + ! Internals + logical :: lfirsttp + integer(I4B) :: i, j, ipleP + real(DP) :: dti, inner_time + + associate(npl => pl%nbody) + dti = dto / NTPHENC + call rmvs_make_planetocentric(param, cb, pl, tp) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + select type(planetocen_system => pl%planetocentric(i)) + class is (rmvs_nbody_system) + select type(cbenci => planetocen_system%cb) + class is (rmvs_cb) + select type(plenci => planetocen_system%pl) + class is (rmvs_pl) + select type(tpenci => planetocen_system%tp) + class is (rmvs_tp) + associate(inner_index => tpenci%index) + ! There are inner encounters with this planet...switch to planetocentric coordinates to proceed + tpenci%lfirst = .true. + inner_time = outer_time + call rmvs_peri_tp(tpenci, pl, inner_time, dti, .true., 0, i, param) + ! now step the encountering test particles fully through the inner encounter + lfirsttp = .true. + do inner_index = 1, NTPHENC ! Integrate over the encounter region, using the "substitute" planetocentric systems at each level + plenci%xh(:,:) = plenci%inner(inner_index - 1)%x(:,:) + call plenci%set_beg_end(xbeg = plenci%inner(inner_index - 1)%x, & + xend = plenci%inner(inner_index)%x) + + if (param%loblatecb) then + cbenci%aoblbeg = cbenci%inner(inner_index - 1)%aobl(:, 1) + cbenci%aoblend = cbenci%inner(inner_index )%aobl(:, 1) + end if + if (param%ltides) then + cbenci%atidebeg = cbenci%inner(inner_index - 1)%atide(:, 1) + cbenci%atideend = cbenci%inner(inner_index )%atide(:, 1) + end if + + call tpenci%step(planetocen_system, param, inner_time, dti) + do j = 1, pl%nenc(i) + tpenci%xheliocentric(:, j) = tpenci%xh(:, j) + pl%inner(inner_index)%x(:,i) + end do + inner_time = outer_time + j * dti + call rmvs_peri_tp(tpenci, pl, inner_time, dti, .false., inner_index, i, param) + end do + tpenci%lmask(:) = .false. + end associate + end select + end select + end select + end select + end do + call rmvs_end_planetocentric(pl, tp) + end associate + return + end subroutine rmvs_step_in + + + subroutine rmvs_make_planetocentric(param, cb, pl, tp) + !! author: David A. Minton + !! + !! When encounters are detected, this method will call the interpolation methods for the planets and + !! creates a Swiftest test particle structure for each planet's encountering test particles to simplify the + !! planetocentric calculations. This subroutine is not based on an existing one from Swift and Swifter + !! + implicit none + ! Arguments + class(swiftest_parameters), intent(in) :: param !! Current run configuration paramete + class(rmvs_cb), intent(inout) :: cb !! RMVS central body object + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object + + ! Internals + integer(I4B) :: i, j, inner_index, ipc2hc + logical, dimension(:), allocatable :: encmask + + associate (npl => pl%nbody, ntp => tp%nbody) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + ! There are inner encounters with this planet + if (allocated(encmask)) deallocate(encmask) + allocate(encmask(ntp)) + encmask(:) = tp%plencP(:) == i + allocate(rmvs_tp :: pl%planetocentric(i)%tp) + ! Create encountering test particle structure + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + select type(tpenci => pl%planetocentric(i)%tp) + class is (rmvs_tp) + tpenci%lplanetocentric = .true. + call tpenci%setup(pl%nenc(i), param) + tpenci%cb_heliocentric = cb + tpenci%ipleP = i + tpenci%lmask(:) = .true. + tpenci%status(:) = ACTIVE + ! Grab all the encountering test particles and convert them to a planetocentric frame + tpenci%id(:) = pack(tp%id(:), encmask(:)) + do j = 1, NDIM + tpenci%xheliocentric(j, :) = pack(tp%xh(j,:), encmask(:)) + tpenci%xh(j, :) = tpenci%xheliocentric(j, :) - pl%inner(0)%x(j, i) + tpenci%vh(j, :) = pack(tp%vh(j,:), encmask(:)) - pl%inner(0)%v(j, i) + end do + tpenci%lperi(:) = pack(tp%lperi(:), encmask(:)) + tpenci%plperP(:) = pack(tp%plperP(:), encmask(:)) + ! Make sure that the test particles get the planetocentric value of mu + allocate(cbenci%inner(0:NTPHENC)) + do inner_index = 0, NTPHENC + allocate(plenci%inner(inner_index)%x, mold=pl%inner(inner_index)%x) + allocate(plenci%inner(inner_index)%v, mold=pl%inner(inner_index)%x) + allocate(cbenci%inner(inner_index)%x(NDIM,1)) + allocate(cbenci%inner(inner_index)%v(NDIM,1)) + cbenci%inner(inner_index)%x(:,1) = pl%inner(inner_index)%x(:, i) + cbenci%inner(inner_index)%v(:,1) = pl%inner(inner_index)%v(:, i) + plenci%inner(inner_index)%x(:,1) = -cbenci%inner(inner_index)%x(:,1) + plenci%inner(inner_index)%v(:,1) = -cbenci%inner(inner_index)%v(:,1) + + if (param%loblatecb) then + allocate(plenci%inner(inner_index)%aobl, mold=pl%inner(inner_index)%aobl) + allocate(cbenci%inner(inner_index)%aobl(NDIM,1)) + cbenci%inner(inner_index)%aobl(:,1) = pl%inner(inner_index)%aobl(:, i) + end if + + if (param%ltides) then + allocate(plenci%inner(inner_index)%atide, mold=pl%inner(inner_index)%atide) + allocate(cbenci%inner(inner_index)%atide(NDIM,1)) + cbenci%inner(inner_index)%atide(:,1) = pl%inner(inner_index)%atide(:, i) + end if + + do j = 2, npl + ipc2hc = plenci%plind(j) + plenci%inner(inner_index)%x(:,j) = pl%inner(inner_index)%x(:, ipc2hc) - cbenci%inner(inner_index)%x(:,1) + plenci%inner(inner_index)%v(:,j) = pl%inner(inner_index)%v(:, ipc2hc) - cbenci%inner(inner_index)%v(:,1) + end do + end do + call tpenci%set_mu(cbenci) + end select + end select + end select + end do + end associate + + return + end subroutine rmvs_make_planetocentric + + + subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) + !! author: David A. Minton + !! + !! Determine planetocentric pericenter passages for test particles in close encounters with a planet + !! + !! Adapted from Hal Levison's Swift routine Adapted from Hal Levison's Swift routine util_peri.f + !! Adapted from David E. Kaufmann's Swifter routine rmvs_peri.f90 + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object (planetocentric) + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object (heliocentric) + real(DP), intent(in) :: t !! current time + real(DP), intent(in) :: dt !! step size + logical, intent(in) :: lfirst !! Logical flag indicating whether current invocation is the first + integer(I4B), intent(in) :: inner_index !! Outer substep number within current set + integer(I4B), intent(in) :: ipleP !! index of RMVS planet being closely encountered + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, id1, id2 + real(DP) :: r2, mu, rhill2, vdotr, a, peri, capm, tperi, rpl + real(DP), dimension(NDIM) :: xh1, xh2, vh1, vh2 + + rhill2 = pl%rhill(ipleP)**2 + mu = pl%Gmass(ipleP) + associate(nenc => tp%nbody, xpc => tp%xh, vpc => tp%vh) + if (lfirst) then + do i = 1, nenc + if (tp%lmask(i)) then + vdotr = dot_product(xpc(:, i), vpc(:, i)) + if (vdotr > 0.0_DP) then + tp%isperi(i) = 1 + else + tp%isperi(i) = -1 + end if + end if + end do + else + do i = 1, nenc + if (tp%lmask(i)) then + vdotr = dot_product(xpc(:, i), vpc(:, i)) + if (tp%isperi(i) == -1) then + if (vdotr >= 0.0_DP) then + tp%isperi(i) = 0 + call orbel_xv2aqt(mu, xpc(:, i), vpc(:, i), a, peri, capm, tperi) + r2 = dot_product(xpc(:, i), xpc(:, i)) + if ((abs(tperi) > FACQDT * dt) .or. (r2 > rhill2)) peri = sqrt(r2) + if (param%enc_out /= "") then + id1 = pl%id(ipleP) + rpl = pl%radius(ipleP) + xh1(:) = pl%inner(inner_index)%x(:, ipleP) + vh1(:) = pl%inner(inner_index)%v(:, ipleP) + id2 = tp%id(i) + xh2(:) = xpc(:, i) + xh1(:) + vh2(:) = xpc(:, i) + vh1(:) + call io_write_encounter(t, id1, id2, mu, 0.0_DP, rpl, 0.0_DP, xh1(:), xh2(:), vh1(:), vh2(:), & + param%enc_out, param%out_type) + end if + if (tp%lperi(i)) then + if (peri < tp%peri(i)) then + tp%peri(i) = peri + tp%plperP(i) = ipleP + end if + else + tp%lperi(i) = .true. + tp%peri(i) = peri + tp%plperP(i) = ipleP + end if + end if + else + if (vdotr > 0.0_DP) then + tp%isperi(i) = 1 + else + tp%isperi(i) = -1 + end if + end if + end if + end do + end if + end associate + return + + end subroutine rmvs_peri_tp + + + subroutine rmvs_end_planetocentric(pl, tp) + !! author: David A. Minton + !! + !! Deallocates all of the encountering particle data structures for next time + !! + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object + class(rmvs_tp), intent(inout) :: tp !! RMVS test particle objec + ! Internals + integer(I4B) :: i, j, inner_index + integer(I4B), dimension(:), allocatable :: tpind + logical, dimension(:), allocatable :: encmask + + associate (npl => pl%nbody, ntp => tp%nbody) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + select type(tpenci => pl%planetocentric(i)%tp) + class is (rmvs_tp) + if (allocated(tpind)) deallocate(tpind) + allocate(tpind(pl%nenc(i))) + ! Index array of encountering test particles + if (allocated(encmask)) deallocate(encmask) + allocate(encmask(ntp)) + encmask(:) = tp%plencP(:) == i + tpind(:) = pack([(j,j=1,ntp)], encmask(:)) + + ! Copy the results of the integration back over and shift back to heliocentric reference + tp%status(tpind(1:pl%nenc(i))) = tpenci%status(1:pl%nenc(i)) + tp%lmask(tpind(1:pl%nenc(i))) = tpenci%lmask(1:pl%nenc(i)) + do j = 1, NDIM + tp%xh(j, tpind(1:pl%nenc(i))) = tpenci%xh(j,1:pl%nenc(i)) + pl%inner(NTPHENC)%x(j, i) + tp%vh(j, tpind(1:pl%nenc(i))) = tpenci%vh(j,1:pl%nenc(i)) + pl%inner(NTPHENC)%v(j, i) + end do + tp%lperi(tpind(1:pl%nenc(i))) = tpenci%lperi(1:pl%nenc(i)) + tp%plperP(tpind(1:pl%nenc(i))) = tpenci%plperP(1:pl%nenc(i)) + deallocate(pl%planetocentric(i)%tp) + deallocate(cbenci%inner) + do inner_index = 0, NTPHENC + deallocate(plenci%inner(inner_index)%x) + deallocate(plenci%inner(inner_index)%v) + if (allocated(plenci%inner(inner_index)%aobl)) deallocate(plenci%inner(inner_index)%aobl) + if (allocated(plenci%inner(inner_index)%atide)) deallocate(plenci%inner(inner_index)%atide) + end do + end select + end select + end select + end do + end associate + return + end subroutine rmvs_end_planetocentric + +end submodule s_rmvs_step diff --git a/src/rmvs/rmvs_util.f90 b/src/rmvs/rmvs_util.f90 new file mode 100644 index 000000000..9f9cf0037 --- /dev/null +++ b/src/rmvs/rmvs_util.f90 @@ -0,0 +1,380 @@ +submodule(rmvs_classes) s_rmvs_util + use swiftest +contains + + module subroutine rmvs_util_append_pl(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one massive body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + !! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (rmvs_pl) + call whm_util_append_pl(self, source, lsource_mask) + + call util_append(self%nenc, source%nenc, lsource_mask) + call util_append(self%tpenc1P, source%tpenc1P, lsource_mask) + call util_append(self%plind, source%plind, lsource_mask) + + ! The following are not implemented as RMVS doesn't make use of fill operations on pl type + ! So they are here as a placeholder in case someone wants to extend the RMVS class for some reason + !call util_append(self%outer, source%outer, lsource_mask) + !call util_append(self%inner, source%inner, lsource_mask) + !call util_append(self%planetocentric, source%planetocentric, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class rmvs_pl or its descendents!" + call util_exit(FAILURE) + end select + + return + end subroutine rmvs_util_append_pl + + + module subroutine rmvs_util_append_tp(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from test particle object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + !! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (rmvs_tp) + call util_append_tp(self, source, lsource_mask) ! Note: whm_tp does not have its own append method, so we skip back to the base class + + call util_append(self%lperi, source%lperi, lsource_mask) + call util_append(self%plperP, source%plperP, lsource_mask) + call util_append(self%plencP, source%plencP, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class rmvs_tp or its descendents!" + call util_exit(FAILURE) + end select + + return + end subroutine rmvs_util_append_tp + + + module subroutine rmvs_util_fill_pl(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new RMVS massive body structure into an old one. + !! This is the inverse of a fill operation. + !! + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + ! Internals + integer(I4B) :: i + + associate(keeps => self) + select type(inserts) + class is (rmvs_pl) + call util_fill(keeps%nenc, inserts%nenc, lfill_list) + call util_fill(keeps%tpenc1P, inserts%tpenc1P, lfill_list) + call util_fill(keeps%plind, inserts%plind, lfill_list) + + ! The following are not implemented as RMVS doesn't make use of fill operations on pl type + ! So they are here as a placeholder in case someone wants to extend the RMVS class for some reason + !call util_fill(keeps%outer, inserts%outer, lfill_list) + !call util_fill(keeps%inner, inserts%inner, lfill_list) + !call util_fill(keeps%planetocentric, inserts%planetocentric, lfill_list) + + call whm_util_fill_pl(keeps, inserts, lfill_list) + class default + write(*,*) "Invalid object passed to the fill method. Source must be of class rmvs_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine rmvs_util_fill_pl + + + module subroutine rmvs_util_fill_tp(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new RMVS test particle structure into an old one. + !! This is the inverse of a fill operation. + !! + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + associate(keeps => self) + select type(inserts) + class is (rmvs_tp) + call util_fill(keeps%lperi, inserts%lperi, lfill_list) + call util_fill(keeps%plperP, inserts%plperP, lfill_list) + call util_fill(keeps%plencP, inserts%plencP, lfill_list) + + call util_fill_tp(keeps, inserts, lfill_list) ! Note: whm_tp does not have its own fill method, so we skip back to the base class + class default + write(*,*) "Invalid object passed to the fill method. Source must be of class rmvs_tp or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine rmvs_util_fill_tp + + + module subroutine rmvs_util_resize_pl(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a massive body object against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call whm_util_resize_pl(self, nnew) + + call util_resize(self%nenc, nnew) + call util_resize(self%tpenc1P, nnew) + call util_resize(self%plind, nnew) + + ! The following are not implemented as RMVS doesn't make use of resize operations on pl type + ! So they are here as a placeholder in case someone wants to extend the RMVS class for some reason + !call util_resize(self%outer, nnew) + !call util_resize(self%inner, nnew) + !call util_resize(self%planetocentric, nnew) + + return + end subroutine rmvs_util_resize_pl + + + module subroutine rmvs_util_resize_tp(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a test particle object against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_tp(self, nnew) + + call util_resize(self%lperi, nnew) + call util_resize(self%plperP, nnew) + call util_resize(self%plencP, nnew) + call util_resize(self%xheliocentric, nnew) + + return + end subroutine rmvs_util_resize_tp + + + module subroutine rmvs_util_sort_pl(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a RMVS massive body object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(pl => self, npl => self%nbody) + select case(sortby) + case("nenc") + call util_sort(direction * pl%nenc(1:npl), ind(1:npl)) + case("tpenc1P") + call util_sort(direction * pl%tpenc1P(1:npl), ind(1:npl)) + case("plind") + call util_sort(direction * pl%plind(1:npl), ind(1:npl)) + case("outer", "inner", "planetocentric", "lplanetocentric") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default ! Look for components in the parent class + call whm_util_sort_pl(pl, sortby, ascending) + return + end select + + call pl%rearrange(ind) + + end associate + return + end subroutine rmvs_util_sort_pl + + + module subroutine rmvs_util_sort_tp(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a RMVS test particle object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(tp => self, ntp => self%nbody) + select case(sortby) + case("plperP") + call util_sort(direction * tp%plperP(1:ntp), ind(1:ntp)) + case("plencP") + call util_sort(direction * tp%plencP(1:ntp), ind(1:ntp)) + case("lperi", "cb_heliocentric", "xheliocentric", "index", "ipleP", "lplanetocentric") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default ! Look for components in the parent class (*NOTE whm_tp does not need its own sort method, so we go straight to the swiftest_tp method) + call util_sort_tp(tp, sortby, ascending) + return + end select + + call tp%rearrange(ind) + + end associate + return + end subroutine rmvs_util_sort_tp + + module subroutine rmvs_util_sort_rearrange_pl(self, ind) + !! author: David A. Minton + !! + !! Rearrange RMVS massive body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(rmvs_pl), allocatable :: pl_sorted !! Temporary holder for sorted body + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + call util_sort_rearrange_pl(pl,ind) + allocate(pl_sorted, source=self) + if (allocated(pl%nenc)) pl%nenc(1:npl) = pl_sorted%nenc(ind(1:npl)) + if (allocated(pl%tpenc1P)) pl%tpenc1P(1:npl) = pl_sorted%tpenc1P(ind(1:npl)) + if (allocated(pl%plind)) pl%plind(1:npl) = pl_sorted%plind(ind(1:npl)) + deallocate(pl_sorted) + end associate + + return + end subroutine rmvs_util_sort_rearrange_pl + + + module subroutine rmvs_util_sort_rearrange_tp(self, ind) + !! author: David A. Minton + !! + !! Rearrange RMVS test particle object in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(rmvs_tp), allocatable :: tp_sorted !! Temporary holder for sorted body + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + call util_sort_rearrange_tp(tp,ind) + allocate(tp_sorted, source=self) + if (allocated(tp%lperi)) tp%lperi(1:ntp) = tp_sorted%lperi(ind(1:ntp)) + if (allocated(tp%plperP)) tp%plperP(1:ntp) = tp_sorted%plperP(ind(1:ntp)) + if (allocated(tp%plencP)) tp%plencP(1:ntp) = tp_sorted%plencP(ind(1:ntp)) + if (allocated(tp%xheliocentric)) tp%xheliocentric(:,1:ntp) = tp_sorted%xheliocentric(:,ind(1:ntp)) + deallocate(tp_sorted) + end associate + + return + end subroutine rmvs_util_sort_rearrange_tp + + + module subroutine rmvs_util_spill_pl(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) RMVS test particle structure from active list to discard list + !! + !! Adapted from David E. Kaufmann's Swifter routine discard_discard_spill.f90 + implicit none + ! Arguments + class(rmvs_pl), intent(inout) :: self !! RMVS massive body body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + ! Internals + integer(I4B) :: i + + associate(keeps => self) + select type(discards) + class is (rmvs_pl) + call util_spill(keeps%nenc, discards%nenc, lspill_list, ldestructive) + call util_spill(keeps%tpenc1P, discards%tpenc1P, lspill_list, ldestructive) + call util_spill(keeps%plind, discards%plind, lspill_list, ldestructive) + + call whm_util_spill_pl(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class rmvs_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine rmvs_util_spill_pl + + + module subroutine rmvs_util_spill_tp(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) RMVS test particle structure from active list to discard list + !! + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + ! Internals + integer(I4B) :: i + + associate(keeps => self) + select type(discards) + class is (rmvs_tp) + call util_spill(keeps%lperi, discards%lperi, lspill_list, ldestructive) + call util_spill(keeps%plperP, discards%plperP, lspill_list, ldestructive) + call util_spill(keeps%plencP, discards%plencP, lspill_list, ldestructive) + + call util_spill_tp(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class rmvs_tp or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine rmvs_util_spill_tp + +end submodule s_rmvs_util diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 new file mode 100644 index 000000000..6cba6d27b --- /dev/null +++ b/src/setup/setup.f90 @@ -0,0 +1,312 @@ +submodule (swiftest_classes) s_setup + use swiftest +contains + + module subroutine setup_construct_system(system, param) + !! author: David A. Minton + !! + !! Constructor for a Swiftest nbody system. Creates the nbody system object based on the user-input integrator + !! + implicit none + ! Arguments + class(swiftest_nbody_system), allocatable, intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Swiftest parameters + + select case(param%integrator) + case (BS) + write(*,*) 'Bulirsch-Stoer integrator not yet enabled' + case (HELIO) + allocate(helio_nbody_system :: system) + select type(system) + class is (helio_nbody_system) + allocate(helio_cb :: system%cb) + allocate(helio_pl :: system%pl) + allocate(helio_tp :: system%tp) + allocate(helio_tp :: system%tp_discards) + end select + case (RA15) + write(*,*) 'Radau integrator not yet enabled' + case (TU4) + write(*,*) 'TU4 integrator not yet enabled' + case (WHM) + allocate(whm_nbody_system :: system) + select type(system) + class is (whm_nbody_system) + allocate(whm_cb :: system%cb) + allocate(whm_pl :: system%pl) + allocate(whm_tp :: system%tp) + allocate(whm_tp :: system%tp_discards) + end select + case (RMVS) + allocate(rmvs_nbody_system :: system) + select type(system) + class is (rmvs_nbody_system) + allocate(rmvs_cb :: system%cb) + allocate(rmvs_pl :: system%pl) + allocate(rmvs_tp :: system%tp) + allocate(rmvs_tp :: system%tp_discards) + end select + case (SYMBA) + allocate(symba_nbody_system :: system) + select type(system) + class is (symba_nbody_system) + allocate(symba_cb :: system%cb) + allocate(symba_pl :: system%pl) + allocate(symba_tp :: system%tp) + allocate(symba_tp :: system%tp_discards) + allocate(symba_merger :: system%mergeadd_list) + allocate(symba_merger :: system%mergesub_list) + allocate(symba_plplenc :: system%plplenc_list) + allocate(symba_pltpenc :: system%pltpenc_list) + end select + case (RINGMOONS) + write(*,*) 'RINGMOONS-SyMBA integrator not yet enabled' + case default + write(*,*) 'Unkown integrator',param%integrator + call util_exit(FAILURE) + end select + + return + end subroutine setup_construct_system + + + module subroutine setup_encounter(self, n) + !! author: David A. Minton + !! + !! A constructor that sets the number of encounters and allocates and initializes all arrays + !! + implicit none + ! Arguments + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter structure + integer(I4B), intent(in) :: n !! Number of encounters to allocate space for + + self%nenc = n + if (n == 0) return + + if (allocated(self%lvdotr)) deallocate(self%lvdotr) + if (allocated(self%status)) deallocate(self%status) + if (allocated(self%index1)) deallocate(self%index1) + if (allocated(self%index2)) deallocate(self%index2) + if (allocated(self%x1)) deallocate(self%x1) + if (allocated(self%x2)) deallocate(self%x2) + if (allocated(self%v1)) deallocate(self%v1) + if (allocated(self%v2)) deallocate(self%v2) + + allocate(self%lvdotr(n)) + allocate(self%status(n)) + allocate(self%index1(n)) + allocate(self%index2(n)) + allocate(self%x1(NDIM,n)) + allocate(self%x2(NDIM,n)) + allocate(self%v1(NDIM,n)) + allocate(self%v2(NDIM,n)) + + self%lvdotr(:) = .false. + self%status(:) = INACTIVE + self%index1(:) = 0 + self%index2(:) = 0 + self%x1(:,:) = 0.0_DP + self%x2(:,:) = 0.0_DP + self%v1(:,:) = 0.0_DP + self%v2(:,:) = 0.0_DP + + return + end subroutine setup_encounter + + + module subroutine setup_initialize_system(self, param) + !! author: David A. Minton + !! + !! Wrapper method to initialize a basic Swiftest nbody system from files + !! + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + + call self%cb%initialize(param) + call self%pl%initialize(param) + call self%tp%initialize(param) + call util_valid(self%pl, self%tp) + self%maxid = maxval([self%pl%id(:), self%tp%id(:)]) + call self%set_msys() + call self%pl%set_mu(self%cb) + call self%tp%set_mu(self%cb) + call self%pl%eucl_index() + if (.not.param%lrhill_present) call self%pl%set_rhill(self%cb) + !if (param%lfirstenergy) then + return + end subroutine setup_initialize_system + + + module subroutine setup_body(self, n, param) + !! author: David A. Minton + !! + !! Constructor for base Swiftest particle class. Allocates space for all particles and + !! initializes all components with a value. + !! Note: Timing tests indicate that (NDIM, n) is more efficient than (NDIM, n) + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + self%nbody = n + if (n <= 0) return + self%lfirst = .true. + + if (allocated(self%id)) deallocate(self%id) + if (allocated(self%name)) deallocate(self%name) + if (allocated(self%status)) deallocate(self%status) + if (allocated(self%ldiscard)) deallocate(self%ldiscard) + if (allocated(self%xh)) deallocate(self%xh) + if (allocated(self%vh)) deallocate(self%vh) + if (allocated(self%xb)) deallocate(self%xb) + if (allocated(self%vb)) deallocate(self%vb) + if (allocated(self%ah)) deallocate(self%ah) + if (allocated(self%ir3h)) deallocate(self%ir3h) + if (allocated(self%mu)) deallocate(self%mu) + if (allocated(self%lmask)) deallocate(self%lmask) + + allocate(self%id(n)) + allocate(self%name(n)) + allocate(self%status(n)) + allocate(self%ldiscard(n)) + allocate(self%xh(NDIM, n)) + allocate(self%vh(NDIM, n)) + allocate(self%xb(NDIM, n)) + allocate(self%vb(NDIM, n)) + allocate(self%ah(NDIM, n)) + allocate(self%ir3h(n)) + allocate(self%mu(n)) + allocate(self%lmask(n)) + + self%id(:) = 0 + self%name(:) = "UNNAMED" + self%status(:) = INACTIVE + self%lmask(:) = .false. + self%ldiscard(:) = .false. + self%xh(:,:) = 0.0_DP + self%vh(:,:) = 0.0_DP + self%xb(:,:) = 0.0_DP + self%vb(:,:) = 0.0_DP + self%ah(:,:) = 0.0_DP + self%ir3h(:) = 0.0_DP + self%mu(:) = 0.0_DP + + if (param%loblatecb) then + if (allocated(self%aobl)) deallocate(self%aobl) + allocate(self%aobl(NDIM, n)) + self%aobl(:,:) = 0.0_DP + end if + if (param%ltides) then + if (allocated(self%atide)) deallocate(self%lmask) + allocate(self%atide(NDIM, n)) + self%atide(:,:) = 0.0_DP + end if + if (param%lgr) then + if (allocated(self%agr)) deallocate(self%lmask) + allocate(self%agr(NDIM, n)) + self%agr(:,:) = 0.0_DP + end if + + return + end subroutine setup_body + + + module subroutine setup_pl(self, n, param) + !! author: David A. Minton + !! + !! Constructor for base Swiftest massive body class. Allocates space for all particles and + !! initializes all components with a value. + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + !> Call allocation method for parent class + !> The parent class here is the abstract swiftest_body class, so we can't use the type-bound procedure + call setup_body(self, n, param) + if (n <= 0) return + + if (allocated(self%mass)) deallocate(self%mass) + if (allocated(self%Gmass)) deallocate(self%Gmass) + if (allocated(self%rhill)) deallocate(self%rhill) + + allocate(self%mass(n)) + allocate(self%Gmass(n)) + allocate(self%rhill(n)) + + self%mass(:) = 0.0_DP + self%Gmass(:) = 0.0_DP + self%rhill(:) = 0.0_DP + + self%nplpl = 0 + + if (param%lclose) then + if (allocated(self%radius)) deallocate(self%radius) + if (allocated(self%density)) deallocate(self%density) + allocate(self%radius(n)) + allocate(self%density(n)) + self%radius(:) = 0.0_DP + self%density(:) = 1.0_DP + end if + + if (param%lrotation) then + if (allocated(self%rot)) deallocate(self%rhill) + if (allocated(self%Ip)) deallocate(self%rhill) + allocate(self%rot(NDIM, n)) + allocate(self%Ip(NDIM, n)) + self%rot(:,:) = 0.0_DP + self%Ip(:,:) = 0.0_DP + end if + + if (param%ltides) then + if (allocated(self%k2)) deallocate(self%rhill) + if (allocated(self%Q)) deallocate(self%rhill) + if (allocated(self%tlag)) deallocate(self%rhill) + allocate(self%k2(n)) + allocate(self%Q(n)) + allocate(self%tlag(n)) + self%k2(:) = 0.0_DP + self%Q(:) = 0.0_DP + self%tlag(:) = 0.0_DP + end if + + return + end subroutine setup_pl + + + module subroutine setup_tp(self, n, param) + !! author: David A. Minton + !! + !! Constructor for base Swiftest test particle particle class. Allocates space for + !! all particles and initializes all components with a value. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + !> Call allocation method for parent class + !> The parent class here is the abstract swiftest_body class, so we can't use the type-bound procedure + call setup_body(self, n, param) + if (n <= 0) return + + if (allocated(self%isperi)) deallocate(self%isperi) + if (allocated(self%peri)) deallocate(self%peri) + if (allocated(self%atp)) deallocate(self%atp) + + allocate(self%isperi(n)) + allocate(self%peri(n)) + allocate(self%atp(n)) + + self%isperi(:) = 0 + self%peri(:) = 0.0_DP + self%atp(:) = 0.0_DP + + return + end subroutine setup_tp + +end submodule s_setup diff --git a/src/symba/symba_collision.f90 b/src/symba/symba_collision.f90 new file mode 100644 index 000000000..952d59709 --- /dev/null +++ b/src/symba/symba_collision.f90 @@ -0,0 +1,525 @@ +submodule (symba_classes) s_symba_collision + use swiftest +contains + + module subroutine symba_collision_check_pltpenc(self, system, param, t, dt, irec) + !! author: David A. Minton + !! + !! Check for merger between massive bodies and test particles in SyMBA + !! + !! Adapted from David E. Kaufmann's Swifter routine symba_merge.f90 and symba_merge_tp.f90 + !! + !! Adapted from Hal Levison's Swift routine symba5_merge.f + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! current time + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + ! Internals + logical, dimension(:), allocatable :: lcollision, lmask + real(DP), dimension(NDIM) :: xr, vr + integer(I4B) :: k + real(DP) :: rlim, mtot + logical :: isplpl + + if (self%nenc == 0) return + select type(self) + class is (symba_plplenc) + isplpl = .true. + class default + isplpl = .false. + end select + + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + associate(nenc => self%nenc, ind1 => self%index1, ind2 => self%index2) + allocate(lmask(nenc)) + lmask(:) = ((self%status(1:nenc) == ACTIVE) .and. (pl%levelg(ind1(1:nenc)) >= irec)) + if (isplpl) then + lmask(:) = lmask(:) .and. (pl%levelg(ind2(1:nenc)) >= irec) + else + lmask(:) = lmask(:) .and. (tp%levelg(ind2(1:nenc)) >= irec) + end if + if (.not.any(lmask(:))) return + + allocate(lcollision(nenc)) + lcollision(:) = .false. + + if (isplpl) then + do concurrent(k = 1:nenc, lmask(k)) + xr(:) = pl%xh(:, ind1(k)) - pl%xh(:, ind2(k)) + vr(:) = pl%vb(:, ind1(k)) - pl%vb(:, ind2(k)) + rlim = pl%radius(ind1(k)) + pl%radius(ind2(k)) + mtot = pl%Gmass(ind1(k)) + pl%Gmass(ind2(k)) + lcollision(k) = symba_collision_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), mtot, rlim, dt, self%lvdotr(k)) + end do + else + do concurrent(k = 1:nenc, lmask(k)) + xr(:) = pl%xh(:, ind1(k)) - tp%xh(:, ind2(k)) + vr(:) = pl%vb(:, ind1(k)) - tp%vb(:, ind2(k)) + lcollision(k) = symba_collision_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), pl%Gmass(ind1(k)), pl%radius(ind1(k)), dt, self%lvdotr(k)) + end do + end if + + if (any(lcollision(:))) then + do k = 1, nenc + if (.not.lcollision(k)) cycle + self%status(k) = COLLISION + self%x1(:,k) = pl%xh(:,ind1(k)) + self%v1(:,k) = pl%vb(:,ind1(k)) + if (isplpl) then + self%x2(:,k) = pl%xh(:,ind2(k)) + self%v2(:,k) = pl%vb(:,ind2(k)) + + ! Check to see if either of these bodies has been involved with a collision before, and if so, make this a collisional family + if (pl%lcollision(ind1(k)) .or. pl%lcollision(ind2(k))) call pl%make_family([ind1(k),ind2(k)]) + + ! Set the collision flag for these to bodies to true in case they become involved in another collision later in the step + pl%lcollision([ind1(k), ind2(k)]) = .true. + pl%ldiscard([ind1(k), ind2(k)]) = .true. + pl%status([ind1(k), ind2(k)]) = COLLISION + else + self%x2(:,k) = tp%xh(:,ind2(k)) + self%v2(:,k) = tp%vb(:,ind2(k)) + tp%status(ind2(k)) = DISCARDED_PLR + tp%ldiscard(ind2(k)) = .true. + write(*,*) 'Test particle ',tp%id(ind2(k)), ' collided with massive body ',pl%id(ind1(k)), ' at time ',t + end if + end do + end if + end associate + end select + end select + + return + end subroutine symba_collision_check_pltpenc + + + pure elemental function symba_collision_check_one(xr, yr, zr, vxr, vyr, vzr, Gmtot, rlim, dt, lvdotr) result(lcollision) + !! author: David A. Minton + !! + !! Check for a merger between a single pair of particles + !! + !! Adapted from David E. Kaufmann's Swifter routines symba_merge_tp.f90 and symba_merge_pl.f90 + !! + !! Adapted from Hal Levison's Swift routine symba5_merge.f + implicit none + ! Arguments + real(DP), intent(in) :: xr, yr, zr !! Relative position vector components + real(DP), intent(in) :: vxr, vyr, vzr !! Relative velocity vector components + real(DP), intent(in) :: Gmtot !! Sum of G*mass of colliding bodies + real(DP), intent(in) :: rlim !! Collision limit - Typically the sum of the radii of colliding bodies + real(DP), intent(in) :: dt !! Step size + logical, intent(in) :: lvdotr !! Logical flag indicating that these two bodies are approaching in the current substep + ! Result + logical :: lcollision !! Logical flag indicating whether these two bodies will collide or not + ! Internals + real(DP) :: r2, rlim2, a, e, q, vdotr, tcr2, dt2 + + r2 = xr**2 + yr**2 + zr**2 + rlim2 = rlim**2 + + if (r2 <= rlim2) then ! checks if bodies are actively colliding in this time step + lcollision = .true. + else ! if they are not actively colliding in this time step, checks if they are going to collide next time step based on velocities and q + lcollision = .false. + vdotr = xr * vxr + yr * vyr + zr * vzr + if (lvdotr .and. (vdotr > 0.0_DP)) then + tcr2 = r2 / (vxr**2 + vyr**2 + vzr**2) + dt2 = dt**2 + if (tcr2 <= dt2) then + call orbel_xv2aeq(Gmtot, [xr, yr, zr], [vxr, vyr, vzr], a, e, q) + lcollision = (q < rlim) + end if + end if + end if + + return + end function symba_collision_check_one + + + function symba_collision_consolidate_familes(pl, param, idx_parent, family, x, v, mass, radius, L_spin, Ip) result(lflag) + !! author: David A. Minton + !! + !! Loops through the pl-pl collision list and groups families together by index. Outputs the indices of all family members, + !! and pairs of quantities (x and v vectors, mass, radius, L_spin, and Ip) that can be used to resolve the collisional outcome. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl !! SyMBA massive body object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(2), intent(inout) :: idx_parent !! Index of the two bodies considered the "parents" of the collision + integer(I4B), dimension(:), allocatable, intent(out) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(NDIM,2), intent(out) :: x, v, L_spin, Ip !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(2), intent(out) :: mass, radius !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + ! Result + logical :: lflag !! Logical flag indicating whether a family was successfully created or not + ! Internals + type family_array + integer(I4B), dimension(:), allocatable :: id + integer(I4B), dimension(:), allocatable :: idx + end type family_array + type(family_array), dimension(2) :: parent_child_index_array + integer(I4B), dimension(2) :: nchild + integer(I4B) :: i, j, fam_size, idx_child + real(DP), dimension(2) :: volume, density + real(DP) :: mchild, mtot, volchild + real(DP), dimension(NDIM) :: xc, vc, xcom, vcom, xchild, vchild, xcrossv + + nchild(:) = pl%kin(idx_parent(:))%nchild + ! If all of these bodies share a parent, but this is still a unique collision, move the last child + ! out of the parent's position and make it the secondary body + if (idx_parent(1) == idx_parent(2)) then + if (nchild(1) == 0) then ! There is only one valid body recorded in this pair (this could happen due to restructuring of the kinship relationships, though it should be rare) + lflag = .false. + return + end if + idx_parent(2) = pl%kin(idx_parent(1))%child(nchild(1)) + nchild(1) = nchild(1) - 1 + nchild(2) = 0 + pl%kin(idx_parent(:))%nchild = nchild(:) + pl%kin(idx_parent(2))%parent = idx_parent(1) + end if + + mass(:) = pl%mass(idx_parent(:)) ! Note: This is meant to mass, not G*mass, as the collisional regime determination uses mass values that will be converted to Si + radius(:) = pl%radius(idx_parent(:)) + volume(:) = (4.0_DP / 3.0_DP) * PI * radius(:)**3 + + ! Group together the ids and indexes of each collisional parent and its children + do j = 1, 2 + allocate(parent_child_index_array(j)%idx(nchild(j)+ 1)) + allocate(parent_child_index_array(j)%id(nchild(j)+ 1)) + associate(idx_arr => parent_child_index_array(j)%idx, & + id_arr => parent_child_index_array(j)%id, & + ncj => nchild(j), & + pl => pl, & + plkinj => pl%kin(idx_parent(j))) + idx_arr(1) = idx_parent(j) + if (ncj > 0) idx_arr(2:ncj + 1) = plkinj%child(1:ncj) + id_arr(:) = pl%id(idx_arr(:)) + end associate + end do + + ! Consolidate the groups of collsional parents with any children they may have into a single "family" index array + fam_size = 2 + sum(nchild(:)) + allocate(family(fam_size)) + family = [parent_child_index_array(1)%idx(:),parent_child_index_array(2)%idx(:)] + fam_size = count(pl%lcollision(family(:))) + family = pack(family(:), pl%lcollision(family(:))) + L_spin(:,:) = 0.0_DP + Ip(:,:) = 0.0_DP + + ! Find the barycenter of each body along with its children, if it has any + do j = 1, 2 + x(:, j) = pl%xb(:, idx_parent(j)) + v(:, j) = pl%vb(:, idx_parent(j)) + ! Assume principal axis rotation about axis corresponding to highest moment of inertia (3rd Ip) + if (param%lrotation) then + Ip(:, j) = mass(j) * pl%Ip(:, idx_parent(j)) + L_spin(:, j) = Ip(3, j) * radius(j)**2 * pl%rot(:, idx_parent(j)) + end if + + if (nchild(j) > 0) then + do i = 1, nchild(j) ! Loop over all children and take the mass weighted mean of the properties + idx_child = parent_child_index_array(j)%idx(i + 1) + if (.not. pl%lcollision(idx_child)) cycle + mchild = pl%mass(idx_child) + xchild(:) = pl%xb(:, idx_child) + vchild(:) = pl%vb(:, idx_child) + volchild = (4.0_DP / 3.0_DP) * PI * pl%radius(idx_child)**3 + volume(j) = volume(j) + volchild + ! Get angular momentum of the child-parent pair and add that to the spin + ! Add the child's spin + if (param%lrotation) then + xcom(:) = (mass(j) * x(:,j) + mchild * xchild(:)) / (mass(j) + mchild) + vcom(:) = (mass(j) * v(:,j) + mchild * vchild(:)) / (mass(j) + mchild) + xc(:) = x(:, j) - xcom(:) + vc(:) = v(:, j) - vcom(:) + xcrossv(:) = xc(:) .cross. vc(:) + L_spin(:, j) = L_spin(:, j) + mass(j) * xcrossv(:) + + xc(:) = xchild(:) - xcom(:) + vc(:) = vchild(:) - vcom(:) + xcrossv(:) = xc(:) .cross. vc(:) + L_spin(:, j) = L_spin(:, j) + mchild * xcrossv(:) + + L_spin(:, j) = L_spin(:, j) + mchild * pl%Ip(3, idx_child) * pl%radius(idx_child)**2 * pl%rot(:, idx_child) + Ip(:, j) = Ip(:, j) + mchild * pl%Ip(:, idx_child) + end if + + ! Merge the child and parent + mass(j) = mass(j) + mchild + x(:, j) = xcom(:) + v(:, j) = vcom(:) + end do + end if + density(j) = mass(j) / volume(j) + radius(j) = ((3 * mass(j)) / (density(j) * 4 * pi))**(1.0_DP / 3.0_DP) + if (param%lrotation) Ip(:, j) = Ip(:, j) / mass(j) + end do + lflag = .true. + + return + end function symba_collision_consolidate_familes + + + module subroutine symba_collision_encounter_scrub(self, system, param) + !! author: David A. Minton + !! + !! Processes the pl-pl encounter list remove only those encounters that led to a collision + !! + implicit none + ! Arguments + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + logical, dimension(self%nenc) :: lplpl_collision + logical, dimension(:), allocatable :: lplpl_unique_parent + integer(I4B), dimension(:), pointer :: plparent + integer(I4B), dimension(:), allocatable :: collision_idx, unique_parent_idx + integer(I4B) :: i, index_coll, ncollisions, nunique_parent + type(symba_plplenc) :: plplenc_noncollision + + select type (pl => system%pl) + class is (symba_pl) + associate(plplenc_list => self, nplplenc => self%nenc, idx1 => self%index1, idx2 => self%index2, plparent => pl%kin%parent) + lplpl_collision(:) = plplenc_list%status(1:nplplenc) == COLLISION + if (any(lplpl_collision)) then ! Collisions have been detected in this step. So we need to determine which of them are between unique bodies. + + ! Get the subset of pl-pl encounters that lead to a collision + ncollisions = count(lplpl_collision(:)) + allocate(collision_idx(ncollisions)) + collision_idx = pack([(i, i=1, nplplenc)], lplpl_collision) + + ! Get the subset of collisions that involve a unique pair of parents + allocate(lplpl_unique_parent(ncollisions)) + + lplpl_unique_parent(:) = plparent(idx1(collision_idx(:))) /= plparent(idx2(collision_idx(:))) + nunique_parent = count(lplpl_unique_parent(:)) + allocate(unique_parent_idx(nunique_parent)) + unique_parent_idx = pack(collision_idx(:), lplpl_unique_parent(:)) + + ! Scrub all pl-pl collisions involving unique pairs of parents, which will remove all duplicates and leave behind + ! all pairs that have themselves as parents but are not part of the unique parent list. This can hapepn in rare cases + ! due to restructuring of parent/child relationships when there are large numbers of multi-body collisions in a single + ! step + lplpl_unique_parent(:) = .true. + do index_coll = 1, ncollisions + associate(ip1 => plparent(idx1(collision_idx(index_coll))), ip2 => plparent(idx2(collision_idx(index_coll)))) + lplpl_unique_parent(:) = .not. ( any(plparent(idx1(unique_parent_idx(:))) == ip1) .or. & + any(plparent(idx2(unique_parent_idx(:))) == ip1) .or. & + any(plparent(idx1(unique_parent_idx(:))) == ip2) .or. & + any(plparent(idx2(unique_parent_idx(:))) == ip2) ) + end associate + end do + + ! Reassemble collision index list to include only those containing the unique pairs of parents, plus all the non-unique pairs that don't + ! contain a parent body on the unique parent list. + ncollisions = nunique_parent + count(lplpl_unique_parent) + collision_idx = [unique_parent_idx(:), pack(collision_idx(:), lplpl_unique_parent(:))] + + ! Create a mask that contains only the pl-pl encounters that did not result in a collision, and then discard them + lplpl_collision(:) = .false. + lplpl_collision(collision_idx(:)) = .true. + end if + call plplenc_list%spill(plplenc_noncollision, .not.lplpl_collision, ldestructive=.true.) ! Remove any encounters that are not collisions from the list. + end associate + end select + + return + end subroutine symba_collision_encounter_scrub + + + module subroutine symba_collision_make_family_pl(self, idx) + !! author: Jennifer L.L. Pouplin, Carlisle A. wishard, and David A. Minton + !! + !! When a single body is involved in more than one collision in a single step, it becomes part of a family. + !! The largest body involved in a multi-body collision is the "parent" and all bodies that collide with it are its "children," + !! including those that collide with the children. + !! + !! Adapted from David E. Kaufmann's Swifter routine symba_merge_pl.f90 + !! + !! Adapted from Hal Levison's Swift routine symba5_merge.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), dimension(2), intent(in) :: idx !! Array holding the indices of the two bodies involved in the collision + ! Internals + integer(I4B) :: i, j, index_parent, index_child, p1, p2 + integer(I4B) :: nchild_inherit, nchild_orig, nchild_new + integer(I4B), dimension(:), allocatable :: temp + + associate(pl => self) + p1 = pl%kin(idx(1))%parent + p2 = pl%kin(idx(2))%parent + if (p1 == p2) return ! This is a collision between to children of a shared parent. We will ignore it. + + if (pl%Gmass(p1) > pl%Gmass(p2)) then + index_parent = p1 + index_child = p2 + else + index_parent = p2 + index_child = p1 + end if + + ! Expand the child array (or create it if necessary) and copy over the previous lists of children + nchild_orig = pl%kin(index_parent)%nchild + nchild_inherit = pl%kin(index_child)%nchild + nchild_new = nchild_orig + nchild_inherit + 1 + allocate(temp(nchild_new)) + + if (nchild_orig > 0) temp(1:nchild_orig) = pl%kin(index_parent)%child(1:nchild_orig) + ! Find out if the child body has any children of its own. The new parent wil inherit these children + if (nchild_inherit > 0) then + temp(nchild_orig+1:nchild_orig+nchild_inherit) = pl%kin(index_child)%child(1:nchild_inherit) + do i = 1, nchild_inherit + j = pl%kin(index_child)%child(i) + ! Set the childrens' parent to the new parent + pl%kin(j)%parent = index_parent + end do + end if + if (allocated(pl%kin(index_child)%child)) deallocate(pl%kin(index_child)%child) + pl%kin(index_child)%nchild = 0 + ! Add the new child to its parent + pl%kin(index_child)%parent = index_parent + temp(nchild_new) = index_child + ! Save the new child array to the parent + pl%kin(index_parent)%nchild = nchild_new + call move_alloc(from=temp, to=pl%kin(index_parent)%child) + end associate + + return + end subroutine symba_collision_make_family_pl + + + module subroutine symba_collision_resolve_fragmentations(self, system, param) + !! author: David A. Minton + !! + !! Process list of collisions, determine the collisional regime, and then create fragments. + !! + implicit none + ! Arguments + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + ! Internals + ! Internals + integer(I4B), dimension(:), allocatable :: family !! List of indices of all bodies inovlved in the collision + integer(I4B), dimension(2) :: idx_parent !! Index of the two bodies considered the "parents" of the collision + real(DP), dimension(NDIM,2) :: x, v, L_spin, Ip !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(2) :: mass, radius !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + logical :: lgoodcollision + integer(I4B) :: i, status, jtarg, jproj, regime + real(DP), dimension(2) :: radius_si, mass_si, density_si + real(DP) :: mtiny_si, Mcb_si + real(DP), dimension(NDIM) :: x1_si, v1_si, x2_si, v2_si + real(DP) :: mlr, mslr, mtot, dentot, msys, msys_new, Qloss, impact_parameter + integer(I4B), parameter :: NRES = 3 !! Number of collisional product results + real(DP), dimension(NRES) :: mass_res + + associate(plpl_collisions => self, ncollisions => self%nenc, idx1 => self%index1, idx2 => self%index2, cb => system%cb) + select type(pl => system%pl) + class is (symba_pl) + do i = 1, ncollisions + idx_parent(1) = pl%kin(idx1(i))%parent + idx_parent(2) = pl%kin(idx2(i))%parent + lgoodcollision = symba_collision_consolidate_familes(pl, param, idx_parent, family, x, v, mass, radius, L_spin, Ip) + if (.not. lgoodcollision) cycle + if (any(pl%status(idx_parent(:)) /= COLLISION)) cycle ! One of these two bodies has already been resolved + + ! Convert all quantities to SI units and determine which of the pair is the projectile vs. target before sending them + ! to symba_regime + if (mass(1) > mass(2)) then + jtarg = 1 + jproj = 2 + else + jtarg = 2 + jproj = 1 + end if + mass_si(:) = (mass(:)) * param%MU2KG !! The collective mass of the parent and its children + radius_si(:) = radius(:) * param%DU2M !! The collective radius of the parent and its children + x1_si(:) = plpl_collisions%x1(:,i) * param%DU2M !! The position of the parent from inside the step (at collision) + v1_si(:) = plpl_collisions%v1(:,i) * param%DU2M / param%TU2S !! The velocity of the parent from inside the step (at collision) + x2_si(:) = plpl_collisions%x2(:,i) * param%DU2M !! The position of the parent from inside the step (at collision) + v2_si(:) = plpl_collisions%v2(:,i) * param%DU2M / param%TU2S !! The velocity of the parent from inside the step (at collision) + density_si(:) = mass_si(:) / (4.0_DP / 3._DP * PI * radius_si(:)**3) !! The collective density of the parent and its children + Mcb_si = cb%mass * param%MU2KG + mtiny_si = (param%MTINY / param%GU) * param%MU2KG + + mass_res(:) = 0.0_DP + + mtot = sum(mass_si(:)) + dentot = sum(mass_si(:) * density_si(:)) / mtot + + !! Use the positions and velocities of the parents from indside the step (at collision) to calculate the collisional regime + call fragmentation_regime(Mcb_si, mass_si(jtarg), mass_si(jproj), radius_si(jtarg), radius_si(jproj), x1_si(:), x2_si(:),& + v1_si(:), v2_si(:), density_si(jtarg), density_si(jproj), regime, mlr, mslr, mtiny_si, Qloss) + + mass_res(1) = min(max(mlr, 0.0_DP), mtot) + mass_res(2) = min(max(mslr, 0.0_DP), mtot) + mass_res(3) = min(max(mtot - mlr - mslr, 0.0_DP), mtot) + mass_res(:) = (mass_res(:) / param%MU2KG) * param%GU + Qloss = Qloss * (param%GU / param%MU2KG) * (param%TU2S / param%DU2M)**2 + + select case (regime) + case (COLLRESOLVE_REGIME_DISRUPTION) + status = symba_fragmentation_casedisruption(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) + case (COLLRESOLVE_REGIME_SUPERCATASTROPHIC) + status = symba_fragmentation_casesupercatastrophic(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) + case (COLLRESOLVE_REGIME_HIT_AND_RUN) + status = symba_fragmentation_casehitandrun(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) + case (COLLRESOLVE_REGIME_MERGE, COLLRESOLVE_REGIME_GRAZE_AND_MERGE) + status = symba_fragmentation_casemerge(system, param, family, x, v, mass, radius, L_spin, Ip) + case default + write(*,*) "Error in symba_collision, unrecognized collision regime" + call util_exit(FAILURE) + end select + end do + end select + end associate + + return + end subroutine symba_collision_resolve_fragmentations + + + module subroutine symba_collision_resolve_mergers(self, system, param) + !! author: David A. Minton + !! + !! Process list of collisions and merge colliding bodies together. + !! + implicit none + ! Arguments + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + ! Internals + integer(I4B), dimension(:), allocatable :: family !! List of indices of all bodies inovlved in the collision + integer(I4B), dimension(2) :: idx_parent !! Index of the two bodies considered the "parents" of the collision + real(DP), dimension(NDIM,2) :: x, v, L_spin, Ip !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(2) :: mass, radius !! Output values that represent a 2-body equivalent of a possibly 2+ body collision + logical :: lgoodcollision + integer(I4B) :: i, status + + associate(plpl_collisions => self, ncollisions => self%nenc, idx1 => self%index1, idx2 => self%index2) + select type(pl => system%pl) + class is (symba_pl) + do i = 1, ncollisions + idx_parent(1) = pl%kin(idx1(i))%parent + idx_parent(2) = pl%kin(idx2(i))%parent + lgoodcollision = symba_collision_consolidate_familes(pl, param, idx_parent, family, x, v, mass, radius, L_spin, Ip) + if (.not. lgoodcollision) cycle + if (any(pl%status(idx_parent(:)) /= COLLISION)) cycle ! One of these two bodies has already been resolved + status = symba_fragmentation_casemerge(system, param, family, x, v, mass, radius, L_spin, Ip) + end do + end select + end associate + + return + end subroutine symba_collision_resolve_mergers + +end submodule s_symba_collision \ No newline at end of file diff --git a/src/symba/symba_discard.f90 b/src/symba/symba_discard.f90 new file mode 100644 index 000000000..5f6d3926a --- /dev/null +++ b/src/symba/symba_discard.f90 @@ -0,0 +1,323 @@ +submodule (symba_classes) s_symba_discard + use swiftest +contains + + subroutine symba_discard_cb_pl(pl, system, param) + !! author: David A. Minton + !! + !! Check to see if planets should be discarded based on their positions relative to the central body. + !! If a body gets flagged here when it has also been previously flagged for a collision with another massive body, + !! its collisional status will be revoked. Discards due to colliding with or escaping the central body take precedence + !! over pl-pl collisions + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_sun.f90 + !! Adapted from Hal Levison's Swift routine discard_massive5.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl !! SyMBA massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, j + real(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, rmaxu2 + + associate(npl => pl%nbody, cb => system%cb) + call system%set_msys() + rmin2 = param%rmin**2 + rmax2 = param%rmax*2 + rmaxu2 = param%rmaxu**2 + do i = 1, npl + if (pl%status(i) == ACTIVE) then + rh2 = dot_product(pl%xh(:,i), pl%xh(:,i)) + if ((param%rmax >= 0.0_DP) .and. (rh2 > rmax2)) then + pl%ldiscard(i) = .true. + pl%lcollision(i) = .false. + pl%status(i) = DISCARDED_RMAX + write(*, *) "Massive body ", pl%id(i), " too far from the central body at t = ", param%t + else if ((param%rmin >= 0.0_DP) .and. (rh2 < rmin2)) then + pl%ldiscard(i) = .true. + pl%lcollision(i) = .false. + pl%status(i) = DISCARDED_RMIN + write(*, *) "Massive body ", pl%id(i), " too close to the central body at t = ", param%t + else if (param%rmaxu >= 0.0_DP) then + rb2 = dot_product(pl%xb(:,i), pl%xb(:,i)) + vb2 = dot_product(pl%vb(:,i), pl%vb(:,i)) + energy = 0.5_DP * vb2 - system%Gmtot / sqrt(rb2) + if ((energy > 0.0_DP) .and. (rb2 > rmaxu2)) then + pl%ldiscard(i) = .true. + pl%lcollision(i) = .false. + pl%status(i) = DISCARDED_RMAXU + write(*, *) "Massive body ", pl%id(i), " is unbound and too far from barycenter at t = ", param%t + end if + end if + end if + end do + end associate + + return + end subroutine symba_discard_cb_pl + + + subroutine symba_discard_conserve_mtm(pl, system, param, ipl, lescape_body) + !! author: David A. Minton + !! + !! Conserves system momentum when a body is lost from the system or collides with central body + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl + class(symba_nbody_system), intent(inout) :: system + class(symba_parameters), intent(inout) :: param + integer(I4B), intent(in) :: ipl + logical, intent(in) :: lescape_body + ! Internals + real(DP), dimension(NDIM) :: Lpl, Ltot, Lcb, xcom, vcom + real(DP) :: pe, ke_orbit, ke_spin + integer(I4B) :: i, oldstat + + select type(cb => system%cb) + class is (symba_cb) + + ! Add the potential and kinetic energy of the lost body to the records + pe = -cb%mass * pl%mass(ipl) / norm2(pl%xb(:, ipl) - cb%xb(:)) + ke_orbit = 0.5_DP * pl%mass(ipl) * dot_product(pl%vb(:, ipl), pl%vb(:, ipl)) + if (param%lrotation) then + ke_spin = 0.5_DP * pl%mass(ipl) * pl%radius(ipl)**2 * pl%Ip(3, ipl) * dot_product(pl%rot(:, ipl), pl%rot(:, ipl)) + else + ke_spin = 0.0_DP + end if + + ! Add the pre-collision ke of the central body to the records + ! Add planet mass to central body accumulator + if (lescape_body) then + system%Mescape = system%Mescape + pl%mass(ipl) + do i = 1, pl%nbody + if (i == ipl) cycle + pe = pe - pl%mass(i) * pl%mass(ipl) / norm2(pl%xb(:, ipl) - pl%xb(:, i)) + end do + + Ltot(:) = 0.0_DP + do i = 1, pl%nbody + Lpl(:) = pL%mass(i) * pl%xb(:,i) .cross. pl%vb(:, i) + Ltot(:) = Ltot(:) + Lpl(:) + end do + Ltot(:) = Ltot(:) + cb%mass * cb%xb(:) .cross. cb%vb(:) + call pl%b2h(cb) + oldstat = pl%status(ipl) + pl%status(ipl) = INACTIVE + call pl%h2b(cb) + pl%status(ipl) = oldstat + do i = 1, pl%nbody + if (i == ipl) cycle + Lpl(:) = pl%mass(i) * pl%xb(:,i) .cross. pl%vb(:, i) + Ltot(:) = Ltot(:) - Lpl(:) + end do + Ltot(:) = Ltot(:) - cb%mass * cb%xb(:) .cross. cb%vb(:) + system%Lescape(:) = system%Lescape(:) + Ltot(:) + if (param%lrotation) system%Lescape(:) = system%Lescape + pl%mass(ipl) * pl%radius(ipl)**2 * pl%Ip(3, ipl) * pl%rot(:, ipl) + + else + xcom(:) = (pl%mass(ipl) * pl%xb(:, ipl) + cb%mass * cb%xb(:)) / (cb%mass + pl%mass(ipl)) + vcom(:) = (pl%mass(ipl) * pl%vb(:, ipl) + cb%mass * cb%vb(:)) / (cb%mass + pl%mass(ipl)) + Lpl(:) = (pl%xb(:,ipl) - xcom(:)) .cross. pL%vb(:,ipl) - vcom(:) + if (param%lrotation) Lpl(:) = pl%mass(ipl) * (Lpl(:) + pl%radius(ipl)**2 * pl%Ip(3,ipl) * pl%rot(:, ipl)) + + Lcb(:) = cb%mass * (cb%xb(:) - xcom(:)) .cross. (cb%vb(:) - vcom(:)) + + ke_orbit = ke_orbit + 0.5_DP * cb%mass * dot_product(cb%vb(:), cb%vb(:)) + if (param%lrotation) ke_spin = ke_spin + 0.5_DP * cb%mass * cb%radius**2 * cb%Ip(3) * dot_product(cb%rot(:), cb%rot(:)) + ! Update mass of central body to be consistent with its total mass + cb%dM = cb%dM + pl%mass(ipl) + cb%dR = cb%dR + 1.0_DP / 3.0_DP * (pl%radius(ipl) / cb%radius)**3 - 2.0_DP / 9.0_DP * (pl%radius(ipl) / cb%radius)**6 + cb%mass = cb%M0 + cb%dM + cb%Gmass = param%GU * cb%mass + cb%radius = cb%R0 + cb%dR + param%rmin = cb%radius + ! Add planet angular momentum to central body accumulator + cb%dL(:) = Lpl(:) + Lcb(:) + cb%dL(:) + ! Update rotation of central body to by consistent with its angular momentum + if (param%lrotation) then + cb%rot(:) = (cb%L0(:) + cb%dL(:)) / (cb%Ip(3) * cb%mass * cb%radius**2) + ke_spin = ke_spin - 0.5_DP * cb%mass * cb%radius**2 * cb%Ip(3) * dot_product(cb%rot(:), cb%rot(:)) + end if + cb%xb(:) = xcom(:) + cb%vb(:) = vcom(:) + ke_orbit = ke_orbit - 0.5_DP * cb%mass * dot_product(cb%vb(:), cb%vb(:)) + end if + call pl%b2h(cb) + + ! We must do this for proper book-keeping, since we can no longer track this body's contribution to energy directly + if (lescape_body) then + system%Ecollisions = system%Ecollisions + ke_orbit + ke_spin + pe + system%Euntracked = system%Euntracked - (ke_orbit + ke_spin + pe) + else + system%Ecollisions = system%Ecollisions + pe + system%Euntracked = system%Euntracked - pe + end if + + end select + return + + end subroutine symba_discard_conserve_mtm + + + subroutine symba_discard_nonplpl(pl, system, param) + !! author: David A. Minton + !! + !! Check to see if planets should be discarded based on their positions or because they are unbound + !s + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_pl.f90 + !! Adapted from Hal Levison's Swift routine discard_massive5.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl !! SyMBA test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + + ! First check for collisions with the central body + associate(npl => pl%nbody, cb => system%cb) + if (npl == 0) return + if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. & + (param%rmaxu >= 0.0_DP) .or. ((param%qmin >= 0.0_DP) .and. (param%qmin_coord == "BARY"))) then + call pl%h2b(cb) + end if + if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. (param%rmaxu >= 0.0_DP)) then + call symba_discard_cb_pl(pl, system, param) + end if + if (param%qmin >= 0.0_DP .and. npl > 0) call symba_discard_peri_pl(pl, system, param) + end associate + + return + end subroutine symba_discard_nonplpl + + + subroutine symba_discard_nonplpl_conservation(pl, system, param) + !! author: David A. Minton + !! + !! If there are any bodies that are removed due to either colliding with the central body or escaping the systme, + !! we need to track the conserved quantities with the system bookkeeping terms. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, ndiscard, dstat + logical :: lescape + logical, dimension(pl%nbody) :: discard_l_pl + integer(I4B), dimension(:), allocatable :: discard_index_list + + associate(npl => pl%nbody) + discard_l_pl(1:npl) = pl%ldiscard(1:npl) .and. .not. pl%lcollision(1:npl) ! These are bodies that are discarded but not flagged as pl-pl collision + ndiscard = count(discard_l_pl(:)) + allocate(discard_index_list(ndiscard)) + discard_index_list(:) = pack([(i, i = 1, npl)], discard_l_pl(1:npl)) + do i = 1, ndiscard + dstat = pl%status(discard_index_list(i)) + if ((dstat == DISCARDED_RMIN) .or. (dstat == DISCARDED_PERI)) then + lescape = .false. + else if ((dstat == DISCARDED_RMAX) .or. (dstat == DISCARDED_RMAXU)) then + lescape = .true. + else + cycle + end if + ! Conserve all the quantities + call symba_discard_conserve_mtm(pl, system, param, discard_index_list(i), lescape) + end do + end associate + + return + end subroutine symba_discard_nonplpl_conservation + + + subroutine symba_discard_peri_pl(pl, system, param) + !! author: David A. Minton + !! + !! Check to see if a test particle should be discarded because its perihelion distance becomes too small + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_discard_peri_pl.f90 + !! Adapted from Hal Levison's Swift routine discard_mass_peri.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: pl !! SyMBA massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + logical, save :: lfirst = .true. + logical :: lfirst_orig + integer(I4B) :: i + + + lfirst_orig = pl%lfirst + pl%lfirst = lfirst + if (lfirst) then + call pl%get_peri(system, param) + lfirst = .false. + else + call pl%get_peri(system, param) + do i = 1, pl%nbody + if (pl%status(i) == ACTIVE) then + if ((pl%isperi(i) == 0) .and. (pl%nplenc(i)== 0)) then + if ((pl%atp(i) >= param%qmin_alo) .and. (pl%atp(i) <= param%qmin_ahi) .and. (pl%peri(i) <= param%qmin)) then + pl%ldiscard(i) = .true. + pl%lcollision(i) = .false. + pl%status(i) = DISCARDED_PERI + write(*, *) "Particle ", pl%id(i), " perihelion distance too small at t = ", param%t + end if + end if + end if + end do + end if + pl%lfirst = lfirst_orig + + return + + end subroutine symba_discard_peri_pl + + + module subroutine symba_discard_pl(self, system, param) + !! author: David A. Minton + !! + !! Call the various flavors of discards for massive bodies in SyMBA runs, including discards due to colling with the central body, + !! escaping the system, or colliding with each other. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + + select type(system) + class is (symba_nbody_system) + select type(param) + class is (symba_parameters) + associate(pl => self, plplenc_list => system%plplenc_list) + call pl%h2b(system%cb) + + ! First deal with the non pl-pl collisions + call symba_discard_nonplpl(self, system, param) + + ! Scrub the pl-pl encounter list of any encounters that did not lead to a collision + call plplenc_list%scrub_non_collision(system, param) + + if ((plplenc_list%nenc > 0) .and. any(pl%lcollision(:))) then + write(*, *) "Collision between massive bodies detected at time t = ",param%t + if (param%lfragmentation) then + call plplenc_list%resolve_fragmentations(system, param) + else + call plplenc_list%resolve_mergers(system, param) + end if + end if + + if (any(pl%ldiscard(:))) then + call symba_discard_nonplpl_conservation(self, system, param) + call pl%rearray(system, param) + end if + + end associate + end select + end select + + return + end subroutine symba_discard_pl + +end submodule s_symba_discard \ No newline at end of file diff --git a/src/symba/symba_drift.f90 b/src/symba/symba_drift.f90 new file mode 100644 index 000000000..c4efee05f --- /dev/null +++ b/src/symba/symba_drift.f90 @@ -0,0 +1,52 @@ + submodule (symba_classes) s_symba_drift + use swiftest +contains + + module subroutine symba_drift_pl(self, system, param, dt) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a symba_pl structure + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + + if (self%nbody == 0) return + + select type(system) + class is (symba_nbody_system) + self%lmask(:) = self%status(:) /= INACTIVE .and. self%levelg(:) == system%irec + call helio_drift_body(self, system, param, dt) + self%lmask(:) = self%status(:) /= INACTIVE + end select + + return + end subroutine symba_drift_pl + + + module subroutine symba_drift_tp(self, system, param, dt) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a symba_pl structure + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + + if (self%nbody == 0) return + + select type(system) + class is (symba_nbody_system) + self%lmask(:) = self%status(:) /= INACTIVE .and. self%levelg(:) == system%irec + call helio_drift_body(self, system, param, dt) + self%lmask(:) = self%status(:) /= INACTIVE + end select + + return + end subroutine symba_drift_tp + +end submodule s_symba_drift diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 new file mode 100644 index 000000000..808ee2347 --- /dev/null +++ b/src/symba/symba_encounter_check.f90 @@ -0,0 +1,223 @@ +submodule (symba_classes) s_symba_encounter_check + use swiftest +contains + + module function symba_encounter_check_pl(self, system, dt, irec) result(lany_encounter) + !! author: David A. Minton + !! + !! Check for an encounter between massive bodies. + !! + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + ! Result + logical :: lany_encounter !! Returns true if there is at least one close encounter + ! Internals + integer(I8B) :: k + integer(I4B) :: nenc + real(DP), dimension(NDIM) :: xr, vr + logical, dimension(:), allocatable :: lencounter, loc_lvdotr + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody, nplpl => self%nplpl) + allocate(lencounter(nplpl), loc_lvdotr(nplpl)) + lencounter(:) = .false. + + do k = 1, nplpl + associate(i => pl%k_plpl(1, k), j => pl%k_plpl(2, k)) + xr(:) = pl%xh(:, j) - pl%xh(:, i) + vr(:) = pl%vh(:, j) - pl%vh(:, i) + call symba_encounter_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), pl%rhill(i), pl%rhill(j), dt, irec, lencounter(k), loc_lvdotr(k)) + end associate + end do + + nenc = count(lencounter(:)) + lany_encounter = nenc > 0 + if (lany_encounter) then + associate(plplenc_list => system%plplenc_list) + call plplenc_list%resize(nenc) + plplenc_list%lvdotr(1:nenc) = pack(loc_lvdotr(:), lencounter(:)) + plplenc_list%index1(1:nenc) = pack(pl%k_plpl(1,:), lencounter(:)) + plplenc_list%index2(1:nenc) = pack(pl%k_plpl(2,:), lencounter(:)) + do k = 1, nenc + plplenc_list%status(k) = ACTIVE + plplenc_list%level(k) = irec + pl%lencounter(plplenc_list%index1(k)) = .true. + pl%lencounter(plplenc_list%index2(k)) = .true. + end do + end associate + end if + end associate + return + end function symba_encounter_check_pl + + + module function symba_encounter_check_pltpenc(self, system, dt, irec) result(lany_encounter) + !! author: David A. Minton + !! + !! Check for an encounter between test particles and massive bodies in the pltpenc list. + !! Note: This method works for the polymorphic symba_pltpenc and symba_plplenc types. + !! + !! Adapted from portions of David E. Kaufmann's Swifter routine: symba_step_recur.f90 + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-pl encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + logical :: lany_encounter !! Returns true if there is at least one close encounter + ! Internals + integer(I4B) :: k + real(DP), dimension(NDIM) :: xr, vr + logical :: lencounter, isplpl + real(DP) :: rlim2, rji2 + logical, dimension(:), allocatable :: lencmask + + lany_encounter = .false. + if (self%nenc == 0) return + + select type(self) + class is (symba_plplenc) + isplpl = .true. + class is (symba_pltpenc) + isplpl = .false. + end select + + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + allocate(lencmask(self%nenc)) + lencmask(:) = (self%status(1:self%nenc) == ACTIVE) .and. (self%level(1:self%nenc) == irec - 1) + if (.not.any(lencmask(:))) return + associate(ind1 => self%index1, ind2 => self%index2) + do concurrent(k = 1:self%nenc, lencmask(k)) + if (isplpl) then + xr(:) = pl%xh(:,ind2(k)) - pl%xh(:,ind1(k)) + vr(:) = pl%vb(:,ind2(k)) - pl%vb(:,ind1(k)) + call symba_encounter_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), pl%rhill(ind1(k)), pl%rhill(ind2(k)), dt, irec, lencounter, self%lvdotr(k)) + else + xr(:) = tp%xh(:,ind2(k)) - pl%xh(:,ind1(k)) + vr(:) = tp%vb(:,ind2(k)) - pl%vb(:,ind1(k)) + call symba_encounter_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), pl%rhill(ind1(k)), 0.0_DP, dt, irec, lencounter, self%lvdotr(k)) + end if + if (lencounter) then + if (isplpl) then + rlim2 = (pl%radius(ind1(k)) + pl%radius(ind2(k)))**2 + else + rlim2 = (pl%radius(ind1(k)))**2 + end if + rji2 = dot_product(xr(:), xr(:))! Check to see if these are physically overlapping bodies first, which we should ignore + if (rji2 > rlim2) then + lany_encounter = .true. + pl%levelg(ind1(k)) = irec + pl%levelm(ind1(k)) = MAX(irec, pl%levelm(ind1(k))) + if (isplpl) then + pl%levelg(ind2(k)) = irec + pl%levelm(ind2(k)) = MAX(irec, pl%levelm(ind2(k))) + else + tp%levelg(ind2(k)) = irec + tp%levelm(ind2(k)) = MAX(irec, tp%levelm(ind2(k))) + end if + self%level(k) = irec + end if + end if + end do + end associate + end select + end select + + return + end function symba_encounter_check_pltpenc + + + module function symba_encounter_check_tp(self, system, dt, irec) result(lany_encounter) + !! author: David A. Minton + !! + !! Check for an encounter between test particles and massive bodies. + !! + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + ! Result + logical :: lany_encounter !! Returns true if there is at least one close encounter + ! Internals + real(DP) :: r2crit, vdotr, r2, v2, tmin, r2min, term2 + integer(I4B) :: i, j, k,nenc + real(DP), dimension(NDIM) :: xr, vr + logical, dimension(:,:), allocatable :: lencounter, loc_lvdotr + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody, pl => system%pl, npl => system%pl%nbody) + allocate(lencounter(ntp, npl), loc_lvdotr(ntp, npl)) + lencounter(:,:) = .false. + + do j = 1, npl + do i = 1, ntp + xr(:) = tp%xh(:, i) - pl%xh(:, j) + vr(:) = tp%vh(:, i) - pl%vh(:, j) + call symba_encounter_check_one(xr(1), xr(2), xr(3), vr(1), vr(2), vr(3), pl%rhill(j), 0.0_DP, dt, irec, lencounter(i,j), loc_lvdotr(i,j)) + end do + end do + + nenc = count(lencounter(:,:)) + lany_encounter = nenc > 0 + if (lany_encounter) then + associate(pltpenc_list => system%pltpenc_list) + call pltpenc_list%resize(nenc) + pltpenc_list%status(1:nenc) = ACTIVE + pltpenc_list%level(1:nenc) = irec + pltpenc_list%lvdotr(1:nenc) = pack(loc_lvdotr(:,:), lencounter(:,:)) + pltpenc_list%index1(1:nenc) = pack(spread([(i, i = 1, npl)], dim=1, ncopies=ntp), lencounter(:,:)) + pltpenc_list%index2(1:nenc) = pack(spread([(i, i = 1, ntp)], dim=2, ncopies=npl), lencounter(:,:)) + select type(pl) + class is (symba_pl) + pl%lencounter(:) = .false. + do k = 1, nenc + pl%lencounter(pltpenc_list%index1(k)) = .true. + end do + end select + end associate + end if + end associate + + return + end function symba_encounter_check_tp + + + module pure elemental subroutine symba_encounter_check_one(xr, yr, zr, vxr, vyr, vzr, rhill1, rhill2, dt, irec, lencounter, lvdotr) + !! author: David A. Minton + !! + !! Check for an encounter. + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_chk.f90 + !! Adapted from Hal Levison's Swift routine symba5_chk.f + implicit none + ! Arguments + real(DP), intent(in) :: xr, yr, zr, vxr, vyr, vzr + real(DP), intent(in) :: rhill1, rhill2, dt + integer(I4B), intent(in) :: irec + logical, intent(out) :: lencounter, lvdotr + ! Internals + real(DP) :: r2, v2, rcrit, r2crit, vdotr + + rcrit = (rhill1 + rhill2)*RHSCALE*(RSHELL**(irec)) + r2crit = rcrit**2 + r2 = xr**2 + yr**2 + zr**2 + v2 = vxr**2 + vyr**2 + vzr**2 + vdotr = xr * vxr + yr * vyr + zr * vzr + lencounter = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) + lvdotr = (vdotr < 0.0_DP) + + return + end subroutine symba_encounter_check_one + +end submodule s_symba_encounter_check \ No newline at end of file diff --git a/src/symba/symba_fragmentation.f90 b/src/symba/symba_fragmentation.f90 new file mode 100644 index 000000000..efdd8c0d7 --- /dev/null +++ b/src/symba/symba_fragmentation.f90 @@ -0,0 +1,581 @@ +submodule (symba_classes) s_symba_fragmentation + use swiftest + + integer(I4B), parameter :: NFRAG_DISRUPT = 12 + integer(I4B), parameter :: NFRAG_SUPERCAT = 20 +contains + + module function symba_fragmentation_casedisruption(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Create the fragments resulting from a non-catastrophic disruption collision + !! + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collision + ! Result + integer(I4B) :: status !! Status flag assigned to this outcome + ! Internals + integer(I4B) :: i, istart, nfrag, ibiggest, nfamily, nstart, nend + real(DP) :: mtot, avg_dens + real(DP), dimension(NDIM) :: xcom, vcom, Ip_new + real(DP), dimension(2) :: vol + real(DP), dimension(:, :), allocatable :: vb_frag, xb_frag, rot_frag, Ip_frag + real(DP), dimension(:), allocatable :: m_frag, rad_frag + logical :: lfailure + logical, dimension(system%pl%nbody) :: lmask + class(symba_pl), allocatable :: plnew + + select type(pl => system%pl) + class is (symba_pl) + associate(mergeadd_list => system%mergeadd_list, mergesub_list => system%mergesub_list, cb => system%cb) + ! Collisional fragments will be uniformly distributed around the pre-impact barycenter + nfrag = NFRAG_DISRUPT + allocate(m_frag(nfrag)) + allocate(rad_frag(nfrag)) + allocate(xb_frag(NDIM, nfrag)) + allocate(vb_frag(NDIM, nfrag)) + allocate(rot_frag(NDIM, nfrag)) + allocate(Ip_frag(NDIM, nfrag)) + + mtot = sum(mass(:)) + xcom(:) = (mass(1) * x(:,1) + mass(2) * x(:,2)) / mtot + vcom(:) = (mass(1) * v(:,1) + mass(2) * v(:,2)) / mtot + + ! Get mass weighted mean of Ip and average density + Ip_new(:) = (mass(1) * Ip(:,1) + mass(2) * Ip(:,2)) / mtot + vol(:) = 4._DP / 3._DP * PI * radius(:)**3 + avg_dens = mtot / sum(vol(:)) + + ! Distribute the mass among fragments, with a branch to check for the size of the second largest fragment + m_frag(1) = mass_res(1) + if (mass_res(2) > mass_res(1) / 3._DP) then + m_frag(2) = mass_res(2) + istart = 3 + else + istart = 2 + end if + ! Distribute remaining mass among the remaining bodies + do i = istart, nfrag + m_frag(i) = (mtot - sum(m_frag(1:istart - 1))) / (nfrag - istart + 1) + end do + + ! Distribute any residual mass if there is any and set the radius + m_frag(nfrag) = m_frag(nfrag) + (mtot - sum(m_frag(:))) + rad_frag(:) = (3 * m_frag(:) / (4 * PI * avg_dens))**(1.0_DP / 3.0_DP) + + do i = 1, nfrag + Ip_frag(:, i) = Ip_new(:) + end do + + call fragmentation_initialize(system, param, family, x, v, L_spin, Ip, mass, radius, & + nfrag, Ip_frag, m_frag, rad_frag, xb_frag, vb_frag, rot_frag, Qloss, lfailure) + + if (lfailure) then + write(*,*) 'No fragment solution found, so treat as a pure hit-and-run' + status = ACTIVE + nfrag = 0 + else + ! Populate the list of new bodies + write(*,'("Generating ",I2.0," fragments")') nfrag + status = DISRUPTION + + ! Add the family bodies to the subtraction list + nfamily = size(family(:)) + lmask(:) = .false. + lmask(family(:)) = .true. + pl%status(family(:)) = MERGED + nstart = mergesub_list%nbody + 1 + nend = mergesub_list%nbody + nfamily + call mergesub_list%append(pl, lmask) + ! Record how many bodies were subtracted in this event + mergesub_list%ncomp(nstart:nend) = nfamily + + allocate(plnew, mold=pl) + call plnew%setup(nfrag, param) + + plnew%id(:) = [(i, i = system%maxid + 1, system%maxid + nfrag)] + system%maxid = system%maxid + nfrag + plnew%status(:) = ACTIVE + plnew%lcollision(:) = .false. + plnew%ldiscard(:) = .false. + plnew%xb(:,:) = xb_frag(:, :) + plnew%vb(:,:) = vb_frag(:, :) + do i = 1, nfrag + plnew%xh(:,i) = xb_frag(:, i) - cb%xb(:) + plnew%vh(:,i) = vb_frag(:, i) - cb%vb(:) + end do + plnew%mass(:) = m_frag(:) + plnew%Gmass(:) = param%GU * m_frag(:) + plnew%density(:) = avg_dens + plnew%radius(:) = rad_frag(:) + plnew%info(:)%origin_type = "Disruption" + plnew%info(:)%origin_time = param%t + do i = 1, nfrag + plnew%info(i)%origin_xh(:) = plnew%xh(:,i) + plnew%info(i)%origin_vh(:) = plnew%vh(:,i) + end do + if (param%lrotation) then + plnew%Ip(:,:) = Ip_frag(:,:) + plnew%rot(:,:) = rot_frag(:,:) + end if + if (param%ltides) then + ibiggest = maxloc(pl%Gmass(family(:)), dim=1) + plnew%Q = pl%Q(ibiggest) + plnew%k2 = pl%k2(ibiggest) + plnew%tlag = pl%tlag(ibiggest) + end if + + ! Append the new merged body to the list and record how many we made + nstart = mergeadd_list%nbody + 1 + nend = mergeadd_list%nbody + plnew%nbody + call mergeadd_list%append(plnew) + mergeadd_list%ncomp(nstart:nend) = plnew%nbody + + call plnew%setup(0, param) + deallocate(plnew) + end if + + end associate + end select + + return + end function symba_fragmentation_casedisruption + + + module function symba_fragmentation_casehitandrun(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Create the fragments resulting from a non-catastrophic hit-and-run collision + !! + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collision + ! Result + integer(I4B) :: status !! Status flag assigned to this outcome + ! Internals + integer(I4B) :: i, nfrag, jproj, jtarg, idstart, ibiggest, nfamily, nstart, nend + real(DP) :: mtot, avg_dens + real(DP), dimension(NDIM) :: xcom, vcom + real(DP), dimension(2) :: vol + real(DP), dimension(:, :), allocatable :: vb_frag, xb_frag, rot_frag, Ip_frag + real(DP), dimension(:), allocatable :: m_frag, rad_frag + integer(I4B), dimension(:), allocatable :: id_frag + logical :: lpure + logical, dimension(system%pl%nbody) :: lmask + class(symba_pl), allocatable :: plnew + + select type(pl => system%pl) + class is (symba_pl) + associate(mergeadd_list => system%mergeadd_list, mergesub_list => system%mergesub_list, cb => system%cb) + mtot = sum(mass(:)) + xcom(:) = (mass(1) * x(:,1) + mass(2) * x(:,2)) / mtot + vcom(:) = (mass(1) * v(:,1) + mass(2) * v(:,2)) / mtot + lpure = .false. + + ! The largest body will stay untouched + if (mass(1) > mass(2)) then + jtarg = 1 + jproj = 2 + else + jtarg = 2 + jproj = 1 + end if + + if (mass_res(2) > 0.9_DP * mass(jproj)) then ! Pure hit and run, so we'll just keep the two bodies untouched + write(*,*) 'Pure hit and run. No new fragments generated.' + nfrag = 0 + lpure = .true. + else ! Imperfect hit and run, so we'll keep the largest body and destroy the other + nfrag = NFRAG_DISRUPT - 1 + lpure = .false. + allocate(m_frag(nfrag)) + allocate(id_frag(nfrag)) + allocate(rad_frag(nfrag)) + allocate(xb_frag(NDIM, nfrag)) + allocate(vb_frag(NDIM, nfrag)) + allocate(rot_frag(NDIM, nfrag)) + allocate(Ip_frag(NDIM, nfrag)) + m_frag(1) = mass(jtarg) + ibiggest = maxloc(pl%Gmass(family(:)), dim=1) + id_frag(1) = pl%id(ibiggest) + rad_frag(1) = radius(jtarg) + xb_frag(:, 1) = x(:, jtarg) + vb_frag(:, 1) = v(:, jtarg) + Ip_frag(:,1) = Ip(:, jtarg) + + ! Get mass weighted mean of Ip and average density + vol(:) = 4._DP / 3._DP * pi * radius(:)**3 + avg_dens = mass(jproj) / vol(jproj) + m_frag(2:nfrag) = (mtot - m_frag(1)) / (nfrag - 1) + rad_frag(2:nfrag) = (3 * m_frag(2:nfrag) / (4 * PI * avg_dens))**(1.0_DP / 3.0_DP) + m_frag(nfrag) = m_frag(nfrag) + (mtot - sum(m_frag(:))) + + do i = 1, nfrag + Ip_frag(:, i) = Ip(:, jproj) + end do + + ! Put the fragments on the circle surrounding the center of mass of the system + call fragmentation_initialize(system, param, family, x, v, L_spin, Ip, mass, radius, & + nfrag, Ip_frag, m_frag, rad_frag, xb_frag, vb_frag, rot_frag, Qloss, lpure) + if (lpure) then + write(*,*) 'Should have been a pure hit and run instead' + nfrag = 0 + else + write(*,'("Generating ",I2.0," fragments")') nfrag + end if + end if + if (lpure) then + status = ACTIVE + else + status = HIT_AND_RUN + + ! Add the family bodies to the subtraction list + nfamily = size(family(:)) + lmask(:) = .false. + lmask(family(:)) = .true. + pl%status(family(:)) = MERGED + nstart = mergesub_list%nbody + 1 + nend = mergesub_list%nbody + nfamily + call mergesub_list%append(pl, lmask) + ! Record how many bodies were subtracted in this event + mergesub_list%ncomp(nstart:nend) = nfamily + + allocate(plnew, mold=pl) + call plnew%setup(nfrag, param) + + plnew%id(:) = [(i, i = system%maxid + 1, system%maxid + nfrag)] + system%maxid = system%maxid + nfrag + plnew%status(:) = ACTIVE + plnew%lcollision(:) = .false. + plnew%ldiscard(:) = .false. + plnew%xb(:,:) = xb_frag(:, :) + plnew%vb(:,:) = vb_frag(:, :) + do i = 1, nfrag + plnew%xh(:,i) = xb_frag(:, i) - cb%xb(:) + plnew%vh(:,i) = vb_frag(:, i) - cb%vb(:) + end do + plnew%mass(:) = m_frag(:) + plnew%Gmass(:) = param%GU * m_frag(:) + plnew%density(:) = avg_dens + plnew%radius(:) = rad_frag(:) + plnew%info(:)%origin_type = "Hit and run fragment" + plnew%info(:)%origin_time = param%t + do i = 1, nfrag + plnew%info(i)%origin_xh(:) = plnew%xh(:,i) + plnew%info(i)%origin_vh(:) = plnew%vh(:,i) + end do + if (param%lrotation) then + plnew%Ip(:,:) = Ip_frag(:,:) + plnew%rot(:,:) = rot_frag(:,:) + end if + if (param%ltides) then + ibiggest = maxloc(pl%Gmass(family(:)), dim=1) + plnew%Q = pl%Q(ibiggest) + plnew%k2 = pl%k2(ibiggest) + plnew%tlag = pl%tlag(ibiggest) + end if + + ! Append the new merged body to the list and record how many we made + nstart = mergeadd_list%nbody + 1 + nend = mergeadd_list%nbody + plnew%nbody + call mergeadd_list%append(plnew) + mergeadd_list%ncomp(nstart:nend) = plnew%nbody + + call plnew%setup(0, param) + deallocate(plnew) + + end if + end associate + end select + + return + end function symba_fragmentation_casehitandrun + + + module function symba_fragmentation_casemerge(system, param, family, x, v, mass, radius, L_spin, Ip) result(status) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Merge planets. + !! + !! Adapted from David E. Kaufmann's Swifter routines symba_merge_pl.f90 and symba_discard_merge_pl.f90 + !! + !! Adapted from Hal Levison's Swift routines symba5_merge.f and discard_mass_merge.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(in) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(in) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + ! Result + integer(I4B) :: status !! Status flag assigned to this outcome + ! Internals + integer(I4B) :: i, j, ibiggest, nfamily, nstart, nend + real(DP) :: mass_new, radius_new, volume_new, pe + real(DP), dimension(NDIM) :: xcom, vcom, xc, vc, xcrossv + real(DP), dimension(2) :: vol + real(DP), dimension(NDIM) :: L_orb_old, L_spin_old + real(DP), dimension(NDIM) :: L_spin_new, rot_new, Ip_new + logical, dimension(system%pl%nbody) :: lmask + class(symba_pl), allocatable :: plnew + + select type(pl => system%pl) + class is (symba_pl) + associate(mergeadd_list => system%mergeadd_list, mergesub_list => system%mergesub_list, cb => system%cb) + status = MERGED + write(*, '("Merging bodies ",99(I8,",",:))') pl%id(family(:)) + mass_new = sum(mass(:)) + + ! Merged body is created at the barycenter of the original bodies + xcom(:) = (mass(1) * x(:,1) + mass(2) * x(:,2)) / mass_new + vcom(:) = (mass(1) * v(:,1) + mass(2) * v(:,2)) / mass_new + + ! Get mass weighted mean of Ip and + vol(:) = 4._DP / 3._DP * PI * radius(:)**3 + volume_new = sum(vol(:)) + radius_new = (3 * volume_new / (4 * PI))**(1._DP / 3._DP) + + L_orb_old(:) = 0.0_DP + + ! Compute orbital angular momentum of pre-impact system + do i = 1, 2 + xc(:) = x(:, i) - xcom(:) + vc(:) = v(:, i) - vcom(:) + xcrossv(:) = xc(:) .cross. vc(:) + L_orb_old(:) = L_orb_old(:) + mass(i) * xcrossv(:) + end do + + if (param%lrotation) then + Ip_new(:) = (mass(1) * Ip(:,1) + mass(2) * Ip(:,2)) / mass_new + L_spin_old(:) = L_spin(:,1) + L_spin(:,2) + + ! Conserve angular momentum by putting pre-impact orbital momentum into spin of the new body + L_spin_new(:) = L_orb_old(:) + L_spin_old(:) + + ! Assume prinicpal axis rotation on 3rd Ip axis + rot_new(:) = L_spin_new(:) / (Ip_new(3) * mass_new * radius_new**2) + else ! If spin is not enabled, we will consider the lost pre-collision angular momentum as "escaped" and add it to our bookkeeping variable + system%Lescape(:) = system%Lescape(:) + L_orb_old(:) + end if + + ! Keep track of the component of potential energy due to the pre-impact family for book-keeping + nfamily = size(family(:)) + pe = 0.0_DP + do j = 1, nfamily + do i = j + 1, nfamily + pe = pe - pl%mass(i) * pl%mass(j) / norm2(pl%xb(:, i) - pl%xb(:, j)) + end do + end do + system%Ecollisions = system%Ecollisions + pe + system%Euntracked = system%Euntracked - pe + + ! Add the family bodies to the subtraction list + lmask(:) = .false. + lmask(family(:)) = .true. + pl%status(family(:)) = MERGED + nstart = mergesub_list%nbody + 1 + nend = mergesub_list%nbody + nfamily + call mergesub_list%append(pl, lmask) + ! Record how many bodies were subtracted in this event + mergesub_list%ncomp(nstart:nend) = nfamily + + ! Create the new merged body + allocate(plnew, mold=pl) + call plnew%setup(1, param) + + ! The merged body's name will be that of the largest of the two parents + ibiggest = maxloc(pl%Gmass(family(:)), dim=1) + plnew%id(1) = pl%id(family(ibiggest)) + plnew%status(1) = ACTIVE + plnew%lcollision = .false. + plnew%ldiscard = .false. + plnew%xb(:,1) = xcom(:) + plnew%vb(:,1) = vcom(:) + plnew%xh(:,1) = xcom(:) - cb%xb(:) + plnew%vh(:,1) = vcom(:) - cb%vb(:) + plnew%mass(1) = mass_new + plnew%Gmass(1) = param%GU * mass_new + plnew%density(1) = mass_new / volume_new + plnew%radius(1) = radius_new + plnew%info(1) = pl%info(family(ibiggest)) + if (param%lrotation) then + plnew%Ip(:,1) = Ip_new(:) + plnew%rot(:,1) = rot_new(:) + end if + if (param%ltides) then + plnew%Q = pl%Q(ibiggest) + plnew%k2 = pl%k2(ibiggest) + plnew%tlag = pl%tlag(ibiggest) + end if + + ! Append the new merged body to the list and record how many we made + nstart = mergeadd_list%nbody + 1 + nend = mergeadd_list%nbody + plnew%nbody + call mergeadd_list%append(plnew) + mergeadd_list%ncomp(nstart:nend) = plnew%nbody + + call plnew%setup(0, param) + deallocate(plnew) + + end associate + end select + + return + + end function symba_fragmentation_casemerge + + + module function symba_fragmentation_casesupercatastrophic(system, param, family, x, v, mass, radius, L_spin, Ip, mass_res, Qloss) result(status) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Create the fragments resulting from a supercatastrophic collision + !! + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters with SyMBA additions + integer(I4B), dimension(:), intent(in) :: family !! List of indices of all bodies inovlved in the collision + real(DP), dimension(:,:), intent(inout) :: x, v, L_spin, Ip !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass, radius !! Input values that represent a 2-body equivalent of a possibly 2+ body collision + real(DP), dimension(:), intent(inout) :: mass_res !! The distribution of fragment mass obtained by the regime calculation + real(DP), intent(inout) :: Qloss !! Energy lost during collision + ! Result + integer(I4B) :: status !! Status flag assigned to this outcome + ! Internals + integer(I4B) :: i, nfrag, ibiggest, nfamily, nstart, nend + real(DP) :: mtot, avg_dens, min_frag_mass + real(DP), dimension(NDIM) :: xcom, vcom + real(DP), dimension(2) :: vol + real(DP), dimension(NDIM) :: Ip_new + real(DP), dimension(:, :), allocatable :: vb_frag, xb_frag, rot_frag, Ip_frag + real(DP), dimension(:), allocatable :: m_frag, rad_frag + logical :: lfailure + logical, dimension(system%pl%nbody) :: lmask + class(symba_pl), allocatable :: plnew + + select type(pl => system%pl) + class is (symba_pl) + associate(mergeadd_list => system%mergeadd_list, mergesub_list => system%mergesub_list, cb => system%cb) + ! Collisional fragments will be uniformly distributed around the pre-impact barycenter + nfrag = NFRAG_SUPERCAT + allocate(m_frag(nfrag)) + allocate(rad_frag(nfrag)) + allocate(xb_frag(NDIM, nfrag)) + allocate(vb_frag(NDIM, nfrag)) + allocate(rot_frag(NDIM, nfrag)) + allocate(Ip_frag(NDIM, nfrag)) + + mtot = sum(mass(:)) + xcom(:) = (mass(1) * x(:,1) + mass(2) * x(:,2)) / mtot + vcom(:) = (mass(1) * v(:,1) + mass(2) * v(:,2)) / mtot + + ! Get mass weighted mean of Ip and average density + Ip_new(:) = (mass(1) * Ip(:,1) + mass(2) * Ip(:,2)) / mtot + vol(:) = 4._DP / 3._DP * pi * radius(:)**3 + avg_dens = mtot / sum(vol(:)) + + ! If we are adding the first and largest fragment (lr), check to see if its mass is SMALLER than an equal distribution of + ! mass between all fragments. If so, we will just distribute the mass equally between the fragments + min_frag_mass = mtot / nfrag + if (mass_res(1) < min_frag_mass) then + m_frag(:) = min_frag_mass + else + m_frag(1) = mass_res(1) + m_frag(2:nfrag) = (mtot - mass_res(1)) / (nfrag - 1) + end if + ! Distribute any residual mass if there is any and set the radius + m_frag(nfrag) = m_frag(nfrag) + (mtot - sum(m_frag(:))) + rad_frag(:) = (3 * m_frag(:) / (4 * PI * avg_dens))**(1.0_DP / 3.0_DP) + + do i = 1, nfrag + Ip_frag(:, i) = Ip_new(:) + end do + + call fragmentation_initialize(system, param, family, x, v, L_spin, Ip, mass, radius, & + nfrag, Ip_frag, m_frag, rad_frag, xb_frag, vb_frag, rot_frag, Qloss, lfailure) + + if (lfailure) then + write(*,*) 'No fragment solution found, so treat as a pure hit-and-run' + status = ACTIVE + nfrag = 0 + else + ! Populate the list of new bodies + write(*,'("Generating ",I2.0," fragments")') nfrag + status = SUPERCATASTROPHIC + + ! Add the family bodies to the subtraction list + nfamily = size(family(:)) + lmask(:) = .false. + lmask(family(:)) = .true. + pl%status(family(:)) = MERGED + nstart = mergesub_list%nbody + 1 + nend = mergesub_list%nbody + nfamily + call mergesub_list%append(pl, lmask) + ! Record how many bodies were subtracted in this event + mergesub_list%ncomp(nstart:nend) = nfamily + + allocate(plnew, mold=pl) + call plnew%setup(nfrag, param) + + plnew%id(:) = [(i, i = system%maxid + 1, system%maxid + nfrag)] + system%maxid = system%maxid + nfrag + plnew%status(:) = ACTIVE + plnew%lcollision(:) = .false. + plnew%ldiscard(:) = .false. + plnew%xb(:,:) = xb_frag(:, :) + plnew%vb(:,:) = vb_frag(:, :) + do i = 1, nfrag + plnew%xh(:,i) = xb_frag(:, i) - cb%xb(:) + plnew%vh(:,i) = vb_frag(:, i) - cb%vb(:) + end do + plnew%mass(:) = m_frag(:) + plnew%Gmass(:) = param%GU * m_frag(:) + plnew%density(:) = avg_dens + plnew%radius(:) = rad_frag(:) + plnew%info(:)%origin_type = "Supercatastrophic" + plnew%info(:)%origin_time = param%t + do i = 1, nfrag + plnew%info(i)%origin_xh(:) = plnew%xh(:,i) + plnew%info(i)%origin_vh(:) = plnew%vh(:,i) + end do + if (param%lrotation) then + plnew%Ip(:,:) = Ip_frag(:,:) + plnew%rot(:,:) = rot_frag(:,:) + end if + if (param%ltides) then + ibiggest = maxloc(pl%Gmass(family(:)), dim=1) + plnew%Q = pl%Q(ibiggest) + plnew%k2 = pl%k2(ibiggest) + plnew%tlag = pl%tlag(ibiggest) + end if + + ! Append the new merged body to the list and record how many we made + nstart = mergeadd_list%nbody + 1 + nend = mergeadd_list%nbody + plnew%nbody + call mergeadd_list%append(plnew) + mergeadd_list%ncomp(nstart:nend) = plnew%nbody + + call plnew%setup(0, param) + deallocate(plnew) + end if + + end associate + end select + + return + end function symba_fragmentation_casesupercatastrophic + +end submodule s_symba_fragmentation diff --git a/src/symba/symba_io.f90 b/src/symba/symba_io.f90 new file mode 100644 index 000000000..2e568dd7e --- /dev/null +++ b/src/symba/symba_io.f90 @@ -0,0 +1,290 @@ +submodule (symba_classes) s_symba_io + use swiftest +contains + + module subroutine symba_io_dump_particle_info(self, param, msg) + !! author: David A. Minton + !! + !! Dumps the particle information data to a file + implicit none + class(symba_particle_info), intent(inout) :: self !! Swiftest base object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation + end subroutine symba_io_dump_particle_info + + + module subroutine symba_io_initialize_particle_info(self, param) + !! author: David A. Minton + !! + !! Initializes a particle info data structure, either starting a new one or reading one in + !! from a file if it is a restarted run + implicit none + class(symba_particle_info), intent(inout) :: self !! SyMBA particle info object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine symba_io_initialize_particle_info + + + module subroutine symba_io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Read in parameters specific to the SyMBA integrator, then calls the base io_param_reader. + !! + !! Adapted from David E. Kaufmann's Swifter routine io_init_param.f90 + !! Adapted from Martin Duncan's Swift routine io_init_param.f + implicit none + ! Arguments + class(symba_parameters), intent(inout) :: self !! Collection of parameters + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + ! internals + integer(I4B) :: ilength, ifirst, ilast !! Variables used to parse input file + character(STRMAX) :: line !! Line of the input file + character (len=:), allocatable :: line_trim,param_name, param_value !! Strings used to parse the param file + integer(I4B) :: nseeds, nseeds_from_file, i + logical :: seed_set = .false. !! Is the random seed set in the input file? + character(len=*),parameter :: linefmt = '(A)' + + associate(param => self) + call io_param_reader(param, unit, iotype, v_list, iostat, iomsg) + + call random_seed(size = nseeds) + if (allocated(param%seed)) deallocate(param%seed) + allocate(param%seed(nseeds)) + rewind(unit) + do + read(unit = unit, fmt = linefmt, iostat = iostat, end = 1) line + line_trim = trim(adjustl(line)) + ilength = len(line_trim) + if ((ilength /= 0)) then + ifirst = 1 + ! Read the pair of tokens. The first one is the parameter name, the second is the value. + param_name = io_get_token(line_trim, ifirst, ilast, iostat) + if (param_name == '') cycle ! No parameter name (usually because this line is commented out) + call io_toupper(param_name) + ifirst = ilast + 1 + param_value = io_get_token(line_trim, ifirst, ilast, iostat) + select case (param_name) + case ("FRAGMENTATION") + call io_toupper(param_value) + if (param_value == "YES" .or. param_value == "T") self%lfragmentation = .true. + case ("MTINY") + read(param_value, *) param%mtiny + case("SEED") + read(param_value, *) nseeds_from_file + ! Because the number of seeds can vary between compilers/systems, we need to make sure we can handle cases in which the input file has a different + ! number of seeds than the current system. If the number of seeds in the file is smaller than required, we will use them as a source to fill in the missing elements. + ! If the number of seeds in the file is larger than required, we will truncate the seed array. + if (nseeds_from_file > nseeds) then + nseeds = nseeds_from_file + deallocate(param%seed) + allocate(param%seed(nseeds)) + do i = 1, nseeds + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%seed(i) + end do + else ! Seed array in file is too small + do i = 1, nseeds_from_file + ifirst = ilast + 1 + param_value = io_get_token(line, ifirst, ilast, iostat) + read(param_value, *) param%seed(i) + end do + param%seed(nseeds_from_file+1:nseeds) = [(param%seed(1) - param%seed(nseeds_from_file) + i, i=nseeds_from_file+1, nseeds)] + end if + seed_set = .true. + end select + end if + end do + 1 continue + + write(*,*) "FRAGMENTATION = ", param%lfragmentation + if (param%lfragmentation) then + if (seed_set) then + call random_seed(put = param%seed) + else + call random_seed(get = param%seed) + end if + write(*,*) "SEED: N,VAL = ",size(param%seed), param%seed(:) + end if + + if (self%mtiny < 0.0_DP) then + write(iomsg,*) "MTINY invalid or not set: ", self%mtiny + iostat = -1 + return + else + write(*,*) "MTINY = ", self%mtiny + end if + + if (.not.self%lclose) then + write(iomsg,*) 'This integrator requires CHK_CLOSE to be enabled.' + iostat = -1 + return + end if + end associate + + iostat = 0 + + return + end subroutine symba_io_param_reader + + + module subroutine symba_io_param_writer(self, unit, iotype, v_list, iostat, iomsg) + !! author: David A. Minton + !! + !! Dump integration parameters specific to SyMBA to file and then call the base io_param_writer method. + !! + !! Adapted from David E. Kaufmann's Swifter routine io_dump_param.f90 + !! Adapted from Martin Duncan's Swift routine io_dump_param.f + implicit none + ! Arguments + class(symba_parameters),intent(in) :: self !! Collection of SyMBA parameters + integer, intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer, intent(in) :: v_list(:) !! Not used in this procedure + integer, intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + ! Internals + character(*),parameter :: Ifmt = '(I0)' !! Format label for integer values + character(*),parameter :: Rfmt = '(ES25.17)' !! Format label for real values + character(*),parameter :: Rarrfmt = '(3(ES25.17,1X))' !! Format label for real values + character(*),parameter :: Lfmt = '(L1)' !! Format label for logical values + character(len=*), parameter :: Afmt = '(A25,1X,64(:,A25,1X))' + character(256) :: param_name, param_value + type character_array + character(25) :: value + end type character_array + type(character_array), dimension(:), allocatable :: param_array + integer(I4B) :: i + + associate(param => self) + call io_param_writer(param, unit, iotype, v_list, iostat, iomsg) + + ! Special handling is required for writing the random number seed array as its size is not known until runtime + ! For the "SEED" parameter line, the first value will be the size of the seed array and the rest will be the seed array elements + write(param_name, Afmt) "PARTICLE_FILE"; write(param_value, Afmt) trim(adjustl(param%particle_file)); write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "MTINY"; write(param_value, Rfmt) param%mtiny; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + write(param_name, Afmt) "FRAGMENTATION"; write(param_value, Lfmt) param%lfragmentation; write(unit, Afmt) adjustl(param_name), adjustl(param_value) + if (param%lfragmentation) then + write(param_name, Afmt) "SEED" + if (allocated(param_array)) deallocate(param_array) + allocate(param_array(0:size(param%seed))) + write(param_array(0)%value, Ifmt) size(param%seed) + do i = 1, size(param%seed) + write(param_array(i)%value, Ifmt) param%seed(i) + end do + write(unit, Afmt, advance='no') adjustl(param_name), adjustl(param_array(0)%value) + do i = 1, size(param%seed) + if (i < size(param%seed)) then + write(unit, Afmt, advance='no') adjustl(param_array(i)%value) + else + write(unit, Afmt) adjustl(param_array(i)%value) + end if + end do + end if + + iostat = 0 + end associate + + return + end subroutine symba_io_param_writer + + + module subroutine symba_io_read_frame_info(self, iu, param, form, ierr) + !! author: David A. Minton + !! + !! Reads a single frame of a particle info data from a file. + implicit none + class(symba_particle_info), intent(inout) :: self !! SyMBA particle info object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code + + ierr = 0 + end subroutine symba_io_read_frame_info + + + module subroutine symba_io_write_discard(self, param) + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B), parameter :: LUN = 40 + integer(I4B) :: iadd, isub, j, ierr, nsub, nadd + logical, save :: lfirst = .true. + real(DP), dimension(:,:), allocatable :: vh + character(*), parameter :: HDRFMT = '(E23.16, 1X, I8, 1X, L1)' + character(*), parameter :: NAMEFMT = '(A, 2(1X, I8))' + character(*), parameter :: VECFMT = '(3(E23.16, 1X))' + character(*), parameter :: NPLFMT = '(I8)' + character(*), parameter :: PLNAMEFMT = '(I8, 2(1X, E23.16))' + class(swiftest_body), allocatable :: pltemp + + associate(pl => self%pl, npl => self%pl%nbody, mergesub_list => self%mergesub_list, mergeadd_list => self%mergeadd_list) + if (self%tp_discards%nbody > 0) call io_write_discard(self, param) + + if (mergesub_list%nbody == 0) return + select case(param%out_stat) + case('APPEND') + open(unit = LUN, file = param%discard_out, status = 'OLD', position = 'APPEND', form = 'FORMATTED', iostat = ierr) + case('NEW', 'REPLACE', 'UNKNOWN') + open(unit = LUN, file = param%discard_out, status = param%out_stat, form = 'FORMATTED', iostat = ierr) + case default + write(*,*) 'Invalid status code for OUT_STAT: ',trim(adjustl(param%out_stat)) + call util_exit(FAILURE) + end select + lfirst = .false. + if (param%lgr) then + call mergesub_list%pv2v(param) + call mergeadd_list%pv2v(param) + end if + + write(LUN, HDRFMT) param%t, mergesub_list%nbody, param%lbig_discard + iadd = 1 + isub = 1 + do while (iadd <= mergeadd_list%nbody) + nadd = mergeadd_list%ncomp(iadd) + nsub = mergesub_list%ncomp(isub) + do j = 1, nadd + if (iadd <= mergeadd_list%nbody) then + write(LUN, NAMEFMT) ADD, mergesub_list%id(iadd), mergesub_list%status(iadd) + write(LUN, VECFMT) mergeadd_list%xh(1, iadd), mergeadd_list%xh(2, iadd), mergeadd_list%xh(3, iadd) + write(LUN, VECFMT) mergeadd_list%vh(1, iadd), mergeadd_list%vh(2, iadd), mergeadd_list%vh(3, iadd) + else + exit + end if + iadd = iadd + 1 + end do + do j = 1, nsub + if (isub <= mergesub_list%nbody) then + write(LUN, NAMEFMT) SUB, mergesub_list%id(isub), mergesub_list%status(isub) + write(LUN, VECFMT) mergesub_list%xh(1, isub), mergesub_list%xh(2, isub), mergesub_list%xh(3, isub) + write(LUN, VECFMT) mergesub_list%vh(1, isub), mergesub_list%vh(2, isub), mergesub_list%vh(3, isub) + else + exit + end if + isub = isub + 1 + end do + end do + + close(LUN) + end associate + + return + end subroutine symba_io_write_discard + + + module subroutine symba_io_write_frame_info(self, iu, param) + implicit none + class(symba_particle_info), intent(in) :: self !! SyMBA particle info object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine symba_io_write_frame_info + +end submodule s_symba_io + diff --git a/src/symba/symba_kick.f90 b/src/symba/symba_kick.f90 new file mode 100644 index 000000000..8625b3d81 --- /dev/null +++ b/src/symba/symba_kick.f90 @@ -0,0 +1,200 @@ +submodule(symba_classes) s_symba_kick + use swiftest +contains + + module subroutine symba_kick_getacch_pl(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of massive bodies + !! + !! Adapted from David E. Kaufmann's Swifter routine symba_kick_getacch.f90 + !! Adapted from Hal Levison's Swift routine symba5_kick_getacch.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + ! Internals + integer(I4B) :: k + real(DP) :: irij3, rji2, rlim2, faci, facj + real(DP), dimension(NDIM) :: dx + + if (self%nbody == 0) return + select type(system) + class is (symba_nbody_system) + associate(pl => self, cb => system%cb, plplenc_list => system%plplenc_list, nplplenc => system%plplenc_list%nenc) + call helio_kick_getacch_pl(pl, system, param, t, lbeg) + ! Remove accelerations from encountering pairs + do k = 1, nplplenc + associate(i => plplenc_list%index1(k), j => plplenc_list%index2(k)) + dx(:) = pl%xh(:, j) - pl%xh(:, i) + rji2 = dot_product(dx(:), dx(:)) + irij3 = 1.0_DP / (rji2 * sqrt(rji2)) + faci = pl%Gmass(i) * irij3 + facj = pl%Gmass(j) * irij3 + pl%ah(:, i) = pl%ah(:, i) - facj * dx(:) + pl%ah(:, j) = pl%ah(:, j) + faci * dx(:) + end associate + end do + end associate + end select + + return + end subroutine symba_kick_getacch_pl + + + module subroutine symba_kick_getacch_tp(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of test particles + !! + !! Adapted from David E. Kaufmann's Swifter routine symba_kick_getacch_tp.f90 + !! Adapted from Hal Levison's Swift routine symba5_kick_getacch.f + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + ! Internals + integer(I4B) :: k + real(DP) :: rji2, fac, rlim2 + real(DP), dimension(NDIM) :: dx + + if (self%nbody == 0) return + select type(system) + class is (symba_nbody_system) + associate(tp => self, cb => system%cb, pl => system%pl, pltpenc_list => system%pltpenc_list, npltpenc => system%pltpenc_list%nenc) + call helio_kick_getacch_tp(tp, system, param, t, lbeg) + ! Remove accelerations from encountering pairs + do k = 1, npltpenc + associate(i => pltpenc_list%index1(k), j => pltpenc_list%index2(k)) + if (tp%lmask(j)) THEN + if (lbeg) then + dx(:) = tp%xh(:,j) - pl%xbeg(:,i) + else + dx(:) = tp%xh(:,j) - pl%xend(:,i) + end if + rji2 = dot_product(dx(:), dx(:)) + fac = pl%Gmass(i) / (rji2 * sqrt(rji2)) + tp%ah(:,j) = tp%ah(:,j) + fac * dx(:) + end IF + end associate + end do + end associate + end select + return + end subroutine symba_kick_getacch_tp + + + module subroutine symba_kick_pltpenc(self, system, dt, irec, sgn) + !! author: David A. Minton + !! + !! Kick barycentric velocities of massive bodies and ACTIVE test particles within SyMBA recursion. + !! Note: This method works for the polymorphic symba_pltpenc and symba_plplenc types + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_kick.f90 + !! Adapted from Hal Levison's Swift routine symba5_kick.f + implicit none + ! Arguments + class(symba_pltpenc), intent(in) :: self !! SyMBA pl-tp encounter list object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level + integer(I4B), intent(in) :: sgn !! sign to be applied to acceleration + ! Internals + integer(I4B) :: k, irm1, irecl + real(DP) :: r, rr, ri, ris, rim1, r2, ir3, fac, faci, facj + real(DP), dimension(NDIM) :: dx + logical :: isplpl, lgoodlevel + + if (self%nenc == 0) return + + select type(self) + class is (symba_plplenc) + isplpl = .true. + class is (symba_pltpenc) + isplpl = .false. + end select + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + associate(ind1 => self%index1, ind2 => self%index2) + if (pl%nbody > 0) pl%lmask(:) = pl%status(:) /= INACTIVE + if (tp%nbody > 0) tp%lmask(:) = tp%status(:) /= INACTIVE + + irm1 = irec - 1 + if (sgn < 0) then + irecl = irec - 1 + else + irecl = irec + end if + do k = 1, self%nenc + if (isplpl) then + pl%ah(:,ind1(k)) = 0.0_DP + pl%ah(:,ind2(k)) = 0.0_DP + else + tp%ah(:,ind2(k)) = 0.0_DP + end if + if (isplpl) then + lgoodlevel = (pl%levelg(ind1(k)) >= irm1) .and. (pl%levelg(ind2(k)) >= irm1) + else + lgoodlevel = (pl%levelg(ind1(k)) >= irm1) .and. (tp%levelg(ind2(k)) >= irm1) + end if + if ((self%status(k) /= INACTIVE) .and. lgoodlevel) then + if (isplpl) then + ri = ((pl%rhill(ind1(k)) + pl%rhill(ind2(k)))**2) * (RHSCALE**2) * (RSHELL**(2*irecl)) + rim1 = ri * (RSHELL**2) + dx(:) = pl%xh(:,ind2(k)) - pl%xh(:,ind1(k)) + else + ri = ((pl%rhill(ind1(k)))**2) * (RHSCALE**2) * (RSHELL**(2*irecl)) + rim1 = ri * (RSHELL**2) + dx(:) = tp%xh(:,ind2(k)) - pl%xh(:,ind1(k)) + end if + r2 = dot_product(dx(:), dx(:)) + if (r2 < rim1) then + fac = 0.0_DP + else if (r2 < ri) then + ris = sqrt(ri) + r = sqrt(r2) + rr = (ris - r) / (ris * (1.0_DP - RSHELL)) + fac = (r2**(-1.5_DP)) * (1.0_DP - 3 * (rr**2) + 2 * (rr**3)) + else + ir3 = 1.0_DP / (r2 * sqrt(r2)) + fac = ir3 + end if + faci = fac * pl%Gmass(ind1(k)) + if (isplpl) then + facj = fac * pl%Gmass(ind2(k)) + pl%ah(:,ind1(k)) = pl%ah(:,ind1(k)) + facj * dx(:) + pl%ah(:,ind2(k)) = pl%ah(:,ind2(k)) - faci * dx(:) + else + tp%ah(:,ind2(k)) = tp%ah(:,ind2(k)) - faci * dx(:) + end if + end if + end do + if (isplpl) then + do k = 1, self%nenc + pl%vb(:,ind1(k)) = pl%vb(:,ind1(k)) + sgn * dt * pl%ah(:,ind1(k)) + pl%vb(:,ind2(k)) = pl%vb(:,ind2(k)) + sgn * dt * pl%ah(:,ind2(k)) + pl%ah(:,ind1(k)) = 0.0_DP + pl%ah(:,ind1(k)) = 0.0_DP + end do + else + do k = 1, self%nenc + tp%vb(:,ind2(k)) = tp%vb(:,ind2(k)) + sgn * dt * tp%ah(:,ind2(k)) + tp%ah(:,ind2(k)) = 0.0_DP + end do + end if + end associate + end select + end select + + return + end subroutine symba_kick_pltpenc + +end submodule s_symba_kick \ No newline at end of file diff --git a/src/symba/symba_setup.f90 b/src/symba/symba_setup.f90 new file mode 100644 index 000000000..021873a70 --- /dev/null +++ b/src/symba/symba_setup.f90 @@ -0,0 +1,177 @@ +submodule(symba_classes) s_symba_setup + use swiftest +contains + + module subroutine symba_setup_initialize_system(self, param) + !! author: David A. Minton + !! + !! Initialize an SyMBA nbody system from files and sets up the planetocentric structures. + !! This subroutine will also sort the massive bodies in descending order by mass + !! + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, j + + ! Call parent method + associate(system => self) + call whm_setup_initialize_system(system, param) + call system%pltpenc_list%setup(0) + call system%plplenc_list%setup(0) + select type(pl => system%pl) + class is (symba_pl) + call pl%sort("mass", ascending=.false.) + select type(param) + class is (symba_parameters) + pl%lmtiny(:) = pl%Gmass(:) > param%MTINY + pl%nplm = count(pl%lmtiny(:)) + end select + end select + end associate + + return + end subroutine symba_setup_initialize_system + + + module subroutine symba_setup_merger(self, n, param) + !! author: David A. Minton + !! + !! Allocate SyMBA test particle structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine symba_setup.f90 + implicit none + ! Arguments + class(symba_merger), intent(inout) :: self !! SyMBA merger list object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + ! Internals + integer(I4B) :: i + + !> Call allocation method for parent class. In this case, helio_pl does not have its own setup method so we use the base method for swiftest_pl + call symba_setup_pl(self, n, param) + if (n <= 0) return + + if (allocated(self%ncomp)) deallocate(self%ncomp) + allocate(self%ncomp(n)) + self%ncomp(:) = 0 + + return + end subroutine symba_setup_merger + + + module subroutine symba_setup_pl(self, n, param) + !! author: David A. Minton + !! + !! Allocate SyMBA test particle structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine symba_setup.f90 + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + ! Internals + integer(I4B) :: i + + !> Call allocation method for parent class. In this case, helio_pl does not have its own setup method so we use the base method for swiftest_pl + call setup_pl(self, n, param) + if (n <= 0) return + + if (allocated(self%lcollision)) deallocate(self%lcollision) + if (allocated(self%lencounter)) deallocate(self%lencounter) + if (allocated(self%lmtiny)) deallocate(self%lmtiny) + if (allocated(self%nplenc)) deallocate(self%nplenc) + if (allocated(self%ntpenc)) deallocate(self%ntpenc) + if (allocated(self%levelg)) deallocate(self%levelg) + if (allocated(self%levelm)) deallocate(self%levelm) + if (allocated(self%isperi)) deallocate(self%isperi) + if (allocated(self%peri)) deallocate(self%peri) + if (allocated(self%atp)) deallocate(self%atp) + if (allocated(self%kin)) deallocate(self%kin) + if (allocated(self%info)) deallocate(self%info) + + allocate(self%lcollision(n)) + allocate(self%lencounter(n)) + allocate(self%lmtiny(n)) + allocate(self%nplenc(n)) + allocate(self%ntpenc(n)) + allocate(self%levelg(n)) + allocate(self%levelm(n)) + allocate(self%isperi(n)) + allocate(self%peri(n)) + allocate(self%atp(n)) + allocate(self%kin(n)) + allocate(self%info(n)) + + self%lcollision(:) = .false. + self%lencounter(:) = .false. + self%lmtiny(:) = .false. + self%nplenc(:) = 0 + self%ntpenc(:) = 0 + self%levelg(:) = -1 + self%levelm(:) = -1 + self%isperi(:) = 0 + self%peri(:) = 0.0_DP + self%atp(:) = 0.0_DP + self%kin(:)%nchild = 0 + self%kin(:)%parent = [(i, i=1, n)] + return + end subroutine symba_setup_pl + + + module subroutine symba_setup_pltpenc(self, n) + !! author: David A. Minton + !! + !! A constructor that sets the number of encounters and allocates and initializes all arrays + !! + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter structure + integer(I4B), intent(in) :: n !! Number of encounters to allocate space for + + call setup_encounter(self, n) + if (n == 0) return + + if (allocated(self%level)) deallocate(self%level) + allocate(self%level(n)) + + self%level(:) = -1 + + return + end subroutine symba_setup_pltpenc + + + module subroutine symba_setup_tp(self, n, param) + !! author: David A. Minton + !! + !! Allocate WHM test particle structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine whm_setup.f90 + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + !> Call allocation method for parent class. In this case, helio_tp does not have its own setup method so we use the base method for swiftest_tp + call setup_tp(self, n, param) + if (n <= 0) return + + if (allocated(self%nplenc)) deallocate(self%nplenc) + if (allocated(self%levelg)) deallocate(self%levelg) + if (allocated(self%levelm)) deallocate(self%levelm) + + allocate(self%nplenc(n)) + allocate(self%levelg(n)) + allocate(self%levelm(n)) + + self%nplenc(:) = 0 + self%levelg(:) = -1 + self%levelm(:) = -1 + + return + end subroutine symba_setup_tp + +end submodule s_symba_setup diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 new file mode 100644 index 000000000..41e7a3a74 --- /dev/null +++ b/src/symba/symba_step.f90 @@ -0,0 +1,277 @@ +submodule (symba_classes) s_symba_step + use swiftest +contains + + module subroutine symba_step_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step planets and active test particles ahead in democratic heliocentric coordinates, descending the recursive + !! branch if necessary to handle possible close encounters + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_pl.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + logical :: lencounter + + call self%reset() + select type(pl => self%pl) + class is (symba_pl) + select type(tp => self%tp) + class is (symba_tp) + lencounter = pl%encounter_check(self, dt, 0) .or. tp%encounter_check(self, dt, 0) + if (lencounter) then + tp%lfirst = pl%lfirst + call self%interp(param, t, dt) + pl%lfirst = .true. + tp%lfirst = .true. + else + call helio_step_system(self, param, t, dt) + end if + end select + end select + + return + end subroutine symba_step_system + + + module subroutine symba_step_interp_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step planets and active test particles ahead in democratic heliocentric coordinates, calling the recursive + !! subroutine to descend to the appropriate level to handle close encounters + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step_interp.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_interp.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP) :: dth !! Half step size + + dth = 0.5_DP * dt + associate(system => self) + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + select type(cb => system%cb) + class is (symba_cb) + system%irec = -1 + call pl%vh2vb(cb) + call pl%lindrift(cb, dth, lbeg=.true.) + call pl%kick(system, param, t, dth, lbeg=.true.) + call pl%drift(system, param, dt) + + call tp%vh2vb(vbcb = -cb%ptbeg) + call tp%lindrift(cb, dth, lbeg=.true.) + call tp%kick(system, param, t, dth, lbeg=.true.) + call tp%drift(system, param, dt) + + call system%recursive_step(param, t, 0) + + call pl%kick(system, param, t, dth, lbeg=.false.) + call pl%vb2vh(cb) + call pl%lindrift(cb, dth, lbeg=.false.) + + call tp%kick(system, param, t, dth, lbeg=.false.) + call tp%vb2vh(vbcb = -cb%ptend) + call tp%lindrift(cb, dth, lbeg=.false.) + end select + end select + end select + end associate + + return + end subroutine symba_step_interp_system + + + module subroutine symba_step_set_recur_levels_system(self, ireci) + !! author: David A. Minton + !! + !! Resets pl, tp,and encounter structures at the start of a new step + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step_recur.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_recur.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + integer(I4B), intent(in) :: ireci !! Input recursion level + ! Internals + integer(I4B) :: k, irecp + + associate(system => self, plplenc_list => self%plplenc_list, pltpenc_list => self%pltpenc_list) + select type(pl => self%pl) + class is (symba_pl) + select type(tp => self%tp) + class is (symba_tp) + irecp = ireci + 1 + + if (plplenc_list%nenc > 0) then + do k = 1, plplenc_list%nenc + associate(i => plplenc_list%index1(k), j => plplenc_list%index2(k)) + if (pl%levelg(i) == irecp) pl%levelg(i) = ireci + if (pl%levelg(j) == irecp) pl%levelg(j) = ireci + end associate + end do + where(plplenc_list%level(1:plplenc_list%nenc) == irecp) plplenc_list%level(1:plplenc_list%nenc) = ireci + end if + + if (pltpenc_list%nenc > 0) then + do k = 1, pltpenc_list%nenc + associate(i => pltpenc_list%index1(k), j => pltpenc_list%index2(k)) + if (pl%levelg(i) == irecp) pl%levelg(i) = ireci + if (tp%levelg(j) == irecp) tp%levelg(j) = ireci + end associate + end do + where(pltpenc_list%level(1:pltpenc_list%nenc) == irecp) pltpenc_list%level(1:pltpenc_list%nenc) = ireci + end if + + system%irec = ireci + + end select + end select + end associate + + return + end subroutine symba_step_set_recur_levels_system + + + module recursive subroutine symba_step_recur_system(self, param, t, ireci) + !! author: David A. Minton + !! + !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current + !! recursion level, if applicable, and descend to the next deeper level if necessarys + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step_recur.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_recur.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), value :: t + integer(I4B), value :: ireci !! input recursion level + ! Internals + integer(I4B) :: i, j, irecp, nloops + real(DP) :: dtl, dth + real(DP), dimension(NDIM) :: xr, vr + logical :: lencounter + + associate(system => self, plplenc_list => self%plplenc_list, pltpenc_list => self%pltpenc_list) + select type(pl => self%pl) + class is (symba_pl) + select type(tp => self%tp) + class is (symba_tp) + system%irec = ireci + dtl = param%dt / (NTENC**ireci) + dth = 0.5_DP * dtl + IF (dtl / param%dt < VSMALL) THEN + write(*, *) "SWIFTEST Warning:" + write(*, *) " In symba_step_recur_system, local time step is too small" + write(*, *) " Roundoff error will be important!" + call util_exit(FAILURE) + END IF + irecp = ireci + 1 + if (ireci == 0) then + nloops = 1 + else + nloops = NTENC + end if + do j = 1, nloops + lencounter = plplenc_list%encounter_check(system, dtl, irecp) .or. pltpenc_list%encounter_check(system, dtl, irecp) + + call plplenc_list%kick(system, dth, irecp, 1) + call pltpenc_list%kick(system, dth, irecp, 1) + if (ireci /= 0) then + call plplenc_list%kick(system, dth, irecp, -1) + call pltpenc_list%kick(system, dth, irecp, -1) + end if + + call pl%drift(system, param, dtl) + call tp%drift(system, param, dtl) + + if (lencounter) call system%recursive_step(param, t+dth,irecp) + system%irec = ireci + + call plplenc_list%kick(system, dth, irecp, 1) + call pltpenc_list%kick(system, dth, irecp, 1) + if (ireci /= 0) then + call plplenc_list%kick(system, dth, irecp, -1) + call pltpenc_list%kick(system, dth, irecp, -1) + end if + + if (param%lclose) then + call plplenc_list%collision_check(system, param, t+dtl, dtl, ireci) + call pltpenc_list%collision_check(system, param, t+dtl, dtl, ireci) + end if + + call self%set_recur_levels(ireci) + + end do + end select + end select + end associate + + return + end subroutine symba_step_recur_system + + + module subroutine symba_step_reset_system(self) + !! author: David A. Minton + !! + !! Resets pl, tp,and encounter structures at the start of a new step + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step.f90 + !! Adapted from Hal Levison's Swift routine symba5_step.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + ! Internals + integer(I4B) :: i + + associate(system => self, pltpenc_list => self%pltpenc_list, plplenc_list => self%plplenc_list, mergeadd_list => self%mergeadd_list, mergesub_list => self%mergesub_list) + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + if (pl%nbody > 0) then + pl%lcollision(:) = .false. + pl%kin(:)%parent = [(i, i=1, pl%nbody)] + pl%kin(:)%nchild = 0 + do i = 1, pl%nbody + if (allocated(pl%kin(i)%child)) deallocate(pl%kin(i)%child) + end do + pl%nplenc(:) = 0 + pl%ntpenc(:) = 0 + pl%levelg(:) = 0 + pl%levelm(:) = 0 + pl%lencounter = .false. + pl%lcollision = .false. + plplenc_list%nenc = 0 + end if + + if (tp%nbody > 0) then + tp%nplenc(:) = 0 + tp%levelg(:) = 0 + tp%levelm(:) = 0 + pltpenc_list%nenc = 0 + end if + + call mergeadd_list%resize(0) + call mergesub_list%resize(0) + end select + end select + end associate + + return + end subroutine symba_step_reset_system + +end submodule s_symba_step diff --git a/src/symba/symba_util.f90 b/src/symba/symba_util.f90 new file mode 100644 index 000000000..98c8889d8 --- /dev/null +++ b/src/symba/symba_util.f90 @@ -0,0 +1,861 @@ +submodule(symba_classes) s_symba_util + use swiftest +contains + + module subroutine symba_util_append_arr_info(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of particle information type onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: arr !! Destination array + type(symba_particle_info), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine symba_util_append_arr_info + + + module subroutine symba_util_append_arr_kin(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of kinship type onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + type(symba_kinship), dimension(:), allocatable, intent(inout) :: arr !! Destination array + type(symba_kinship), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine symba_util_append_arr_kin + + + module subroutine symba_util_append_pl(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one massive body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + !! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (symba_pl) + call util_append_pl(self, source, lsource_mask) ! Note: helio_pl does not have its own append method, so we skip back to the base class + + call util_append(self%lcollision, source%lcollision, lsource_mask) + call util_append(self%lencounter, source%lencounter, lsource_mask) + call util_append(self%lmtiny, source%lmtiny, lsource_mask) + call util_append(self%nplenc, source%nplenc, lsource_mask) + call util_append(self%ntpenc, source%ntpenc, lsource_mask) + call util_append(self%levelg, source%levelg, lsource_mask) + call util_append(self%levelm, source%levelm, lsource_mask) + call util_append(self%isperi, source%isperi, lsource_mask) + call util_append(self%peri, source%peri, lsource_mask) + call util_append(self%atp, source%atp, lsource_mask) + call util_append(self%kin, source%kin, lsource_mask) + call util_append(self%info, source%info, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class symba_pl or its descendents!" + call util_exit(FAILURE) + end select + + return + end subroutine symba_util_append_pl + + + module subroutine symba_util_append_merger(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one massive body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + ! Arguments + class(symba_merger), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B), dimension(:), allocatable :: ncomp_tmp !! Temporary placeholder for ncomp incase we are appending a symba_pl object to a symba_merger + + select type(source) + class is (symba_merger) + call symba_util_append_pl(self, source, lsource_mask) + call util_append(self%ncomp, source%ncomp, lsource_mask) + class is (symba_pl) + call symba_util_append_pl(self, source, lsource_mask) + allocate(ncomp_tmp, mold=source%id) + ncomp_tmp(:) = 0 + call util_append(self%ncomp, ncomp_tmp, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class symba_pl or its descendents!" + call util_exit(FAILURE) + end select + + return + end subroutine symba_util_append_merger + + + module subroutine symba_util_append_tp(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from test particle object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + !! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (symba_tp) + call util_append_tp(self, source, lsource_mask) ! Note: helio_tp does not have its own append method, so we skip back to the base class + + call util_append(self%nplenc, source%nplenc, lsource_mask) + call util_append(self%levelg, source%levelg, lsource_mask) + call util_append(self%levelm, source%levelm, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class symba_tp or its descendents!" + call util_exit(FAILURE) + end select + + return + end subroutine symba_util_append_tp + + + module subroutine symba_util_fill_arr_info(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of particle origin information types + !! This is the inverse of a spill operation + implicit none + ! Arguments + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_particle_info), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine symba_util_fill_arr_info + + + module subroutine symba_util_fill_arr_kin(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of particle kinship types + !! This is the inverse of a spill operation + implicit none + ! Arguments + type(symba_kinship), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_kinship), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine symba_util_fill_arr_kin + + + module subroutine symba_util_fill_pl(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new SyMBA test particle structure into an old one. + !! This is the inverse of a fill operation. + !! + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA masive body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + associate(keeps => self) + select type(inserts) + class is (symba_pl) + call util_fill(keeps%lcollision, inserts%lcollision, lfill_list) + call util_fill(keeps%lencounter, inserts%lencounter, lfill_list) + call util_fill(keeps%lmtiny, inserts%lmtiny, lfill_list) + call util_fill(keeps%nplenc, inserts%nplenc, lfill_list) + call util_fill(keeps%ntpenc, inserts%ntpenc, lfill_list) + call util_fill(keeps%levelg, inserts%levelg, lfill_list) + call util_fill(keeps%levelm, inserts%levelm, lfill_list) + call util_fill(keeps%isperi, inserts%isperi, lfill_list) + call util_fill(keeps%peri, inserts%peri, lfill_list) + call util_fill(keeps%atp, inserts%atp, lfill_list) + call util_fill(keeps%kin, inserts%kin, lfill_list) + call util_fill(keeps%info, inserts%info, lfill_list) + + call util_fill_pl(keeps, inserts, lfill_list) ! Note: helio_pl does not have its own fill method, so we skip back to the base class + class default + write(*,*) "Invalid object passed to the fill method. Source must be of class symba_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine symba_util_fill_pl + + + module subroutine symba_util_fill_tp(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new SyMBA test particle structure into an old one. + !! This is the inverse of a fill operation. + !! + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + associate(keeps => self) + select type(inserts) + class is (symba_tp) + call util_fill(keeps%nplenc, inserts%nplenc, lfill_list) + call util_fill(keeps%levelg, inserts%levelg, lfill_list) + call util_fill(keeps%levelm, inserts%levelm, lfill_list) + + call util_fill_tp(keeps, inserts, lfill_list) ! Note: helio_tp does not have its own fill method, so we skip back to the base class + class default + write(*,*) "Invalid object passed to the fill method. Source must be of class symba_tp or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine symba_util_fill_tp + + + module subroutine symba_util_peri_pl(self, system, param) + !! author: David A. Minton + !! + !! Determine system pericenter passages for planets in SyMBA + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_peri.f90 + !! Adapted from Hal Levison's Swift routine util_mass_peri.f + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP) :: vdotr, e + + associate(pl => self, npl => self%nbody) + if (pl%lfirst) then + if (param%qmin_coord == "HELIO") then + do i = 1, npl + if (pl%status(i) == ACTIVE) then + vdotr = dot_product(pl%xh(:,i), pl%vh(:,i)) + if (vdotr > 0.0_DP) then + pl%isperi(i) = 1 + else + pl%isperi(i) = -1 + end if + end if + end do + else + do i = 1, npl + if (pl%status(i) == ACTIVE) then + vdotr = dot_product(pl%xb(:,i), pl%vb(:,i)) + if (vdotr > 0.0_DP) then + pl%isperi(i) = 1 + else + pl%isperi(i) = -1 + end if + end if + end do + end if + else + if (param%qmin_coord == "HELIO") then + do i = 1, npl + if (pl%status(i) == ACTIVE) then + vdotr = dot_product(pl%xh(:,i), pl%vh(:,i)) + if (pl%isperi(i) == -1) then + if (vdotr >= 0.0_DP) then + pl%isperi(i) = 0 + CALL orbel_xv2aeq(pl%mu(i), pl%xh(:,i), pl%vh(:,i), pl%atp(i), e, pl%peri(i)) + end if + else + if (vdotr > 0.0_DP) then + pl%isperi(i) = 1 + else + pl%isperi(i) = -1 + end if + end if + end if + end do + else + do i = 1, npl + if (pl%status(i) == ACTIVE) then + vdotr = dot_product(pl%xb(:,i), pl%vb(:,i)) + if (pl%isperi(i) == -1) then + if (vdotr >= 0.0_DP) then + pl%isperi(i) = 0 + CALL orbel_xv2aeq(system%Gmtot, pl%xb(:,i), pl%vb(:,i), pl%atp(i), e, pl%peri(i)) + end if + else + if (vdotr > 0.0_DP) then + pl%isperi(i) = 1 + else + pl%isperi(i) = -1 + end if + end if + end if + end do + end if + end if + end associate + + return + end subroutine symba_util_peri_pl + + + module subroutine symba_util_rearray_pl(self, system, param) + !! Author: the Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Clean up the massive body structures to remove discarded bodies and add new bodies + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(symba_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(symba_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + class(symba_pl), allocatable :: pl_discards !! The discarded body list. + + associate(pl => self, mergeadd_list => system%mergeadd_list) + allocate(pl_discards, mold=pl) + ! Remove the discards + call pl%spill(pl_discards, lspill_list=(pl%ldiscard(:) .or. pl%status(:) == INACTIVE), ldestructive=.true.) + + ! Add in any new bodies + call pl%append(mergeadd_list) + + ! If there are still bodies in the system, sort by mass in descending order and re-index + if (pl%nbody > 0) then + call pl%sort("mass", ascending=.false.) + pl%lmtiny(:) = pl%Gmass(:) > param%MTINY + pl%nplm = count(pl%lmtiny(:)) + call pl%eucl_index() + end if + + ! Destroy the discarded body list, since we already have what we need in the mergesub_list + call pl_discards%setup(0,param) + deallocate(pl_discards) + end associate + + return + end subroutine symba_util_rearray_pl + + + module subroutine symba_util_resize_arr_info(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of type character string. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + type(symba_particle_info), dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine symba_util_resize_arr_info + + + module subroutine symba_util_resize_arr_kin(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of type character string. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + type(symba_kinship), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + type(symba_kinship), dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine symba_util_resize_arr_kin + + + module subroutine symba_util_resize_merger(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a SyMBA merger list against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(symba_merger), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call symba_util_resize_pl(self, nnew) + + call util_resize(self%ncomp, nnew) + + return + end subroutine symba_util_resize_merger + + + module subroutine symba_util_resize_pl(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a SyMBA massive body object against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_pl(self, nnew) + + call util_resize(self%lcollision, nnew) + call util_resize(self%lencounter, nnew) + call util_resize(self%lmtiny, nnew) + call util_resize(self%nplenc, nnew) + call util_resize(self%ntpenc, nnew) + call util_resize(self%levelg, nnew) + call util_resize(self%levelm, nnew) + call util_resize(self%isperi, nnew) + call util_resize(self%peri, nnew) + call util_resize(self%atp, nnew) + call util_resize(self%kin, nnew) + call util_resize(self%info, nnew) + + return + end subroutine symba_util_resize_pl + + + module subroutine symba_util_resize_tp(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a test particle object against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_tp(self, nnew) + + call util_resize(self%nplenc, nnew) + call util_resize(self%levelg, nnew) + call util_resize(self%levelm, nnew) + + return + end subroutine symba_util_resize_tp + + + module subroutine symba_util_sort_pl(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a SyMBA massive body object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (self%nbody == 0) return + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(pl => self, npl => self%nbody) + select case(sortby) + case("nplenc") + call util_sort(direction * pl%nplenc(1:npl), ind(1:npl)) + case("ntpenc") + call util_sort(direction * pl%ntpenc(1:npl), ind(1:npl)) + case("levelg") + call util_sort(direction * pl%levelg(1:npl), ind(1:npl)) + case("levelm") + call util_sort(direction * pl%levelm(1:npl), ind(1:npl)) + case("peri") + call util_sort(direction * pl%peri(1:npl), ind(1:npl)) + case("atp") + call util_sort(direction * pl%atp(1:npl), ind(1:npl)) + case("lcollision", "lencounter", "lmtiny", "nplm", "nplplm", "kin", "info") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default ! Look for components in the parent class + call util_sort_pl(pl, sortby, ascending) + return + end select + + call pl%rearrange(ind) + + end associate + return + end subroutine symba_util_sort_pl + + + module subroutine symba_util_sort_tp(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a SyMBA test particle object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (self%nbody == 0) return + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(tp => self, ntp => self%nbody) + select case(sortby) + case("nplenc") + call util_sort(direction * tp%nplenc(1:ntp), ind(1:ntp)) + case("levelg") + call util_sort(direction * tp%levelg(1:ntp), ind(1:ntp)) + case("levelm") + call util_sort(direction * tp%levelm(1:ntp), ind(1:ntp)) + case default ! Look for components in the parent class + call util_sort_tp(tp, sortby, ascending) + return + end select + + call tp%rearrange(ind) + end associate + + return + end subroutine symba_util_sort_tp + + + module subroutine symba_util_sort_rearrange_pl(self, ind) + !! author: David A. Minton + !! + !! Rearrange SyMBA massive body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(symba_pl), allocatable :: pl_sorted !! Temporary holder for sorted body + integer(I4B) :: i, j + + associate(pl => self, npl => self%nbody) + call util_sort_rearrange_pl(pl,ind) + allocate(pl_sorted, source=self) + if (allocated(pl%lcollision)) pl%lcollision(1:npl) = pl_sorted%lcollision(ind(1:npl)) + if (allocated(pl%lencounter)) pl%lencounter(1:npl) = pl_sorted%lencounter(ind(1:npl)) + if (allocated(pl%lmtiny)) pl%lmtiny(1:npl) = pl_sorted%lmtiny(ind(1:npl)) + if (allocated(pl%nplenc)) pl%nplenc(1:npl) = pl_sorted%nplenc(ind(1:npl)) + if (allocated(pl%ntpenc)) pl%ntpenc(1:npl) = pl_sorted%ntpenc(ind(1:npl)) + if (allocated(pl%levelg)) pl%levelg(1:npl) = pl_sorted%levelg(ind(1:npl)) + if (allocated(pl%levelm)) pl%levelm(1:npl) = pl_sorted%levelm(ind(1:npl)) + if (allocated(pl%isperi)) pl%isperi(1:npl) = pl_sorted%isperi(ind(1:npl)) + if (allocated(pl%peri)) pl%peri(1:npl) = pl_sorted%peri(ind(1:npl)) + if (allocated(pl%atp)) pl%atp(1:npl) = pl_sorted%atp(ind(1:npl)) + if (allocated(pl%info)) pl%info(1:npl) = pl_sorted%info(ind(1:npl)) + if (allocated(pl%kin)) then + pl%kin(1:npl) = pl_sorted%kin(ind(1:npl)) + do i = 1, npl + do j = 1, pl%kin(i)%nchild + pl%kin(i)%child(j) = ind(pl%kin(i)%child(j)) + end do + end do + end if + deallocate(pl_sorted) + end associate + + return + end subroutine symba_util_sort_rearrange_pl + + + module subroutine symba_util_sort_rearrange_tp(self, ind) + !! author: David A. Minton + !! + !! Rearrange SyMBA test particle object in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(symba_tp), allocatable :: tp_sorted !! Temporary holder for sorted body + + associate(tp => self, ntp => self%nbody) + call util_sort_rearrange_tp(tp,ind) + allocate(tp_sorted, source=self) + if (allocated(tp%nplenc)) tp%nplenc(1:ntp) = tp_sorted%nplenc(ind(1:ntp)) + if (allocated(tp%levelg)) tp%levelg(1:ntp) = tp_sorted%levelg(ind(1:ntp)) + if (allocated(tp%levelm)) tp%levelm(1:ntp) = tp_sorted%levelm(ind(1:ntp)) + deallocate(tp_sorted) + end associate + + return + end subroutine symba_util_sort_rearrange_tp + + + module subroutine symba_util_spill_arr_info(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of particle origin information types + !! This is the inverse of a spill operation + implicit none + ! Arguments + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_particle_info), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine symba_util_spill_arr_info + + + module subroutine symba_util_spill_arr_kin(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of particle kinships + !! This is the inverse of a spill operation + implicit none + ! Arguments + type(symba_kinship), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + type(symba_kinship), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine symba_util_spill_arr_kin + + + module subroutine symba_util_spill_pl(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) SyMBA massive body particle structure from active list to discard list + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(symba_pl), intent(inout) :: self !! SyMBA massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + ! For each component, pack the discarded bodies into the discard object and do the inverse with the keeps + !> Spill all the common components + associate(keeps => self) + select type(discards) + class is (symba_pl) + call util_spill(keeps%lcollision, discards%lcollision, lspill_list, ldestructive) + call util_spill(keeps%lencounter, discards%lencounter, lspill_list, ldestructive) + call util_spill(keeps%lmtiny, discards%lmtiny, lspill_list, ldestructive) + call util_spill(keeps%nplenc, discards%nplenc, lspill_list, ldestructive) + call util_spill(keeps%ntpenc, discards%ntpenc, lspill_list, ldestructive) + call util_spill(keeps%levelg, discards%levelg, lspill_list, ldestructive) + call util_spill(keeps%levelm, discards%levelm, lspill_list, ldestructive) + call util_spill(keeps%isperi, discards%isperi, lspill_list, ldestructive) + call util_spill(keeps%peri, discards%peri, lspill_list, ldestructive) + call util_spill(keeps%atp, discards%atp, lspill_list, ldestructive) + call util_spill(keeps%info, discards%info, lspill_list, ldestructive) + call util_spill(keeps%kin, discards%kin, lspill_list, ldestructive) + + call util_spill_pl(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class symba_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine symba_util_spill_pl + + + module subroutine symba_util_spill_pltpenc(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) SyMBA encounter structure from active list to discard list + !! Note: Because the symba_plplenc currently does not contain any additional variable components, this method can recieve it as an input as well. + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + class(swiftest_encounter), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + associate(keeps => self) + select type(discards) + class is (symba_pltpenc) + call util_spill(keeps%level, discards%level, lspill_list, ldestructive) + call util_spill_encounter(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class symba_pltpenc or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine symba_util_spill_pltpenc + + + module subroutine symba_util_spill_tp(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) SyMBA test particle structure from active list to discard list + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + ! For each component, pack the discarded bodies into the discard object and do the inverse with the keeps + !> Spill all the common components + associate(keeps => self) + select type(discards) + class is (symba_tp) + call util_spill(keeps%nplenc, discards%nplenc, lspill_list, ldestructive) + call util_spill(keeps%levelg, discards%levelg, lspill_list, ldestructive) + call util_spill(keeps%levelm, discards%levelm, lspill_list, ldestructive) + + call util_spill_tp(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class symba_tp or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine symba_util_spill_tp + +end submodule s_symba_util \ No newline at end of file diff --git a/src/tides/tides_getacch_pl.f90 b/src/tides/tides_getacch_pl.f90 new file mode 100644 index 000000000..f0bf64cc7 --- /dev/null +++ b/src/tides/tides_getacch_pl.f90 @@ -0,0 +1,65 @@ +submodule(swiftest_classes) s_tides_kick_getacch + use swiftest +contains + + module subroutine tides_kick_getacch_pl(self, system) + !! author: Jennifer L.L. Pouplin, Carlisle A. wishard, and David A. Minton + !! + !! Calculated tidal torques from central body to any planet and from any planet to central body + !! planet - planet interactions are considered negligable. + !! This is a constant time lag model. + !! + !! Adapted from Mercury-T code from Bolmont et al. (2015) + !! + !! Reference: + !! Bolmont, E., Raymond, S.N., Leconte, J., Hersant, F., Correia, A.C.M., 2015. + !! Mercury-T : A new code to study tidally evolving multi-planet systems. + !! Applications to Kepler-62. A&A 583, A116. https://doi.org/10.1051/0004-6361/201525909 + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + ! Internals + integer(I4B) :: i + real(DP) :: rmag, vmag + real(DP), dimension(NDIM) :: r_unit, v_unit, h_unit, theta_unit, theta_dot, F_T + real(DP) :: Ftr, Ptopl, Ptocb, r5cbterm, r5plterm + + associate(pl => self, npl => self%nbody, cb => system%cb) + pl%atide(:,:) = 0.0_DP + cb%atide(:) = 0.0_DP + do i = 1, npl + rmag = norm2(pl%xh(:,i)) + vmag = norm2(pl%vh(:,i)) + r_unit(:) = pl%xh(:,i) / rmag + v_unit(:) = pl%vh(:,i) / vmag + h_unit(:) = r_unit(:) .cross. v_unit(:) + theta_unit(:) = h_unit(:) .cross. r_unit(:) + theta_dot = dot_product(pl%vh(:,i), theta_unit(:)) + + ! First calculate the tangential component of the force vector (eq. 5 & 6 of Bolmont et al. 2015) + ! The radial component is already computed in the obl_acc methods + r5cbterm = pl%Gmass(i)**2 * cb%k2 * cb%radius**5 + r5plterm = cb%Gmass**2 * pl%k2(i) * pl%radius(i)**5 + + Ptopl = 3 * r5plterm * pl%tlag(i) / rmag**7 + Ptocb = 3 * r5cbterm * cb%tlag / rmag**7 + + Ftr = -3 / rmag**7 * (r5cbterm + r5plterm) - 3 * vmag / rmag * (Ptocb + Ptopl) + + F_T(:) = (Ftr + (Ptocb + Ptopl) * dot_product(v_unit, r_unit) / rmag) * r_unit(:) & + + Ptopl * (pl%rot(:,i) - theta_dot(:)) .cross. r_unit(:) & + + Ptocb * (cb%rot(:) - theta_dot(:)) .cross. r_unit(:) + cb%atide(:) = cb%atide(:) + F_T(:) / cb%Gmass + pl%atide(:,i) = F_T(:) / pl%Gmass(i) + end do + + do i = 1, npl + pl%ah(:,i) = pl%ah(:,i) + pl%atide(:,i) + cb%atide(:) + end do + end associate + + return + end subroutine tides_kick_getacch_pl + +end submodule s_tides_kick_getacch \ No newline at end of file diff --git a/src/tides/tides_spin_step.f90 b/src/tides/tides_spin_step.f90 new file mode 100644 index 000000000..576aff8d7 --- /dev/null +++ b/src/tides/tides_spin_step.f90 @@ -0,0 +1,132 @@ +submodule(swiftest_classes) s_tides_step_spin + use swiftest + + type, extends(lambda_obj_tvar) :: tides_derivs_func + !! Base class for an lambda function object. This object takes no additional arguments other than the dependent variable x, an array of real numbers + procedure(tidederiv), pointer, nopass :: lambdaptr_tides_deriv + real(DP), dimension(:,:), allocatable :: xbeg + real(DP), dimension(:,:), allocatable :: xend + real(DP) :: dt + contains + generic :: init => tides_derivs_init + procedure :: evalt => tides_derivs_eval + procedure, nopass :: tides_derivs_init + end type + interface lambda_obj + module procedure tides_derivs_init + end interface + abstract interface + function tidederiv(x, t, dt, xbeg, xend) result(y) + ! Template for a 0 argument function + import DP, swiftest_nbody_system + real(DP), dimension(:), intent(in) :: x + real(DP), intent(in) :: t + real(DP), intent(in) :: dt + real(DP), dimension(:,:), intent(in) :: xbeg + real(DP), dimension(:,:), intent(in) :: xend + real(DP), dimension(:), allocatable :: y + end function + end interface + +contains + + module subroutine tides_step_spin_system(self, param, t, dt) + !! author: Jennifer L.L. Pouplin and David A. Minton + !! + !! Integrates the spin equations for central and massive bodies of the system subjected to tides. + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP), dimension(:), allocatable :: rot0, rot1 + real(DP) :: subt + real(DP), parameter :: tol=1e-6_DP !! Just a guess at the moment + real(DP) :: subdt + + associate(pl => self%pl, npl => self%pl%nbody, cb => self%cb) + allocate(rot0(NDIM*(npl+1))) + rot0 = [pack(pl%rot(:,1:npl),.true.), pack(cb%rot(:),.true.)] + ! Use this space call the ode_solver, passing tides_spin_derivs as the function: + subdt = dt / 20._DP + !rot1(:) = util_solve_rkf45(lambda_obj(tides_spin_derivs, subdt, pl%xbeg, pl%xend), rot0, dt, subdt tol) + ! Recover with unpack + !pl%rot(:,1:npl) = unpack(rot1... + !cb%rot(:) = unpack(rot1... + end associate + + return + end subroutine tides_step_spin_system + + + function tides_spin_derivs(rot_pl_cb, t, dt, xbeg, xend) result(drot) !! Need to add more arguments so we can pull in mass, radius, Ip, J2, etc... + !! author: Jennifer L.L. Pouplin and David A. Minton + !! + !! function used to calculate the derivatives that are fed to the ODE solver + implicit none + ! Arguments + real(DP), dimension(:,:), intent(in) :: rot_pl_cb !! Array of rotations. The last element is the central body, and all others are massive bodies + real(DP), intent(in) :: t !! Current time, which is used to interpolate the massive body positions + real(DP), intent(in) :: dt !! Total step size + real(DP), dimension(:,:), intent(in) :: xbeg + real(DP), dimension(:,:), intent(in) :: xend + ! Internals + real(DP), dimension(:,:), allocatable :: drot + real(DP), dimension(:), allocatable :: flatrot + real(DP), dimension(NDIM) :: N_Tcb, N_Rcb, N_Tpl, N_Rpl, xinterp + real(DP) :: C_cb, C_pl, r_dot_rot_cb, r_dot_rot_pl, rmag + integer(I4B) :: i, n + + + n = size(rot_pl_cb,2) + if (allocated(drot)) deallocate(drot) + allocate(drot, mold=rot_pl_cb) + drot(:,:) = 0.0_DP + do i = 1,n-1 + xinterp(:) = xbeg(:,i) + t / dt * (xend(:,i) - xbeg(:,i)) + ! Calculate Ncb and Npl as a function of xinterp + !drot(:,i) = -Mcb / (Mcb + Mpl(i)) * (N_Tpl + N_Rpl) + !drot(:,n) = drot(:,n) - Mcb / (Mcb + Mpl(i) * (N_Tcb + N_Rcb) + ! + end do + + return + end function tides_spin_derivs + + function tides_derivs_eval(self, x, t) result(y) + implicit none + ! Arguments + class(tides_derivs_func), intent(inout) :: self + real(DP), dimension(:), intent(in) :: x + real(DP), intent(in) :: t + ! Result + real(DP), dimension(:), allocatable :: y + if (associated(self%lambdaptr_tides_deriv)) then + y = self%lambdaptr_tides_deriv(x, t, self%dt, self%xbeg, self%xend) + else + error stop "Lambda function was not initialized" + end if + + return + end function tides_derivs_eval + + function tides_derivs_init(lambda, dt, xbeg, xend) result(f) + implicit none + ! Arguments + procedure(tidederiv) :: lambda + real(DP), intent(in) :: dt + real(DP), dimension(:,:), intent(in) :: xbeg + real(DP), dimension(:,:), intent(in) :: xend + ! Result + type(tides_derivs_func) :: f + f%lambdaptr_tides_deriv => lambda + f%dt = dt + allocate(f%xbeg, source = xbeg) + allocate(f%xend, source = xend) + + return + end function tides_derivs_init + +end submodule s_tides_step_spin \ No newline at end of file diff --git a/src/user/user_getacch.f90 b/src/user/user_getacch.f90 new file mode 100644 index 000000000..2775de3dd --- /dev/null +++ b/src/user/user_getacch.f90 @@ -0,0 +1,21 @@ +submodule(swiftest_classes) s_user_kick_getacch + use swiftest +contains + module subroutine user_kick_getacch_body(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Add user-supplied heliocentric accelerations to planets. + !! + !! Adapted from David E. Kaufmann's Swifter routine whm_user_kick_getacch.f90 + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody_system_object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters user parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the ste + + return + end subroutine user_kick_getacch_body + +end submodule s_user_kick_getacch diff --git a/src/util/util_append.f90 b/src/util/util_append.f90 new file mode 100644 index 000000000..0f7ac0bde --- /dev/null +++ b/src/util/util_append.f90 @@ -0,0 +1,307 @@ +submodule (swiftest_classes) s_util_append + use swiftest +contains + + module subroutine util_append_arr_char_string(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of character string type onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: arr !! Destination array + character(len=STRMAX), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine util_append_arr_char_string + + + module subroutine util_append_arr_DP(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of double precision type onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + real(DP), dimension(:), allocatable, intent(inout) :: arr !! Destination array + real(DP), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine util_append_arr_DP + + + module subroutine util_append_arr_DPvec(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of double precision vector type of size (NDIM, n) onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + real(DP), dimension(:,:), allocatable, intent(inout) :: arr !! Destination array + real(DP), dimension(:,:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source, dim=2) + end if + + if (allocated(arr)) then + narr = size(arr, dim=2) + else + allocate(arr(NDIM, nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(1, narr + 1:narr + nsrc) = pack(source(1,:), lsource_mask(:)) + arr(2, narr + 1:narr + nsrc) = pack(source(2,:), lsource_mask(:)) + arr(3, narr + 1:narr + nsrc) = pack(source(3,:), lsource_mask(:)) + else + arr(:, narr + 1:narr + nsrc) = source(:,:) + end if + + return + end subroutine util_append_arr_DPvec + + + module subroutine util_append_arr_I4B(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of integer(I4B) onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + integer(I4B), dimension(:), allocatable, intent(inout) :: arr !! Destination array + integer(I4B), dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine util_append_arr_I4B + + + module subroutine util_append_arr_logical(arr, source, lsource_mask) + !! author: David A. Minton + !! + !! Append a single array of logical type onto another. If the destination array is not allocated, or is not big enough, this will allocate space for it. + implicit none + ! Arguments + logical, dimension(:), allocatable, intent(inout) :: arr !! Destination array + logical, dimension(:), allocatable, intent(in) :: source !! Array to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + ! Internals + integer(I4B) :: narr, nsrc + + if (.not. allocated(source)) return + + if (allocated(arr)) then + narr = size(arr) + else + allocate(arr(nsrc)) + narr = 0 + end if + + if (present(lsource_mask)) then + nsrc = count(lsource_mask) + else + nsrc = size(source) + end if + + call util_resize(arr, narr + nsrc) + + if (present(lsource_mask)) then + arr(narr + 1:narr + nsrc) = pack(source(:), lsource_mask(:)) + else + arr(narr + 1:narr + nsrc) = source(:) + end if + + return + end subroutine util_append_arr_logical + + + module subroutine util_append_body(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one Swiftest body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + call util_append(self%name, source%name, lsource_mask) + call util_append(self%id, source%id, lsource_mask) + call util_append(self%status, source%status, lsource_mask) + call util_append(self%ldiscard, source%ldiscard, lsource_mask) + call util_append(self%lmask, source%lmask, lsource_mask) + call util_append(self%mu, source%mu, lsource_mask) + call util_append(self%xh, source%xh, lsource_mask) + call util_append(self%vh, source%vh, lsource_mask) + call util_append(self%xb, source%xb, lsource_mask) + call util_append(self%vb, source%vb, lsource_mask) + call util_append(self%ah, source%ah, lsource_mask) + call util_append(self%aobl, source%aobl, lsource_mask) + call util_append(self%atide, source%atide, lsource_mask) + call util_append(self%agr, source%agr, lsource_mask) + call util_append(self%ir3h, source%ir3h, lsource_mask) + call util_append(self%a, source%a, lsource_mask) + call util_append(self%e, source%e, lsource_mask) + call util_append(self%inc, source%inc, lsource_mask) + call util_append(self%capom, source%capom, lsource_mask) + call util_append(self%omega, source%omega, lsource_mask) + call util_append(self%capm, source%capm, lsource_mask) + + self%nbody = count(self%status(:) /= INACTIVE) + + return + end subroutine util_append_body + + + module subroutine util_append_pl(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one Swiftest body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + + select type(source) + class is (swiftest_pl) + call util_append_body(self, source, lsource_mask) + + call util_append(self%mass, source%mass, lsource_mask) + call util_append(self%Gmass, source%Gmass, lsource_mask) + call util_append(self%rhill, source%rhill, lsource_mask) + call util_append(self%radius, source%radius, lsource_mask) + call util_append(self%xbeg, source%xbeg, lsource_mask) + call util_append(self%xend, source%xend, lsource_mask) + call util_append(self%vbeg, source%vbeg, lsource_mask) + call util_append(self%density, source%density, lsource_mask) + call util_append(self%Ip, source%Ip, lsource_mask) + call util_append(self%rot, source%rot, lsource_mask) + call util_append(self%k2, source%k2, lsource_mask) + call util_append(self%Q, source%Q, lsource_mask) + call util_append(self%tlag, source%tlag, lsource_mask) + + call self%eucl_index() + class default + write(*,*) "Invalid object passed to the append method. Source must be of class swiftest_pl or its descendents" + call util_exit(FAILURE) + end select + + return + end subroutine util_append_pl + + + module subroutine util_append_tp(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one Swiftest body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (swiftest_tp) + call util_append_body(self, source, lsource_mask) + + call util_append(self%isperi, source%isperi, lsource_mask) + call util_append(self%peri, source%peri, lsource_mask) + call util_append(self%atp, source%atp, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class swiftest_tp or its descendents" + call util_exit(FAILURE) + end select + + return + end subroutine util_append_tp + +end submodule s_util_append \ No newline at end of file diff --git a/src/util/util_coord.f90 b/src/util/util_coord.f90 new file mode 100644 index 000000000..c10dbace7 --- /dev/null +++ b/src/util/util_coord.f90 @@ -0,0 +1,132 @@ +submodule(swiftest_classes) s_util_coord + use swiftest +contains + + module subroutine util_coord_h2b_pl(self, cb) + !! author: David A. Minton + !! + !! Convert massive bodies from heliocentric to barycentric coordinates (position and velocity) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_h2b.f90 + !! Adapted from Hal Levison's Swift routine coord_h2b.f + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + integer(I4B) :: i + real(DP) :: Gmtot + real(DP), dimension(NDIM) :: xtmp, vtmp + + if (self%nbody == 0) return + associate(pl => self, npl => self%nbody) + Gmtot = cb%Gmass + xtmp(:) = 0.0_DP + vtmp(:) = 0.0_DP + do i = 1, npl + Gmtot = Gmtot + pl%Gmass(i) + xtmp(:) = xtmp(:) + pl%Gmass(i) * pl%xh(:,i) + vtmp(:) = vtmp(:) + pl%Gmass(i) * pl%vh(:,i) + end do + cb%xb(:) = -xtmp(:) / Gmtot + cb%vb(:) = -vtmp(:) / Gmtot + do i = 1, npl + pl%xb(:,i) = pl%xh(:,i) + cb%xb(:) + pl%vb(:,i) = pl%vh(:,i) + cb%vb(:) + end do + end associate + + return + end subroutine util_coord_h2b_pl + + + module subroutine util_coord_h2b_tp(self, cb) + !! author: David A. Minton + !! + !! Convert massive bodies from heliocentric to barycentric coordinates (position and velocity) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_h2b_tp.f90 + !! Adapted from Hal Levison's Swift routine coord_h2b_tp.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + + if (self%nbody == 0) return + associate(ntp => self%nbody, xbcb => cb%xb, vbcb => cb%vb, status => self%status, & + xb => self%xb, xh => self%xh, vb => self%vb, vh => self%vh) + + where(status(1:ntp) /= INACTIVE) + xb(1, 1:ntp) = xh(1, 1:ntp) + xbcb(1) + xb(2, 1:ntp) = xh(2, 1:ntp) + xbcb(2) + xb(3, 1:ntp) = xh(3, 1:ntp) + xbcb(3) + + vb(1, 1:ntp) = vh(1, 1:ntp) + vbcb(1) + vb(2, 1:ntp) = vh(2, 1:ntp) + vbcb(2) + vb(3, 1:ntp) = vh(3, 1:ntp) + vbcb(3) + end where + end associate + + return + end subroutine util_coord_h2b_tp + + + module subroutine util_coord_b2h_pl(self, cb) + !! author: David A. Minton + !! + !! Convert massive bodies from barycentric to heliocentric coordinates (position and velocity) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_b2h.f90 + !! Adapted from Hal Levison's Swift routine coord_b2h.f + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(npl => self%nbody, xbcb => cb%xb, vbcb => cb%vb, xb => self%xb, xh => self%xh, & + vb => self%vb, vh => self%vh) + do i = 1, NDIM + xh(i, 1:npl) = xb(i, 1:npl) - xbcb(i) + vh(i, 1:npl) = vb(i, 1:npl) - vbcb(i) + end do + end associate + + return + end subroutine util_coord_b2h_pl + + + module subroutine util_coord_b2h_tp(self, cb) + !! author: David A. Minton + !! + !! Convert test particles from barycentric to heliocentric coordinates (position and velocity) + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_b2h_tp.f90 + !! Adapted from Hal Levison's Swift routine coord_b2h_tp.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + + if (self%nbody == 0) return + + associate(ntp => self%nbody, xbcb => cb%xb, vbcb => cb%vb, xb => self%xb, xh => self%xh, & + vb => self%vb, vh => self%vh, status => self%status) + where(status(1:ntp) /= INACTIVE) + xh(1, 1:ntp) = xb(1, 1:ntp) - xbcb(1) + xh(2, 1:ntp) = xb(2, 1:ntp) - xbcb(2) + xh(3, 1:ntp) = xb(3, 1:ntp) - xbcb(3) + + vh(1, 1:ntp) = vb(1, 1:ntp) - vbcb(1) + vh(2, 1:ntp) = vb(2, 1:ntp) - vbcb(2) + vh(3, 1:ntp) = vb(3, 1:ntp) - vbcb(3) + end where + end associate + + return + end subroutine util_coord_b2h_tp + +end submodule s_util_coord \ No newline at end of file diff --git a/src/util/util_copy.f90 b/src/util/util_copy.f90 new file mode 100644 index 000000000..f44777eec --- /dev/null +++ b/src/util/util_copy.f90 @@ -0,0 +1,29 @@ +submodule(swiftest_classes) s_util_copy + use swiftest +contains + +module subroutine util_copy_encounter(self, source) + !! author: David A. Minton + !! + !! Copies elements from the source encounter list into self. + implicit none + ! Arguments + class(swiftest_encounter), intent(inout) :: self !! Encounter list + class(swiftest_encounter), intent(in) :: source !! Source object to copy into + + associate(n => source%nenc) + self%nenc = n + self%lvdotr(1:n) = source%lvdotr(1:n) + self%status(1:n) = source%status(1:n) + self%index1(1:n) = source%index1(1:n) + self%index2(1:n) = source%index2(1:n) + self%x1(:,1:n) = source%x1(:,1:n) + self%x2(:,1:n) = source%x2(:,1:n) + self%v1(:,1:n) = source%v1(:,1:n) + self%v2(:,1:n) = source%v2(:,1:n) + end associate + + return +end subroutine util_copy_encounter + +end submodule s_util_copy diff --git a/src/util/util_exit.f90 b/src/util/util_exit.f90 new file mode 100644 index 000000000..e770c10f5 --- /dev/null +++ b/src/util/util_exit.f90 @@ -0,0 +1,36 @@ +submodule (swiftest_classes) s_util_exit + use swiftest +contains + + module subroutine util_exit(code) + !! author: David A. Minton + !! + !! Print termination message and exit program + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_exit.f90 + !! Adapted from Hal Levison's Swift routine util_exit.f + implicit none + ! Arguments + integer(I4B), intent(in) :: code + ! Internals + character(*), parameter :: BAR = '("------------------------------------------------")' + + select case(code) + case(SUCCESS) + write(*, SUCCESS_MSG) VERSION_NUMBER + write(*, BAR) + case(USAGE) + write(*, USAGE_MSG) + case(HELP) + write(*, HELP_MSG) + case default + write(*, FAIL_MSG) VERSION_NUMBER + write(*, BAR) + error stop + end select + + stop + + end subroutine util_exit + +end submodule s_util_exit diff --git a/src/util/util_fill.f90 b/src/util/util_fill.f90 new file mode 100644 index 000000000..4a5a70311 --- /dev/null +++ b/src/util/util_fill.f90 @@ -0,0 +1,219 @@ +submodule (swiftest_classes) s_util_fill + use swiftest +contains + + module subroutine util_fill_arr_char_string(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of type character strings + !! This is the inverse of a spill operation + implicit none + ! Arguments + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + character(len=STRMAX), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine util_fill_arr_char_string + + module subroutine util_fill_arr_DP(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of type DP + !! This is the inverse of a spill operation + implicit none + ! Arguments + real(DP), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine util_fill_arr_DP + + module subroutine util_fill_arr_DPvec(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of DP vectors with shape (NDIM, n) + !! This is the inverse of a spill operation + implicit none + ! Arguments + real(DP), dimension(:,:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:,:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + ! Internals + integer(I4B) :: i + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + do i = 1, NDIM + keeps(i,:) = unpack(keeps(i,:), .not.lfill_list(:), keeps(i,:)) + keeps(i,:) = unpack(inserts(i,:), lfill_list(:), keeps(i,:)) + end do + + return + end subroutine util_fill_arr_DPvec + + module subroutine util_fill_arr_I4B(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of type I4B + !! This is the inverse of a spill operation + implicit none + ! Arguments + integer(I4B), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + integer(I4B), dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine util_fill_arr_I4B + + module subroutine util_fill_arr_logical(keeps, inserts, lfill_list) + !! author: David A. Minton + !! + !! Performs a fill operation on a single array of logicals + !! This is the inverse of a spill operation + implicit none + ! Arguments + logical, dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + logical, dimension(:), allocatable, intent(in) :: inserts !! Array of values to insert into keep + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + if (.not.allocated(keeps) .or. .not.allocated(inserts)) return + + keeps(:) = unpack(keeps(:), .not.lfill_list(:), keeps(:)) + keeps(:) = unpack(inserts(:), lfill_list(:), keeps(:)) + + return + end subroutine util_fill_arr_logical + + + module subroutine util_fill_body(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new Swiftest generic particle structure into an old one. + !! This is the inverse of a spill operation. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_body), intent(in) :: inserts !! Inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + ! internals + integer(I4B) :: i + + ! For each component, pack the discarded bodies into the discard object and do the inverse with the keeps + !> Fill all the common components + associate(keeps => self) + call util_fill(keeps%id, inserts%id, lfill_list) + call util_fill(keeps%name, inserts%name, lfill_list) + call util_fill(keeps%status, inserts%status, lfill_list) + call util_fill(keeps%ldiscard, inserts%ldiscard, lfill_list) + call util_fill(keeps%lmask, inserts%lmask, lfill_list) + call util_fill(keeps%mu, inserts%mu, lfill_list) + call util_fill(keeps%xh, inserts%xh, lfill_list) + call util_fill(keeps%vh, inserts%vh, lfill_list) + call util_fill(keeps%xb, inserts%xb, lfill_list) + call util_fill(keeps%vb, inserts%vb, lfill_list) + call util_fill(keeps%ah, inserts%ah, lfill_list) + call util_fill(keeps%aobl, inserts%aobl, lfill_list) + call util_fill(keeps%agr, inserts%agr, lfill_list) + call util_fill(keeps%atide, inserts%atide, lfill_list) + call util_fill(keeps%a, inserts%a, lfill_list) + call util_fill(keeps%e, inserts%e, lfill_list) + call util_fill(keeps%inc, inserts%inc, lfill_list) + call util_fill(keeps%capom, inserts%capom, lfill_list) + call util_fill(keeps%omega, inserts%omega, lfill_list) + call util_fill(keeps%capm, inserts%capm, lfill_list) + + ! This is the base class, so will be the last to be called in the cascade. + keeps%nbody = size(keeps%id(:)) + end associate + + return + end subroutine util_fill_body + + + module subroutine util_fill_pl(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new Swiftest massive body structure into an old one. + !! This is the inverse of a spill operation. + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(in) :: inserts !! Swiftest body object to be inserted + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + ! Internals + integer(I4B) :: i + + associate(keeps => self) + + select type (inserts) ! The standard requires us to select the type of both arguments in order to access all the components + class is (swiftest_pl) + !> Fill components specific to the massive body class + call util_fill(keeps%mass, inserts%mass, lfill_list) + call util_fill(keeps%Gmass, inserts%Gmass, lfill_list) + call util_fill(keeps%rhill, inserts%rhill, lfill_list) + call util_fill(keeps%radius, inserts%radius, lfill_list) + call util_fill(keeps%density, inserts%density, lfill_list) + call util_fill(keeps%k2, inserts%k2, lfill_list) + call util_fill(keeps%Q, inserts%Q, lfill_list) + call util_fill(keeps%tlag, inserts%tlag, lfill_list) + call util_fill(keeps%xbeg, inserts%xbeg, lfill_list) + call util_fill(keeps%vbeg, inserts%vbeg, lfill_list) + call util_fill(keeps%Ip, inserts%Ip, lfill_list) + call util_fill(keeps%rot, inserts%rot, lfill_list) + + call util_fill_body(keeps, inserts, lfill_list) + class default + write(*,*) 'Error! fill method called for incompatible return type on swiftest_pl' + end select + end associate + + return + end subroutine util_fill_pl + + + module subroutine util_fill_tp(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new Swiftest test particle structure into an old one. + !! This is the inverse of a fill operation. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(in) :: inserts !! Swiftest body object to be inserted + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + + associate(keeps => self) + select type(inserts) + class is (swiftest_tp) + !> Spill components specific to the test particle class + call util_fill(keeps%isperi, inserts%isperi, lfill_list) + call util_fill(keeps%peri, inserts%peri, lfill_list) + call util_fill(keeps%atp, inserts%atp, lfill_list) + + call util_fill_body(keeps, inserts, lfill_list) + class default + write(*,*) 'Error! fill method called for incompatible return type on swiftest_tp' + end select + end associate + + return + end subroutine util_fill_tp + +end submodule s_util_fill \ No newline at end of file diff --git a/src/util/util_get_energy_momentum.f90 b/src/util/util_get_energy_momentum.f90 new file mode 100644 index 000000000..38701229d --- /dev/null +++ b/src/util/util_get_energy_momentum.f90 @@ -0,0 +1,117 @@ +submodule (swiftest_classes) s_util_get_energy_momentum + use swiftest +contains + module subroutine util_get_energy_momentum_system(self, param) + !! author: David A. Minton + !! + !! Compute total system angular momentum vector and kinetic, potential and total system energy + !! + !! Adapted from David E. Kaufmann Swifter routine symba_energy_eucl.f90 + !! + !! Adapted from Martin Duncan's Swift routine anal_energy.f + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i, j + integer(I8B) :: k + real(DP) :: rmag, v2, rot2, oblpot, hx, hy, hz, hsx, hsy, hsz + real(DP), dimension(self%pl%nbody) :: irh, kepl, kespinpl, pecb + real(DP), dimension(self%pl%nbody) :: Lplorbitx, Lplorbity, Lplorbitz + real(DP), dimension(self%pl%nbody) :: Lplspinx, Lplspiny, Lplspinz + real(DP), dimension(self%pl%nplpl) :: pepl + logical, dimension(self%pl%nplpl) :: lstatpl + logical, dimension(self%pl%nbody) :: lstatus + + associate(system => self, pl => self%pl, npl => self%pl%nbody, cb => self%cb) + system%Lorbit(:) = 0.0_DP + system%Lspin(:) = 0.0_DP + system%ke_orbit = 0.0_DP + system%ke_spin = 0.0_DP + + kepl(:) = 0.0_DP + Lplorbitx(:) = 0.0_DP + Lplorbity(:) = 0.0_DP + Lplorbitz(:) = 0.0_DP + Lplspinx(:) = 0.0_DP + Lplspiny(:) = 0.0_DP + Lplspinz(:) = 0.0_DP + lstatus(1:npl) = pl%status(1:npl) /= INACTIVE + !!$omp simd private(v2, rot2, hx, hy, hz) + do i = 1, npl + v2 = dot_product(pl%vb(:,i), pl%vb(:,i)) + hx = pl%xb(2,i) * pl%vb(3,i) - pl%xb(3,i) * pl%vb(2,i) + hy = pl%xb(3,i) * pl%vb(1,i) - pl%xb(1,i) * pl%vb(3,i) + hz = pl%xb(1,i) * pl%vb(2,i) - pl%xb(2,i) * pl%vb(1,i) + + ! Angular momentum from orbit + Lplorbitx(i) = pl%mass(i) * hx + Lplorbity(i) = pl%mass(i) * hy + Lplorbitz(i) = pl%mass(i) * hz + + ! Kinetic energy from orbit and spin + kepl(i) = pl%mass(i) * v2 + end do + + if (param%lrotation) then + do i = 1, npl + rot2 = dot_product(pl%rot(:,i), pl%rot(:,i)) + ! For simplicity, we always assume that the rotation pole is the 3rd principal axis + hsx = pl%Ip(3,i) * pl%radius(i)**2 * pl%rot(1,i) + hsy = pl%Ip(3,i) * pl%radius(i)**2 * pl%rot(2,i) + hsz = pl%Ip(3,i) * pl%radius(i)**2 * pl%rot(3,i) + + ! Angular momentum from spin + Lplspinx(i) = pl%mass(i) * hsx + Lplspiny(i) = pl%mass(i) * hsy + Lplspinz(i) = pl%mass(i) * hsz + kespinpl(i) = pl%mass(i) * pl%Ip(3, i) * pl%radius(i)**2 * rot2 + end do + else + kespinpl(:) = 0.0_DP + end if + + ! Do the central body potential energy component first + !$omp simd + do i = 1, npl + associate(px => pl%xh(1,i), py => pl%xh(2,i), pz => pl%xh(3,i)) + pecb(i) = -cb%mass * pl%mass(i) / sqrt(px**2 + py**2 + pz**2) + end associate + end do + + ! Do the potential energy between pairs of massive bodies + do k = 1, pl%nplpl + associate(ik => pl%k_plpl(1, k), jk => pl%k_plpl(2, k)) + pepl(k) = -pl%mass(ik) * pl%mass(jk) / norm2(pl%xb(:, jk) - pl%xb(:, ik)) + lstatpl(k) = (lstatus(ik) .and. lstatus(jk)) + end associate + end do + + system%ke_orbit = 0.5_DP * sum(kepl(1:npl), lstatus(:)) + if (param%lrotation) system%ke_spin = 0.5_DP * sum(kespinpl(1:npl), lstatus(:)) + + system%pe = sum(pepl(:), lstatpl(:)) + sum(pecb(2:npl), lstatus(2:npl)) + + ! Potential energy from the oblateness term + if (param%loblatecb) then + !$omp simd + do i = 1, npl + irh(i) = 1.0_DP / norm2(pl%xh(:,i)) + end do + call obl_pot(npl, cb%mass, pl%mass, cb%j2rp2, cb%j4rp4, pl%xh, irh, oblpot) + system%pe = system%pe + oblpot + end if + + system%Lorbit(1) = sum(Lplorbitx(1:npl), lstatus(1:npl)) + system%Lorbit(2) = sum(Lplorbity(1:npl), lstatus(1:npl)) + system%Lorbit(3) = sum(Lplorbitz(1:npl), lstatus(1:npl)) + + system%Lspin(1) = sum(Lplspinx(1:npl), lstatus(1:npl)) + system%Lspin(2) = sum(Lplspiny(1:npl), lstatus(1:npl)) + system%Lspin(3) = sum(Lplspinz(1:npl), lstatus(1:npl)) + end associate + + return + end subroutine util_get_energy_momentum_system + +end submodule s_util_get_energy_momentum diff --git a/src/util/util_minimize_bfgs.f90 b/src/util/util_minimize_bfgs.f90 new file mode 100644 index 000000000..fbd48c8c2 --- /dev/null +++ b/src/util/util_minimize_bfgs.f90 @@ -0,0 +1,584 @@ +submodule (swiftest_classes) s_util_minimize_bfgs + use swiftest +contains + module function util_minimize_bfgs(f, N, x0, eps, lerr) result(x1) + !! author: David A. Minton + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! This function implements the Broyden-Fletcher-Goldfarb-Shanno method to determine the minimum of a function of N variables. + !! It recieves as input: + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! N : Number of variables of function f + !! x0 : Initial starting value of x + !! eps : Accuracy of 1 - dimensional minimization at each step + !! The outputs include + !! lerr : Returns .true. if it could not find the minimum + !! Returns + !! x1 : Final minimum (all 0 if none found) + !! 0 = No miniumum found + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + use, intrinsic :: ieee_exceptions + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0 + real(DP), intent(in) :: eps + logical, intent(out) :: lerr + ! Result + real(DP), dimension(:), allocatable :: x1 + ! Internals + integer(I4B) :: i, j, k, l, conv, num + integer(I4B), parameter :: MAXLOOP = 1000 !! Maximum number of loops before method is determined to have failed + real(DP), parameter :: graddelta = 1e-4_DP !! Delta x for gradient calculations + real(DP), dimension(N) :: S !! Direction vectors + real(DP), dimension(N,N) :: H !! Approximated inverse Hessian matrix + real(DP), dimension(N) :: grad1 !! gradient of f + real(DP), dimension(N) :: grad0 !! old value of gradient + real(DP) :: astar !! 1D minimized value + real(DP), dimension(N) :: y, P + real(DP), dimension(N,N) :: PP, PyH, HyP + real(DP) :: yHy, Py + type(ieee_status_type) :: original_fpe_status + logical, dimension(:), allocatable :: fpe_flag + + call ieee_get_status(original_fpe_status) ! Save the original floating point exception status + call ieee_set_flag(ieee_all, .false.) ! Set all flags to quiet + allocate(fpe_flag(size(ieee_usual))) + + lerr = .false. + allocate(x1, source=x0) + ! Initialize approximate Hessian with the identity matrix (i.e. begin with method of steepest descent) + ! Get initial gradient and initialize arrays for updated values of gradient and x + H(:,:) = reshape([((0._DP, i=1, j-1), 1._DP, (0._DP, i=j+1, N), j=1, N)], [N,N]) + grad0 = gradf(f, N, x0(:), graddelta, lerr) + if (lerr) then + call ieee_set_status(original_fpe_status) + return + end if + grad1(:) = grad0(:) + do i = 1, MAXLOOP + !check for convergence + conv = count(abs(grad1(:)) > eps) + if (conv == 0) then + !write(*,*) "BFGS converged on gradient after ",i," iterations" + exit + end if + S(:) = -matmul(H(:,:), grad1(:)) + astar = minimize1D(f, x1, S, N, graddelta, lerr) + if (lerr) then + !write(*,*) "Exiting BFGS with error in minimize1D step" + exit + end if + ! Get new x values + P(:) = astar * S(:) + x1(:) = x1(:) + P(:) + ! Calculate new gradient + grad0(:) = grad1(:) + grad1 = gradf(f, N, x1, graddelta, lerr) + y(:) = grad1(:) - grad0(:) + Py = sum(P(:) * y(:)) + ! set up factors for H matrix update + yHy = 0._DP + do k = 1, N + do j = 1, N + yHy = yHy + y(j) * H(j,k) * y(k) + end do + end do + ! prevent divide by zero (convergence) + if (abs(Py) < tiny(Py)) then + !write(*,*) "BFGS Converged on tiny Py after ",i," iterations" + exit + end if + ! set up update + PyH(:,:) = 0._DP + HyP(:,:) = 0._DP + do k = 1, N + do j = 1, N + PP(j, k) = P(j) * P(k) + do l = 1, N + PyH(j, k) = PyH(j, k) + P(j) * y(l) * H(l,k) + HyP(j, k) = HyP(j, k) + P(k) * y(l) * H(j,l) + end do + end do + end do + ! update H matrix + H(:,:) = H(:,:) + ((1._DP - yHy / Py) * PP(:,:) - PyH(:,:) - HyP(:,:)) / Py + ! Normalize to prevent it from blowing up if it takes many iterations to find a solution + H(:,:) = H(:,:) / norm2(H(:,:)) + ! Stop everything if there are any exceptions to allow the routine to fail gracefully + call ieee_get_flag(ieee_usual, fpe_flag) + if (any(fpe_flag)) exit + if (i == MAXLOOP) then + lerr = .true. + !write(*,*) "BFGS ran out of loops!" + end if + end do + call ieee_get_flag(ieee_usual, fpe_flag) + lerr = lerr .or. any(fpe_flag) + !if (any(fpe_flag)) write(*,*) 'BFGS did not converge due to fpe' + !if (lerr) write(*,*) "BFGS did not converge!" + call ieee_set_status(original_fpe_status) + + return + + contains + + function gradf(f, N, x1, dx, lerr) result(grad) + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! Purpose: Estimates the gradient of a function using a central difference + !! approximation + !! Inputs: + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! N : number of variables N + !! x1 : x value array + !! dx : step size to use when calculating derivatives + !! Outputs: + !! lerr : .true. if an error occurred. Otherwise returns .false. + !! Returns + !! grad : N sized array containing estimated gradient of f at x1 + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x1 + real(DP), intent(in) :: dx + logical, intent(out) :: lerr + ! Result + real(DP), dimension(N) :: grad + ! Internals + integer(I4B) :: i, j + real(DP), dimension(N) :: xp, xm + real(DP) :: fp, fm + logical :: lerrp, lerrm + + do i = 1, N + do j = 1, N + if (j == i) then + xp(j) = x1(j) + dx + xm(j) = x1(j) - dx + else + xp(j) = x1(j) + xm(j) = x1(j) + end if + end do + select type (f) + class is (lambda_obj_err) + fp = f%eval(xp) + lerrp = f%lerr + fm = f%eval(xm) + lerrm = f%lerr + lerr = lerrp .or. lerrm + class is (lambda_obj) + fp = f%eval(xp) + fm = f%eval(xm) + lerr = .false. + end select + grad(i) = (fp - fm) / (2 * dx) + if (lerr) return + end do + return + end function gradf + + function minimize1D(f, x0, S, N, eps, lerr) result(astar) + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! This program find the minimum of a function of N variables in a single direction + !! S using in sequence: + !! 1. A Bracketing method + !! 2. The golden section method + !! 3. A quadratic polynomial fit + !! Inputs + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! x0 : Array of size N of initial x values + !! S : Array of size N that determines the direction of minimization + !! N : Number of variables of function f + !! eps : Accuracy of 1 - dimensional minimization at each step + !! Output + !! lerr : .true. if an error occurred. Otherwise returns .false. + !! Returns + !! astar : Final minimum along direction S + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0, S + real(DP), intent(in) :: eps + logical, intent(out) :: lerr + ! Result + real(DP) :: astar + ! Internals + integer(I4B) :: num = 0 + real(DP), parameter :: step = 0.7_DP !! Bracketing method step size + real(DP), parameter :: gam = 1.2_DP !! Bracketing method expansion parameter + real(DP), parameter :: greduce = 0.2_DP !! Golden section method reduction factor + real(DP), parameter :: greduce2 = 0.1_DP ! Secondary golden section method reduction factor + real(DP) :: alo, ahi !! High and low values for 1 - D minimization routines + real(DP), parameter :: a0 = epsilon(1.0_DP) !! Initial guess of alpha + + alo = a0 + call bracket(f, x0, S, N, gam, step, alo, ahi, lerr) + if (lerr) then + !write(*,*) "BFGS bracketing step failed!" + return + end if + if (abs(alo - ahi) < eps) then + astar = alo + lerr = .false. + return + end if + call golden(f, x0, S, N, greduce, alo, ahi, lerr) + if (lerr) then + !write(*,*) "BFGS golden section step failed!" + return + end if + if (abs(alo - ahi) < eps) then + astar = alo + lerr = .false. + return + end if + call quadfit(f, x0, S, N, eps, alo, ahi, lerr) + if (lerr) then + !write(*,*) "BFGS quadfit failed!" + return + end if + if (abs(alo - ahi) < eps) then + astar = alo + lerr = .false. + return + end if + ! Quadratic fit method won't converge, so finish off with another golden section + call golden(f, x0, S, N, greduce2, alo, ahi, lerr) + if (.not. lerr) astar = (alo + ahi) / 2.0_DP + return + end function minimize1D + + function n2one(f, x0, S, N, a, lerr) result(fnew) + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0, S + real(DP), intent(in) :: a + logical, intent(out) :: lerr + + ! Return + real(DP) :: fnew + ! Internals + real(DP), dimension(N) :: xnew + integer(I4B) :: i + + xnew(:) = x0(:) + a * S(:) + fnew = f%eval(xnew(:)) + select type(f) + class is (lambda_obj_err) + lerr = f%lerr + class is (lambda_obj) + lerr = .false. + end select + return + end function n2one + + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + subroutine bracket(f, x0, S, N, gam, step, lo, hi, lerr) + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! This subroutine brackets the minimum. It recieves as input: + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! x0 : Array of size N of initial x values + !! S : Array of size N that determines the direction of minimization + !! gam : expansion parameter + !! step : step size + !! lo : initial guess of lo bracket value + !! The outputs include + !! lo : lo bracket + !! hi : hi bracket + !! lerr : .true. if an error occurred. Otherwise returns .false. + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0, S + real(DP), intent(in) :: gam, step + real(DP), intent(inout) :: lo + real(DP), intent(out) :: hi + logical, intent(out) :: lerr + ! Internals + real(DP) :: a0, a1, a2, atmp, da + real(DP) :: f0, f1, f2 + integer(I4B) :: i, j + integer(I4B), parameter :: MAXLOOP = 100 ! maximum number of loops before method is determined to have failed + real(DP), parameter :: eps = epsilon(lo) ! small number precision to test floating point equality + + ! set up initial bracket points + a0 = lo + da = step + a1 = a0 + da + a2 = a0 + 2 * da + f0 = n2one(f, x0, S, N, a0, lerr) + if (lerr) return + f1 = n2one(f, x0, S, N, a1, lerr) + if (lerr) return + f2 = n2one(f, x0, S, N, a2, lerr) + if (lerr) return + ! loop over bracket method until either min is bracketed method fails + do i = 1, MAXLOOP + if ((f0 > f1) .and. (f1 < f2)) then ! Minimum was found + lo = a0 + hi = a2 + return + else if ((f0 >= f1) .and. (f1 > f2)) then ! Function appears to decrease + da = da * gam + atmp = a2 + da + a0 = a1 + a1 = a2 + a2 = atmp + f0 = f1 + f1 = f2 + f2 = n2one(f, x0, S, N, a2, lerr) + else if ((f0 < f1) .and. (f1 <= f2)) then ! Function appears to increase + da = da * gam + atmp = a0 - da + a2 = a1 + a1 = a0 + a0 = atmp + f2 = f1 + f0 = n2one(f, x0, S, N, a0, lerr) + else if ((f0 < f1) .and. (f1 > f2)) then ! We are at a peak. Pick the direction that descends the fastest + da = da * gam + if (f2 > f0) then ! LHS is lower than RHS + atmp = a2 + da + a0 = a1 + a1 = a2 + a2 = atmp + f0 = f1 + f1 = f2 + f2 = n2one(f, x0, S, N, a2, lerr) + else ! RHS is lower than LHS + atmp = a0 - da + a2 = a1 + a1 = a0 + a0 = atmp + f2 = f1 + f1 = f2 + f0 = n2one(f, x0, S, N, a0, lerr) + end if + else if ((f0 > f1) .and. (abs(f2 - f1) <= eps)) then ! Decrasging but RHS equal + da = da * gam + atmp = a2 + da + a2 = atmp + f2 = n2one(f, x0, S, N, a2, lerr) + else if ((abs(f0 - f1) < eps) .and. (f1 < f2)) then ! Increasing but LHS equal + da = da * gam + atmp = a0 - da + a0 = atmp + f0 = n2one(f, x0, S, N, a0, lerr) + else ! all values equal. Expand in either direction and try again + a0 = a0 - da + a2 = a2 + da + f0 = n2one(f, x0, S, N, a0, lerr) + if (lerr) exit ! An error occurred while evaluating the function + f2 = n2one(f, x0, S, N, a2, lerr) + end if + if (lerr) exit ! An error occurred while evaluating the function + end do + lerr = .true. + return ! no minimum found + end subroutine bracket + + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + subroutine golden(f, x0, S, N, eps, lo, hi, lerr) + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! This function uses the golden section method to reduce the starting interval lo, hi by some amount sigma. + !! It recieves as input: + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! x0 : Array of size N of initial x values + !! S : Array of size N that determines the direction of minimization + !! gam : expansion parameter + !! eps : reduction interval in range (0 < sigma < 1) such that: + !! hi(new) - lo(new) = eps * (hi(old) - lo(old)) + !! lo : initial guess of lo bracket value + !! The outputs include + !! lo : lo bracket + !! hi : hi bracket + !! lerr : .true. if an error occurred. Otherwise returns .false. + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0, S + real(DP), intent(in) :: eps + real(DP), intent(inout) :: lo + real(DP), intent(out) :: hi + logical, intent(out) :: lerr + ! Internals + real(DP), parameter :: tau = 0.5_DP * (sqrt(5.0_DP) - 1.0_DP) ! Golden section constant + integer(I4B), parameter :: MAXLOOP = 40 ! maximum number of loops before method is determined to have failed (unlikely, but could occur if no minimum exists between lo and hi) + real(DP) :: i0 ! Initial interval value + real(DP) :: a1, a2 + real(DP) :: f1, f2 + integer(I4B) :: i, j + + i0 = hi - lo + a1 = hi - tau * i0 + a2 = lo + tau * i0 + f1 = n2one(f, x0, S, N, a1, lerr) + if (lerr) return + f2 = n2one(f, x0, S, N, a2, lerr) + if (lerr) return + do i = 1, MAXLOOP + if (abs((hi - lo) / i0) <= eps) return ! interval reduced to input amount + if (f2 > f1) then + hi = a2 + a2 = a1 + f2 = f1 + a1 = hi - tau * (hi - lo) + f1 = n2one(f, x0, S, N, a1, lerr) + else + lo = a1 + a1 = a2 + f2 = f1 + a2 = hi - (1.0_DP - tau) * (hi - lo) + f2 = n2one(f, x0, S, N, a2, lerr) + end if + if (lerr) exit + end do + lerr = .true. + return ! search took too many iterations - no minimum found + end subroutine golden + + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + subroutine quadfit(f, x0, S, N, eps, lo, hi, lerr) + ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + !! This function uses a quadratic polynomial fit to locate the minimum of a function + !! to some accuracy eps. It recieves as input: + !! f%eval(x) : lambda function object containing the objective function as the eval metho + !! lo : low bracket value + !! hi : high bracket value + !! eps : desired accuracy of final minimum location + !! The outputs include + !! lo : final minimum location + !! hi : final minimum location + !! Notes: Uses the ieee_exceptions intrinsic module to allow for graceful failure due to floating point exceptions, which won't terminate the run. + !! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + implicit none + ! Arguments + integer(I4B), intent(in) :: N + class(lambda_obj), intent(inout) :: f + real(DP), dimension(:), intent(in) :: x0, S + real(DP), intent(in) :: eps + real(DP), intent(inout) :: lo + real(DP), intent(out) :: hi + logical, intent(out) :: lerr + ! Internals + integer(I4B), parameter :: MAXLOOP = 20 ! maximum number of loops before method is determined to have failed. + real(DP) :: a1, a2, a3, astar ! three points for the polynomial fit and polynomial minimum + real(DP) :: f1, f2, f3, fstar ! three function values for the polynomial and polynomial minimum + real(DP), dimension(3) :: row_1, row_2, row_3, rhs, soln ! matrix for 3 equation solver (gaussian elimination) + real(DP), dimension(3,3) :: lhs + real(DP) :: d1, d2, d3, aold, denom, errval + integer(I4B) :: i + + lerr = .false. + ! Get initial a1, a2, a3 values + a1 = lo + a2 = lo + 0.5_DP * (hi - lo) + a3 = hi + aold = a1 + astar = a2 + f1 = n2one(f, x0, S, N, a1, lerr) + if (lerr) return + f2 = n2one(f, x0, S, N, a2, lerr) + if (lerr) return + f3 = n2one(f, x0, S, N, a3, lerr) + if (lerr) return + do i = 1, MAXLOOP + ! check to see if convergence is reached and exit + errval = abs((astar - aold) / astar) + call ieee_get_flag(ieee_usual, fpe_flag) + if (any(fpe_flag)) then + !write(*,*) 'quadfit fpe' + !write(*,*) 'aold : ',aold + !write(*,*) 'astar: ',astar + lerr = .true. + exit + end if + if (errval < eps) then + lo = astar + hi = astar + exit + end if + ! Set up system for gaussian elimination equation solver + row_1 = [1.0_DP, a1, a1**2] + row_2 = [1.0_DP, a2, a2**2] + row_3 = [1.0_DP, a3, a3**2] + rhs = [f1, f2, f3] + lhs(1, :) = row_1 + lhs(2, :) = row_2 + lhs(3, :) = row_3 + ! Solve system of equations + soln(:) = util_solve_linear_system(lhs, rhs, 3, lerr) + call ieee_set_flag(ieee_all, .false.) ! Set all flags back to quiet + call ieee_set_halting_mode(ieee_divide_by_zero, .false.) + if (lerr) then + !write(*,*) 'quadfit fpe:' + !write(*,*) 'util_solve_linear_system failed' + exit + end if + aold = astar + if (soln(2) == soln(3)) then ! Handles the case where they are both 0. 0/0 is an unhandled exception + astar = -0.5_DP + else + astar = -soln(2) / (2 * soln(3)) + end if + call ieee_get_flag(ieee_usual, fpe_flag) + if (any(fpe_flag)) then + !write(*,*) 'quadfit fpe' + !write(*,*) 'soln(2:3): ',soln(2:3) + !write(*,*) 'a1, a2, a3' + !write(*,*) a1, a2, a3 + !write(*,*) 'f1, f2, f3' + !write(*,*) f1, f2, f3 + lerr = .true. + exit + end if + fstar = n2one(f, x0, S, N, astar, lerr) + if (lerr) exit + ! keep the three closest a values to astar and discard the fourth + d1 = abs(a1 - astar) + d2 = abs(a2 - astar) + d3 = abs(a3 - astar) + + if (d1 > d2) then + if (d1 > d3) then + f1 = fstar + a1 = astar + else if (d3 > d2) then + f3 = fstar + a3 = astar + end if + else + if (d2 > d3) then + f2 = fstar + a2 = astar + else if (d3 > d1) then + f3 = fstar + a3 = astar + end if + end if + end do + if (lerr) return + lo = a1 + hi = a3 + return + end subroutine quadfit + + end function util_minimize_bfgs +end submodule s_util_minimize_bfgs \ No newline at end of file diff --git a/src/util/util_peri.f90 b/src/util/util_peri.f90 new file mode 100644 index 000000000..66f2254e1 --- /dev/null +++ b/src/util/util_peri.f90 @@ -0,0 +1,64 @@ +submodule (swiftest_classes) s_util_peri + use swiftest +contains + + module subroutine util_peri_tp(self, system, param) + !! author: David A. Minton + !! + !! Determine system pericenter passages for test particles + !! Note: If the coordinate system used is barycentric, then this routine assumes that the barycentric coordinates in the + !! test particle structures are up-to-date and are not recomputed + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_peri.f90 + !! Adapted from Hal Levison's Swift routine util_peri.f + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP) :: e + real(DP), dimension(:), allocatable :: vdotr + + associate(tp => self, ntp => self%nbody) + allocate(vdotr(ntp)) + if (param%qmin_coord == "HELIO") then + do i = 1, ntp + vdotr(i) = dot_product(tp%xh(:, i), tp%vh(:, i)) + if (tp%isperi(i) == -1) then + if (vdotr(i) >= 0.0_DP) then + tp%isperi(i) = 0 + call orbel_xv2aeq(tp%mu(i), tp%xh(:, i), tp%vh(:, i), tp%atp(i), e, tp%peri(i)) + end if + else + if (vdotr(i) > 0.0_DP) then + tp%isperi(i) = 1 + else + tp%isperi(i) = -1 + end if + end if + end do + else + do i = 1, ntp + vdotr(i) = dot_product(tp%xb(:, i), tp%vb(:, i)) + if (tp%isperi(i) == -1) then + if (vdotr(i) >= 0.0_DP) then + tp%isperi(i) = 0 + call orbel_xv2aeq(system%Gmtot, tp%xb(:, i), tp%vb(:, i), tp%atp(i), e, tp%peri(i)) + end if + else + if (vdotr(i) > 0.0_DP) then + tp%isperi(i) = 1 + else + tp%isperi(i) = -1 + end if + end if + end do + end if + end associate + + return + end subroutine util_peri_tp + +end submodule s_util_peri diff --git a/src/util/util_resize.f90 b/src/util/util_resize.f90 new file mode 100644 index 000000000..c6d5aa34f --- /dev/null +++ b/src/util/util_resize.f90 @@ -0,0 +1,297 @@ +submodule (swiftest_classes) s_util_resize + use swiftest +contains + module subroutine util_resize_arr_char_string(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of type character string. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + character(len=STRMAX), dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine util_resize_arr_char_string + + + module subroutine util_resize_arr_DP(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of double precision type. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + real(DP), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + real(DP), dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine util_resize_arr_DP + + + module subroutine util_resize_arr_DPvec(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of double precision vectors of size (NDIM, n). Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + real(DP), dimension(:,:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + real(DP), dimension(:,:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr, dim=2) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(NDIM, nnew)) + if (nnew > nold) then + tmp(:, 1:nold) = arr(:, 1:nold) + else + tmp(:, 1:nnew) = arr(:, 1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine util_resize_arr_DPvec + + + module subroutine util_resize_arr_I4B(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of integer type. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + integer(I4B), dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + integer(I4B), dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine util_resize_arr_I4B + + + module subroutine util_resize_arr_logical(arr, nnew) + !! author: David A. Minton + !! + !! Resizes an array component of logical type. Array will only be resized if has previously been allocated. Passing nnew = 0 will deallocate. + implicit none + ! Arguments + logical, dimension(:), allocatable, intent(inout) :: arr !! Array to resize + integer(I4B), intent(in) :: nnew !! New size + ! Internals + logical, dimension(:), allocatable :: tmp !! Temporary storage array in case the input array is already allocated + integer(I4B) :: nold !! Old size + + if (.not. allocated(arr) .or. nnew < 0) return + + nold = size(arr) + if (nnew == nold) return + + if (nnew == 0) then + deallocate(arr) + return + end if + + allocate(tmp(nnew)) + if (nnew > nold) then + tmp(1:nold) = arr(1:nold) + else + tmp(1:nnew) = arr(1:nnew) + end if + call move_alloc(tmp, arr) + + return + end subroutine util_resize_arr_logical + + + module subroutine util_resize_body(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize(self%name, nnew) + call util_resize(self%id, nnew) + call util_resize(self%status, nnew) + call util_resize(self%ldiscard, nnew) + call util_resize(self%lmask, nnew) + call util_resize(self%mu, nnew) + call util_resize(self%xh, nnew) + call util_resize(self%vh, nnew) + call util_resize(self%xb, nnew) + call util_resize(self%vb, nnew) + call util_resize(self%ah, nnew) + call util_resize(self%aobl, nnew) + call util_resize(self%atide, nnew) + call util_resize(self%agr, nnew) + call util_resize(self%ir3h, nnew) + call util_resize(self%a, nnew) + call util_resize(self%e, nnew) + call util_resize(self%inc, nnew) + call util_resize(self%capom, nnew) + call util_resize(self%omega, nnew) + call util_resize(self%capm, nnew) + self%nbody = count(self%status(1:nnew) /= INACTIVE) + + return + end subroutine util_resize_body + + + module subroutine util_resize_encounter(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of the encounter list against the required size and extends it by a factor of 2 more than requested if it is too small. + !! Note: The reason to extend it by a factor of 2 is for performance. When there are many enounters per step, resizing every time you want to add an + !! encounter takes significant computational effort. Resizing by a factor of 2 is a tradeoff between performance (fewer resize calls) and memory managment + !! Memory usage grows by a factor of 2 each time it fills up, but no more. + implicit none + ! Arguments + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter list + integer(I4B), intent(in) :: nnew !! New size of list needed + ! Internals + class(swiftest_encounter), allocatable :: enc_temp + integer(I4B) :: nold + logical :: lmalloc + + lmalloc = allocated(self%status) + if (lmalloc) then + nold = size(self%status) + else + nold = 0 + end if + if (nnew > nold) then + if (lmalloc) allocate(enc_temp, source=self) + call self%setup(2 * nnew) + if (lmalloc) then + call self%copy(enc_temp) + deallocate(enc_temp) + end if + else + self%status(nnew+1:nold) = INACTIVE + end if + self%nenc = nnew + + return + end subroutine util_resize_encounter + + + module subroutine util_resize_pl(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_body(self, nnew) + + call util_resize(self%mass, nnew) + call util_resize(self%Gmass, nnew) + call util_resize(self%rhill, nnew) + call util_resize(self%radius, nnew) + call util_resize(self%xbeg, nnew) + call util_resize(self%xend, nnew) + call util_resize(self%vbeg, nnew) + call util_resize(self%density, nnew) + call util_resize(self%Ip, nnew) + call util_resize(self%rot, nnew) + call util_resize(self%k2, nnew) + call util_resize(self%Q, nnew) + call util_resize(self%tlag, nnew) + call self%eucl_index() + + return + end subroutine util_resize_pl + + + module subroutine util_resize_tp(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_body(self, nnew) + + call util_resize(self%isperi, nnew) + call util_resize(self%peri, nnew) + call util_resize(self%atp, nnew) + + return + end subroutine util_resize_tp + + +end submodule s_util_resize \ No newline at end of file diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 new file mode 100644 index 000000000..86e021ab6 --- /dev/null +++ b/src/util/util_set.f90 @@ -0,0 +1,138 @@ +submodule(swiftest_classes) s_util_set + !! author: David A. Minton + !! This submodule contains a collection of setter method implementations + use swiftest +contains + + module subroutine util_set_beg_end_pl(self, xbeg, xend, vbeg) + !! author: David A. Minton + !! + !! Sets one or more of the values of xbeg, xend, and vbeg + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + real(DP), dimension(:,:), intent(in), optional :: xbeg, xend, vbeg + + if (present(xbeg)) then + if (allocated(self%xbeg)) deallocate(self%xbeg) + allocate(self%xbeg, source=xbeg) + end if + if (present(xend)) then + if (allocated(self%xend)) deallocate(self%xend) + allocate(self%xend, source=xend) + end if + if (present(vbeg)) then + if (allocated(self%vbeg)) deallocate(self%vbeg) + allocate(self%vbeg, source=vbeg) + end if + + return + end subroutine util_set_beg_end_pl + + + module subroutine util_set_ir3h(self) + !! author: David A. Minton + !! + !! Sets the inverse heliocentric radius term (1/rh**3) for all bodies in a structure + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + ! Internals + integer(I4B) :: i + real(DP) :: r2, irh + + if (self%nbody > 0) then + + do i = 1, self%nbody + r2 = dot_product(self%xh(:, i), self%xh(:, i)) + irh = 1.0_DP / sqrt(r2) + self%ir3h(i) = irh / r2 + end do + end if + + return + end subroutine util_set_ir3h + + + module subroutine util_set_msys(self) + !! author: David A. Minton + !! + !! Sets the value of msys and the vector mass quantities based on the total mass of the system + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nobdy system object + + self%Gmtot = self%cb%Gmass + sum(self%pl%Gmass(1:self%pl%nbody), self%pl%status(1:self%pl%nbody) /= INACTIVE) + + return + end subroutine util_set_msys + + + module subroutine util_set_mu_pl(self, cb) + !! author: David A. Minton + !! + !! Computes G * (M + m) for each massive body + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + + if (self%nbody > 0) self%mu(:) = cb%Gmass + self%Gmass(:) + + return + end subroutine util_set_mu_pl + + + module subroutine util_set_mu_tp(self, cb) + !! author: David A. Minton + !! + !! Converts certain scalar values to arrays so that they can be used in elemental functions + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + + if (self%nbody > 0) self%mu(:) = cb%Gmass + + return + end subroutine util_set_mu_tp + + + module subroutine util_set_rhill(self,cb) + !! author: David A. Minton + !! + !! Sets the value of the Hill's radius + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + + if (self%nbody > 0) then + call self%xv2el(cb) + self%rhill(:) = self%a(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD + end if + + return + end subroutine util_set_rhill + + + module subroutine util_set_rhill_approximate(self,cb) + !! author: David A. Minton + !! + !! Sets the approximate value of the Hill's radius using the heliocentric radius instead of computing the semimajor axis + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + real(DP), dimension(:), allocatable :: rh + + if (self%nbody > 0) then + rh(:) = .mag. self%xh(:,:) + self%rhill(:) = rh(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD + end if + + return + end subroutine util_set_rhill_approximate + +end submodule s_util_set \ No newline at end of file diff --git a/src/util/util_solve.f90 b/src/util/util_solve.f90 new file mode 100644 index 000000000..057ed1182 --- /dev/null +++ b/src/util/util_solve.f90 @@ -0,0 +1,228 @@ +submodule(swiftest_classes) s_util_solve + use swiftest +contains + + module function util_solve_linear_system_d(A,b,n,lerr) result(x) + !! Author: David A. Minton + !! + !! Solves the linear equation of the form A*x = b for x. + !! A is an (n,n) arrays + !! x and b are (n) arrays + !! Uses Gaussian elimination, so will have issues if system is ill-conditioned. + !! Uses quad precision intermidiate values, so works best on small arrays. + use, intrinsic :: ieee_exceptions + implicit none + ! Arguments + integer(I4B), intent(in) :: n + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), intent(in) :: b + logical, intent(out) :: lerr + ! Result + real(DP), dimension(n) :: x + ! Internals + real(QP), dimension(:), allocatable :: qx + type(ieee_status_type) :: original_fpe_status + logical, dimension(:), allocatable :: fpe_flag + + call ieee_get_status(original_fpe_status) ! Save the original floating point exception status + call ieee_set_flag(ieee_all, .false.) ! Set all flags to quiet + allocate(fpe_flag(size(ieee_usual))) + + qx = solve_wbs(ge_wpp(real(A, kind=QP), real(b, kind=QP))) + + call ieee_get_flag(ieee_usual, fpe_flag) + lerr = any(fpe_flag) + if (lerr .or. (any(abs(qx) > huge(x))) .or. (any(abs(qx) < tiny(x)))) then + x = 0.0_DP + else + x = real(qx, kind=DP) + end if + call ieee_set_status(original_fpe_status) + + return + end function util_solve_linear_system_d + + module function util_solve_linear_system_q(A,b,n,lerr) result(x) + !! Author: David A. Minton + !! + !! Solves the linear equation of the form A*x = b for x. + !! A is an (n,n) arrays + !! x and b are (n) arrays + !! Uses Gaussian elimination, so will have issues if system is ill-conditioned. + !! Uses quad precision intermidiate values, so works best on small arrays. + use, intrinsic :: ieee_exceptions + implicit none + ! Arguments + integer(I4B), intent(in) :: n + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), intent(in) :: b + logical, intent(out) :: lerr + ! Result + real(QP), dimension(n) :: x + ! Internals + type(ieee_status_type) :: original_fpe_status + logical, dimension(:), allocatable :: fpe_flag + + call ieee_get_status(original_fpe_status) ! Save the original floating point exception status + call ieee_set_flag(ieee_all, .false.) ! Set all flags to quiet + allocate(fpe_flag(size(ieee_usual))) + + x = solve_wbs(ge_wpp(A, b)) + + call ieee_get_flag(ieee_usual, fpe_flag) + lerr = any(fpe_flag) + if (lerr) x = 0.0_DP + call ieee_set_status(original_fpe_status) + + return + end function util_solve_linear_system_q + + function solve_wbs(u) result(x) ! solve with backward substitution + !! Based on code available on Rosetta Code: https://rosettacode.org/wiki/Gaussian_elimination#Fortran + use, intrinsic :: ieee_exceptions + use swiftest + implicit none + ! Arguments + real(QP), intent(in), dimension(:,:), allocatable :: u + ! Result + real(QP), dimension(:), allocatable :: x + ! Internals + integer(I4B) :: i,n + + n = size(u, 1) + if (allocated(x)) deallocate(x) + if (.not.allocated(x)) allocate(x(n)) + if (any(abs(u) < tiny(1._DP)) .or. any(abs(u) > huge(1._DP))) then + x(:) = 0._DP + return + end if + call ieee_set_halting_mode(ieee_divide_by_zero, .false.) + do i = n, 1, -1 + x(i) = (u(i, n + 1) - sum(u(i, i + 1:n) * x(i + 1:n))) / u(i, i) + end do + return + end function solve_wbs + + function ge_wpp(A, b) result(u) ! gaussian eliminate with partial pivoting + !! Solve Ax=b using Gaussian elimination then backwards substitution. + !! A being an n by n matrix. + !! x and b are n by 1 vectors. + !! Based on code available on Rosetta Code: https://rosettacode.org/wiki/Gaussian_elimination#Fortran + use, intrinsic :: ieee_exceptions + use swiftest + implicit none + ! Arguments + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), intent(in) :: b + ! Result + real(QP), dimension(:,:), allocatable :: u + ! Internals + integer(I4B) :: i,j,n,p + real(QP) :: upi + + n = size(a, 1) + allocate(u(n, (n + 1))) + u = reshape([A, b], [n, n + 1]) + call ieee_set_halting_mode(ieee_divide_by_zero, .false.) + do j = 1, n + p = maxloc(abs(u(j:n, j)), 1) + j - 1 ! maxloc returns indices between (1, n - j + 1) + if (p /= j) u([p, j], j) = u([j, p], j) + u(j + 1:, j) = u(j + 1:, j) / u(j, j) + do i = j + 1, n + 1 + upi = u(p, i) + if (p /= j) u([p, j], i) = u([j, p], i) + u(j + 1:n, i) = u(j + 1:n, i) - upi * u(j + 1:n, j) + end do + end do + return + end function ge_wpp + + module function util_solve_rkf45(f, y0in, t1, dt0, tol) result(y1) + !! author: David A. Minton + !! + !! Implements the 4th order Runge-Kutta-Fehlberg ODE solver for initial value problems of the form f=dy/dt, y0 = y(t=0), solving for y1 = y(t=t1). Uses a 5th order adaptive step size control. + !! Uses a lambda function object as defined in the lambda_function module + implicit none + ! Arguments + class(lambda_obj), intent(inout) :: f !! lambda function object that has been initialized to be a function of derivatives. The object will return with components lastarg and lasteval set + real(DP), dimension(:), intent(in) :: y0in !! Initial value at t=0 + real(DP), intent(in) :: t1 !! Final time + real(DP), intent(in) :: dt0 !! Initial step size guess + real(DP), intent(in) :: tol !! Tolerance on solution + ! Result + real(DP), dimension(:), allocatable :: y1 !! Final result + ! Internals + integer(I4B), parameter :: MAXREDUX = 1000 !! Maximum number of times step size can be reduced + real(DP), parameter :: DTFAC = 0.95_DP !! Step size reduction safety factor (Value just under 1.0 to prevent adaptive step size control from discarding steps too aggressively) + integer(I4B), parameter :: RKS = 6 !! Number of RK stages + real(DP), dimension(RKS, RKS - 1), parameter :: rkf45_btab = reshape( & !! Butcher tableau for Runge-Kutta-Fehlberg method + (/ 1./4., 1./4., 0., 0., 0., 0.,& + 3./8., 3./32., 9./32., 0., 0., 0.,& + 12./13., 1932./2197., -7200./2197., 7296./2197., 0., 0.,& + 1., 439./216., -8., 3680./513., -845./4104., 0.,& + 1./2., -8./27., 2., -3544./2565., 1859./4104., -11./40./), shape(rkf45_btab)) + real(DP), dimension(RKS), parameter :: rkf4_coeff = (/ 25./216., 0., 1408./2565. , 2197./4104. , -1./5., 0. /) + real(DP), dimension(RKS), parameter :: rkf5_coeff = (/ 16./135., 0., 6656./12825., 28561./56430., -9./50., 2./55. /) + real(DP), dimension(:, :), allocatable :: k !! Runge-Kutta coefficient vector + real(DP), dimension(:), allocatable :: ynorm !! Normalized y value used for adaptive step size control + real(DP), dimension(:), allocatable :: y0 !! Value of y at the beginning of each substep + integer(I4B) :: Nvar !! Number of variables in problem + integer(I4B) :: rkn !! Runge-Kutta loop index + real(DP) :: t, x1, dt, trem !! Current time, step size and total time remaining + real(DP) :: s, yerr, yscale !! Step size reduction factor, error in dependent variable, and error scale factor + integer(I4B) :: i, n + + allocate(y0, source=y0in) + allocate(y1, mold=y0) + allocate(ynorm, mold=y0) + Nvar = size(y0) + allocate(k(Nvar, RKS)) + + dt = dt0 + + trem = t1 + t = 0._DP + do + yscale = norm2(y0(:)) + do i = 1, MAXREDUX + select type(f) + class is (lambda_obj_tvar) + do rkn = 1, RKS + y1(:) = y0(:) + matmul(k(:, 1:rkn - 1), rkf45_btab(2:rkn, rkn - 1)) + if (rkn == 1) then + x1 = t + else + x1 = t + rkf45_btab(1,rkn-1) + end if + k(:, rkn) = dt * f%evalt(y1(:), t) + end do + class is (lambda_obj) + do rkn = 1, RKS + y1(:) = y0(:) + matmul(k(:, 1:rkn - 1), rkf45_btab(2:rkn, rkn - 1)) + k(:, rkn) = dt * f%eval(y1(:)) + end do + end select + ! Now determine if the step size needs adjusting + ynorm(:) = matmul(k(:,:), (rkf5_coeff(:) - rkf4_coeff(:))) / yscale + yerr = norm2(ynorm(:)) + s = (tol / (2 * yerr))**(0.25_DP) + dt = min(s * DTFAC * dt, trem) ! Alter step size either up or down, but never bigger than the remaining time + if (s >= 1.0_DP) exit ! Good step! + if (i == MAXREDUX) then + write(*,*) "Something has gone wrong in util_solve_rkf45!! Step size reduction has gone too far this time!" + call util_exit(FAILURE) + end if + end do + + ! Compute new value then step ahead in time + y1(:) = y0(:) + matmul(k(:, :), rkf4_coeff(:)) + trem = trem - dt + t = t + dt + if (trem <= 0._DP) exit + y0(:) = y1(:) + end do + + return + end function util_solve_rkf45 + +end submodule s_util_solve \ No newline at end of file diff --git a/src/util/util_sort.f90 b/src/util/util_sort.f90 new file mode 100644 index 000000000..752e78ab7 --- /dev/null +++ b/src/util/util_sort.f90 @@ -0,0 +1,419 @@ +submodule (swiftest_classes) s_util_sort + use swiftest +contains + + module subroutine util_sort_body(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a Swiftest body structure in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(body => self, n => self%nbody) + select case(sortby) + case("id") + call util_sort(direction * body%id(1:n), ind(1:n)) + case("status") + call util_sort(direction * body%status(1:n), ind(1:n)) + case("ir3h") + call util_sort(direction * body%ir3h(1:n), ind(1:n)) + case("a") + call util_sort(direction * body%a(1:n), ind(1:n)) + case("e") + call util_sort(direction * body%e(1:n), ind(1:n)) + case("inc") + call util_sort(direction * body%inc(1:n), ind(1:n)) + case("capom") + call util_sort(direction * body%capom(1:n), ind(1:n)) + case("mu") + call util_sort(direction * body%mu(1:n), ind(1:n)) + case("lfirst", "nbody", "ldiscard", "xh", "vh", "xb", "vb", "ah", "aobl", "atide", "agr") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not found!' + return + end select + + call body%rearrange(ind) + + end associate + + return + end subroutine util_sort_body + + + module subroutine util_sort_pl(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a Swiftest massive body object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(pl => self, npl => self%nbody) + select case(sortby) + case("Gmass","mass") + call util_sort(direction * pl%Gmass(1:npl), ind(1:npl)) + case("rhill") + call util_sort(direction * pl%rhill(1:npl), ind(1:npl)) + case("radius") + call util_sort(direction * pl%radius(1:npl), ind(1:npl)) + case("density") + call util_sort(direction * pl%density(1:npl), ind(1:npl)) + case("k2") + call util_sort(direction * pl%k2(1:npl), ind(1:npl)) + case("Q") + call util_sort(direction * pl%Q(1:npl), ind(1:npl)) + case("tlag") + call util_sort(direction * pl%tlag(1:npl), ind(1:npl)) + case("xbeg", "xend", "vbeg", "Ip", "rot", "k_plpl", "nplpl") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default ! Look for components in the parent class + call util_sort_body(pl, sortby, ascending) + return + end select + + call pl%rearrange(ind) + + end associate + + return + end subroutine util_sort_pl + + + module subroutine util_sort_tp(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a Swiftest test particle object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(tp => self, ntp => self%nbody) + select case(sortby) + case("peri") + call util_sort(direction * tp%peri(1:ntp), ind(1:ntp)) + case("atp") + call util_sort(direction * tp%atp(1:ntp), ind(1:ntp)) + case("isperi") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default ! Look for components in the parent class + call util_sort_body(tp, sortby, ascending) + return + end select + + call tp%rearrange(ind) + + end associate + + return + end subroutine util_sort_tp + + + module subroutine util_sort_rearrange_body(self, ind) + !! author: David A. Minton + !! + !! Rearrange Swiftest body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(swiftest_body), allocatable :: body_sorted !! Temporary holder for sorted body + + associate(n => self%nbody) + allocate(body_sorted, source=self) + if (allocated(self%id)) self%id(1:n) = body_sorted%id(ind(1:n)) + if (allocated(self%name)) self%name(1:n) = body_sorted%name(ind(1:n)) + if (allocated(self%status)) self%status(1:n) = body_sorted%status(ind(1:n)) + if (allocated(self%ldiscard)) self%ldiscard(1:n) = body_sorted%ldiscard(ind(1:n)) + if (allocated(self%xh)) self%xh(:,1:n) = body_sorted%xh(:,ind(1:n)) + if (allocated(self%vh)) self%vh(:,1:n) = body_sorted%vh(:,ind(1:n)) + if (allocated(self%xb)) self%xb(:,1:n) = body_sorted%xb(:,ind(1:n)) + if (allocated(self%vb)) self%vb(:,1:n) = body_sorted%vb(:,ind(1:n)) + if (allocated(self%ah)) self%ah(:,1:n) = body_sorted%ah(:,ind(1:n)) + if (allocated(self%ir3h)) self%ir3h(1:n) = body_sorted%ir3h(ind(1:n)) + if (allocated(self%mu)) self%mu(1:n) = body_sorted%mu(ind(1:n)) + if (allocated(self%lmask)) self%lmask(1:n) = body_sorted%lmask(ind(1:n)) + if (allocated(self%a)) self%a(1:n) = body_sorted%a(ind(1:n)) + if (allocated(self%e)) self%e(1:n) = body_sorted%e(ind(1:n)) + if (allocated(self%inc)) self%inc(1:n) = body_sorted%inc(ind(1:n)) + if (allocated(self%capom)) self%capom(1:n) = body_sorted%capom(ind(1:n)) + if (allocated(self%omega)) self%omega(1:n) = body_sorted%omega(ind(1:n)) + if (allocated(self%capm)) self%capm(1:n) = body_sorted%capm(ind(1:n)) + if (allocated(self%aobl)) self%aobl(:,1:n) = body_sorted%aobl(:,ind(1:n)) + if (allocated(self%atide)) self%atide(:,1:n) = body_sorted%atide(:,ind(1:n)) + if (allocated(self%agr)) self%agr(:,1:n) = body_sorted%agr(:,ind(1:n)) + deallocate(body_sorted) + end associate + + return + end subroutine util_sort_rearrange_body + + + module subroutine util_sort_rearrange_pl(self, ind) + !! author: David A. Minton + !! + !! Rearrange Swiftest massive body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(swiftest_pl), allocatable :: pl_sorted !! Temporary holder for sorted body + + associate(pl => self, npl => self%nbody) + call util_sort_rearrange_body(pl,ind) + allocate(pl_sorted, source=self) + if (allocated(pl%mass)) pl%mass(1:npl) = pl_sorted%mass(ind(1:npl)) + if (allocated(pl%Gmass)) pl%Gmass(1:npl) = pl_sorted%Gmass(ind(1:npl)) + if (allocated(pl%rhill)) pl%rhill(1:npl) = pl_sorted%rhill(ind(1:npl)) + if (allocated(pl%xbeg)) pl%xbeg(:,1:npl) = pl_sorted%xbeg(:,ind(1:npl)) + if (allocated(pl%xend)) pl%xend(:,1:npl) = pl_sorted%xend(:,ind(1:npl)) + if (allocated(pl%vbeg)) pl%vbeg(:,1:npl) = pl_sorted%vbeg(:,ind(1:npl)) + if (allocated(pl%radius)) pl%radius(1:npl) = pl_sorted%radius(ind(1:npl)) + if (allocated(pl%density)) pl%density(1:npl) = pl_sorted%density(ind(1:npl)) + if (allocated(pl%Ip)) pl%Ip(:,1:npl) = pl_sorted%Ip(:,ind(1:npl)) + if (allocated(pl%rot)) pl%rot(:,1:npl) = pl_sorted%rot(:,ind(1:npl)) + if (allocated(pl%k2)) pl%k2(1:npl) = pl_sorted%k2(ind(1:npl)) + if (allocated(pl%Q)) pl%Q(1:npl) = pl_sorted%Q(ind(1:npl)) + if (allocated(pl%tlag)) pl%tlag(1:npl) = pl_sorted%tlag(ind(1:npl)) + + deallocate(pl_sorted) + end associate + + return + end subroutine util_sort_rearrange_pl + + + module subroutine util_sort_rearrange_tp(self, ind) + !! author: David A. Minton + !! + !! Rearrange Swiftest massive body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(swiftest_tp), allocatable :: tp_sorted !! Temporary holder for sorted body + + associate(tp => self, ntp => self%nbody) + call util_sort_rearrange_body(tp,ind) + allocate(tp_sorted, source=self) + if (allocated(tp%isperi)) tp%isperi(1:ntp) = tp_sorted%isperi(ind(1:ntp)) + if (allocated(tp%peri)) tp%peri(1:ntp) = tp_sorted%peri(ind(1:ntp)) + if (allocated(tp%atp)) tp%atp(1:ntp) = tp_sorted%atp(ind(1:ntp)) + deallocate(tp_sorted) + end associate + + return + end subroutine util_sort_rearrange_tp + + + module subroutine util_sort_dp(arr) + !! author: David A. Minton + !! + !! Sort input double precision array in place into ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + !! + implicit none + ! Arguments + real(DP), dimension(:), intent(inout) :: arr + ! Internals + real(DP) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + do i = 2, n + tmp = arr(i) + do j = i - 1, 1, -1 + if (arr(j) <= tmp) exit + arr(j + 1) = arr(j) + end do + arr(j + 1) = tmp + end do + + return + end subroutine util_sort_dp + + + module subroutine util_sort_index_dp(arr, ind) + !! author: David A. Minton + !! + !! Sort input double precision array by index in ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + !! + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + ! Internals + real(DP) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + ind = [(i, i=1, n)] + do i = 2, n + tmp = arr(ind(i)) + do j = i - 1, 1, -1 + if (arr(ind(j)) <= tmp) exit + ind(j + 1) = ind(j) + end do + ind(j + 1) = i + end do + + return + end subroutine util_sort_index_dp + + + module subroutine util_sort_i4b(arr) + !! author: David A. Minton + !! + !! Sort input integer array in place into ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + !! + implicit none + ! Arguments + integer(I4B), dimension(:), intent(inout) :: arr + ! Internals + integer(I4B) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + do i = 2, n + tmp = arr(i) + do j = i - 1, 1, -1 + if (arr(j) <= tmp) exit + arr(j + 1) = arr(j) + end do + arr(j + 1) = tmp + end do + + return + end subroutine util_sort_i4b + + + module subroutine util_sort_index_i4b(arr, ind) + !! author: David A. Minton + !! + !! Sort input integer array by index in ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + !! + implicit none + ! Arguments + integer(I4B), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + ! Internals + integer(I4B) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + ind = [(i, i=1, n)] + do i = 2, n + tmp = arr(ind(i)) + do j = i - 1, 1, -1 + if (arr(ind(j)) <= tmp) exit + ind(j + 1) = ind(j) + end do + ind(j + 1) = i + end do + + return + end subroutine util_sort_index_i4b + + + module subroutine util_sort_sp(arr) + !! author: David A. Minton + !! + !! Sort input single precision array in place into ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + ! + implicit none + ! Arguments + real(SP), dimension(:), intent(inout) :: arr + ! Internals + real(SP) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + do i = 2, n + tmp = arr(i) + do j = i - 1, 1, -1 + if (arr(j) <= tmp) exit + arr(j + 1) = arr(j) + end do + arr(j + 1) = tmp + end do + + return + end subroutine util_sort_sp + + + module subroutine util_sort_index_sp(arr, ind) + !! author: David A. Minton + !! + !! Sort input single precision array by index in ascending numerical order using insertion sort. + !! This algorithm works well for partially sorted arrays (which is usually the case here) + !! + implicit none + ! Arguments + real(SP), dimension(:), intent(in) :: arr + integer(I4B), dimension(:), intent(out) :: ind + ! Internals + real(SP) :: tmp + integer(I4B) :: n, i, j + + n = size(arr) + ind = [(i, i=1, n)] + do i = 2, n + tmp = arr(ind(i)) + do j = i - 1, 1, -1 + if (arr(ind(j)) <= tmp) exit + ind(j + 1) = ind(j) + end do + ind(j + 1) = i + end do + + return + end subroutine util_sort_index_sp + +end submodule s_util_sort diff --git a/src/util/util_spill.f90 b/src/util/util_spill.f90 new file mode 100644 index 000000000..9acc6ae93 --- /dev/null +++ b/src/util/util_spill.f90 @@ -0,0 +1,300 @@ +submodule (swiftest_classes) s_util_spill + use swiftest +contains + + module subroutine util_spill_arr_char_string(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of type character strings + !! This is the inverse of a spill operation + implicit none + ! Arguments + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + character(len=STRMAX), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine util_spill_arr_char_string + + module subroutine util_spill_arr_DP(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of type DP + !! This is the inverse of a spill operation + implicit none + ! Arguments + real(DP), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardss + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine util_spill_arr_DP + + module subroutine util_spill_arr_DPvec(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of DP vectors with shape (NDIM, n) + !! This is the inverse of a spill operation + implicit none + ! Arguments + real(DP), dimension(:,:), allocatable, intent(inout) :: keeps !! Array of values to keep + real(DP), dimension(:,:), allocatable, intent(inout) :: discards !! Array discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + ! Internals + integer(I4B) :: i + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(NDIM, count(lspill_list(:)))) + + do i = 1, NDIM + discards(i,:) = pack(keeps(i,:), lspill_list(:)) + end do + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + do i = 1, NDIM + keeps(i,:) = pack(keeps(i,:), .not. lspill_list(:)) + end do + end if + end if + + return + end subroutine util_spill_arr_DPvec + + module subroutine util_spill_arr_I4B(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of type I4B + !! This is the inverse of a spill operation + implicit none + ! Arguments + integer(I4B), dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + integer(I4B), dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine util_spill_arr_I4B + + module subroutine util_spill_arr_logical(keeps, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Performs a spill operation on a single array of logicals + !! This is the inverse of a spill operation + implicit none + ! Arguments + logical, dimension(:), allocatable, intent(inout) :: keeps !! Array of values to keep + logical, dimension(:), allocatable, intent(inout) :: discards !! Array of discards + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or no + + if (.not.allocated(keeps) .or. count(lspill_list(:)) == 0) return + if (.not.allocated(discards)) allocate(discards(count(lspill_list(:)))) + + discards(:) = pack(keeps(:), lspill_list(:)) + if (ldestructive) then + if (count(.not.lspill_list(:)) > 0) then + keeps(:) = pack(keeps(:), .not. lspill_list(:)) + else + deallocate(keeps) + end if + end if + + return + end subroutine util_spill_arr_logical + + + module subroutine util_spill_body(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) Swiftest generic particle structure from active list to discard list + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + ! For each component, pack the discarded bodies into the discard object and do the inverse with the keeps + !> Spill all the common components + associate(keeps => self) + call util_spill(keeps%id, discards%id, lspill_list, ldestructive) + call util_spill(keeps%name, discards%name, lspill_list, ldestructive) + call util_spill(keeps%status, discards%status, lspill_list, ldestructive) + call util_spill(keeps%lmask, discards%lmask, lspill_list, ldestructive) + call util_spill(keeps%ldiscard, discards%ldiscard, lspill_list, ldestructive) + call util_spill(keeps%mu, discards%mu, lspill_list, ldestructive) + call util_spill(keeps%xh, discards%xh, lspill_list, ldestructive) + call util_spill(keeps%vh, discards%vh, lspill_list, ldestructive) + call util_spill(keeps%xb, discards%xb, lspill_list, ldestructive) + call util_spill(keeps%vb, discards%vb, lspill_list, ldestructive) + call util_spill(keeps%ah, discards%ah, lspill_list, ldestructive) + call util_spill(keeps%aobl, discards%aobl, lspill_list, ldestructive) + call util_spill(keeps%agr, discards%agr, lspill_list, ldestructive) + call util_spill(keeps%atide, discards%atide, lspill_list, ldestructive) + call util_spill(keeps%a, discards%a, lspill_list, ldestructive) + call util_spill(keeps%e, discards%e, lspill_list, ldestructive) + call util_spill(keeps%inc, discards%inc, lspill_list, ldestructive) + call util_spill(keeps%capom, discards%capom, lspill_list, ldestructive) + call util_spill(keeps%omega, discards%omega, lspill_list, ldestructive) + call util_spill(keeps%capm, discards%capm, lspill_list, ldestructive) + + ! This is the base class, so will be the last to be called in the cascade. + ! Therefore we need to set the nbody values for both the keeps and discareds + discards%nbody = count(lspill_list(:)) + keeps%nbody = count(.not.lspill_list(:)) + if (keeps%nbody > size(keeps%status)) keeps%status(keeps%nbody+1:size(keeps%status)) = INACTIVE + + end associate + + return + end subroutine util_spill_body + + module subroutine util_spill_encounter(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) Swiftest encounter structure from active list to discard list + implicit none + ! Arguments + class(swiftest_encounter), intent(inout) :: self !! Swiftest encounter list + class(swiftest_encounter), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + associate(keeps => self) + + call util_spill(keeps%lvdotr, discards%lvdotr, lspill_list, ldestructive) + call util_spill(keeps%status, discards%status, lspill_list, ldestructive) + call util_spill(keeps%index1, discards%index1, lspill_list, ldestructive) + call util_spill(keeps%index2, discards%index2, lspill_list, ldestructive) + call util_spill(keeps%x1, discards%x1, lspill_list, ldestructive) + call util_spill(keeps%x2, discards%x2, lspill_list, ldestructive) + call util_spill(keeps%v1, discards%v1, lspill_list, ldestructive) + call util_spill(keeps%v2, discards%v2, lspill_list, ldestructive) + + ! This is the base class, so will be the last to be called in the cascade. + ! Therefore we need to set the nenc values for both the keeps and discareds + discards%nenc = count(lspill_list(:)) + keeps%nenc = count(.not.lspill_list(:)) + if (keeps%nenc > size(keeps%status)) keeps%status(keeps%nenc+1:size(keeps%status)) = INACTIVE + end associate + + return + end subroutine util_spill_encounter + + + module subroutine util_spill_pl(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) Swiftest massive body structure from active list to discard list + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + ! Internals + integer(I4B) :: i + + associate(keeps => self) + + select type (discards) ! The standard requires us to select the type of both arguments in order to access all the components + class is (swiftest_pl) + !> Spill components specific to the massive body class + call util_spill(keeps%mass, discards%mass, lspill_list, ldestructive) + call util_spill(keeps%Gmass, discards%Gmass, lspill_list, ldestructive) + call util_spill(keeps%rhill, discards%rhill, lspill_list, ldestructive) + call util_spill(keeps%radius, discards%radius, lspill_list, ldestructive) + call util_spill(keeps%density, discards%density, lspill_list, ldestructive) + call util_spill(keeps%k2, discards%k2, lspill_list, ldestructive) + call util_spill(keeps%Q, discards%Q, lspill_list, ldestructive) + call util_spill(keeps%tlag, discards%tlag, lspill_list, ldestructive) + call util_spill(keeps%xbeg, discards%xbeg, lspill_list, ldestructive) + call util_spill(keeps%vbeg, discards%vbeg, lspill_list, ldestructive) + call util_spill(keeps%Ip, discards%Ip, lspill_list, ldestructive) + call util_spill(keeps%rot, discards%rot, lspill_list, ldestructive) + + call util_spill_body(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) 'Error! spill method called for incompatible return type on swiftest_pl' + end select + end associate + + return + end subroutine util_spill_pl + + + module subroutine util_spill_tp(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) Swiftest test particle structure from active list to discard list + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discardse + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter body by removing the discard list + + associate(keeps => self, ntp => self%nbody) + select type(discards) + class is (swiftest_tp) + !> Spill components specific to the test particle class + call util_spill(keeps%isperi, discards%isperi, lspill_list, ldestructive) + call util_spill(keeps%peri, discards%peri, lspill_list, ldestructive) + call util_spill(keeps%atp, discards%atp, lspill_list, ldestructive) + + call util_spill_body(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) 'Error! spill method called for incompatible return type on swiftest_tp' + end select + end associate + + return + end subroutine util_spill_tp + +end submodule s_util_spill \ No newline at end of file diff --git a/src/util/util_valid.f90 b/src/util/util_valid.f90 new file mode 100644 index 000000000..c5923b38e --- /dev/null +++ b/src/util/util_valid.f90 @@ -0,0 +1,41 @@ +submodule (swiftest_classes) s_util_valid + use swiftest +contains + + module subroutine util_valid(pl, tp) + !! author: David A. Minton + !! + !! Validate massive body and test particle ids + !! Subroutine causes program to exit with error if any ids are not unique + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_valid.f90 + implicit none + ! Arguments + class(swiftest_pl), intent(in) :: pl + class(swiftest_tp), intent(in) :: tp + ! Internals + integer(I4B) :: i + integer(I4B), dimension(:), allocatable :: idarr + + associate(npl => pl%nbody, ntp => tp%nbody) + allocate(idarr(npl+ntp)) + do i = 1, npl + idarr(i) = pl%id(i) + end do + do i = 1, ntp + idarr(npl+i) = tp%id(i) + end do + call util_sort(idarr) + do i = 1, npl + ntp - 1 + if (idarr(i) == idarr(i+1)) then + write(*, *) "Swiftest error:" + write(*, *) " more than one body/particle has id = ", idarr(i) + call util_exit(FAILURE) + end if + end do + end associate + + return + end subroutine util_valid + +end submodule s_util_valid diff --git a/src/util/util_version.f90 b/src/util/util_version.f90 new file mode 100644 index 000000000..54ef0e14a --- /dev/null +++ b/src/util/util_version.f90 @@ -0,0 +1,53 @@ +submodule (swiftest_classes) s_util_version + use swiftest +contains + + module subroutine util_version() + !! author: David A. Minton + !! + !! Print program version information to terminale + !! + !! Adapted from David E. Kaufmann's Swifter routine: util_version.f90 + implicit none + write(*, 200) VERSION_NUMBER +200 format(/, "************* Swiftest: Version ", f3.1, " *************", //, & + "Based off of Swifter:", //, & + "Authors:", //, & + " The Purdue University Swiftest Development team ", /, & + " Lead by David A. Minton ", /, & + " Single loop blocking by Jacob R. Elliott", /, & + " Fragmentation by Carlisle A. Wishard and", //, & + " Jennifer L. L. Poutplin ", //, & + "Please address comments and questions to:", //, & + " David A. Minton", /, & + " Department Earth, Atmospheric, & Planetary Sciences ",/, & + " Purdue University", /, & + " 550 Stadium Mall Drive", /, & + " West Lafayette, Indiana 47907", /, & + " 765-250-8034 ", /, & + " daminton@purdue.edu", /, & + "Special thanks to Hal Levison and Martin Duncan for the original",/,& + "SWIFTER and SWIFT codes that made this possible.", //, & + "************************************************", /) + + + 100 FORMAT(/, "************* SWIFTER: Version ", F3.1, " *************", //, & + "Authors:", //, & + " Martin Duncan: Queen's University", /, & + " Hal Levison : Southwest Research Institute", //, & + "Please address comments and questions to:", //, & + " Hal Levison or David Kaufmann", /, & + " Department of Space Studies", /, & + " Southwest Research Institute", /, & + " 1050 Walnut Street, Suite 400", /, & + " Boulder, Colorado 80302", /, & + " 303-546-0290 (HFL), 720-240-0119 (DEK)", /, & + " 303-546-9687 (fax)", /, & + " hal@gort.boulder.swri.edu (HFL)", /, & + " kaufmann@boulder.swri.edu (DEK)", //, & + "************************************************", /) + + return + end subroutine util_version + +end submodule s_util_version diff --git a/src/whm/whm_coord.f90 b/src/whm/whm_coord.f90 new file mode 100644 index 000000000..e7aa63e1f --- /dev/null +++ b/src/whm/whm_coord.f90 @@ -0,0 +1,118 @@ +submodule (whm_classes) s_whm_coord + use swiftest +contains + + module subroutine whm_coord_h2j_pl(self, cb) + !! author: David A. Minton + !! + !! Convert from heliocentric to Jacobi coordinates, massive bodies only + !! + !! Uses pre-computed eta rather than computing it each time + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_h2j.f90 + !! + !! Adapted from Hal Levison's Swift routine coord_h2j.f + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: sumx, sumv, cap, capv + + if (self%nbody == 0) return + + associate(npl => self%nbody, GMpl => self%Gmass, eta => self%eta, xh => self%xh, vh => self%vh, & + xj => self%xj, vj => self%vj) + xj(:, 1) = xh(:, 1) + vj(:, 1) = vh(:, 1) + sumx(:) = 0.0_DP + sumv(:) = 0.0_DP + do i = 2, npl + sumx(:) = sumx(:) + GMpl(i - 1) * xh(:, i - 1) + sumv(:) = sumv(:) + GMpl(i - 1) * vh(:, i - 1) + cap(:) = sumx(:) / eta(i - 1) + capv(:) = sumv(:) / eta(i - 1) + xj(:, i) = xh(:, i) - cap(:) + vj(:, i) = vh(:, i) - capv(:) + end do + end associate + + return + end subroutine whm_coord_h2j_pl + + + module subroutine whm_coord_j2h_pl(self, cb) + !! author: David A. Minton + !! + !! Convert from Jacobi to heliocentric coordinates, massive bodies only. + !! + !! Uses pre-computed eta rather than computing it each time + !! + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_j2h.f90 + !! + !! Adapted from Hal Levison's Swift routine coord_j2h.f + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: sumx, sumv + + if (self%nbody == 0) return + + associate(npl => self%nbody, GMpl => self%Gmass, eta => self%eta, xh => self%xh, vh => self%vh, & + xj => self%xj, vj => self%vj) + xh(:, 1) = xj(:, 1) + vh(:, 1) = vj(:, 1) + sumx(:) = 0.0_DP + sumv(:) = 0.0_DP + do i = 2, npl + sumx(:) = sumx(:) + GMpl(i - 1) * xj(:, i - 1) / eta(i - 1) + sumv(:) = sumv(:) + GMpl(i - 1) * vj(:, i - 1) / eta(i - 1) + xh(:, i) = xj(:, i) + sumx(:) + vh(:, i) = vj(:, i) + sumv(:) + end do + end associate + + return + end subroutine whm_coord_j2h_pl + + + module subroutine whm_coord_vh2vj_pl(self, cb) + !! author: David A. Minton + !! + !! Convert from heliocentric to Jadcobi coordinates, massive body velocities only + !! + !! Uses pre-computed eta rather than computing it each time + !! + !! Adapted from David E. Kaufmann's Swifter routine coord_vh2vj.f90 + !! + !! Adapted from Hal Levison's Swift routine coord_vh2vj.f + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: sumv, capv + + if (self%nbody == 0) return + + associate(npl => self%nbody, GMpl => self%Gmass, vh => self%vh, vj => self%vj, eta => self%eta) + vj(:, 1) = vh(:, 1) + sumv(:) = 0.0_DP + do i = 2, npl + sumv(:) = sumv(:) + GMpl(i - 1) * vh(:, i - 1) + capv(:) = sumv(:) / eta(i - 1) + vj(:, i) = vh(:, i) - capv(:) + end do + end associate + + return + end subroutine whm_coord_vh2vj_pl + +end submodule s_whm_coord + diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 new file mode 100644 index 000000000..f68fcaeb7 --- /dev/null +++ b/src/whm/whm_drift.f90 @@ -0,0 +1,49 @@ +submodule(whm_classes) whm_drift + use swiftest +contains + + module subroutine whm_drift_pl(self, system, param, dt) + !! author: David A. Minton + !! + !! Loop through planets and call Danby drift routine + !! + !! Adapted from Hal Levison's Swift routine drift.f + !! Adapted from David E. Kaufmann's Swifter routine whm_drift.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + ! Internals + integer(I4B) :: i + integer(I4B), dimension(:), allocatable :: iflag + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + allocate(iflag(npl)) + iflag(:) = 0 + call drift_all(pl%muj, pl%xj, pl%vj, npl, param, dt, pl%lmask, iflag) + if (any(iflag(1:npl) /= 0)) then + where(iflag(1:npl) /= 0) + pl%status(1:npl) = DISCARDED_DRIFTERR + pl%lmask(1:npl) = .false. + end where + do i = 1, npl + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!!!" + WRITE(*, *) pl%muj(i), dt + WRITE(*, *) pl%xj(:,i) + WRITE(*, *) pl%vj(:,i) + WRITE(*, *) " STOPPING " + end if + end do + call util_exit(FAILURE) + end if + end associate + + return + end subroutine whm_drift_pl + +end submodule whm_drift diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 new file mode 100644 index 000000000..bfba5c6a2 --- /dev/null +++ b/src/whm/whm_gr.f90 @@ -0,0 +1,114 @@ +submodule(whm_classes) s_whm_gr + use swiftest +contains + + module subroutine whm_gr_kick_getacch_pl(self, param) + !! author: David A. Minton + !! + !! Compute relativisitic accelerations of massive bodies + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_kick_getacch.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: suma + real(DP), dimension(:, :), allocatable :: aj + real(DP) :: beta, rjmag4 + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody, inv_c2 => param%inv_c2) + call gr_kick_getacch(pl%muj, pl%xj, pl%lmask, npl, param%inv_c2, pl%agr) + suma(:) = 0.0_DP + pl%ah(:, 1) = pl%ah(:, 1) + pl%agr(:, 1) + do i = 2, npl + suma(:) = suma(:) + pl%Gmass(i) * pl%agr(:, i) / pl%eta(i) + pl%ah(:, i) = pl%ah(:, i) + pl%agr(:, i) + suma(:) + end do + end associate + + return + end subroutine whm_gr_kick_getacch_pl + + + module subroutine whm_gr_kick_getacch_tp(self, param) + !! author: David A. Minton + !! + !! Compute relativisitic accelerations of test particles + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_kick_getacch.f90 + implicit none + ! Arguments + class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals + integer(I4B) :: i + real(DP) :: rjmag4, beta + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody, inv_c2 => param%inv_c2) + call gr_kick_getacch(tp%mu, tp%xh, tp%lmask, ntp, param%inv_c2, tp%agr) + tp%ah(:,1:ntp) = tp%ah(:,1:ntp) + tp%agr(:,1:ntp) + end associate + + return + end subroutine whm_gr_kick_getacch_tp + + + module pure subroutine whm_gr_p4_pl(self, param, dt) + !! author: David A. Minton + !! + !! Position kick to massive bodies due to p**4 term in the post-Newtonian correction + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_p4.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + ! Internals + integer(I4B) :: i + + associate(pl => self, npl => self%nbody) + if (npl == 0) return + do concurrent(i = 1:npl, pl%lmask(i)) + call gr_p4_pos_kick(param, pl%xj(:, i), pl%vj(:, i), dt) + end do + end associate + + return + end subroutine whm_gr_p4_pl + + module pure subroutine whm_gr_p4_tp(self, param, dt) + !! author: David A. Minton + !! + !! Position kick to test particles due to p**4 term in the post-Newtonian correction + !! Based on Saha & Tremaine (1994) Eq. 28 + !! + !! Adapted from David A. Minton's Swifter routine routine gr_whm_p4.f90 + implicit none + ! Arguments + class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Step size + ! Internals + integer(I4B) :: i + + associate(tp => self, ntp => self%nbody) + if (ntp == 0) return + do concurrent(i = 1:ntp, tp%lmask(i)) + call gr_p4_pos_kick(param, tp%xh(:, i), tp%vh(:, i), dt) + end do + end associate + + return + end subroutine whm_gr_p4_tp + +end submodule s_whm_gr \ No newline at end of file diff --git a/src/whm/whm_kick.f90 b/src/whm/whm_kick.f90 new file mode 100644 index 000000000..2da00c332 --- /dev/null +++ b/src/whm/whm_kick.f90 @@ -0,0 +1,281 @@ +submodule(whm_classes) s_whm_kick + use swiftest +contains + + module subroutine whm_kick_getacch_pl(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of planets + !! + !! Adapted from Hal Levison's Swift routine getacch.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah0 + + if (self%nbody == 0) return + + associate(cb => system%cb, pl => self, npl => self%nbody) + call pl%set_ir3() + + ah0(:) = whm_kick_getacch_ah0(pl%Gmass(2:npl), pl%xh(:,2:npl), npl-1) + do i = 1, npl + pl%ah(:, i) = pl%ah(:, i) + ah0(:) + end do + + call whm_kick_getacch_ah1(cb, pl) + call whm_kick_getacch_ah2(cb, pl) + call pl%accel_int() + + if (param%loblatecb) then + call pl%accel_obl(system) + if (lbeg) then + cb%aoblbeg = cb%aobl + else + cb%aoblend = cb%aobl + end if + if (param%ltides) then + cb%atidebeg = cb%aobl + call pl%accel_tides(system) + cb%atideend = cb%atide + end if + end if + + if (param%lgr) call pl%accel_gr(param) + + if (param%lextra_force) call pl%accel_user(system, param, t, lbeg) + end associate + + return + end subroutine whm_kick_getacch_pl + + + module subroutine whm_kick_getacch_tp(self, system, param, t, lbeg) + !! author: David A. Minton + !! + !! Compute heliocentric accelerations of test particles + !! + !! Adapted from Hal Levison's Swift routine getacch_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch_tp.f90 + implicit none + ! Arguments + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah0 + + associate(tp => self, ntp => self%nbody, pl => system%pl, cb => system%cb, npl => system%pl%nbody) + if (ntp == 0 .or. npl == 0) return + system%lbeg = lbeg + + if (lbeg) then + ah0(:) = whm_kick_getacch_ah0(pl%Gmass(:), pl%xbeg(:,:), npl) + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%ah(:, i) = tp%ah(:, i) + ah0(:) + end do + call tp%accel_int(pl%Gmass(:), pl%xbeg(:,:), npl) + else + ah0(:) = whm_kick_getacch_ah0(pl%Gmass(:), pl%xend(:,:), npl) + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%ah(:, i) = tp%ah(:, i) + ah0(:) + end do + call tp%accel_int(pl%Gmass(:), pl%xend(:,:), npl) + end if + + if (param%loblatecb) call tp%accel_obl(system) + if (param%lextra_force) call tp%accel_user(system, param, t, lbeg) + if (param%lgr) call tp%accel_gr(param) + end associate + + return + end subroutine whm_kick_getacch_tp + + + function whm_kick_getacch_ah0(mu, xhp, n) result(ah0) + !! author: David A. Minton + !! + !! Compute zeroth term heliocentric accelerations of planets + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: mu + real(DP), dimension(:,:), intent(in) :: xhp + integer(I4B), intent(in) :: n + ! Result + real(DP), dimension(NDIM) :: ah0 + ! Internals + real(DP) :: fac, r2, ir3h, irh + integer(I4B) :: i + + ah0(:) = 0.0_DP + do i = 1, n + r2 = dot_product(xhp(:, i), xhp(:, i)) + irh = 1.0_DP / sqrt(r2) + ir3h = irh / r2 + fac = mu(i) * ir3h + ah0(:) = ah0(:) - fac * xhp(:, i) + end do + + return + end function whm_kick_getacch_ah0 + + + pure subroutine whm_kick_getacch_ah1(cb, pl) + !! author: David A. Minton + !! + !! Compute first term heliocentric accelerations of planets + !! + !! Adapted from Hal Levison's Swift routine getacch_ah1.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch_ah1.f90 + implicit none + ! Arguments + class(swiftest_cb), intent(in) :: cb !! WHM central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object + ! Internals + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah1h, ah1j + + associate(npl => pl%nbody) + do concurrent (i = 2:npl, pl%lmask(i)) + ah1j(:) = pl%xj(:, i) * pl%ir3j(i) + ah1h(:) = pl%xh(:, i) * pl%ir3h(i) + pl%ah(:, i) = pl%ah(:, i) + cb%Gmass * (ah1j(:) - ah1h(:)) + end do + end associate + + return + end subroutine whm_kick_getacch_ah1 + + + pure subroutine whm_kick_getacch_ah2(cb, pl) + !! author: David A. Minton + !! + !! Compute second term heliocentric accelerations of planets + !! + !! Adapted from Hal Levison's Swift routine getacch_ah2.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kick_getacch_ah2.f90 + implicit none + ! Arguments + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object + ! Internals + integer(I4B) :: i + real(DP) :: etaj, fac + real(DP), dimension(NDIM) :: ah2, ah2o + + associate(npl => pl%nbody) + ah2(:) = 0.0_DP + ah2o(:) = 0.0_DP + etaj = cb%Gmass + do concurrent(i = 2:npl, pl%lmask(i)) + etaj = etaj + pl%Gmass(i - 1) + fac = pl%Gmass(i) * cb%Gmass * pl%ir3j(i) / etaj + ah2(:) = ah2o + fac * pl%xj(:, i) + pl%ah(:,i) = pl%ah(:, i) + ah2(:) + ah2o(:) = ah2(:) + end do + end associate + + return + end subroutine whm_kick_getacch_ah2 + + + module subroutine whm_kick_vh_pl(self, system, param, t, dt, lbeg) + !! author: David A. Minton + !! + !! Kick heliocentric velocities of massive bodies + !! + !! Adapted from Martin Duncan and Hal Levison's Swift routine kickvh.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kickvh.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + ! Internals + integer(I4B) :: i + + associate(pl => self, npl => self%nbody, cb => system%cb) + if (npl == 0) return + if (lbeg) then + if (pl%lfirst) then + call pl%h2j(cb) + pl%ah(:,:) = 0.0_DP + call pl%accel(system, param, t, lbeg) + pl%lfirst = .false. + end if + call pl%set_beg_end(xbeg = pl%xh) + else + pl%ah(:,:) = 0.0_DP + call pl%accel(system, param, t, lbeg) + call pl%set_beg_end(xend = pl%xh) + end if + do concurrent(i = 1:npl, pl%lmask(i)) + pl%vh(:, i) = pl%vh(:, i) + pl%ah(:, i) * dt + end do + end associate + + return + end subroutine whm_kick_vh_pl + + + module subroutine whm_kick_vh_tp(self, system, param, t, dt, lbeg) + !! author: David A. Minton + !! + !! Kick heliocentric velocities of test particles + !! + !! Adapted from Martin Duncan and Hal Levison's Swift routine kickvh_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_kickvh_tp.f90 + implicit none + ! Arguments + class(whm_tp), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: dt !! Stepsize + logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. + ! Internals + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(tp => self, ntp => self%nbody) + if (tp%lfirst) then + where(tp%lmask(1:ntp)) + tp%ah(1,1:ntp) = 0.0_DP + tp%ah(2,1:ntp) = 0.0_DP + tp%ah(3,1:ntp) = 0.0_DP + end where + call tp%accel(system, param, t, lbeg=.true.) + tp%lfirst = .false. + end if + if (.not.lbeg) then + where(tp%lmask(1:ntp)) + tp%ah(1,1:ntp) = 0.0_DP + tp%ah(2,1:ntp) = 0.0_DP + tp%ah(3,1:ntp) = 0.0_DP + end where + call tp%accel(system, param, t, lbeg) + end if + do concurrent(i = 1:ntp, tp%lmask(i)) + tp%vh(:, i) = tp%vh(:, i) + tp%ah(:, i) * dt + end do + end associate + + return + end subroutine whm_kick_vh_tp + +end submodule s_whm_kick diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 new file mode 100644 index 000000000..cbf36cc90 --- /dev/null +++ b/src/whm/whm_setup.f90 @@ -0,0 +1,96 @@ +submodule(whm_classes) s_whm_setup + use swiftest +contains + + module subroutine whm_setup_pl(self, n, param) + !! author: David A. Minton + !! + !! Allocate WHM planet structure + !! + !! Equivalent in functionality to David E. Kaufmann's Swifter routine whm_setup.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! Swiftest test particle object + integer(I4B), intent(in) :: n !! Number of particles to allocate space for + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + + !> Call allocation method for parent class + call setup_pl(self, n, param) + if (n <= 0) return + + if (allocated(self%eta)) deallocate(self%eta) + if (allocated(self%muj)) deallocate(self%muj) + if (allocated(self%xj)) deallocate(self%xj) + if (allocated(self%vj)) deallocate(self%vj) + if (allocated(self%ir3j)) deallocate(self%ir3j) + + allocate(self%eta(n)) + allocate(self%muj(n)) + allocate(self%xj(NDIM, n)) + allocate(self%vj(NDIM, n)) + allocate(self%ir3j(n)) + + self%eta(:) = 0.0_DP + self%muj(:) = 0.0_DP + self%xj(:,:) = 0.0_DP + self%vj(:,:) = 0.0_DP + self%ir3j(:) = 0.0_DP + + return + end subroutine whm_setup_pl + + + module subroutine whm_util_set_mu_eta_pl(self, cb) + !! author: David A. Minton + !! + !! Sets the Jacobi mass value eta for all massive bodies + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM system object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + integer(I4B) :: i + + associate(pl => self, npl => self%nbody) + if (npl == 0) return + call util_set_mu_pl(pl, cb) + pl%eta(1) = cb%Gmass + pl%Gmass(1) + pl%muj(1) = pl%eta(1) + do i = 2, npl + pl%eta(i) = pl%eta(i - 1) + pl%Gmass(i) + pl%muj(i) = cb%Gmass * pl%eta(i) / pl%eta(i - 1) + end do + end associate + + return + end subroutine whm_util_set_mu_eta_pl + + + module subroutine whm_setup_initialize_system(self, param) + !! author: David A. Minton + !! + !! Initialize a WHM nbody system from files + !! + implicit none + ! Arguments + class(whm_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + + call setup_initialize_system(self, param) + ! First we need to make sure that the massive bodies are sorted by heliocentric distance before computing jacobies + call util_set_ir3h(self%pl) + call self%pl%sort("ir3h", ascending=.false.) + + ! Make sure that the discard list gets allocated initially + call self%tp_discards%setup(self%tp%nbody, param) + call self%pl%set_mu(self%cb) + call self%tp%set_mu(self%cb) + if (param%lgr) then + call self%pl%v2pv(param) + call self%tp%v2pv(param) + end if + + return + end subroutine whm_setup_initialize_system + +end submodule s_whm_setup \ No newline at end of file diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 new file mode 100644 index 000000000..d194e2c02 --- /dev/null +++ b/src/whm/whm_step.f90 @@ -0,0 +1,98 @@ +submodule(whm_classes) s_whm_step + use swiftest +contains + + module subroutine whm_step_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step massive bodies and and active test particles ahead in heliocentric coordinates + !! + !! Adapted from Hal Levison's Swift routine step_kdk.f + !! Adapted from David E. Kaufmann's Swifter routine whm_step.f90 + implicit none + ! Arguments + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize + + associate(system => self, cb => self%cb, pl => self%pl, tp => self%tp) + tp%lfirst = pl%lfirst + call pl%step(system, param, t, dt) + call tp%step(system, param, t, dt) + if (param%ltides) call system%step_spin(param, t, dt) + end associate + return + end subroutine whm_step_system + + + module subroutine whm_step_pl(self, system, param, t, dt) + !! author: David A. Minton + !! + !! Step planets ahead using kick-drift-kick algorithm + !! + !! Adapted from Hal Levison's Swift routine step_kdk_pl.f + !! Adapted from David E. Kaufmann's Swifter routine whm_step_pl.f90 + !logical, save :: lfirst = .true. + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP) :: dth + + if (self%nbody == 0) return + + associate(pl => self, cb => system%cb) + dth = 0.5_DP * dt + call pl%kick(system, param, t, dth,lbeg=.true.) + call pl%vh2vj(cb) + if (param%lgr) call pl%gr_pos_kick(param, dth) + call pl%drift(system, param, dt) + if (param%lgr) call pl%gr_pos_kick(param, dth) + call pl%j2h(cb) + call pl%kick(system, param, t + dt, dth, lbeg=.false.) + end associate + + return + end subroutine whm_step_pl + + + module subroutine whm_step_tp(self, system, param, t, dt) + !! author: David A. Minton + !! + !! Step active test particles ahead using kick-drift-kick algorithm + !! + !! Adapted from Hal Levison's Swift routine step_kdk_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_step_tp.f90 + implicit none + ! Arguments + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP) :: dth + + if (self%nbody == 0) return + + select type(system) + class is (whm_nbody_system) + associate(tp => self, cb => system%cb, pl => system%pl) + dth = 0.5_DP * dt + call tp%kick(system, param, t, dth, lbeg=.true.) + if (param%lgr) call tp%gr_pos_kick(param, dth) + call tp%drift(system, param, dt) + if (param%lgr) call tp%gr_pos_kick(param, dth) + call tp%kick(system, param, t + dt, dth, lbeg=.false.) + end associate + end select + + return + end subroutine whm_step_tp + +end submodule s_whm_step diff --git a/src/whm/whm_util.f90 b/src/whm/whm_util.f90 new file mode 100644 index 000000000..f3dc15d3e --- /dev/null +++ b/src/whm/whm_util.f90 @@ -0,0 +1,220 @@ +submodule(whm_classes) s_whm_util + use swiftest +contains + + module subroutine whm_util_append_pl(self, source, lsource_mask) + !! author: David A. Minton + !! + !! Append components from one massive body object to another. + !! This method will automatically resize the destination body if it is too small + implicit none + !! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(in) :: source !! Source object to append + logical, dimension(:), optional, intent(in) :: lsource_mask !! Logical mask indicating which elements to append to + + select type(source) + class is (whm_pl) + call util_append_pl(self, source, lsource_mask) + + call util_append(self%eta, source%eta, lsource_mask) + call util_append(self%muj, source%muj, lsource_mask) + call util_append(self%ir3j, source%ir3j, lsource_mask) + call util_append(self%xj, source%xj, lsource_mask) + call util_append(self%vj, source%vj, lsource_mask) + class default + write(*,*) "Invalid object passed to the append method. Source must be of class whm_pl or its descendents" + call util_exit(FAILURE) + end select + + return + end subroutine whm_util_append_pl + + module subroutine whm_util_fill_pl(self, inserts, lfill_list) + !! author: David A. Minton + !! + !! Insert new WHM test particle structure into an old one. + !! This is the inverse of a fill operation. + !! + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(in) :: inserts !! inserted object + logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps + ! Internals + integer(I4B) :: i + + associate(keeps => self) + select type(inserts) + class is (whm_pl) + call util_fill(keeps%eta, inserts%eta, lfill_list) + call util_fill(keeps%muj, inserts%muj, lfill_list) + call util_fill(keeps%ir3j, inserts%ir3j, lfill_list) + call util_fill(keeps%xj, inserts%xj, lfill_list) + call util_fill(keeps%vj, inserts%vj, lfill_list) + + call util_fill_pl(keeps, inserts, lfill_list) + class default + write(*,*) "Invalid object passed to the fill method. Inserts must be of class whm_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine whm_util_fill_pl + + + module subroutine whm_util_resize_pl(self, nnew) + !! author: David A. Minton + !! + !! Checks the current size of a massive body against the requested size and resizes it if it is too small. + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + integer(I4B), intent(in) :: nnew !! New size neded + + call util_resize_pl(self, nnew) + + call util_resize(self%eta, nnew) + call util_resize(self%xj, nnew) + call util_resize(self%vj, nnew) + call util_resize(self%muj, nnew) + call util_resize(self%ir3j, nnew) + + return + end subroutine whm_util_resize_pl + + + module subroutine whm_util_set_ir3j(self) + !! author: David A. Minton + !! + !! Sets the inverse Jacobi and heliocentric radii cubed (1/rj**3 and 1/rh**3) + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + ! Internals + integer(I4B) :: i + real(DP) :: r2, ir + + if (self%nbody > 0) then + do i = 1, self%nbody + r2 = dot_product(self%xh(:, i), self%xh(:, i)) + ir = 1.0_DP / sqrt(r2) + self%ir3h(i) = ir / r2 + r2 = dot_product(self%xj(:, i), self%xj(:, i)) + ir = 1.0_DP / sqrt(r2) + self%ir3j(i) = ir / r2 + end do + end if + + return + end subroutine whm_util_set_ir3j + + + module subroutine whm_util_sort_pl(self, sortby, ascending) + !! author: David A. Minton + !! + !! Sort a WHM massive body object in-place. + !! sortby is a string indicating which array component to sort. + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + character(*), intent(in) :: sortby !! Sorting attribute + logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order + ! Internals + integer(I4B), dimension(self%nbody) :: ind + integer(I4B) :: direction + + if (ascending) then + direction = 1 + else + direction = -1 + end if + + associate(pl => self, npl => self%nbody) + select case(sortby) + case("eta") + call util_sort(direction * pl%eta(1:npl), ind(1:npl)) + case("muj") + call util_sort(direction * pl%muj(1:npl), ind(1:npl)) + case("ir3j") + call util_sort(direction * pl%ir3j(1:npl), ind(1:npl)) + case("xj", "vj") + write(*,*) 'Cannot sort by ' // trim(adjustl(sortby)) // '. Component not sortable!' + case default + call util_sort_pl(pl, sortby, ascending) + return + end select + + call pl%rearrange(ind) + end associate + + return + end subroutine whm_util_sort_pl + + + module subroutine whm_util_sort_rearrange_pl(self, ind) + !! author: David A. Minton + !! + !! Rearrange WHM massive body structure in-place from an index list. + !! This is a helper utility used to make polymorphic sorting work on Swiftest structures. + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) + ! Internals + class(whm_pl), allocatable :: pl_sorted !! Temporary holder for sorted body + integer(I4B) :: i + + if (self%nbody == 0) return + + associate(pl => self, npl => self%nbody) + call util_sort_rearrange_pl(pl,ind) + allocate(pl_sorted, source=self) + if (allocated(pl%eta)) pl%eta(1:npl) = pl_sorted%eta(ind(1:npl)) + if (allocated(pl%xj)) pl%xj(:,1:npl) = pl_sorted%xj(:,ind(1:npl)) + if (allocated(pl%vj)) pl%vj(:,1:npl) = pl_sorted%vj(:,ind(1:npl)) + if (allocated(pl%muj)) pl%muj(1:npl) = pl_sorted%muj(ind(1:npl)) + if (allocated(pl%ir3j)) pl%ir3j(1:npl) = pl_sorted%ir3j(ind(1:npl)) + deallocate(pl_sorted) + end associate + + return + end subroutine whm_util_sort_rearrange_pl + + + module subroutine whm_util_spill_pl(self, discards, lspill_list, ldestructive) + !! author: David A. Minton + !! + !! Move spilled (discarded) WHM test particle structure from active list to discard list + !! + !! Adapted from David E. Kaufmann's Swifter routine whm_discard_spill.f90 + implicit none + ! Arguments + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_body), intent(inout) :: discards !! Discarded object + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards + logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not + ! Internals + integer(I4B) :: i + associate(keeps => self) + select type(discards) + class is (whm_pl) + call util_spill(keeps%eta, discards%eta, lspill_list, ldestructive) + call util_spill(keeps%muj, discards%muj, lspill_list, ldestructive) + call util_spill(keeps%ir3j, discards%ir3j, lspill_list, ldestructive) + call util_spill(keeps%xj, discards%xj, lspill_list, ldestructive) + call util_spill(keeps%vj, discards%vj, lspill_list, ldestructive) + + call util_spill_pl(keeps, discards, lspill_list, ldestructive) + class default + write(*,*) "Invalid object passed to the spill method. Source must be of class whm_pl or its descendents!" + call util_exit(FAILURE) + end select + end associate + + return + end subroutine whm_util_spill_pl + +end submodule s_whm_util diff --git a/symba/symba_chk.f90 b/symba/symba_chk.f90 deleted file mode 100644 index 46ae3afc5..000000000 --- a/symba/symba_chk.f90 +++ /dev/null @@ -1,81 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_chk -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check for an encounter -! -! Input -! Arguments : xr : position of body 2 relative to body 1 -! vr : velocity of body 2 relative to body 1 -! rhill1 : Hill sphere radius of body 1 -! rhill2 : Hill sphere radius of body 2 -! dt : time step -! irec : recursion level -! Terminal : none -! File : none -! -! Output -! Arguments : lencounter : logical flag indicating whether there is an encounter this time step -! lvdotr : logical flag indicating whether the two bodies are approaching -! Terminal : none -! File : none -! -! Invocation : CALL symba_chk(xr, vr, rhill1, rhill2, dt, irec, lencounter, lvdotr) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_chk.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_chk(xr, vr, rhill1, rhill2, dt, irec, lencounter, lvdotr) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_chk - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(OUT) :: lencounter, lvdotr - INTEGER(I4B), INTENT(IN) :: irec - REAL(DP), INTENT(IN) :: rhill1, rhill2, dt - REAL(DP), DIMENSION(:), INTENT(IN) :: xr, vr - -! Internals - INTEGER(I4B) :: iflag - REAL(DP) :: rcrit, r2crit, vdotr - -! Executable code - lencounter = .FALSE. - rcrit = (rhill1 + rhill2)*RHSCALE*(RSHELL**(irec)) - r2crit = rcrit*rcrit - CALL rmvs_chk_ind(xr(:), vr(:), dt, r2crit, iflag) - IF (iflag /= 0) lencounter = .TRUE. - vdotr = DOT_PRODUCT(vr(:), xr(:)) - lvdotr = (vdotr < 0.0_DP) - - RETURN - -END SUBROUTINE symba_chk -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_merge_pl.f90 b/symba/symba_discard_merge_pl.f90 deleted file mode 100644 index 360b41683..000000000 --- a/symba/symba_discard_merge_pl.f90 +++ /dev/null @@ -1,147 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_merge_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Merge planets -! -! Input -! Arguments : t : time -! npl : number of planets -! nsppl : number of spilled planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! nplplenc : number of planet-planet encounters -! plplenc_list : array of planet-planet encounter structures -! Terminal : none -! File : none -! -! Output -! Arguments : npl : number of planets -! nsppl : number of spilled planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_discard_merge_pl(t, npl, nsppl, symba_pl1P, symba_pld1P, nplplenc, plplenc_list) -! -! Notes : Adapted from Hal Levison's Swift routine discard_mass_merge.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_merge_pl(t, npl, nsppl, symba_pl1P, symba_pld1P, nplplenc, plplenc_list) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_merge_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: nplplenc - INTEGER(I4B), INTENT(INOUT) :: npl, nsppl - REAL(DP), INTENT(IN) :: t - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - -! Internals - INTEGER(I4B) :: i, j, nchild - REAL(DP) :: m, mmax, mtot, r, r3, mu, energy, ap, v2, msun - REAL(DP), DIMENSION(NDIM) :: x, v, vbs - TYPE(swifter_pl), POINTER :: swifter_plP, swifter_plspP - TYPE(symba_pl), POINTER :: symba_plP, symba_plkP, symba_plspP - -! Executable code - swifter_plP => symba_pl1P%helio%swifter - msun = swifter_plP%mass - vbs(:) = swifter_plP%vb(:) - DO i = 1, nplplenc - IF (plplenc_list(i)%status == MERGED) THEN - IF ((plplenc_list(i)%pl1P%helio%swifter%status == ACTIVE) .AND. & - (plplenc_list(i)%pl2P%helio%swifter%status == ACTIVE)) THEN - symba_plkP => plplenc_list(i)%pl1P%parentP - swifter_plP => symba_plkP%helio%swifter - m = swifter_plP%mass - r = swifter_plP%radius - r3 = r**3 - mmax = m - mtot = m - x(:) = m*swifter_plP%xh(:) - v(:) = m*swifter_plP%vb(:) - symba_plP => symba_plkP - nchild = symba_plP%nchild - DO j = 1, nchild - symba_plP => symba_plP%childP - swifter_plP => symba_plP%helio%swifter - m = swifter_plP%mass - r = swifter_plP%radius - r3 = r3 + r**3 - mtot = mtot + m - x(:) = x(:) + m*swifter_plP%xh(:) - v(:) = v(:) + m*swifter_plP%vb(:) - IF (m > mmax) THEN - mmax = m - symba_plkP => symba_plP - END IF - END DO - x(:) = x(:)/mtot - v(:) = v(:)/mtot - r = r3**(1.0_DP/3.0_DP) - symba_plP => plplenc_list(i)%pl1P%parentP - DO j = 0, nchild - swifter_plP => symba_plP%helio%swifter - IF (ASSOCIATED(symba_plP, symba_plkP)) THEN - swifter_plP%mass = mtot - swifter_plP%radius = r - swifter_plP%xh(:) = x(:) - swifter_plP%vb(:) = v(:) - swifter_plP%vh(:) = v(:) - vbs(:) - mu = msun*mtot/(msun + mtot) - r = SQRT(DOT_PRODUCT(x(:), x(:))) - v(:) = swifter_plP%vh(:) - v2 = DOT_PRODUCT(v(:), v(:)) - energy = -1.0_DP*msun*mtot/r + 0.5_DP*mu*v2 - ap = -1.0_DP*msun*mtot/(2.0_DP*energy) - swifter_plP%rhill = ap*(((mu/msun)/3.0_DP)**(1.0_DP/3.0_DP)) - ELSE - swifter_plP%status = MERGED - END IF - symba_plP => symba_plP%childP - END DO - END IF - END IF - END DO - symba_plP => symba_pl1P%nextP - DO i = 2, npl - symba_plspP => symba_plP - symba_plP => symba_plP%nextP - swifter_plspP => symba_plspP%helio%swifter - IF (swifter_plspP%status /= ACTIVE) CALL symba_discard_spill_pl(npl, nsppl, symba_pld1P, symba_plspP) - END DO - - RETURN - -END SUBROUTINE symba_discard_merge_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_peri_pl.f90 b/symba/symba_discard_peri_pl.f90 deleted file mode 100644 index 0c24e550d..000000000 --- a/symba/symba_discard_peri_pl.f90 +++ /dev/null @@ -1,102 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_peri_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check to see if planets should be discarded based on their pericenter distances -! -! Input -! Arguments : t : time -! npl : number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! msys : total system mass -! qmin : minimum allowed pericenter distance -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! qmin_coord : coordinate frame for qmin -! ldiscards : logical flag indicating whether any planets are discarded -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! ldiscards : logical flag indicating whether any planets are discarded -! Terminal : status message -! File : none -! -! Invocation : CALL symba_discard_peri_pl(t, npl, symba_pl1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, ldiscards) -! -! Notes : Adapted from Hal Levison's Swift routine discard_mass_peri.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_peri_pl(t, npl, symba_pl1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, ldiscards) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_peri_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(INOUT) :: ldiscards - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t, msys, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lfirst = .TRUE. - INTEGER(I4B) :: i, j, ih - REAL(DP) :: r2 - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(symba_pl), POINTER :: symba_plP - -! Executable code - IF (lfirst) THEN - CALL symba_peri(lfirst, npl, symba_pl1P, msys, qmin_coord) - lfirst = .FALSE. - ELSE - CALL symba_peri(lfirst, npl, symba_pl1P, msys, qmin_coord) - symba_plP => symba_pl1P - DO i = 2, npl - symba_plP => symba_plP%nextP - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status == ACTIVE) THEN - IF ((symba_plP%isperi == 0) .AND. (symba_plP%nplenc == 0)) THEN - IF ((symba_plP%atp >= qmin_alo) .AND. (symba_plP%atp <= qmin_ahi) .AND. (symba_plP%peri <= qmin)) THEN - ldiscards = .TRUE. - swifter_plP%status = DISCARDED_PERI - WRITE(*, *) "Particle ", swifter_plP%id, " perihelion distance too small at t = ", t - END IF - END IF - END IF - END DO - END IF - - RETURN - -END SUBROUTINE symba_discard_peri_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_pl.f90 b/symba/symba_discard_pl.f90 deleted file mode 100644 index fd001fe0f..000000000 --- a/symba/symba_discard_pl.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check to see if planets should be discarded based on their positions or because they are unbound -! -! Input -! Arguments : t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! nsp : number of spilled planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! rmin : minimum allowed heliocentric radius -! rmax : maximum allowed heliocentric radius -! rmaxu : maximum allowed heliocentric radius for unbound planets -! qmin : minimum allowed pericenter distance -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! eoffset : energy offset -! Terminal : none -! File : none -! -! Output -! Arguments : npl : number of planets -! nsp : number of spilled planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! eoffset : energy offset -! Terminal : none -! File : none -! -! Invocation : CALL symba_discard_pl(t, npl, nplmax, nsp, symba_pl1P, symba_pld1P, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, j2rp2, j4rp4, eoffset) -! -! Notes : Adapted from Hal Levison's Swift routine discard_massive5.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_pl(t, npl, nplmax, nsp, symba_pl1P, symba_pld1P, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, j2rp2, j4rp4, eoffset) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: nplmax - INTEGER(I4B), INTENT(INOUT) :: npl, nsp - REAL(DP), INTENT(IN) :: t, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, j2rp2, j4rp4 - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P, symba_pld1P - -! Internals - LOGICAL(LGT) :: ldiscards - INTEGER(I4B) :: i - REAL(DP) :: msys, ke, pe, tei, tef - REAL(DP), DIMENSION(NDIM) :: htot - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plspP - TYPE(symba_pl), POINTER :: symba_plP, symba_plspP - -! Executable code - ldiscards = .FALSE. - swifter_pl1P => symba_pl1P%helio%swifter - IF ((rmin >= 0.0_DP) .OR. (rmax >= 0.0_DP) .OR. (rmaxu >= 0.0_DP) .OR. ((qmin >= 0.0_DP) .AND. (qmin_coord == "BARY"))) & - CALL coord_h2b(npl, swifter_pl1P, msys) - IF ((rmin >= 0.0_DP) .OR. (rmax >= 0.0_DP) .OR. (rmaxu >= 0.0_DP)) & - CALL symba_discard_sun_pl(t, npl, msys, swifter_pl1P, rmin, rmax, rmaxu, ldiscards) - IF (qmin >= 0.0_DP) CALL symba_discard_peri_pl(t, npl, symba_pl1P, msys, qmin, qmin_alo, qmin_ahi, qmin_coord, ldiscards) - IF (ldiscards) THEN - CALL symba_energy(npl, nplmax, swifter_pl1P, j2rp2, j4rp4, ke, pe, tei, htot) - symba_plP => symba_pl1P%nextP - DO i = 2, npl - symba_plspP => symba_plP - symba_plP => symba_plP%nextP - swifter_plspP => symba_plspP%helio%swifter - IF (swifter_plspP%status /= ACTIVE) CALL symba_discard_spill_pl(npl, nsp, symba_pld1P, symba_plspP) - END DO - CALL symba_energy(npl, nplmax, swifter_pl1P, j2rp2, j4rp4, ke, pe, tef, htot) - eoffset = eoffset + tei - tef - END IF - - RETURN - -END SUBROUTINE symba_discard_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_spill_pl.f90 b/symba/symba_discard_spill_pl.f90 deleted file mode 100644 index 46d58c636..000000000 --- a/symba/symba_discard_spill_pl.f90 +++ /dev/null @@ -1,108 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_spill_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) SyMBA planet structure from active list to discard list -! -! Input -! Arguments : npl : number of planets -! nsp : number of spilled planets -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! symba_plspP : pointer to SyMBA planet structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : npl : number of planets -! nsp : number of spilled planets -! symba_pld1P : pointer to head of discard SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_discard_spill_pl(npl, nsp, symba_pld1P, symba_plspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_spill_pl(npl, nsp, symba_pld1P, symba_plspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_spill_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: npl, nsp - TYPE(symba_pl), POINTER :: symba_pld1P, symba_plspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plspP - TYPE(helio_pl), POINTER :: helio_plspP - TYPE(symba_pl), POINTER :: symba_plP - -! Executable code - helio_plspP => symba_plspP%helio - swifter_plspP => helio_plspP%swifter - IF (nsp == 0) THEN - symba_pld1P => symba_plspP - ELSE - symba_plP => symba_pld1P - DO i = 1, nsp - 1 - symba_plP => symba_plP%nextP - END DO - symba_plP%nextP => symba_plspP - symba_plP%helio%nextP => helio_plspP - symba_plP%helio%swifter%nextP => swifter_plspP - END IF - symba_plspP%prevP%nextP => symba_plspP%nextP - helio_plspP%prevP%nextP => helio_plspP%nextP - swifter_plspP%prevP%nextP => swifter_plspP%nextP - IF (ASSOCIATED(symba_plspP%nextP)) THEN - symba_plspP%nextP%prevP => symba_plspP%prevP - helio_plspP%nextP%prevP => helio_plspP%prevP - swifter_plspP%nextP%prevP => swifter_plspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(symba_plspP%prevP) - NULLIFY(helio_plspP%prevP) - NULLIFY(swifter_plspP%prevP) - ELSE - symba_plspP%prevP => symba_plP - helio_plspP%prevP => symba_plP%helio - swifter_plspP%prevP => symba_plP%helio%swifter - END IF - NULLIFY(symba_plspP%nextP) - NULLIFY(helio_plspP%nextP) - NULLIFY(swifter_plspP%nextP) - nsp = nsp + 1 - npl = npl - 1 - - RETURN - -END SUBROUTINE symba_discard_spill_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_spill_tp.f90 b/symba/symba_discard_spill_tp.f90 deleted file mode 100644 index 2d457d8f5..000000000 --- a/symba/symba_discard_spill_tp.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_spill_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) SyMBA test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! symba_tpd1P : pointer to head of discard SyMBA test particle structure linked-list -! symba_tpspP : pointer to SyMBA test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! symba_tpd1P : pointer to head of discard SyMBA test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_discard_spill_tp(ntp, nsp, symba_tp1P, symba_tpd1P, symba_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_spill_tp(ntp, nsp, symba_tp1P, symba_tpd1P, symba_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_spill_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(symba_tp), POINTER :: symba_tp1P, symba_tpd1P, symba_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(helio_tp), POINTER :: helio_tpspP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - helio_tpspP => symba_tpspP%helio - swifter_tpspP => helio_tpspP%swifter - IF (nsp == 0) THEN - symba_tpd1P => symba_tpspP - ELSE - symba_tpP => symba_tpd1P - DO i = 1, nsp - 1 - symba_tpP => symba_tpP%nextP - END DO - symba_tpP%nextP => symba_tpspP - symba_tpP%helio%nextP => helio_tpspP - symba_tpP%helio%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(symba_tpspP%prevP)) THEN - symba_tpspP%prevP%nextP => symba_tpspP%nextP - helio_tpspP%prevP%nextP => helio_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - symba_tp1P => symba_tpspP%nextP - END IF - IF (ASSOCIATED(symba_tpspP%nextP)) THEN - symba_tpspP%nextP%prevP => symba_tpspP%prevP - helio_tpspP%nextP%prevP => helio_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(symba_tpspP%prevP) - NULLIFY(helio_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - symba_tpspP%prevP => symba_tpP - helio_tpspP%prevP => symba_tpP%helio - swifter_tpspP%prevP => symba_tpP%helio%swifter - END IF - NULLIFY(symba_tpspP%nextP) - NULLIFY(helio_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE symba_discard_spill_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_sun_pl.f90 b/symba/symba_discard_sun_pl.f90 deleted file mode 100644 index 2d0fcb39f..000000000 --- a/symba/symba_discard_sun_pl.f90 +++ /dev/null @@ -1,103 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_sun_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check to see if planets should be discarded based on their positions relative to the Sun -! -! Input -! Arguments : t : time -! npl : number of planets -! msys : total system mass -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! rmin : minimum allowed heliocentric radius -! rmax : maximum allowed heliocentric radius -! rmaxu : maximum allowed heliocentric radius for unbound planets -! ldiscards : logical flag indicating whether any planets are discarded -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of Swifter planet structure linked-list -! ldiscards : logical flag indicating whether any planets are discarded -! Terminal : status message -! File : none -! -! Invocation : CALL symba_discard_sun_pl(t, npl, msys, swifter_pl1P, rmin, rmax, rmaxu, ldiscards) -! -! Notes : Adapted from Hal Levison's Swift routine discard_massive5.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_sun_pl(t, npl, msys, swifter_pl1P, rmin, rmax, rmaxu, ldiscards) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_sun_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(INOUT) :: ldiscards - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t, msys, rmin, rmax, rmaxu - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, rmaxu2 - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - rmin2 = rmin*rmin - rmax2 = rmax*rmax - rmaxu2 = rmaxu*rmaxu - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - IF (swifter_plP%status == ACTIVE) THEN - rh2 = DOT_PRODUCT(swifter_plP%xh(:), swifter_plP%xh(:)) - IF ((rmax >= 0.0_DP) .AND. (rh2 > rmax2)) THEN - ldiscards = .TRUE. - swifter_plP%status = DISCARDED_RMAX - WRITE(*, *) "Particle ", swifter_plP%id, " too far from Sun at t = ", t - ELSE IF ((rmin >= 0.0_DP) .AND. (rh2 < rmin2)) THEN - ldiscards = .TRUE. - swifter_plP%status = DISCARDED_RMIN - WRITE(*, *) "Particle ", swifter_plP%id, " too close to Sun at t = ", t - ELSE IF (rmaxu >= 0.0_DP) THEN - rb2 = DOT_PRODUCT(swifter_plP%xb(:), swifter_plP%xb(:)) - vb2 = DOT_PRODUCT(swifter_plP%vb(:), swifter_plP%vb(:)) - energy = 0.5_DP*vb2 - msys/SQRT(rb2) - IF ((energy > 0.0_DP) .AND. (rb2 > rmaxu2)) THEN - ldiscards = .TRUE. - swifter_plP%status = DISCARDED_RMAXU - WRITE(*, *) "Particle ", swifter_plP%id, " is unbound and too far from barycenter at t = ", t - END IF - END IF - END IF - END DO - - RETURN - -END SUBROUTINE symba_discard_sun_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_discard_tp.f90 b/symba/symba_discard_tp.f90 deleted file mode 100644 index 828012d1d..000000000 --- a/symba/symba_discard_tp.f90 +++ /dev/null @@ -1,106 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_discard_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! symba_tpd1P : pointer to head of discard SyMBA test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! symba_tpd1P : pointer to head of discard SyMBA test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_discard_tp(t, npl, ntp, nsp, symba_pl1P, symba_tp1P, symba_tpd1P, dt, rmin, rmax, rmaxu, qmin, -! qmin_coord, qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_discard_tp(t, npl, ntp, nsp, symba_pl1P, symba_tp1P, symba_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, & - qmin_alo, qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_discard_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P, symba_tpd1P - -! Internals - LOGICAL(LGT) :: lclosel = .FALSE. - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(symba_tp), POINTER :: symba_tpP, symba_tpspP - -! Executable code - swifter_pl1P => symba_pl1P%helio%swifter - swifter_tp1P => symba_tp1P%helio%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclosel, & - lrhill_present) - symba_tpP => symba_tp1P - DO i = 1, ntp - symba_tpspP => symba_tpP - symba_tpP => symba_tpP%nextP - swifter_tpspP => symba_tpspP%helio%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL symba_discard_spill_tp(ntp, nsp, symba_tp1P, symba_tpd1P, symba_tpspP) - END DO - - RETURN - -END SUBROUTINE symba_discard_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_energy.f90 b/symba/symba_energy.f90 deleted file mode 100644 index 75154942f..000000000 --- a/symba/symba_energy.f90 +++ /dev/null @@ -1,128 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_energy -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Compute total system angular momentum vector and kinetic, potential and total system energy -! -! Input -! Arguments : npl : number of planets -! nplmax : maximum allowed number of planets -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : ke : kinetic energy -! pe : potential energy -! te : total energy -! htot : angular momentum vector -! Terminal : none -! File : none -! -! Invocation : CALL symba_energy(npl, nplmax, swifter_pl1P, j2rp2, j4rp4, ke, pe, te, htot) -! -! Notes : Adapted from Martin Duncan's Swift routine anal_energy.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_energy(npl, nplmax, swifter_pl1P, j2rp2, j4rp4, ke, pe, te, htot) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => symba_energy - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: j2rp2, j4rp4 - REAL(DP), INTENT(OUT) :: ke, pe, te - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: htot - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: mass, msys, r2, v2, oblpot - REAL(DP), DIMENSION(NDIM) :: h, x, v, dx - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh - TYPE(swifter_pl), POINTER :: swifter_pliP, swifter_pljP - -! Executable code - CALL coord_h2b(npl, swifter_pl1P, msys) - htot = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - ke = 0.0_DP - pe = 0.0_DP - swifter_pliP => swifter_pl1P - DO i = 1, npl - 1 - x(:) = swifter_pliP%xb(:) - v(:) = swifter_pliP%vb(:) - mass = swifter_pliP%mass - h(1) = mass*(x(2)*v(3) - x(3)*v(2)) - h(2) = mass*(x(3)*v(1) - x(1)*v(3)) - h(3) = mass*(x(1)*v(2) - x(2)*v(1)) - htot(:) = htot(:) + h(:) - v2 = DOT_PRODUCT(v(:), v(:)) - ke = ke + 0.5_DP*mass*v2 - swifter_pljP => swifter_pliP - DO j = i + 1, npl - swifter_pljP => swifter_pljP%nextP - dx(:) = swifter_pljP%xb(:) - x(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - pe = pe - mass*swifter_pljP%mass/SQRT(r2) - END DO - swifter_pliP => swifter_pliP%nextP - END DO - x(:) = swifter_pliP%xb(:) - v(:) = swifter_pliP%vb(:) - mass = swifter_pliP%mass - h(1) = mass*(x(2)*v(3) - x(3)*v(2)) - h(2) = mass*(x(3)*v(1) - x(1)*v(3)) - h(3) = mass*(x(1)*v(2) - x(2)*v(1)) - htot(:) = htot(:) + h(:) - v2 = DOT_PRODUCT(v(:), v(:)) - ke = ke + 0.5_DP*mass*v2 - IF (j2rp2 /= 0.0_DP) THEN - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - swifter_pliP => swifter_pl1P - DO i = 2, npl - swifter_pliP => swifter_pliP%nextP - xh(:, i) = swifter_pliP%xh(:) - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - CALL obl_pot(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, oblpot) - pe = pe + oblpot - END IF - te = ke + pe - - RETURN - -END SUBROUTINE symba_energy -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_getacch.f90 b/symba/symba_getacch.f90 deleted file mode 100644 index 6f5d6fcbc..000000000 --- a/symba/symba_getacch.f90 +++ /dev/null @@ -1,220 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of planets -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! nplplenc : number of planet-planet encounters -! plplenc_list : array of planet-test particle encounter structures -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_getacch(lextra_force, t, npl, nplm, nplmax, symba_pl1P, j2rp2, j4rp4, nplplenc, plplenc_list) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_getacch.f -! -! Accelerations in an encounter are not included here -! -!********************************************************************************************************************************** -SUBROUTINE symba_getacch(lextra_force, t, npl, nplm, nplmax, symba_pl1P, j2rp2, j4rp4, nplplenc, plplenc_list) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_getacch - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, nplplenc - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, faci, facj, r2, fac - REAL(DP), DIMENSION(NDIM) :: dx - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(helio_pl), POINTER :: helio_pliP, helio_pljP - TYPE(symba_pl), POINTER :: symba_pliP, symba_pljP -! Added by D. Minton - REAL(DP), DIMENSION(NDIM) :: accsum - -! Executable code - - !Removed by D. Minton - !helio_pliP => symba_pl1P%helio - !symba_pliP => symba_pl1P - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,helio_pliP) & - !$OMP SHARED(npl,symba_pl1P) - DO i = 2, npl - !Removed by D. Minton - !helio_pliP => helio_pliP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - helio_pliP => symba_pl1P%symba_plPA(i)%thisP%helio - !^^^^^^^^^^^^^^^^^^ - helio_pliP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - !$OMP END PARALLEL DO - symba_pliP => symba_pl1P - DO i = 2, nplm - symba_pliP => symba_pliP%nextP - helio_pliP => symba_pliP%helio - !Removed by D. Minton - !symba_pljP => symba_pliP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - accsum(:)=0.0_DP - !^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(j,symba_pljP,helio_pljP,dx,rji2,irij3,faci,facj) & - !$OMP SHARED(i,npl,symba_pliP,helio_pliP,symba_pl1P) & - !$OMP REDUCTION (+:accsum) - DO j = i + 1, npl - !Removed by D. Minton - !symba_pljP => symba_pljP%nextP - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - symba_pljP=>symba_pl1P%symba_plPA(j)%thisP - !^^^^^^^^^^^^^^^^^^ - IF ((.NOT. symba_pliP%lmerged) .OR. (.NOT. symba_pljP%lmerged) .OR. & - (.NOT. ASSOCIATED(symba_pliP%parentP, symba_pljP%parentP))) THEN - helio_pljP => symba_pljP%helio - dx(:) = helio_pljP%swifter%xh(:) - helio_pliP%swifter%xh(:) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - faci = helio_pliP%swifter%mass*irij3 - facj = helio_pljP%swifter%mass*irij3 - !Removed by D. Minton - !helio_pliP%ah(:) = helio_pliP%ah(:) + facj*dx(:) - !^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - accsum(:) = accsum(:) + facj*dx(:) - !^^^^^^^^^^^^^^^^^^^^ - helio_pljP%ah(:) = helio_pljP%ah(:) - faci*dx(:) - END IF - END DO - !$OMP END PARALLEL DO - !Added by D. Minton - helio_pliP%ah(:)=helio_pliP%ah(:)+accsum(:) - !^^^^^^^^^^^^^^^^^^^^ - END DO - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,symba_pliP,symba_pljP,helio_pliP,helio_pljP,dx,rji2,irij3,faci,facj) & - !$OMP SHARED(plplenc_list,nplplenc) - DO i = 1, nplplenc - symba_pliP => plplenc_list(i)%pl1P - symba_pljP => plplenc_list(i)%pl2P - IF ((.NOT. symba_pliP%lmerged) .OR. (.NOT. symba_pljP%lmerged) .OR. & - (.NOT. ASSOCIATED(symba_pliP%parentP, symba_pljP%parentP))) THEN - helio_pliP => symba_pliP%helio - helio_pljP => symba_pljP%helio - dx(:) = helio_pljP%swifter%xh(:) - helio_pliP%swifter%xh(:) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - faci = helio_pliP%swifter%mass*irij3 - facj = helio_pljP%swifter%mass*irij3 - !$OMP CRITICAL - helio_pliP%ah(:) = helio_pliP%ah(:) - facj*dx(:) - helio_pljP%ah(:) = helio_pljP%ah(:) + faci*dx(:) - !$OMP END CRITICAL - END IF - END DO - !$OMP END PARALLEL DO - IF (j2rp2 /= 0.0_DP) THEN - swifter_pl1P => symba_pl1P%helio%swifter - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - !Removed by D. Minton - !swifter_plP => swifter_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP,r2) & - !$OMP SHARED(npl,symba_pl1P,xh,irh) - DO i = 2, npl - !Removed by D. Minton - !swifter_plP => swifter_plP%nextP - !^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - swifter_plP=>symba_pl1P%symba_plPA(i)%thisP%helio%swifter - !^^^^^^^^^^^^^^^^^^ - xh(:, i) = swifter_plP%xh(:) - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - !$OMP END PARALLEL DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - !Removed by D. Minton - !helio_pliP => symba_pl1P%helio - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,helio_pliP) & - !$OMP SHARED(npl,symba_pl1P,aobl) - DO i = 2, npl - !Removed by D. Minton - !helio_pliP => helio_pliP%nextP - !^^^^^^^^^^^^^^^^^^^^^ - !Aded by D. Minton - helio_pliP => symba_pl1P%symba_plPA(i)%thisP%helio - !^^^^^^^^^^^^^^^^^ - helio_pliP%ah(:) = helio_pliP%ah(:) + aobl(:, i) - aobl(:, 1) - END DO - !$OMP END PARALLEL DO - END IF - IF (lextra_force) CALL symba_user_getacch(t, npl, symba_pl1P) - - RETURN - -END SUBROUTINE symba_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_getacch_tp.f90 b/symba/symba_getacch_tp.f90 deleted file mode 100644 index c283ef577..000000000 --- a/symba/symba_getacch_tp.f90 +++ /dev/null @@ -1,166 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of test particles -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! xh : heliocentric positions of planets at time t -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! npltpenc : number of planet-test particle encounters -! pltpenc_list : array of planet-test particle encounter structures -! Terminal : none -! File : none -! -! Output -! Arguments : symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_getacch_tp(lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, xh, j2rp2, j4rp4, -! npltpenc, pltpenc_list) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_getacch.f -! -! Accelerations in an encounter are not included here -! -!********************************************************************************************************************************** -SUBROUTINE symba_getacch_tp(lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, xh, j2rp2, j4rp4, npltpenc, & - pltpenc_list) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_getacch_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax, npltpenc - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_pltpenc), DIMENSION(:), INTENT(IN) :: pltpenc_list - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, faci, facj, r2, fac, mu - REAL(DP), DIMENSION(NDIM) :: dx - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh, irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: aobl, xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_tp), POINTER :: helio_tpP - -! Executable code - swifter_pl1P => symba_pl1P%helio%swifter - !Removed by D. Minton - !helio_tpP => symba_tp1P%helio - !^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,helio_tpP,swifter_tpP,swifter_plP,dx,r2,fac) & - !$OMP SHARED(ntp,npl,symba_tp1P,swifter_pl1P,xh) - DO i = 1, ntp - !Added by D. Minton - helio_tpP => symba_tp1P%symba_tpPA(i)%thisP%helio - !^^^^^^^^^^^^^^^^^^ - helio_tpP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - swifter_tpP => helio_tpP%swifter - IF (swifter_tpP%status == ACTIVE) THEN - swifter_plP => swifter_pl1P - !DO j = 2, nplm - DO j = 2, npl - swifter_plP => swifter_plP%nextP - dx(:) = swifter_tpP%xh(:) - xh(:, j) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = swifter_plP%mass/(r2*SQRT(r2)) - helio_tpP%ah(:) = helio_tpP%ah(:) - fac*dx(:) - END DO - END IF - !Removed by D. Minton - !helio_tpP => helio_tpP%nextP - !^^^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP,helio_tpP,dx,r2,fac) & - !$OMP SHARED(pltpenc_list,npltpenc) - DO i = 1, npltpenc - swifter_plP => pltpenc_list(i)%plP%helio%swifter - helio_tpP => pltpenc_list(i)%tpP%helio - IF (helio_tpP%swifter%status == ACTIVE) THEN - dx(:) = helio_tpP%swifter%xh(:) - swifter_plP%xh(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = swifter_plP%mass/(r2*SQRT(r2)) - helio_tpP%ah(:) = helio_tpP%ah(:) + fac*dx(:) - END IF - END DO - !$OMP END PARALLEL DO - IF (j2rp2 /= 0.0_DP) THEN - IF (lmalloc) THEN - ALLOCATE(aobl(NDIM, nplmax), irh(nplmax), xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - DO i = 2, npl - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - mu = swifter_pl1P%mass - swifter_tpP => symba_tp1P%helio%swifter - DO i = 1, ntp - xht(:, i) = swifter_tpP%xh(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - swifter_tpP => swifter_tpP%nextP - END DO - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - helio_tpP => symba_tp1P%helio - DO i = 1, ntp - IF (helio_tpP%swifter%status == ACTIVE) helio_tpP%ah(:) = helio_tpP%ah(:) + aoblt(:, i) - aobl(:, 1) - helio_tpP => helio_tpP%nextP - END DO - END IF - IF (lextra_force) CALL symba_user_getacch_tp(t, ntp, symba_tp1P) - - RETURN - -END SUBROUTINE symba_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_helio_drift.f90 b/symba/symba_helio_drift.f90 deleted file mode 100644 index d52056947..000000000 --- a/symba/symba_helio_drift.f90 +++ /dev/null @@ -1,101 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_helio_drift -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Loop through planets and call Danby drift routine -! -! Input -! Arguments : irec : input recursion level -! npl : number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL symba_helio_drift(irec, npl, symba_pl1P, dt) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_helio_drift.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_helio_drift(irec, npl, symba_pl1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_helio_drift - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: irec, npl - REAL(DP), INTENT(IN) :: dt - TYPE(symba_pl), POINTER :: symba_pl1P - -! Internals - INTEGER(I4B) :: i, iflag - REAL(DP) :: mu - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(symba_pl), POINTER :: symba_plP - -! Executable code - mu = symba_pl1P%helio%swifter%mass - ! Removed by D. Minton - !symba_plP => symba_pl1P - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_plP,symba_plP,iflag) & - !$OMP SHARED(npl,symba_pl1P,mu,dt,irec) - DO i = 2, npl - ! Removed by D. Minton - !symba_plP => symba_plP%nextP - !^^^^^^^^^^^^^^^^^^^^^ - !Added by D. Minton - symba_plP => symba_pl1P%symba_plPA(i)%thisP - !^^^^^^^^^^^^^^^^^^ - swifter_plP => symba_plP%helio%swifter - IF ((symba_plP%levelg == irec) .AND. (swifter_plP%status == ACTIVE)) THEN - CALL drift_one(mu, swifter_plP%xh(:), swifter_plP%vb(:), dt, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", swifter_plP%id, " is lost!!!!!!!!!!" - WRITE(*, *) mu, dt - WRITE(*, *) swifter_plP%xh(:) - WRITE(*, *) swifter_plP%vb(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - END IF - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE symba_helio_drift -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_helio_drift_tp.f90 b/symba/symba_helio_drift_tp.f90 deleted file mode 100644 index 9e87f95ed..000000000 --- a/symba/symba_helio_drift_tp.f90 +++ /dev/null @@ -1,94 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_helio_drift_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Loop through test particles and call Danby drift routine -! -! Input -! Arguments : irec : input recursion level -! ntp : number of active test particles -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! mu : mass of the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL symba_helio_drift_tp(irec, ntp, symba_tp1P, mu, dt) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_helio_drift.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_helio_drift_tp(irec, ntp, symba_tp1P, mu, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_helio_drift_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: irec, ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(symba_tp), POINTER :: symba_tp1P - -! Internals - INTEGER(I4B) :: i, iflag - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - !Removed by D. Minton - !symba_tpP => symba_tp1P - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,swifter_tpP,symba_tpP,iflag) & - !$OMP SHARED(ntp,symba_tp1P,mu,dt,irec) - DO i = 1, ntp - symba_tpP => symba_tp1P%symba_tpPA(i)%thisP - swifter_tpP => symba_tpP%helio%swifter - IF ((symba_tpP%levelg == irec) .AND. (swifter_tpP%status == ACTIVE)) THEN - CALL drift_one(mu, swifter_tpP%xh(:), swifter_tpP%vb(:), dt, iflag) - IF (iflag /= 0) THEN - swifter_tpP%status = DISCARDED_DRIFTERR - WRITE(*, *) "Particle ", swifter_tpP%id, " lost due to error in Danby drift" - END IF - END IF - !Removed by D. Minton - !symba_tpP => symba_tpP%nextP - !^^^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - - RETURN - -END SUBROUTINE symba_helio_drift_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_helio_getacch.f90 b/symba/symba_helio_getacch.f90 deleted file mode 100644 index 7f466a2c0..000000000 --- a/symba/symba_helio_getacch.f90 +++ /dev/null @@ -1,116 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_helio_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of planets -! -! Input -! Arguments : lflag : logical flag indicating whether to recompute direct cross term heliocentric accelerations -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_helio_getacch(lflag, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_helio_getacch.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_helio_getacch(lflag, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_helio_getacch - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lflag, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(helio_pl), POINTER :: helio_plP - -! Executable code - IF (lflag) THEN - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ahi(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - CALL symba_helio_getacch_int(npl, nplm, helio_pl1P) - END IF - IF (j2rp2 /= 0.0_DP) THEN - swifter_pl1P => helio_pl1P%swifter - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xh(:, i) = swifter_plP%xh(:) - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ah(:) = helio_plP%ahi(:) + aobl(:, i) - aobl(:, 1) - END DO - ELSE - helio_plP => helio_pl1P - DO i = 2, npl - helio_plP => helio_plP%nextP - helio_plP%ah(:) = helio_plP%ahi(:) - END DO - END IF - IF (lextra_force) CALL helio_user_getacch(t, npl, helio_pl1P) - - RETURN - -END SUBROUTINE symba_helio_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_helio_getacch_int.f90 b/symba/symba_helio_getacch_int.f90 deleted file mode 100644 index fd0f84c4e..000000000 --- a/symba/symba_helio_getacch_int.f90 +++ /dev/null @@ -1,84 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_helio_getacch_int -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Compute direct cross term heliocentric accelerations of planets -! -! Input -! Arguments : npl : number of planets -! nplm : number of planets with mass > mtiny -! helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : helio_pl1P : pointer to head of helio planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_helio_getacch_int(npl, nplm, helio_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_helio_getacch.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_helio_getacch_int(npl, nplm, helio_pl1P) - -! Modules - USE module_parameters - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_helio_getacch_int - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, nplm - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, faci, facj - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(helio_pl), POINTER :: helio_pliP, helio_pljP - -! Executable code - helio_pliP => helio_pl1P - DO i = 2, nplm - helio_pliP => helio_pliP%nextP - helio_pljP => helio_pliP - DO j = i + 1, npl - helio_pljP => helio_pljP%nextP - dx(:) = helio_pljP%swifter%xh(:) - helio_pliP%swifter%xh(:) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - faci = helio_pliP%swifter%mass*irij3 - facj = helio_pljP%swifter%mass*irij3 - helio_pliP%ahi(:) = helio_pliP%ahi(:) + facj*dx(:) - helio_pljP%ahi(:) = helio_pljP%ahi(:) - faci*dx(:) - END DO - END DO - - RETURN - -END SUBROUTINE symba_helio_getacch_int -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_kick.f90 b/symba/symba_kick.f90 deleted file mode 100644 index a0e366651..000000000 --- a/symba/symba_kick.f90 +++ /dev/null @@ -1,174 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_kick -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Kick barycentric velocities of planets and active test particles within SyMBA recursion -! -! Input -! Arguments : irec : input recursion level -! nplplenc : number of planet-planet encounters -! npltpenc : number of planet-test particle encounters -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! dt : time step -! sgn : sign to be applied to acceleration -! Terminal : none -! File : none -! -! Output -! Arguments : plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! Terminal : none -! File : none -! -! Invocation : CALL symba_kick(irec, nplplenc, npltpenc, plplenc_list, pltpenc_list, dt, sgn) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_kick.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_kick(irec, nplplenc, npltpenc, plplenc_list, pltpenc_list, dt, sgn) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_kick - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: irec, nplplenc, npltpenc - REAL(DP), INTENT(IN) :: dt, sgn - TYPE(symba_plplenc), DIMENSION(:), INTENT(IN) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(IN) :: pltpenc_list - -! Internals - INTEGER(I4B) :: i, j, irm1, irecl - REAL(DP) :: r, rr, ri, ris, rim1, r2, ir3, fac, faci, facj - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(swifter_pl), POINTER :: swifter_pliP, swifter_pljP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_pl), POINTER :: helio_pliP, helio_pljP - TYPE(helio_tp), POINTER :: helio_tpP - TYPE(symba_pl), POINTER :: symba_pliP, symba_pljP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - irm1 = irec - 1 - IF (sgn < 0.0_DP) THEN - irecl = irec - 1 - ELSE - irecl = irec - END IF - DO i = 1, nplplenc - helio_pliP => plplenc_list(i)%pl1P%helio - helio_pljP => plplenc_list(i)%pl2P%helio - helio_pliP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - helio_pljP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - DO i = 1, npltpenc - helio_tpP => pltpenc_list(i)%tpP%helio - helio_tpP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - DO i = 1, nplplenc - IF (plplenc_list(i)%status == ACTIVE) THEN - symba_pliP => plplenc_list(i)%pl1P - symba_pljP => plplenc_list(i)%pl2P - IF ((symba_pliP%levelg >= irm1) .AND. (symba_pljP%levelg >= irm1)) THEN - helio_pliP => symba_pliP%helio - helio_pljP => symba_pljP%helio - swifter_pliP => helio_pliP%swifter - swifter_pljP => helio_pljP%swifter - ri = ((swifter_pliP%rhill + swifter_pljP%rhill)**2)*(RHSCALE**2)*(RSHELL**(2*irecl)) - rim1 = ri*(RSHELL**2) - dx(:) = swifter_pljP%xh(:) - swifter_pliP%xh(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - IF (r2 < rim1) THEN - fac = 0.0_DP - ELSE IF (r2 < ri) THEN - ris = SQRT(ri) - r = SQRT(r2) - rr = (ris - r)/(ris*(1.0_DP - RSHELL)) - fac = (r2**(-1.5_DP))*(1.0_DP - 3.0_DP*(rr**2) + 2.0_DP*(rr**3)) - ELSE - ir3 = 1.0_DP/(r2*SQRT(r2)) - fac = ir3 - END IF - faci = fac*swifter_pliP%mass - facj = fac*swifter_pljP%mass - helio_pliP%ah(:) = helio_pliP%ah(:) + facj*dx(:) - helio_pljP%ah(:) = helio_pljP%ah(:) - faci*dx(:) - END IF - END IF - END DO - DO i = 1, npltpenc - IF (pltpenc_list(i)%status == ACTIVE) THEN - symba_pliP => pltpenc_list(i)%plP - symba_tpP => pltpenc_list(i)%tpP - IF ((symba_pliP%levelg >= irm1) .AND. (symba_tpP%levelg >= irm1)) THEN - helio_pliP => symba_pliP%helio - helio_tpP => symba_tpP%helio - swifter_pliP => helio_pliP%swifter - swifter_tpP => helio_tpP%swifter - ri = ((swifter_pliP%rhill)**2)*(RHSCALE**2)*(RSHELL**(2*irecl)) - rim1 = ri*(RSHELL**2) - dx(:) = swifter_tpP%xh(:) - swifter_pliP%xh(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - IF (r2 < rim1) THEN - fac = 0.0_DP - ELSE IF (r2 < ri) THEN - ris = SQRT(ri) - r = SQRT(r2) - rr = (ris - r)/(ris*(1.0_DP - RSHELL)) - fac = (r2**(-1.5_DP))*(1.0_DP - 3.0_DP*(rr**2) + 2.0_DP*(rr**3)) - ELSE - ir3 = 1.0_DP/(r2*SQRT(r2)) - fac = ir3 - END IF - faci = fac*swifter_pliP%mass - helio_tpP%ah(:) = helio_tpP%ah(:) - faci*dx(:) - END IF - END IF - END DO - DO i = 1, nplplenc - helio_pliP => plplenc_list(i)%pl1P%helio - helio_pljP => plplenc_list(i)%pl2P%helio - swifter_pliP => helio_pliP%swifter - swifter_pljP => helio_pljP%swifter - swifter_pliP%vb(:) = swifter_pliP%vb(:) + sgn*dt*helio_pliP%ah(:) - swifter_pljP%vb(:) = swifter_pljP%vb(:) + sgn*dt*helio_pljP%ah(:) - helio_pliP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - helio_pljP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - DO i = 1, npltpenc - helio_tpP => pltpenc_list(i)%tpP%helio - swifter_tpP => helio_tpP%swifter - IF (swifter_tpP%status == ACTIVE) swifter_tpP%vb(:) = swifter_tpP%vb(:) + sgn*dt*helio_tpP%ah(:) - helio_tpP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - END DO - - RETURN - -END SUBROUTINE symba_kick -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_merge_pl.f90 b/symba/symba_merge_pl.f90 deleted file mode 100644 index cdefe0e41..000000000 --- a/symba/symba_merge_pl.f90 +++ /dev/null @@ -1,253 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_merge_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check for merger between planets in SyMBA -! -! Input -! Arguments : t : time -! dt : time step -! index : index of planet-planet encounter in array plplenc_list -! nplplenc : number of planet-planet encounters -! plplenc_list : array of planet-planet encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! eoffset : energy offset (net energy lost in mergers) -! vbs : barycentric velocity of the Sun -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : plplenc_list : array of planet-planet encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! eoffset : energy offset (net energy lost in mergers) -! Terminal : status message -! File : none -! -! Invocation : CALL symba_merge_pl(t, dt, index, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, -! eoffset, vbs, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_merge.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_merge_pl(t, dt, index, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, vbs, & - encounter_file, out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_merge_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: index, nplplenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, dt - REAL(DP), INTENT(INOUT) :: eoffset - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vbs - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - -! Internals - LOGICAL(LGT) :: lmerge - INTEGER(I4B) :: i, j, k, id1, id2, stat1, stat2 - REAL(DP) :: r2, rlim, rlim2, vdotr, tcr2, dt2, mtot, a, e, q, m1, m2, mtmp, mmax, eold, enew, rad1, rad2 - REAL(DP), DIMENSION(NDIM) :: xr, vr, x1, v1, x2, v2, xnew, vnew - TYPE(swifter_pl), POINTER :: swifter_pliP, swifter_pljP, swifter_plP - TYPE(symba_pl), POINTER :: symba_pliP, symba_pljP, symba_plP - -! Executable code - lmerge = .FALSE. - symba_pliP => plplenc_list(index)%pl1P - symba_pljP => plplenc_list(index)%pl2P - swifter_pliP => symba_pliP%helio%swifter - swifter_pljP => symba_pljP%helio%swifter - rlim = swifter_pliP%radius + swifter_pljP%radius - xr(:) = swifter_pljP%xh(:) - swifter_pliP%xh(:) - r2 = DOT_PRODUCT(xr(:), xr(:)) - rlim2 = rlim*rlim - IF (rlim2 >= r2) THEN - lmerge = .TRUE. - ELSE - vr(:) = swifter_pljP%vb(:) - swifter_pliP%vb(:) - vdotr = DOT_PRODUCT(xr(:), vr(:)) - IF (plplenc_list(index)%lvdotr .AND. (vdotr > 0.0_DP)) THEN - tcr2 = r2/DOT_PRODUCT(vr(:), vr(:)) - dt2 = dt*dt - IF (tcr2 <= dt2) THEN - mtot = swifter_pliP%mass + swifter_pljP%mass - CALL orbel_xv2aeq(xr(:), vr(:), mtot, a, e, q) - IF (q < rlim) lmerge = .TRUE. - END IF - IF (.NOT. lmerge) THEN - IF (encounter_file /= "") THEN - id1 = swifter_pliP%id - m1 = swifter_pliP%mass - rad1 = swifter_pliP%radius - x1(:) = swifter_pliP%xh(:) - v1(:) = swifter_pliP%vb(:) - vbs(:) - id2 = swifter_pljP%id - m2 = swifter_pljP%mass - rad2 = swifter_pljP%radius - x2(:) = swifter_pljP%xh(:) - v2(:) = swifter_pljP%vb(:) - vbs(:) - CALL io_write_encounter(t, id1, id2, m1, m2, rad1, rad2, x1(:), x2(:), v1(:), v2(:), encounter_file, & - out_type) - END IF - END IF - END IF - END IF - IF (lmerge) THEN - symba_pliP%lmerged = .TRUE. - symba_pljP%lmerged = .TRUE. - symba_pliP => symba_pliP%parentP - m1 = symba_pliP%helio%swifter%mass - x1(:) = m1*symba_pliP%helio%swifter%xh(:) - v1(:) = m1*symba_pliP%helio%swifter%vb(:) - mmax = m1 - id1 = symba_pliP%helio%swifter%id - stat1 = symba_pliP%helio%swifter%status - symba_plP => symba_pliP - DO i = 1, symba_pliP%nchild - symba_plP => symba_plP%childP - mtmp = symba_plP%helio%swifter%mass - IF (mtmp > mmax) THEN - mmax = mtmp - id1 = symba_plP%helio%swifter%id - stat1 = symba_plP%helio%swifter%status - END IF - m1 = m1 + mtmp - x1(:) = x1(:) + mtmp*symba_plP%helio%swifter%xh(:) - v1(:) = v1(:) + mtmp*symba_plP%helio%swifter%vb(:) - END DO - x1(:) = x1(:)/m1 - v1(:) = v1(:)/m1 - symba_pljP => symba_pljP%parentP - m2 = symba_pljP%helio%swifter%mass - x2(:) = m2*symba_pljP%helio%swifter%xh(:) - v2(:) = m2*symba_pljP%helio%swifter%vb(:) - mmax = m2 - id2 = symba_pljP%helio%swifter%id - stat2 = symba_pljP%helio%swifter%status - symba_plP => symba_pljP - DO i = 1, symba_pljP%nchild - symba_plP => symba_plP%childP - mtmp = symba_plP%helio%swifter%mass - IF (mtmp > mmax) THEN - mmax = mtmp - id2 = symba_plP%helio%swifter%id - stat2 = symba_plP%helio%swifter%status - END IF - m2 = m2 + mtmp - x2(:) = x2(:) + mtmp*symba_plP%helio%swifter%xh(:) - v2(:) = v2(:) + mtmp*symba_plP%helio%swifter%vb(:) - END DO - x2(:) = x2(:)/m2 - v2(:) = v2(:)/m2 - mtot = m1 + m2 - xnew(:) = (m1*x1(:) + m2*x2(:))/mtot - vnew(:) = (m1*v1(:) + m2*v2(:))/mtot - WRITE(*, *) "Merging particles ", id1, " and ", id2, " at time t = ",t - nmergesub = nmergesub + 1 - mergesub_list(nmergesub)%id = id1 - mergesub_list(nmergesub)%status = MERGED - mergesub_list(nmergesub)%xh(:) = x1(:) - mergesub_list(nmergesub)%vh(:) = v1(:) - vbs(:) - nmergesub = nmergesub + 1 - mergesub_list(nmergesub)%id = id2 - mergesub_list(nmergesub)%status = MERGED - mergesub_list(nmergesub)%xh(:) = x2(:) - mergesub_list(nmergesub)%vh(:) = v2(:) - vbs(:) - nmergeadd = nmergeadd + 1 - IF (m2 > m1) THEN - mergeadd_list(nmergeadd)%id = id2 - mergeadd_list(nmergeadd)%status = stat2 - ELSE - mergeadd_list(nmergeadd)%id = id1 - mergeadd_list(nmergeadd)%status = stat1 - END IF - mergeadd_list(nmergeadd)%ncomp = 2 - mergeadd_list(nmergeadd)%xh(:) = xnew(:) - mergeadd_list(nmergeadd)%vh(:) = vnew(:) - vbs(:) - eold = 0.5_DP*(m1*DOT_PRODUCT(v1(:), v1(:)) + m2*DOT_PRODUCT(v2(:), v2(:))) - xr(:) = x2(:) - x1(:) - eold = eold - m1*m2/SQRT(DOT_PRODUCT(xr(:), xr(:))) - enew = 0.5_DP*mtot*DOT_PRODUCT(vnew(:), vnew(:)) - eoffset = eoffset + eold - enew - DO k = 1, nplplenc - IF (plplenc_list(k)%status == ACTIVE) THEN - symba_pliP => plplenc_list(index)%pl1P%parentP - DO i = 0, symba_pliP%nchild - symba_pljP => plplenc_list(index)%pl2P%parentP - DO j = 0, symba_pljP%nchild - IF (ASSOCIATED(plplenc_list(k)%pl1P, symba_pliP) .AND. & - ASSOCIATED(plplenc_list(k)%pl2P, symba_pljP)) THEN - plplenc_list(k)%status = MERGED - ELSE IF (ASSOCIATED(plplenc_list(k)%pl1P, symba_pljP) .AND. & - ASSOCIATED(plplenc_list(k)%pl2P, symba_pliP)) THEN - plplenc_list(k)%status = MERGED - END IF - symba_pljP => symba_pljP%childP - END DO - symba_pliP => symba_pliP%childP - END DO - END IF - END DO - symba_pliP => plplenc_list(index)%pl1P%parentP - symba_plP => symba_pliP - swifter_plP => symba_plP%helio%swifter - swifter_plP%xh(:) = xnew(:) - swifter_plP%vb(:) = vnew(:) - DO i = 1, symba_pliP%nchild - symba_plP => symba_plP%childP - swifter_plP => symba_plP%helio%swifter - swifter_plP%xh(:) = xnew(:) - swifter_plP%vb(:) = vnew(:) - END DO - symba_pljP => plplenc_list(index)%pl2P%parentP - symba_plP%childP => symba_pljP - DO i = 0, symba_pljP%nchild - symba_plP => symba_plP%childP - symba_plP%parentP => symba_pliP - swifter_plP => symba_plP%helio%swifter - swifter_plP%xh(:) = xnew(:) - swifter_plP%vb(:) = vnew(:) - END DO - symba_pliP%nchild = symba_pliP%nchild + symba_pljP%nchild + 1 - END IF - - RETURN - -END SUBROUTINE symba_merge_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_merge_tp.f90 b/symba/symba_merge_tp.f90 deleted file mode 100644 index 4250af81a..000000000 --- a/symba/symba_merge_tp.f90 +++ /dev/null @@ -1,124 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_merge_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Check for merger between planet and test particle in SyMBA -! -! Input -! Arguments : t : time -! dt : time step -! index : index of planet-test particle encounter in array pltpenc_list -! npltpenc : number of planet-test particle encounters -! pltpenc_list : array of planet-test particle encounter structures -! vbs : barycentric velocity of the Sun -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : pltpenc_list : array of planet-test particle encounter structures -! Terminal : status message -! File : none -! -! Invocation : CALL symba_merge_tp(t, dt, index, npltpenc, pltpenc_list, vbs, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_merge.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_merge_tp(t, dt, index, npltpenc, pltpenc_list, vbs, encounter_file, out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_merge_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: index, npltpenc - REAL(DP), INTENT(IN) :: t, dt - REAL(DP), DIMENSION(NDIM), INTENT(IN) :: vbs - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - -! Internals - LOGICAL(LGT) :: lmerge - INTEGER(I4B) :: id1, id2 - REAL(DP) :: r2, rlim, rlim2, vdotr, tcr2, dt2, mu, a, e, q, rad1 - REAL(DP), DIMENSION(NDIM) :: xr, vr, xh1, vh1, xh2, vh2 - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(symba_pl), POINTER :: symba_plP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - lmerge = .FALSE. - symba_plP => pltpenc_list(index)%plP - symba_tpP => pltpenc_list(index)%tpP - swifter_plP => symba_plP%helio%swifter - swifter_tpP => symba_tpP%helio%swifter - rlim = swifter_plP%radius - xr(:) = swifter_tpP%xh(:) - swifter_plP%xh(:) - r2 = DOT_PRODUCT(xr(:), xr(:)) - rlim2 = rlim*rlim - IF (rlim2 >= r2) THEN - lmerge = .TRUE. - ELSE - vr(:) = swifter_tpP%vb(:) - swifter_plP%vb(:) - vdotr = DOT_PRODUCT(xr(:), vr(:)) - IF (pltpenc_list(index)%lvdotr .AND. (vdotr > 0.0_DP)) THEN - mu = swifter_plP%mass - tcr2 = r2/DOT_PRODUCT(vr(:), vr(:)) - dt2 = dt*dt - IF (tcr2 <= dt2) THEN - CALL orbel_xv2aeq(xr(:), vr(:), mu, a, e, q) - IF (q < rlim) lmerge = .TRUE. - END IF - IF (.NOT. lmerge) THEN - IF (encounter_file /= "") THEN - id1 = swifter_plP%id - rad1 = swifter_plP%radius - xh1(:) = swifter_plP%xh(:) - vh1(:) = swifter_plP%vb(:) - vbs(:) - id2 = swifter_tpP%id - xh2(:) = swifter_tpP%xh(:) - vh2(:) = swifter_tpP%vb(:) - vbs(:) - CALL io_write_encounter(t, id1, id2, mu, 0.0_DP, rad1, 0.0_DP, xh1(:), xh2(:), vh1(:), vh2(:), & - encounter_file, out_type) - END IF - END IF - END IF - END IF - IF (lmerge) THEN - pltpenc_list(index)%status = MERGED - swifter_tpP%status = DISCARDED_PLR - WRITE(*, *) "Particle ", swifter_tpP%id, " too close to Planet ", swifter_plP%id, " at t = ", t - END IF - - RETURN - -END SUBROUTINE symba_merge_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_peri.f90 b/symba/symba_peri.f90 deleted file mode 100644 index a3a6b6a65..000000000 --- a/symba/symba_peri.f90 +++ /dev/null @@ -1,152 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_peri -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Determine system pericenter passages for planets in SyMBA -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! npl : number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! msys : total system mass -! qmin_coord : coordinate frame for qmin -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_peri(lfirst, npl, symba_pl1P, msys, qmin_coord) -! -! Notes : Adapted from Hal Levison's Swift routine util_mass_peri.f -! -! If the coordinate system used is barycentric, then this routine assumes that the barycentric coordinates in the -! planet structures are up-to-date and are not recomputed -! -!********************************************************************************************************************************** -SUBROUTINE symba_peri(lfirst, npl, symba_pl1P, msys, qmin_coord) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_peri - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: msys - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(symba_pl), POINTER :: symba_pl1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: vdotr, e, mu, msun - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(symba_pl), POINTER :: symba_plP - -! Executable code - msun = symba_pl1P%helio%swifter%mass - symba_plP => symba_pl1P - IF (lfirst) THEN - IF (qmin_coord == "HELIO") THEN - DO i = 2, npl - symba_plP => symba_plP%nextP - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_plP%xh(:), swifter_plP%vh(:)) - IF (vdotr > 0.0_DP) THEN - symba_plP%isperi = 1 - ELSE - symba_plP%isperi = -1 - END IF - END IF - END DO - ELSE - DO i = 2, npl - symba_plP => symba_plP%nextP - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_plP%xb(:), swifter_plP%vb(:)) - IF (vdotr > 0.0_DP) THEN - symba_plP%isperi = 1 - ELSE - symba_plP%isperi = -1 - END IF - END IF - END DO - END IF - ELSE - IF (qmin_coord == "HELIO") THEN - DO i = 2, npl - symba_plP => symba_plP%nextP - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_plP%xh(:), swifter_plP%vh(:)) - IF (symba_plP%isperi == -1) THEN - IF (vdotr >= 0.0_DP) THEN - symba_plP%isperi = 0 - mu = msun + swifter_plP%mass - CALL orbel_xv2aeq(swifter_plP%xh(:), swifter_plP%vh(:), mu, symba_plP%atp, e, symba_plP%peri) - END IF - ELSE - IF (vdotr > 0.0_DP) THEN - symba_plP%isperi = 1 - ELSE - symba_plP%isperi = -1 - END IF - END IF - END IF - END DO - ELSE - DO i = 2, npl - symba_plP => symba_plP%nextP - swifter_plP => symba_plP%helio%swifter - IF (swifter_plP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_plP%xb(:), swifter_plP%vb(:)) - IF (symba_plP%isperi == -1) THEN - IF (vdotr >= 0.0_DP) THEN - symba_plP%isperi = 0 - CALL orbel_xv2aeq(swifter_plP%xb(:), swifter_plP%vb(:), msys, symba_plP%atp, e, symba_plP%peri) - END IF - ELSE - IF (vdotr > 0.0_DP) THEN - symba_plP%isperi = 1 - ELSE - symba_plP%isperi = -1 - END IF - END IF - END IF - END DO - END IF - END IF - - RETURN - -END SUBROUTINE symba_peri -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_reorder_pl.f90 b/symba/symba_reorder_pl.f90 deleted file mode 100644 index 5ca812170..000000000 --- a/symba/symba_reorder_pl.f90 +++ /dev/null @@ -1,92 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_reorder_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Rearrange SyMBA planet structure linked-list in order of decreasing mass -! -! Input -! Arguments : npl : number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_reorder_pl(npl, symba_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_reorder_pl(npl, symba_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_reorder_pl - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(symba_pl), POINTER :: symba_pl1P - -! Internals - INTEGER(I4B) :: i - INTEGER(I4B), DIMENSION(:), ALLOCATABLE :: index - REAL(DP), DIMENSION(:), ALLOCATABLE :: mass - TYPE(symba_pl), DIMENSION(:), ALLOCATABLE :: symba_plwkspA - TYPE(symba_pl), POINTER :: symba_plP - -! Executable code - ALLOCATE(index(npl), mass(npl), symba_plwkspA(npl)) - symba_plP => symba_pl1P - DO i = 1, npl - symba_plwkspA(i) = symba_plP - mass(i) = symba_plP%helio%swifter%mass - symba_plP => symba_plP%nextP - END DO - CALL util_index(mass, index) - symba_plP => symba_pl1P - DO i = 1, npl - symba_plP%helio%swifter%id = symba_plwkspA(index(npl-i+1))%helio%swifter%id - symba_plP%helio%swifter%status = symba_plwkspA(index(npl-i+1))%helio%swifter%status - symba_plP%helio%swifter%mass = symba_plwkspA(index(npl-i+1))%helio%swifter%mass - symba_plP%helio%swifter%radius = symba_plwkspA(index(npl-i+1))%helio%swifter%radius - symba_plP%helio%swifter%rhill = symba_plwkspA(index(npl-i+1))%helio%swifter%rhill - symba_plP%helio%swifter%xh(:) = symba_plwkspA(index(npl-i+1))%helio%swifter%xh(:) - symba_plP%helio%swifter%vh(:) = symba_plwkspA(index(npl-i+1))%helio%swifter%vh(:) - symba_plP => symba_plP%nextP - END DO - IF (ALLOCATED(symba_plwkspA)) DEALLOCATE(symba_plwkspA) - IF (ALLOCATED(mass)) DEALLOCATE(mass) - IF (ALLOCATED(index)) DEALLOCATE(index) - - RETURN - -END SUBROUTINE symba_reorder_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_setup.f90 b/symba/symba_setup.f90 deleted file mode 100644 index 5df7cc461..000000000 --- a/symba/symba_setup.f90 +++ /dev/null @@ -1,157 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_setup -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Set up pointers within SyMBA, helio and Swifter planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! symba_plA : SyMBA planet structure array -! symba_tpA : SyMBA test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : symba_plA : SyMBA planet structure array -! symba_tpA : SyMBA test particle structure array -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! swifter_pl1P : pointer to head of Swifter planet structure linked-list -! swifter_tp1P : pointer to head of active Swifter test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_setup(npl, ntp, symba_plA, symba_tpA, symba_pl1P, symba_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_setup(npl, ntp, symba_plA, symba_tpA, symba_pl1P, symba_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(symba_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: symba_plA - TYPE(symba_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: symba_tpA - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_pl), POINTER :: helio_pl1P, helio_plP - TYPE(helio_tp), POINTER :: helio_tp1P, helio_tpP - TYPE(symba_pl), POINTER :: symba_plP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - symba_pl1P => symba_plA(1) - helio_pl1P => symba_plA(1)%helio - swifter_pl1P => symba_plA(1)%helio%swifter - NULLIFY(symba_pl1P%prevP) - NULLIFY(helio_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(symba_pl1P%nextP) - NULLIFY(helio_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - symba_pl1P%nextP => symba_plA(2) - helio_pl1P%nextP => symba_plA(2)%helio - swifter_pl1P%nextP => symba_plA(2)%helio%swifter - DO i = 2, npl - 1 - symba_plA(i)%prevP => symba_plA(i-1) - symba_plA(i)%nextP => symba_plA(i+1) - helio_plP => symba_plA(i)%helio - helio_plP%prevP => symba_plA(i-1)%helio - helio_plP%nextP => symba_plA(i+1)%helio - swifter_plP => symba_plA(i)%helio%swifter - swifter_plP%prevP => symba_plA(i-1)%helio%swifter - swifter_plP%nextP => symba_plA(i+1)%helio%swifter - END DO - symba_plA(npl)%prevP => symba_plA(npl-1) - symba_plP => symba_plA(npl) - NULLIFY(symba_plP%nextP) - helio_plP => symba_plA(npl)%helio - helio_plP%prevP => symba_plA(npl-1)%helio - NULLIFY(helio_plP%nextP) - swifter_plP => symba_plA(npl)%helio%swifter - swifter_plP%prevP => symba_plA(npl-1)%helio%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(symba_tp1P) - NULLIFY(helio_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - symba_tp1P => symba_tpA(1) - helio_tp1P => symba_tpA(1)%helio - swifter_tp1P => symba_tpA(1)%helio%swifter - NULLIFY(symba_tp1P%prevP) - NULLIFY(helio_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(symba_tp1P%nextP) - NULLIFY(helio_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - symba_tp1P%nextP => symba_tpA(2) - helio_tp1P%nextP => symba_tpA(2)%helio - swifter_tp1P%nextP => symba_tpA(2)%helio%swifter - DO i = 2, ntp - 1 - symba_tpA(i)%prevP => symba_tpA(i-1) - symba_tpA(i)%nextP => symba_tpA(i+1) - helio_tpP => symba_tpA(i)%helio - helio_tpP%prevP => symba_tpA(i-1)%helio - helio_tpP%nextP => symba_tpA(i+1)%helio - swifter_tpP => symba_tpA(i)%helio%swifter - swifter_tpP%prevP => symba_tpA(i-1)%helio%swifter - swifter_tpP%nextP => symba_tpA(i+1)%helio%swifter - END DO - symba_tpA(ntp)%prevP => symba_tpA(ntp-1) - symba_tpP => symba_tpA(ntp) - NULLIFY(symba_tpP%nextP) - helio_tpP => symba_tpA(ntp)%helio - helio_tpP%prevP => symba_tpA(ntp-1)%helio - NULLIFY(helio_tpP%nextP) - swifter_tpP => symba_tpA(ntp)%helio%swifter - swifter_tpP%prevP => symba_tpA(ntp-1)%helio%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE symba_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_step.f90 b/symba/symba_step.f90 deleted file mode 100644 index 4354a763a..000000000 --- a/symba/symba_step.f90 +++ /dev/null @@ -1,284 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_step -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in democratic heliocentric coordinates, descending the recursive -! branch if necessary to handle possible close encounters -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! lclose : logical flag indicating whether to check for mergers -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! nplplenc : number of planet-planet encounters -! npltpenc : number of planet-test particle encounters -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! eoffset : energy offset (net energy lost in mergers) -! mtiny : smallest self-gravitating mass -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! nplplenc : number of planet-planet encounters -! npltpenc : number of planet-test particle encounters -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! eoffset : energy offset (net energy lost in mergers) -! Terminal : error message -! File : none -! -! Invocation : CALL symba_step(lfirst, lextra_force, lclose, t, npl, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, -! dt, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, -! mergesub_list, eoffset, mtiny, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_step_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_step(lfirst, lextra_force, lclose, t, npl, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, dt, & - nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, eoffset, mtiny, & - encounter_file, out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force, lclose - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - INTEGER(I4B), INTENT(INOUT) :: nplplenc, npltpenc, nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt, mtiny - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - -! Internals - LOGICAL(LGT) :: lencounter, lvdotr - INTEGER(I4B) :: i, j, irec, nplm - REAL(DP), DIMENSION(NDIM) :: xr, vr - TYPE(swifter_pl), POINTER :: swifter_pliP, swifter_pljP - !Added by D. Minton - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - !^^^^^^^^^^^^^^^^^^ - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - TYPE(symba_pl), POINTER :: symba_pliP, symba_pljP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - symba_pliP => symba_pl1P - helio_pl1P => symba_pl1P%helio - !Added by D. Minton - swifter_pl1P => helio_pl1P%swifter - IF (ALLOCATED(symba_pl1P%symba_plPA)) DEALLOCATE(symba_pl1P%symba_plPA) - ALLOCATE(symba_pl1P%symba_plPA(npl)) - IF (ALLOCATED(swifter_pl1P%swifter_plPA)) DEALLOCATE(swifter_pl1P%swifter_plPA) - ALLOCATE(swifter_pl1P%swifter_plPA(npl)) - IF (ALLOCATED(helio_pl1P%helio_plPA)) DEALLOCATE(helio_pl1P%helio_plPA) - ALLOCATE(helio_pl1P%helio_plPA(npl)) - IF (ntp>0) THEN - IF (ALLOCATED(symba_tp1P%symba_tpPA)) DEALLOCATE(symba_tp1P%symba_tpPA) - ALLOCATE(symba_tp1P%symba_tpPA(ntp)) - END IF - !^^^^^^^^^^^^^^^^^^ - DO i = 1, npl - symba_pliP%nplenc = 0 - symba_pliP%ntpenc = 0 - symba_pliP%levelg = -1 - symba_pliP%levelm = -1 - ! Added by D. Minton - symba_pl1P%symba_plPA(i)%thisP => symba_pliP - helio_pl1p%helio_plPA(i)%thisP => symba_pliP%helio - swifter_pl1P%swifter_plPA(i)%thisP => symba_pliP%helio%swifter - !^^^^^^^^^^^^ - symba_pliP => symba_pliP%nextP - END DO - symba_tpP => symba_tp1P - DO i = 1, ntp - symba_tpP%nplenc = 0 - symba_tpP%levelg = -1 - symba_tpP%levelm = -1 - ! Added by D. Minton - symba_tp1P%symba_tpPA(i)%thisP => symba_tpP - !^^^^^^^^^^^^ - symba_tpP => symba_tpP%nextP - END DO - nplplenc = 0 - npltpenc = 0 - IF (symba_pl1P%helio%swifter%mass < mtiny) THEN - nplm = 0 - ELSE - nplm = 1 - END IF - irec = 0 - symba_pliP => symba_pl1P - DO i = 2, npl - symba_pliP => symba_pliP%nextP - swifter_pliP => symba_pliP%helio%swifter - IF (swifter_pliP%mass < mtiny) EXIT - nplm = nplm + 1 - ! Removed by D. Minton - !symba_pljP => symba_pliP - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(j,xr,vr,lencounter,lvdotr,symba_pljP,swifter_pljP) & - !$OMP SHARED(i,npl,irec,symba_pl1P,symba_pliP,swifter_pliP,dt,plplenc_list,nplplenc) - DO j = i + 1, npl - ! Added by D. Minton - symba_pljP=>symba_pl1P%symba_plPA(j)%thisP - !^^^^^^^^^^^^^^^^^^ - ! Removed by D. Minton - !symba_pljP => symba_pljP%nextP - !^^^^^^^^^^^^^^^^^^^^ - swifter_pljP => symba_pljP%helio%swifter - xr(:) = swifter_pljP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_pljP%vh(:) - swifter_pliP%vh(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, swifter_pljP%rhill, dt, irec, lencounter, lvdotr) - IF (lencounter) THEN - ! Added by D. Minton - !$OMP CRITICAL - nplplenc = nplplenc + 1 - IF (nplplenc > NENMAX) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " PL-PL encounter list is full." - WRITE(*, *) " STOPPING..." - CALL util_exit(FAILURE) - END IF - plplenc_list(nplplenc)%status = ACTIVE - plplenc_list(nplplenc)%lvdotr = lvdotr - plplenc_list(nplplenc)%level = irec - plplenc_list(nplplenc)%pl1P => symba_pliP - plplenc_list(nplplenc)%pl2P => symba_pljP - symba_pliP%lmerged = .FALSE. - symba_pliP%nplenc = symba_pliP%nplenc + 1 - symba_pliP%levelg = irec - symba_pliP%levelm = irec - symba_pliP%parentP => symba_pliP - !$OMP END CRITICAL - NULLIFY(symba_pliP%childP) - symba_pliP%nchild = 0 - symba_pljP%lmerged = .FALSE. - symba_pljP%nplenc = symba_pljP%nplenc + 1 - symba_pljP%levelg = irec - symba_pljP%levelm = irec - symba_pljP%parentP => symba_pljP - NULLIFY(symba_pljP%childP) - symba_pljP%nchild = 0 - END IF - END DO - !$OMP END PARALLEL DO - ! Removed by D. Minton - !symba_tpP => symba_tp1P - !^^^^^^^^^^^^^^^^^^^^^ - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE(STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(j,xr,vr,lencounter,lvdotr,symba_tpP,swifter_tpP) & - !$OMP SHARED(ntp,irec,symba_tp1P,dt,swifter_pliP,symba_pliP,pltpenc_list,npltpenc) - DO j = 1, ntp - !Added by D. Minton - symba_tpP => symba_tp1P%symba_tpPA(j)%thisP - !^^^^^^^^^^^^^^^^^^ - swifter_tpP => symba_tpP%helio%swifter - xr(:) = swifter_tpP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_tpP%vh(:) - swifter_pliP%vh(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, 0.0_DP, dt, irec, lencounter, lvdotr) - IF (lencounter) THEN - symba_pliP%ntpenc = symba_pliP%ntpenc + 1 - symba_pliP%levelg = irec - symba_pliP%levelm = irec - symba_tpP%nplenc = symba_tpP%nplenc + 1 - symba_tpP%levelg = irec - symba_tpP%levelm = irec - ! Added by D. Minton - !$OMP CRITICAL - npltpenc = npltpenc + 1 - IF (npltpenc > NENMAX) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " PL-TP encounter list is full." - WRITE(*, *) " STOPPING..." - CALL util_exit(FAILURE) - END IF - pltpenc_list(npltpenc)%status = ACTIVE - pltpenc_list(npltpenc)%lvdotr = lvdotr - pltpenc_list(npltpenc)%level = irec - pltpenc_list(npltpenc)%plP => symba_pliP - pltpenc_list(npltpenc)%tpP => symba_tpP - !$OMP END CRITICAL - END IF - !Removed by D. Minton - !symba_tpP => symba_tpP%nextP - !^^^^^^^^^^^^^^^^^^^^ - END DO - !$OMP END PARALLEL DO - END DO - lencounter = ((nplplenc > 0) .OR. (npltpenc > 0)) - IF (lencounter) THEN - CALL symba_step_interp(lextra_force, lclose, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, & - dt, eoffset, mtiny, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, encounter_file, out_type) - lfirst = .TRUE. - ELSE - helio_pl1P => symba_pl1P%helio - helio_tp1P => symba_tp1P%helio - CALL symba_step_helio(lfirst, lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) - END IF - - RETURN - -END SUBROUTINE symba_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_step_helio.f90 b/symba/symba_step_helio.f90 deleted file mode 100644 index 8b9df12db..000000000 --- a/symba/symba_step_helio.f90 +++ /dev/null @@ -1,95 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_step_helio -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Step planets and test particles ahead in democratic heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of helio test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! helio_pl1P : pointer to head of helio planet structure linked-list -! helio_tp1P : pointer to head of helio test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL symba_step_helio(lfirst, lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, -! j4rp4, dt) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_step_helio(lfirst, lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_step_helio - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - REAL(DP), DIMENSION(NDIM) :: ptb, pte - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, xend - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - lfirsttp = lfirst - CALL symba_step_helio_pl(lfirst, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) - IF (ntp > 0) CALL helio_step_tp(lfirsttp, lextra_force, t, nplm, nplmax, ntp, ntpmax, helio_pl1P, helio_tp1P, j2rp2, j4rp4, & - dt, xbeg, xend, ptb, pte) - - RETURN - -END SUBROUTINE symba_step_helio -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_step_helio_pl.f90 b/symba/symba_step_helio_pl.f90 deleted file mode 100644 index 40e6ebb1d..000000000 --- a/symba/symba_step_helio_pl.f90 +++ /dev/null @@ -1,114 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_step_helio_pl -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Step planets ahead in democratic heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! helio_pl1P : pointer to head of helio planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! helio_pl1P : pointer to head of helio planet structure linked-list -! xbeg : heliocentric positions of planets with mass > mtiny prior to Kepler drift -! xend : heliocentric positions of planets with mass > mtiny after Kepler drift -! ptb : negative barycentric velocity of the Sun prior to the first kick -! pte : negative barycentric velocity of the Sun after the second kick -! Terminal : none -! File : none -! -! Invocation : CALL symba_step_helio_pl(lfirst, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, -! ptb, pte) -! -! Notes : Adapted from Hal Levison's Swift routines symba5_step_helio.f and helio_step_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_step_helio_pl(lfirst, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4, dt, xbeg, xend, ptb, pte) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_step_helio_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM, nplm), INTENT(OUT) :: xbeg, xend - REAL(DP), DIMENSION(NDIM), INTENT(OUT) :: ptb, pte - TYPE(helio_pl), POINTER :: helio_pl1P - -! Internals - LOGICAL(LGT) :: lflag - INTEGER(I4B) :: i - REAL(DP) :: dth, msys - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - -! Executable code - dth = 0.5_DP*dt - lflag = lfirst - swifter_pl1P => helio_pl1P%swifter - IF (lfirst) THEN - CALL coord_vh2vb(npl, swifter_pl1P, msys) - lfirst = .FALSE. - END IF - CALL helio_lindrift(npl, swifter_pl1P, dth, ptb) - CALL symba_helio_getacch(lflag, lextra_force, t, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4) - lflag = .TRUE. - CALL helio_kickvb(npl, helio_pl1P, dth) - swifter_plP => swifter_pl1P - DO i = 2, nplm - swifter_plP => swifter_plP%nextP - xbeg(:, i) = swifter_plP%xh(:) - END DO - CALL helio_drift(npl, swifter_pl1P, dt) - swifter_plP => swifter_pl1P - DO i = 2, nplm - swifter_plP => swifter_plP%nextP - xend(:, i) = swifter_plP%xh(:) - END DO - CALL symba_helio_getacch(lflag, lextra_force, t+dt, npl, nplm, nplmax, helio_pl1P, j2rp2, j4rp4) - CALL helio_kickvb(npl, helio_pl1P, dth) - CALL helio_lindrift(npl, swifter_pl1P, dth, pte) - CALL coord_vb2vh(npl, swifter_pl1P) - - RETURN - -END SUBROUTINE symba_step_helio_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_step_interp.f90 b/symba/symba_step_interp.f90 deleted file mode 100644 index df801cd20..000000000 --- a/symba/symba_step_interp.f90 +++ /dev/null @@ -1,168 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_step_interp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in democratic heliocentric coordinates, calling the recursive -! subroutine to descend to the appropriate level to handle close encounters -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! lclose : logical flag indicating whether to check for mergers -! t : time -! npl : number of planets -! nplm : number of planets with mass > mtiny -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! eoffset : energy offset (net energy lost in mergers) -! mtiny : smallest self-gravitating mass -! nplplenc : number of planet-planet encounters -! npltpenc : number of planet-test particle encounters -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! eoffset : energy offset (net energy lost in mergers) -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! Terminal : none -! File : none -! -! Invocation : CALL symba_step_interp(lextra_force, lclose, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, -! j4rp4, dt, eoffset, mtiny, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, -! nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_step_interp.f -! -!********************************************************************************************************************************** -SUBROUTINE symba_step_interp(lextra_force, lclose, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, j2rp2, j4rp4, dt, & - eoffset, mtiny, nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - encounter_file, out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_step_interp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force, lclose - INTEGER(I4B), INTENT(IN) :: npl, nplm, nplmax, ntp, ntpmax, nplplenc, npltpenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt, mtiny - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, irec - REAL(DP) :: dth, msys - REAL(DP), DIMENSION(NDIM) :: ptb, pte - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, xend - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(helio_pl), POINTER :: helio_pl1P - TYPE(helio_tp), POINTER :: helio_tp1P - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - dth = 0.5_DP*dt - helio_pl1P => symba_pl1P%helio - swifter_pl1P => helio_pl1P%swifter - CALL coord_vh2vb(npl, swifter_pl1P, msys) - CALL helio_lindrift(npl, swifter_pl1P, dth, ptb) - IF (ntp > 0) THEN - helio_tp1P => symba_tp1P%helio - swifter_tp1P => helio_tp1P%swifter - CALL coord_vh2vb_tp(ntp, swifter_tp1P, -ptb) - CALL helio_lindrift_tp(ntp, swifter_tp1P, dth, ptb) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xbeg(:, i) = swifter_plP%xh(:) - END DO - END IF - CALL symba_getacch(lextra_force, t, npl, nplm, nplmax, symba_pl1P, j2rp2, j4rp4, nplplenc, plplenc_list) - IF (ntp > 0) CALL symba_getacch_tp(lextra_force, t, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, xbeg, j2rp2, & - j4rp4, npltpenc, pltpenc_list) - CALL helio_kickvb(npl, helio_pl1P, dth) - IF (ntp > 0) CALL helio_kickvb_tp(ntp, helio_tp1P, dth) - irec = -1 - CALL symba_helio_drift(irec, npl, symba_pl1P, dt) - IF (ntp > 0) CALL symba_helio_drift_tp(irec, ntp, symba_tp1P, swifter_pl1P%mass, dt) - irec = 0 - CALL symba_step_recur(lclose, t, irec, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt, eoffset, nplplenc, npltpenc, & - plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) - IF (ntp > 0) THEN - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xend(:, i) = swifter_plP%xh(:) - END DO - END IF - CALL symba_getacch(lextra_force, t+dt, npl, nplm, nplmax, symba_pl1P, j2rp2, j4rp4, nplplenc, plplenc_list) - IF (ntp > 0) CALL symba_getacch_tp(lextra_force, t+dt, npl, nplm, nplmax, ntp, ntpmax, symba_pl1P, symba_tp1P, xend, j2rp2, & - j4rp4, npltpenc, pltpenc_list) - CALL helio_kickvb(npl, helio_pl1P, dth) - IF (ntp > 0) CALL helio_kickvb_tp(ntp, helio_tp1P, dth) - CALL coord_vb2vh(npl, swifter_pl1P) - CALL helio_lindrift(npl, swifter_pl1P, dth, pte) - IF (ntp > 0) THEN - CALL coord_vb2vh_tp(ntp, swifter_tp1P, -pte) - CALL helio_lindrift_tp(ntp, swifter_tp1P, dth, pte) - END IF - - RETURN - -END SUBROUTINE symba_step_interp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_step_recur.f90 b/symba/symba_step_recur.f90 deleted file mode 100644 index d5cf2fc5f..000000000 --- a/symba/symba_step_recur.f90 +++ /dev/null @@ -1,294 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_step_recur -! Unit Type : recursive subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current -! recursion level, if applicable, and descend to the next deeper level if necessary -! -! Input -! Arguments : lclose : logical flag indicating whether to check for mergers -! t : time -! ireci : input recursion level -! npl : number of planets -! nplm : number of planets with mass > mtiny -! ntp : number of active test particles -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! dt0 : time step (primary time step for overall integration) -! eoffset : energy offset (net energy lost in mergers) -! nplplenc : number of planet-planet encounters -! npltpenc : number of planet-test particle encounters -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! encounter_file : name of output file for encounters -! out_type : binary format of output file -! Terminal : none -! File : none -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! eoffset : energy offset (net energy lost in mergers) -! plplenc_list : array of planet-planet encounter structures -! pltpenc_list : array of planet-test particle encounter structures -! nmergeadd : number of merged planets to add -! nmergesub : number of merged planets to subtract -! mergeadd_list : array of structures of merged planets to add -! mergesub_list : array of structures of merged planets to subtract -! Terminal : warning message -! File : none -! -! Invocation : CALL symba_step_recur(lclose, t, ireci, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt0, eoffset, nplplenc, npltpenc, -! plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, -! encounter_file, out_type) -! -! Notes : Adapted from Hal Levison's Swift routine symba5_step_recur.F -! -!********************************************************************************************************************************** -RECURSIVE SUBROUTINE symba_step_recur(lclose, t, ireci, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt0, eoffset, nplplenc, npltpenc, & - plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) - -! Modules - USE module_parameters - USE module_swifter - USE module_helio - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_step_recur - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose - INTEGER(I4B), INTENT(IN) :: ireci, npl, nplm, ntp, nplplenc, npltpenc - INTEGER(I4B), INTENT(INOUT) :: nmergeadd, nmergesub - REAL(DP), INTENT(IN) :: t, dt0 - REAL(DP), INTENT(INOUT) :: eoffset - CHARACTER(*), INTENT(IN) :: encounter_file, out_type - TYPE(symba_pl), POINTER :: symba_pl1P - TYPE(symba_tp), POINTER :: symba_tp1P - TYPE(symba_plplenc), DIMENSION(:), INTENT(INOUT) :: plplenc_list - TYPE(symba_pltpenc), DIMENSION(:), INTENT(INOUT) :: pltpenc_list - TYPE(symba_merger), DIMENSION(:), INTENT(INOUT) :: mergeadd_list, mergesub_list - -! Internals - LOGICAL(LGT) :: lencounter - INTEGER(I4B) :: i, j, irecp, icflg - REAL(DP) :: dtl, dth, sgn - REAL(DP), DIMENSION(NDIM) :: xr, vr, vbs - TYPE(swifter_pl), POINTER :: swifter_pliP, swifter_pljP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(symba_pl), POINTER :: symba_pliP, symba_pljP - TYPE(symba_tp), POINTER :: symba_tpP - -! Executable code - dtl = dt0/(NTENC**ireci) - dth = 0.5_DP*dtl - IF (dtl/dt0 < TINY) THEN - WRITE(*, *) "SWIFTER Warning:" - WRITE(*, *) " In symba_step_recur, local time step is too small" - WRITE(*, *) " Roundoff error will be important!" - END IF - irecp = ireci + 1 - IF (ireci == 0) THEN - icflg = 0 - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,symba_pliP,symba_pljP,swifter_pliP,swifter_pljP,xr,vr,lencounter) & - !$OMP SHARED(plplenc_list,nplplenc,irecp,icflg,ireci,dtl) - DO i = 1, nplplenc - IF ((plplenc_list(i)%status == ACTIVE) .AND. (plplenc_list(i)%level == ireci)) THEN - symba_pliP => plplenc_list(i)%pl1P - symba_pljP => plplenc_list(i)%pl2P - swifter_pliP => symba_pliP%helio%swifter - swifter_pljP => symba_pljP%helio%swifter - xr(:) = swifter_pljP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_pljP%vb(:) - swifter_pliP%vb(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, swifter_pljP%rhill, dtl, irecp, lencounter, & - plplenc_list(i)%lvdotr) - IF (lencounter) THEN - !Added by D. Minton - !$OMP CRITICAL - icflg = 1 - symba_pliP%levelg = irecp - symba_pliP%levelm = MAX(irecp, symba_pliP%levelm) - symba_pljP%levelg = irecp - symba_pljP%levelm = MAX(irecp, symba_pljP%levelm) - plplenc_list(i)%level = irecp - !$OMP END CRITICAL - END IF - END IF - END DO - !$OMP END PARALLEL DO - DO i = 1, npltpenc - IF ((pltpenc_list(i)%status == ACTIVE) .AND. (pltpenc_list(i)%level == ireci)) THEN - symba_pliP => pltpenc_list(i)%plP - symba_tpP => pltpenc_list(i)%tpP - swifter_pliP => symba_pliP%helio%swifter - swifter_tpP => symba_tpP%helio%swifter - xr(:) = swifter_tpP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_tpP%vb(:) - swifter_pliP%vb(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, 0.0_DP, dtl, irecp, lencounter, pltpenc_list(i)%lvdotr) - IF (lencounter) THEN - icflg = 1 - symba_pliP%levelg = irecp - symba_pliP%levelm = MAX(irecp, symba_pliP%levelm) - symba_tpP%levelg = irecp - symba_tpP%levelm = MAX(irecp, symba_tpP%levelm) - pltpenc_list(i)%level = irecp - END IF - END IF - END DO - lencounter = (icflg == 1) - sgn = 1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - CALL symba_helio_drift(ireci, npl, symba_pl1P, dtl) - IF (ntp > 0) CALL symba_helio_drift_tp(ireci, ntp, symba_tp1P, symba_pl1P%helio%swifter%mass, dtl) - IF (lencounter) CALL symba_step_recur(lclose, t, irecp, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt0, eoffset, nplplenc, & - npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, encounter_file, out_type) - sgn = 1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - IF (lclose) THEN - vbs(:) = symba_pl1P%helio%swifter%vb(:) - DO i = 1, nplplenc - IF ((plplenc_list(i)%status == ACTIVE) .AND. & - (plplenc_list(i)%pl1P%levelg >= ireci) .AND. & - (plplenc_list(i)%pl2P%levelg >= ireci)) & - CALL symba_merge_pl(t, dtl, i, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, eoffset, vbs, encounter_file, out_type) - END DO - DO i = 1, npltpenc - IF ((pltpenc_list(i)%status == ACTIVE) .AND. & - (pltpenc_list(i)%plP%levelg >= ireci) .AND. & - (pltpenc_list(i)%tpP%levelg >= ireci)) & - CALL symba_merge_tp(t, dtl, i, npltpenc, pltpenc_list, vbs, encounter_file, out_type) - END DO - END IF - DO i = 1, nplplenc - IF (plplenc_list(i)%pl1P%levelg == irecp) plplenc_list(i)%pl1P%levelg = ireci - IF (plplenc_list(i)%pl2P%levelg == irecp) plplenc_list(i)%pl2P%levelg = ireci - IF (plplenc_list(i)%level == irecp) plplenc_list(i)%level = ireci - END DO - DO i = 1, npltpenc - IF (pltpenc_list(i)%plP%levelg == irecp) pltpenc_list(i)%plP%levelg = ireci - IF (pltpenc_list(i)%tpP%levelg == irecp) pltpenc_list(i)%tpP%levelg = ireci - IF (pltpenc_list(i)%level == irecp) pltpenc_list(i)%level = ireci - END DO - ELSE - DO j = 1, NTENC - icflg = 0 - ! OpenMP parallelization added by D. Minton - !$OMP PARALLEL DO SCHEDULE (STATIC) DEFAULT(NONE) & - !$OMP PRIVATE(i,symba_pliP,symba_pljP,swifter_pliP,swifter_pljP,xr,vr,lencounter) & - !$OMP SHARED(plplenc_list,nplplenc,irecp,icflg,ireci,dtl) - DO i = 1, nplplenc - IF ((plplenc_list(i)%status == ACTIVE) .AND. (plplenc_list(i)%level == ireci)) THEN - symba_pliP => plplenc_list(i)%pl1P - symba_pljP => plplenc_list(i)%pl2P - swifter_pliP => symba_pliP%helio%swifter - swifter_pljP => symba_pljP%helio%swifter - xr(:) = swifter_pljP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_pljP%vb(:) - swifter_pliP%vb(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, swifter_pljP%rhill, dtl, irecp, lencounter, & - plplenc_list(i)%lvdotr) - IF (lencounter) THEN - !$OMP CRITICAL - icflg = 1 - symba_pliP%levelg = irecp - symba_pliP%levelm = MAX(irecp, symba_pliP%levelm) - symba_pljP%levelg = irecp - symba_pljP%levelm = MAX(irecp, symba_pljP%levelm) - plplenc_list(i)%level = irecp - !$OMP END CRITICAL - END IF - END IF - END DO - DO i = 1, npltpenc - IF ((pltpenc_list(i)%status == ACTIVE) .AND. (pltpenc_list(i)%level == ireci)) THEN - symba_pliP => pltpenc_list(i)%plP - symba_tpP => pltpenc_list(i)%tpP - swifter_pliP => symba_pliP%helio%swifter - swifter_tpP => symba_tpP%helio%swifter - xr(:) = swifter_tpP%xh(:) - swifter_pliP%xh(:) - vr(:) = swifter_tpP%vb(:) - swifter_pliP%vb(:) - CALL symba_chk(xr(:), vr(:), swifter_pliP%rhill, 0.0_DP, dtl, irecp, lencounter, pltpenc_list(i)%lvdotr) - IF (lencounter) THEN - icflg = 1 - symba_pliP%levelg = irecp - symba_pliP%levelm = MAX(irecp, symba_pliP%levelm) - symba_tpP%levelg = irecp - symba_tpP%levelm = MAX(irecp, symba_tpP%levelm) - pltpenc_list(i)%level = irecp - END IF - END IF - END DO - lencounter = (icflg == 1) - sgn = 1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - sgn = -1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - CALL symba_helio_drift(ireci, npl, symba_pl1P, dtl) - IF (ntp > 0) CALL symba_helio_drift_tp(ireci, ntp, symba_tp1P, symba_pl1P%helio%swifter%mass, dtl) - IF (lencounter) CALL symba_step_recur(lclose, t, irecp, npl, nplm, ntp, symba_pl1P, symba_tp1P, dt0, eoffset, & - nplplenc, npltpenc, plplenc_list, pltpenc_list, nmergeadd, nmergesub, mergeadd_list, mergesub_list, & - encounter_file, out_type) - sgn = 1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - sgn = -1.0_DP - CALL symba_kick(irecp, nplplenc, npltpenc, plplenc_list, pltpenc_list, dth, sgn) - IF (lclose) THEN - vbs(:) = symba_pl1P%helio%swifter%vb(:) - DO i = 1, nplplenc - IF ((plplenc_list(i)%status == ACTIVE) .AND. & - (plplenc_list(i)%pl1P%levelg >= ireci) .AND. & - (plplenc_list(i)%pl2P%levelg >= ireci)) & - CALL symba_merge_pl(t, dtl, i, nplplenc, plplenc_list, nmergeadd, nmergesub, mergeadd_list, & - mergesub_list, eoffset, vbs, encounter_file, out_type) - END DO - DO i = 1, npltpenc - IF ((pltpenc_list(i)%status == ACTIVE) .AND. & - (pltpenc_list(i)%plP%levelg >= ireci) .AND. & - (pltpenc_list(i)%tpP%levelg >= ireci)) & - CALL symba_merge_tp(t, dtl, i, npltpenc, pltpenc_list, vbs, encounter_file, out_type) - END DO - END IF - DO i = 1, nplplenc - IF (plplenc_list(i)%pl1P%levelg == irecp) plplenc_list(i)%pl1P%levelg = ireci - IF (plplenc_list(i)%pl2P%levelg == irecp) plplenc_list(i)%pl2P%levelg = ireci - IF (plplenc_list(i)%level == irecp) plplenc_list(i)%level = ireci - END DO - DO i = 1, npltpenc - IF (pltpenc_list(i)%plP%levelg == irecp) pltpenc_list(i)%plP%levelg = ireci - IF (pltpenc_list(i)%tpP%levelg == irecp) pltpenc_list(i)%tpP%levelg = ireci - IF (pltpenc_list(i)%level == irecp) pltpenc_list(i)%level = ireci - END DO - END DO - END IF - - RETURN - -END SUBROUTINE symba_step_recur -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_user_getacch.f90 b/symba/symba_user_getacch.f90 deleted file mode 100644 index a2609c47b..000000000 --- a/symba/symba_user_getacch.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_user_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : symba_pl1P : pointer to head of SyMBA planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL symba_user_getacch(t, npl, symba_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_user_getacch(t, npl, symba_pl1P) - -! Modules - USE module_parameters - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_user_getacch - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(symba_pl), POINTER :: symba_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE symba_user_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/symba/symba_user_getacch_tp.f90 b/symba/symba_user_getacch_tp.f90 deleted file mode 100644 index 35ae05fc2..000000000 --- a/symba/symba_user_getacch_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : symba_user_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : symba -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : symba_tp1P : pointer to head of active SyMBA test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL symba_user_getacch_tp(t, ntp, symba_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE symba_user_getacch_tp(t, ntp, symba_tp1P) - -! Modules - USE module_parameters - USE module_symba - USE module_interfaces, EXCEPT_THIS_ONE => symba_user_getacch_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(symba_tp), POINTER :: symba_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE symba_user_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tool/tool_encounter_read.f90 b/tool/tool_encounter_read.f90 deleted file mode 100644 index b090a95c4..000000000 --- a/tool/tool_encounter_read.f90 +++ /dev/null @@ -1,110 +0,0 @@ -!****************************************************************************** -! -! Unit Name : -! Unit Type : -! Project : SWIFTER -! Package : -! Language : Fortran 90/95 -! -! Description : -! -! Input -! Arguments : -! Terminal : -! File : -! -! Output -! Arguments : -! Terminal : -! File : -! -! Invocation : -! -! Notes : -! -!****************************************************************************** -PROGRAM tool_encounter_read - -! Modules - USE module_parameters - USE module_interfaces - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - -! Internals - INTEGER(I4B) :: i,ierr,id1,id2 - REAL(DP) :: t,mass1,mass2 - REAL(DP), DIMENSION(NDIM) :: xh1,xh2,vh1,vh2 - CHARACTER(STRMAX) :: inparfile - -! Executable code - WRITE(*,100,ADVANCE="NO")"Enter name of parameter data file: " - READ(*,100)inparfile - 100 FORMAT(A) - inparfile=TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile,nplmax,ntpmax,t0,tstop,dt,inplfile,intpfile,in_type,istep_out,outfile,out_type,out_form, & - out_stat,istep_dump,j2rp2,j4rp4,lclose,rmin,rmax,rmaxu,qmin,qmin_coord,qmin_alo,qmin_ahi,encounter_file,lextra_force, & - lbig_discard,lrhill_present) - ierr=0 - i=0 - DO - ierr=io_read_encounter(t,id1,id2,mass1,mass2,xh1,xh2,vh1,vh2,encounter_file,out_type) - IF (ierr /= 0) EXIT - i=i+1 - WRITE(*,*)"Encounter #",i - WRITE(*,*)"Time = ",t - WRITE(*,*)" Body1: ",id1,mass1,xh1,vh1 - WRITE(*,*)" Body2: ",id2,mass2,xh2,vh2 - END DO - CALL util_exit(SUCCESS) - - STOP - -END PROGRAM tool_encounter_read -!****************************************************************************** -! -! Author(s) : -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!****************************************************************************** diff --git a/tool/tool_follow.f90 b/tool/tool_follow.f90 deleted file mode 100644 index d6b328e7b..000000000 --- a/tool/tool_follow.f90 +++ /dev/null @@ -1,243 +0,0 @@ -!****************************************************************************** -! -! Unit Name : -! Unit Type : -! Project : SWIFTER -! Package : -! Language : Fortran 90/95 -! -! Description : -! -! Input -! Arguments : -! Terminal : -! File : -! -! Output -! Arguments : -! Terminal : -! File : -! -! Invocation : -! -! Notes : -! -!****************************************************************************** -PROGRAM tool_follow - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - -! Internals - LOGICAL(LGT) :: lxdr - INTEGER(I4B) :: npl,ntp,ntp0,nsp,iout,idump,iloop,i,iu,ifol,nskp,ierr,iout_form,ic,istep,id - REAL(DP) :: t,tfrac,tbase,tmax - CHARACTER(STRMAX) :: inparfile - REAL(DP) :: gmsum,msun,a,e,inc,capom,omega,capm,mass,peri,apo,radius - REAL(DP) :: xh,yh,zh,vxh,vyh,vzh - LOGICAL(LGT) :: lfirst - TYPE(whm_pl), DIMENSION(:), ALLOCATABLE, TARGET :: whm_plA - TYPE(whm_tp), DIMENSION(:), ALLOCATABLE, TARGET :: whm_tpA - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P,whm_tpd1P - TYPE(swifter_pl), POINTER :: swifter_pl1P,swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P,swifter_tpd1P,swifter_tpP - -! Executable code - CALL util_version - WRITE(*,100,ADVANCE="NO")"Enter name of parameter data file: " - READ (*,100)inparfile - 100 FORMAT(A) - inparfile=TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile,nplmax,ntpmax,t0,tstop,dt,inplfile,intpfile,in_type,istep_out,outfile,out_type,out_form, & - out_stat,istep_dump,j2rp2,j4rp4,lclose,rmin,rmax,rmaxu,qmin,qmin_coord,qmin_alo,qmin_ahi,encounter_file,lextra_force, & - lbig_discard,lrhill_present) - CALL io_getn(inplfile,intpfile,in_type,npl,nplmax,ntp,ntpmax) - ALLOCATE(whm_plA(nplmax)) - CALL set_point(whm_plA) - IF (ntp > 0) THEN - ALLOCATE(whm_tpA(ntpmax)) - CALL set_point(whm_tpA) - END IF - CALL whm_setup(npl,ntp,whm_plA,whm_tpA,whm_pl1P,whm_tp1P,swifter_pl1P,swifter_tp1P) - CALL io_init_pl(inplfile,in_type,lclose,lrhill_present,npl,swifter_pl1P) - CALL io_init_tp(intpfile,in_type,ntp,swifter_tp1P) - CALL util_valid(npl,ntp,swifter_pl1P,swifter_tp1P) - lxdr=((out_type == XDR4_TYPE) .OR. (out_type == XDR8_TYPE)) - iu=20 - WRITE(*,100,ADVANCE="NO")"Enter the id of the particle to follow: " - READ(*,*)ifol - WRITE(*,*)"Following particle ",ifol - WRITE(*,100,ADVANCE="NO")"Enter the frequency: " - READ(*,*)nskp - IF (lxdr) THEN - CALL io_open_fxdr(outfile,"R",.TRUE.,iu,ierr) - ELSE - CALL io_open(iu,outfile,"OLD","UNFORMATTED",ierr) - END IF - IF (ierr /= 0) THEN - WRITE(*,*)"SWIFTER Error:" - WRITE(*,*)" Unable to open output binary file" - CALL util_exit(FAILURE) - END IF - SELECT CASE (out_form) - CASE ("EL") - iout_form=EL - CASE ("XV") - iout_form=XV - CASE ("FILT") - iout_form=FILT - END SELECT - OPEN(UNIT=7,FILE="follow.out") - - tmax=t0 - ic=0 - DO - ierr=io_read_hdr(iu,t,npl,ntp,iout_form,out_type) - IF (ierr /= 0) EXIT - istep=0 - SELECT CASE (iout_form) - CASE (EL) - DO i=2,npl - ierr=io_read_line(iu,id,a,e,inc,capom,omega,capm,out_type,MASS=mass,RADIUS=radius) - IF (ierr /= 0) THEN - WRITE(*,*)"SWIFTER Error:" - WRITE(*,*)" Stop while reading planets ierr = ",ierr - CALL util_exit(FAILURE) - END IF - IF (id == ifol) THEN - istep=1 - ic=ic+1 - IF (MOD(ic,nskp) == 0) THEN - inc=inc*DEGRAD - capom=capom*DEGRAD - omega=omega*DEGRAD - capm=capm*DEGRAD - peri=a*(1.0_DP-e) - apo=a*(1.0_DP+e) - WRITE(7,1000)t,ifol,a,e,inc,capom,omega,capm,peri,apo - 1000 FORMAT(1x,e15.7,1x,i3,1x,f10.4,1x,f7.5,4(1x,f9.4),2(1x,f10.4)) - END IF - tmax=t - END IF - END DO - DO i=1,ntp - ierr=io_read_line(iu,id,a,e,inc,capom,omega,capm,out_type) - IF (ierr /= 0) THEN - WRITE(*,*)"SWIFTER Error:" - WRITE(*,*)" Stop while reading test particles ierr = ",ierr - CALL util_exit(FAILURE) - END IF - IF (id == ifol) THEN - istep=1 - ic=ic+1 - IF (MOD(ic,nskp) == 0) THEN - inc=inc*DEGRAD - capom=capom*DEGRAD - omega=omega*DEGRAD - capm=capm*DEGRAD - peri=a*(1.0_DP-e) - apo=a*(1.0_DP+e) - WRITE(7,1000)t,ifol,a,e,inc,capom,omega,capm,peri,apo - END IF - tmax=t - END IF - END DO - CASE (XV) - DO i=2,npl - ierr=io_read_line(iu,id,xh,yh,zh,vxh,vyh,vzh,out_type,MASS=mass,RADIUS=radius) - IF (ierr /= 0) THEN - WRITE(*,*)"SWIFTER Error:" - WRITE(*,*)" Stop while reading planets ierr = ",ierr - CALL util_exit(FAILURE) - END IF - IF (id == ifol) THEN - istep=1 - ic=ic+1 - IF (MOD(ic,nskp) == 0) THEN - WRITE(7,1001)t,ifol,xh,yh,zh,vxh,vyh,vzh - 1001 FORMAT(1x,e15.7,1x,i3,6(1x,es15.7)) - END IF - tmax=t - END IF - END DO - DO i=1,ntp - ierr=io_read_line(iu,id,xh,yh,zh,vxh,vyh,vzh,out_type) - IF (ierr /= 0) THEN - WRITE(*,*)"SWIFTER Error:" - WRITE(*,*)" Stop while reading test particles ierr = ",ierr - CALL util_exit(FAILURE) - END IF - IF (id == ifol) THEN - istep=1 - ic=ic+1 - IF (MOD(ic,nskp) == 0) THEN - WRITE(7,1001)t,ifol,xh,yh,zh,vxh,vyh,vzh - END IF - tmax=t - END IF - END DO - CASE (FILT) - ! DEK - to be implemented - END SELECT - IF (istep == 0) EXIT - END DO - - WRITE(*,*)"Tmax = ",tmax - - STOP - -END PROGRAM tool_follow -!****************************************************************************** -! -! Author(s) : -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!****************************************************************************** diff --git a/tool/tool_left.f90 b/tool/tool_left.f90 deleted file mode 100644 index f703fc981..000000000 --- a/tool/tool_left.f90 +++ /dev/null @@ -1,177 +0,0 @@ -!****************************************************************************** -! -! Unit Name : -! Unit Type : -! Project : SWIFTER -! Package : -! Language : Fortran 90/95 -! -! Description : -! -! Input -! Arguments : -! Terminal : -! File : -! -! Output -! Arguments : -! Terminal : -! File : -! -! Invocation : -! -! Notes : -! -!****************************************************************************** -PROGRAM left - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_random_access - USE module_interfaces - IMPLICIT NONE - -! Arguments - INTEGER(I4B) :: nplmax ! Maximum number of planets - INTEGER(I4B) :: ntpmax ! Maximum number of test particles - INTEGER(I4B) :: istep_out ! Time steps between binary outputs - INTEGER(I4B) :: istep_dump ! Time steps between dumps - REAL(DP) :: t0 ! Integration start time - REAL(DP) :: tstop ! Integration stop time - REAL(DP) :: dt ! Time step - REAL(DP) :: j2rp2 ! J2*R^2 term for central body - REAL(DP) :: j4rp4 ! J4*R^4 term for central body - REAL(DP) :: rmin ! Minimum heliocentric radius for test particle - REAL(DP) :: rmax ! Maximum heliocentric radius for test particle - REAL(DP) :: rmaxu ! Maximum unbound heliocentric radius for test particle - REAL(DP) :: qmin ! Minimum pericenter distance for test particle - REAL(DP) :: qmin_alo ! Minimum semimajor axis for qmin - REAL(DP) :: qmin_ahi ! Maximum semimajor axis for qmin - CHARACTER(STRMAX) :: qmin_coord ! Coordinate frame to use for qmin - CHARACTER(STRMAX) :: encounter_file ! Name of output file for encounters - CHARACTER(STRMAX) :: inplfile ! Name of input file for planets - CHARACTER(STRMAX) :: intpfile ! Name of input file for test particles - CHARACTER(STRMAX) :: in_type ! Format of input data files - CHARACTER(STRMAX) :: outfile ! Name of output binary file - CHARACTER(STRMAX) :: out_type ! Binary format of output file - CHARACTER(STRMAX) :: out_form ! Data to write to output file - CHARACTER(STRMAX) :: out_stat ! Open status for output binary file - LOGICAL(LGT) :: lclose ! Check for planet-test particle encounters - LOGICAL(LGT) :: lextra_force ! Use user-supplied force routines - LOGICAL(LGT) :: lbig_discard ! Dump planet data with discards - LOGICAL(LGT) :: lrhill_present ! Hill's sphere radius present - -! Internals - INTEGER(I4B) :: npl,ntp,ntp0,nsp,iout,idump,iloop,i - REAL(DP) :: t,tfrac,tbase - CHARACTER(STRMAX) :: inparfile - REAL(DP) :: gmsum,msun,a,e,inc,capom,omega,capm,peri,apo - LOGICAL(LGT) :: lfirst - TYPE(whm_pl), DIMENSION(:), ALLOCATABLE, TARGET :: whm_plA - TYPE(whm_tp), DIMENSION(:), ALLOCATABLE, TARGET :: whm_tpA - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P,whm_tpd1P - TYPE(swifter_pl), POINTER :: swifter_pl1P,swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P,swifter_tpd1P,swifter_tpP - -! Executable code - CALL util_version - WRITE(*,100,ADVANCE="NO")"Enter name of parameter dump file: " - READ (*,100)inparfile - 100 FORMAT(A) - inparfile=TRIM(ADJUSTL(inparfile)) - CALL io_init_param(inparfile,nplmax,ntpmax,t0,tstop,dt,inplfile,intpfile,in_type,istep_out,outfile,out_type,out_form, & - out_stat,istep_dump,j2rp2,j4rp4,lclose,rmin,rmax,rmaxu,qmin,qmin_coord,qmin_alo,qmin_ahi,encounter_file,lextra_force, & - lbig_discard,lrhill_present) - CALL io_getn(inplfile,intpfile,in_type,npl,nplmax,ntp,ntpmax) - ALLOCATE(whm_plA(nplmax)) - CALL set_point(whm_plA) - IF (ntp > 0) THEN - ALLOCATE(whm_tpA(ntpmax)) - CALL set_point(whm_tpA) - END IF - CALL whm_setup(npl,ntp,whm_plA,whm_tpA,whm_pl1P,whm_tp1P,swifter_pl1P,swifter_tp1P) - CALL io_init_pl(inplfile,in_type,lclose,lrhill_present,npl,swifter_pl1P) - CALL io_init_tp(intpfile,in_type,ntp,swifter_tp1P) - CALL util_valid(npl,ntp,swifter_pl1P,swifter_tp1P) - - tfrac = t0/tstop - - OPEN(7,FILE="left_pl.out") - WRITE(7,*)' ' - IF (t0 < 10000.0_DP) THEN - WRITE(*,*) 'Time = ', t0 - WRITE(7,*) 'Time = ', t0 - ELSE - WRITE(*,10) t0 - WRITE(7,10) t0 - END IF - 10 FORMAT(' Time = ', ES13.5) - WRITE(*,*) 'Fraction done = ', tfrac - WRITE(7,*) 'Fraction done = ', tfrac - - WRITE(7,*)' ' - WRITE(7,*)'Number of planets (including the Sun): ',npl - WRITE(7,*)' ' - WRITE(7,*)'Planet:' - WRITE(7,*)' id mass a e i' - msun=swifter_pl1P%mass - swifter_plP=>swifter_pl1P - DO i=2,npl - swifter_plP=>swifter_plP%nextP - gmsum=swifter_plP%mass+msun - CALL orbel_xv2el(swifter_plP%xh(:),swifter_plP%vh(:),gmsum,a,e,inc,capom,omega,capm) - WRITE(7,101)swifter_plP%id,swifter_plP%mass,a,e,inc*DEGRAD - 101 FORMAT(5x,i4,1x,1p1e13.5,3(5x,0p1f10.4)) - END DO - CLOSE(7) - - OPEN(7,FILE="left_tp.out") - WRITE(7,*)' ' - IF (t0 < 10000.0_DP) THEN - WRITE(7,*) 'Time = ', t0 - ELSE - WRITE(7,10) t0 - END IF - WRITE(7,*)'Fraction done = ', tfrac - - WRITE(7,*)' ' - WRITE(*,*)'Number of active test particles: ',ntp - WRITE(7,*)'Number of active test particles: ',ntp - WRITE(7,*)' ' - WRITE(7,*)'Test particle:' - WRITE(7,*)' id a q Q i' - swifter_tpP=>swifter_tp1P - DO i=1,ntp - CALL orbel_xv2el(swifter_tpP%xh(:),swifter_tpP%vh(:),msun,a,e,inc,capom,omega,capm) - apo = a*(1.0_DP + e) - peri = a*(1.0_DP - e) - WRITE(7,102)swifter_tpP%id,a,peri,apo,inc*DEGRAD - 102 FORMAT(5x,i4,4(5x,f10.4)) - swifter_tpP=>swifter_tpP%nextP - ENDDO - CLOSE(7) - - STOP - -END PROGRAM left -!****************************************************************************** -! -! Author(s) : -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!****************************************************************************** diff --git a/tp_maker.py b/tp_maker.py new file mode 100644 index 000000000..900283375 --- /dev/null +++ b/tp_maker.py @@ -0,0 +1,59 @@ +import rebound +import numpy as np + +sim = rebound.Simulation() +sim.units = ('AU', 'yr', 'Msun') +sim.add(m=1.) +sim.move_to_com() +ps = sim.particles + +#!!!!!!! CHANGE THESE THINGS !!!!!!!!!!!!! + +sim.convert_particle_units('AU', 'd', 'Msun') + +N_tp = 3000 +N_ps = 2001 + +#TP_OUTFILE_SWIFT = open('Feb25_tp_2_swift.txt', 'w') +TP_OUTFILE_SWIFTER = open('tp.in', 'w') + +np.random.seed(2) + +#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +def uniform(minimum, maximum): + return np.random.uniform()*(maximum-minimum)+minimum + +while sim.N < (1+N_tp): + a_tp = uniform(1.7,2.0) + e_tp = uniform(0.0, 0.3) + inc_tp = uniform(0.0, 0.3) + O_tp = uniform(0,2*np.pi) + o_tp = uniform(0,2*np.pi) + M_tp = uniform(-np.pi, np.pi) + tp = rebound.Particle(simulation=sim,primary=sim.particles[0],m=0.0, r=0.0, a=a_tp, e=e_tp, inc=inc_tp, Omega=O_tp, omega=o_tp, M=M_tp) + sim.add(tp) + +x_tp = [ps[i].x for i in range(0, sim.N)] +y_tp = [ps[i].y for i in range(0, sim.N)] +z_tp = [ps[i].z for i in range(0, sim.N)] +vx_tp = [ps[i].vx for i in range(0, sim.N)] +vy_tp = [ps[i].vy for i in range(0, sim.N)] +vz_tp = [ps[i].vz for i in range(0, sim.N)] + +#with TP_OUTFILE_SWIFT as output: +# output.write("%s \n" %(N_tp)) #number of particles in the system +# for i in range (1, sim.N): +# output.write("%s %s %s \n" % ("{:10.8e}".format(x_tp[i]), "{:10.8e}".format(y_tp[i]), "{:10.8e}".format(z_tp[i]))) #x y z +# output.write("%s %s %s \n" % ("{:10.8e}".format(vx_tp[i]), "{:10.8e}".format(vy_tp[i]), "{:10.8e}".format(vz_tp[i]))) #vx vy vz +# output.write("0 0 0 0 0 0 0 0 0 0 0 0 0\n") #flags +# output.write("0.0d0 0.0d0 0.0d0 0.0d0 0.0d0\n") #flags +# output.write("0.0d0 0.0d0 0.0d0 0.0d0 0.0d0\n") #flags +# output.write("0.0d0 0.0d0 0.0d0\n") #flags + +with TP_OUTFILE_SWIFTER as output: + output.write("%s \n" %(N_tp)) #number of particles in the system + for i in range (1, sim.N): + output.write("%s \n" % ((i+N_ps) )) #ID + output.write("%s %s %s \n" % ("{:10.8e}".format(x_tp[i]), "{:10.8e}".format(y_tp[i]), "{:10.8e}".format(z_tp[i]))) #x y z + output.write("%s %s %s \n" % ("{:10.8e}".format(vx_tp[i]), "{:10.8e}".format(vy_tp[i]), "{:10.8e}".format(vz_tp[i]))) #vx vy vz \ No newline at end of file diff --git a/tu4/tu4_discard.f90 b/tu4/tu4_discard.f90 deleted file mode 100644 index 29d4f7b95..000000000 --- a/tu4/tu4_discard.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_discard -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! tu4_tpd1P : pointer to head of discard TU4 test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! tu4_tpd1P : pointer to head of discard TU4 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_discard(t, npl, ntp, nsp, tu4_pl1P, tu4_tp1P, tu4_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE tu4_discard(t, npl, ntp, nsp, tu4_pl1P, tu4_tp1P, tu4_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P, tu4_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(tu4_tp), POINTER :: tu4_tpP, tu4_tpspP - -! Executable code - swifter_pl1P => tu4_pl1P%swifter - swifter_tp1P => tu4_tp1P%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - tu4_tpP => tu4_tp1P - DO i = 1, ntp - tu4_tpspP => tu4_tpP - tu4_tpP => tu4_tpP%nextP - swifter_tpspP => tu4_tpspP%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL tu4_discard_spill(ntp, nsp, tu4_tp1P, tu4_tpd1P, tu4_tpspP) - END DO - - RETURN - -END SUBROUTINE tu4_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_discard_spill.f90 b/tu4/tu4_discard_spill.f90 deleted file mode 100644 index 4dd718a79..000000000 --- a/tu4/tu4_discard_spill.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) TU4 test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! tu4_tpd1P : pointer to head of discard TU4 test particle structure linked-list -! tu4_tpspP : pointer to TU4 test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! tu4_tpd1P : pointer to head of discard TU4 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_discard_spill(ntp, nsp, tu4_tp1P, tu4_tpd1P, tu4_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE tu4_discard_spill(ntp, nsp, tu4_tp1P, tu4_tpd1P, tu4_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(tu4_tp), POINTER :: tu4_tp1P, tu4_tpd1P, tu4_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(tu4_tp), POINTER :: tu4_tpP - -! Executable code - swifter_tpspP => tu4_tpspP%swifter - IF (nsp == 0) THEN - tu4_tpd1P => tu4_tpspP - ELSE - tu4_tpP => tu4_tpd1P - DO i = 1, nsp - 1 - tu4_tpP => tu4_tpP%nextP - END DO - tu4_tpP%nextP => tu4_tpspP - tu4_tpP%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(tu4_tpspP%prevP)) THEN - tu4_tpspP%prevP%nextP => tu4_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - tu4_tp1P => tu4_tpspP%nextP - END IF - IF (ASSOCIATED(tu4_tpspP%nextP)) THEN - tu4_tpspP%nextP%prevP => tu4_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(tu4_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - tu4_tpspP%prevP => tu4_tpP - swifter_tpspP%prevP => tu4_tpP%swifter - END IF - NULLIFY(tu4_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE tu4_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_getaccb.f90 b/tu4/tu4_getaccb.f90 deleted file mode 100644 index 5696c08e6..000000000 --- a/tu4/tu4_getaccb.f90 +++ /dev/null @@ -1,127 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of planets -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : tu4_pl1P : pointer to head of TU4 planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_getaccb(lextra_force, t, npl, nplmax, tu4_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb.f -! -!********************************************************************************************************************************** -SUBROUTINE tu4_getaccb(lextra_force, t, npl, nplmax, tu4_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_getaccb - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(tu4_pl), POINTER :: tu4_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: mu, massi, massj, r2, ir3 - REAL(DP), DIMENSION(NDIM) :: dx, acc - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_pliP, swifter_pljP - TYPE(tu4_pl), POINTER :: tu4_pliP, tu4_pljP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => tu4_pl1P%swifter - mu = swifter_pl1P%mass - tu4_pl1P%ab(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - tu4_pliP => tu4_pl1P - DO i = 2, npl - tu4_pliP => tu4_pliP%nextP - swifter_pliP => tu4_pliP%swifter - massi = swifter_pliP%mass - dx(:) = swifter_pl1P%xb(:) - swifter_pliP%xb(:) - xh(:, i) = -dx(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - irh(i) = 1.0_DP/SQRT(r2) - ir3 = irh(i)/r2 - acc(:) = ir3*dx(:) - tu4_pl1P%ab(:) = tu4_pl1P%ab(:) - massi*acc(:) - tu4_pliP%ab(:) = mu*acc(:) - END DO - tu4_pliP => tu4_pl1P - DO i = 2, npl - 1 - tu4_pliP => tu4_pliP%nextP - swifter_pliP => tu4_pliP%swifter - massi = swifter_pliP%mass - tu4_pljP => tu4_pliP - DO j = i + 1, npl - tu4_pljP => tu4_pljP%nextP - swifter_pljP => tu4_pljP%swifter - massj = swifter_pljP%mass - dx(:) = swifter_pliP%xb(:) - swifter_pljP%xb(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - ir3 = 1.0_DP/(r2*SQRT(r2)) - acc(:) = ir3*dx(:) - tu4_pliP%ab(:) = tu4_pliP%ab(:) - massj*acc(:) - tu4_pljP%ab(:) = tu4_pljP%ab(:) + massi*acc(:) - END DO - END DO - IF (j2rp2 /= 0.0_DP) THEN - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - tu4_pliP => tu4_pl1P - DO i = 1, npl - tu4_pliP%ab(:) = tu4_pliP%ab(:) + aobl(:, i) - tu4_pliP => tu4_pliP%nextP - END DO - END IF - IF (lextra_force) CALL tu4_user_getaccb(t, npl, tu4_pl1P) - - RETURN - -END SUBROUTINE tu4_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_getaccb_tp.f90 b/tu4/tu4_getaccb_tp.f90 deleted file mode 100644 index 12d993dac..000000000 --- a/tu4/tu4_getaccb_tp.f90 +++ /dev/null @@ -1,118 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Compute barycentric accelerations of test particles -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_getaccb_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE tu4_getaccb_tp(lextra_force, t, npl, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_getaccb_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i, j - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(NDIM) :: dx, x1tmp, x2tmp, acc - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(tu4_tp), POINTER :: tu4_tpP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => tu4_pl1P%swifter - x1tmp(:) = swifter_pl1P%xb(:) - tu4_tpP => tu4_tp1P - DO i = 1, ntp - swifter_tpP => tu4_tpP%swifter - acc(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - xht(:, i) = swifter_tpP%xb(:) - x1tmp(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - x2tmp(:) = swifter_tpP%xb(:) - swifter_plP => swifter_pl1P - DO j = 1, npl - dx(:) = x2tmp(:) - swifter_plP%xb(:) - r2 = DOT_PRODUCT(dx(:), dx(:)) - fac = swifter_plP%mass/(r2*SQRT(r2)) - acc(:) = acc(:) - fac*dx(:) - swifter_plP => swifter_plP%nextP - END DO - tu4_tpP%ab(:) = acc(:) - tu4_tpP => tu4_tpP%nextP - END DO - IF (j2rp2 /= 0.0_DP) THEN - mu = swifter_pl1P%mass - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - tu4_tpP => tu4_tp1P - DO i = 1, ntp - tu4_tpP%ab(:) = tu4_tpP%ab(:) + aoblt(:, i) - tu4_tpP => tu4_tpP%nextP - END DO - END IF - IF (lextra_force) CALL tu4_user_getaccb_tp(t, ntp, tu4_tp1P) - - RETURN - -END SUBROUTINE tu4_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_kickvb.f90 b/tu4/tu4_kickvb.f90 deleted file mode 100644 index 2545f173b..000000000 --- a/tu4/tu4_kickvb.f90 +++ /dev/null @@ -1,87 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_kickvb -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Kick barycentric velocities of planets and test particles -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_kickvb(npl, ntp, tu4_pl1P, tu4_tp1P, dt) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_vkickb.f -! -!********************************************************************************************************************************** -SUBROUTINE tu4_kickvb(npl, ntp, tu4_pl1P, tu4_tp1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_kickvb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(tu4_pl), POINTER :: tu4_plP - TYPE(tu4_tp), POINTER :: tu4_tpP - -! Executable code - tu4_plP => tu4_pl1P - DO i = 1, npl - swifter_plP => tu4_plP%swifter - swifter_plP%vb(:) = swifter_plP%vb(:) + tu4_plP%ab(:)*dt - tu4_plP => tu4_plP%nextP - END DO - tu4_tpP => tu4_tp1P - DO i = 1, ntp - swifter_tpP => tu4_tpP%swifter - swifter_tpP%vb(:) = swifter_tpP%vb(:) + tu4_tpP%ab(:)*dt - tu4_tpP => tu4_tpP%nextP - END DO - - RETURN - -END SUBROUTINE tu4_kickvb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_ldrift.f90 b/tu4/tu4_ldrift.f90 deleted file mode 100644 index 8fa51e66b..000000000 --- a/tu4/tu4_ldrift.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_ldrift -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Perform linear drift in barycentric coordinates for planets and test particles -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_ldrift(npl, ntp, swifter_pl1P, swifter_tp1P, dt) -! -! Notes : Adapted from Martin Duncan's Swift routine tu4_ldrift.f -! -!********************************************************************************************************************************** -SUBROUTINE tu4_ldrift(npl, ntp, swifter_pl1P, swifter_tp1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => tu4_ldrift - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), INTENT(IN) :: dt - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_plP => swifter_pl1P - DO i = 1, npl - swifter_plP%xb(:) = swifter_plP%xb(:) + swifter_plP%vb(:)*dt - swifter_plP => swifter_plP%nextP - END DO - swifter_tpP => swifter_tp1P - DO i = 1, ntp - swifter_tpP%xb(:) = swifter_tpP%xb(:) + swifter_tpP%vb(:)*dt - swifter_tpP => swifter_tpP%nextP - END DO - - RETURN - -END SUBROUTINE tu4_ldrift -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_setup.f90 b/tu4/tu4_setup.f90 deleted file mode 100644 index 08de76b7e..000000000 --- a/tu4/tu4_setup.f90 +++ /dev/null @@ -1,133 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_setup -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Set up pointers within TU4 and SWIFTER planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! tu4_plA : TU4 planet structure array -! tu4_tpA : TU4 test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : tu4_plA : TU4 planet structure array -! tu4_tpA : TU4 test particle structure array -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_setup(npl, ntp, tu4_plA, tu4_tpA, tu4_pl1P, tu4_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE tu4_setup(npl, ntp, tu4_plA, tu4_tpA, tu4_pl1P, tu4_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(tu4_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: tu4_plA - TYPE(tu4_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: tu4_tpA - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(tu4_pl), POINTER :: tu4_plP - TYPE(tu4_tp), POINTER :: tu4_tpP - -! Executable code - tu4_pl1P => tu4_plA(1) - swifter_pl1P => tu4_plA(1)%swifter - NULLIFY(tu4_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(tu4_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - tu4_pl1P%nextP => tu4_plA(2) - swifter_pl1P%nextP => tu4_plA(2)%swifter - DO i = 2, npl - 1 - tu4_plA(i)%prevP => tu4_plA(i-1) - tu4_plA(i)%nextP => tu4_plA(i+1) - swifter_plP => tu4_plA(i)%swifter - swifter_plP%prevP => tu4_plA(i-1)%swifter - swifter_plP%nextP => tu4_plA(i+1)%swifter - END DO - tu4_plA(npl)%prevP => tu4_plA(npl-1) - tu4_plP => tu4_plA(npl) - NULLIFY(tu4_plP%nextP) - swifter_plP => tu4_plA(npl)%swifter - swifter_plP%prevP => tu4_plA(npl-1)%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(tu4_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - tu4_tp1P => tu4_tpA(1) - swifter_tp1P => tu4_tpA(1)%swifter - NULLIFY(tu4_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(tu4_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - tu4_tp1P%nextP => tu4_tpA(2) - swifter_tp1P%nextP => tu4_tpA(2)%swifter - DO i = 2, ntp - 1 - tu4_tpA(i)%prevP => tu4_tpA(i-1) - tu4_tpA(i)%nextP => tu4_tpA(i+1) - swifter_tpP => tu4_tpA(i)%swifter - swifter_tpP%prevP => tu4_tpA(i-1)%swifter - swifter_tpP%nextP => tu4_tpA(i+1)%swifter - END DO - tu4_tpA(ntp)%prevP => tu4_tpA(ntp-1) - tu4_tpP => tu4_tpA(ntp) - NULLIFY(tu4_tpP%nextP) - swifter_tpP => tu4_tpA(ntp)%swifter - swifter_tpP%prevP => tu4_tpA(ntp-1)%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE tu4_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_step.f90 b/tu4/tu4_step.f90 deleted file mode 100644 index 2b38c94ff..000000000 --- a/tu4/tu4_step.f90 +++ /dev/null @@ -1,119 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_step -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL tu4_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine tu4_step.f -! -!********************************************************************************************************************************** -SUBROUTINE tu4_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(tu4_pl), POINTER :: tu4_pl1P - TYPE(tu4_tp), POINTER :: tu4_tp1P - -! Internals - INTEGER(I4B) :: j - REAL(DP) :: msys, adt, bdt, tm - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(tu4_pl), POINTER :: tu4_plP - -! Executable code - IF (lfirst) THEN - w1 = 1.0_DP/(2.0_DP - (2.0_DP**(1.0_DP/3.0_DP))) - w0 = 1.0_DP - 2.0_DP*w1 - asymp(1) = 0.5_DP*w1 - asymp(2) = 0.5_DP*(w0 + w1) - asymp(3) = asymp(2) - asymp(4) = asymp(1) - bsymp(1) = 0.0_DP - bsymp(2) = w1 - bsymp(3) = w0 - bsymp(4) = w1 - lfirst = .FALSE. - END IF - swifter_pl1P => tu4_pl1P%swifter - CALL coord_h2b(npl, swifter_pl1P, msys) - IF (ntp > 0) THEN - swifter_tp1P => tu4_tp1P%swifter - CALL coord_h2b_tp(ntp, swifter_tp1P, swifter_pl1P) - END IF - tm = t - adt = asymp(1)*dt - CALL tu4_ldrift(npl, ntp, swifter_pl1P, swifter_tp1P, adt) - tm = tm + adt - DO j = 2, 4 - CALL tu4_getaccb(lextra_force, tm, npl, nplmax, tu4_pl1P, j2rp2, j4rp4) - IF (ntp > 0) CALL tu4_getaccb_tp(lextra_force, tm, npl, ntp, ntpmax, tu4_pl1P, tu4_tp1P, j2rp2, j4rp4) - bdt = bsymp(j)*dt - CALL tu4_kickvb(npl, ntp, tu4_pl1P, tu4_tp1P, bdt) - adt = asymp(j)*dt - CALL tu4_ldrift(npl, ntp, swifter_pl1P, swifter_tp1P, adt) - tm = tm + adt - END DO - CALL coord_b2h(npl, swifter_pl1P) - IF (ntp > 0) CALL coord_b2h_tp(ntp, swifter_tp1P, swifter_pl1P) - - RETURN - -END SUBROUTINE tu4_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_user_getaccb.f90 b/tu4/tu4_user_getaccb.f90 deleted file mode 100644 index 420519b03..000000000 --- a/tu4/tu4_user_getaccb.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_user_getaccb -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! tu4_pl1P : pointer to head of TU4 planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : tu4_pl1P : pointer to head of TU4 planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL tu4_user_getaccb(t, npl, tu4_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE tu4_user_getaccb(t, npl, tu4_pl1P) - -! Modules - USE module_parameters - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_user_getaccb - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(tu4_pl), POINTER :: tu4_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE tu4_user_getaccb -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/tu4/tu4_user_getaccb_tp.f90 b/tu4/tu4_user_getaccb_tp.f90 deleted file mode 100644 index fced7bc37..000000000 --- a/tu4/tu4_user_getaccb_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : tu4_user_getaccb_tp -! Unit Type : subroutine -! Project : Swifter -! Package : tu4 -! Language : Fortran 90/95 -! -! Description : Add user-supplied barycentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : tu4_tp1P : pointer to head of active TU4 test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL tu4_user_getaccb_tp(t, ntp, tu4_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE tu4_user_getaccb_tp(t, ntp, tu4_tp1P) - -! Modules - USE module_parameters - USE module_tu4 - USE module_interfaces, EXCEPT_THIS_ONE => tu4_user_getaccb_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(tu4_tp), POINTER :: tu4_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE tu4_user_getaccb_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_exit.f90 b/util/util_exit.f90 deleted file mode 100644 index 693d9db99..000000000 --- a/util/util_exit.f90 +++ /dev/null @@ -1,67 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_exit -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Print termination message and exit program -! -! Input -! Arguments : code : exit code -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : termination message -! File : none -! -! Invocation : CALL util_exit(code) -! -! Notes : Adapted from Hal Levison's Swift routine util_exit.f -! -!********************************************************************************************************************************** -SUBROUTINE util_exit(code) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_exit - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: code - -! Executable code - IF (code == SUCCESS) THEN - WRITE(*, 100) VERSION_NUMBER - ELSE - WRITE(*, 200) VERSION_NUMBER - END IF - 100 FORMAT(/, "Normal termination of SWIFTER (Version ", F3.1, ")") - 200 FORMAT(/, "Terminating SWIFTER (Version ", F3.1, ") due to ERROR!!") - WRITE(*, 300) "------------------------------------------------" - 300 FORMAT(A) - - STOP - -END SUBROUTINE util_exit -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_hills.f90 b/util/util_hills.f90 deleted file mode 100644 index 46a06fa89..000000000 --- a/util/util_hills.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_hills -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Compute Hill sphere radii of planets -! -! Input -! Arguments : npl : number of planets -! swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL util_hills(npl, swifter_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine util_hills.f -! -!********************************************************************************************************************************** -SUBROUTINE util_hills(npl, swifter_pl1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => util_hills - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(swifter_pl), POINTER :: swifter_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: msun, mp, mu, energy, ap, r, v2 - TYPE(swifter_pl), POINTER :: swifter_plP - -! Executable code - msun = swifter_pl1P%mass - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - mp = swifter_plP%mass - IF (mp > 0.0_DP) THEN - mu = msun + mp - r = SQRT(DOT_PRODUCT(swifter_plP%xh(:), swifter_plP%xh(:))) - v2 = DOT_PRODUCT(swifter_plP%vh(:), swifter_plP%vh(:)) - energy = 0.5_DP*v2 - mu/r - ap = -0.5_DP*mu/energy - swifter_plP%rhill = ap*(((mp/mu)/3.0_DP)**(1.0_DP/3.0_DP)) - ELSE - swifter_plP%rhill = 0.0_DP - END IF - END DO - - RETURN - -END SUBROUTINE util_hills -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_index.f90 b/util/util_index.f90 deleted file mode 100644 index f97f16421..000000000 --- a/util/util_index.f90 +++ /dev/null @@ -1,139 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_index -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Index input real array into ascending numerical order using Quicksort algorithm -! -! Input -! Arguments : arr : array to index -! Terminal : none -! File : none -! -! Output -! Arguments : index : index table for sorted array -! Terminal : error message -! File : none -! -! Invocation : CALL util_index(arr, index) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1173-4 -! -!********************************************************************************************************************************** -SUBROUTINE util_index(arr, index) - -! Modules - USE module_parameters - USE module_nrutil - USE module_interfaces, EXCEPT_THIS_ONE => util_index - IMPLICIT NONE - -! Arguments - INTEGER(I4B), DIMENSION(:), INTENT(OUT) :: index - REAL(DP), DIMENSION(:), INTENT(IN) :: arr - -! Internals - INTEGER(I4B), PARAMETER :: NN = 15, NSTACK = 50 - INTEGER(I4B) :: n, k, i, j, indext, jstack, l, r, dum - INTEGER(I4B), DIMENSION(NSTACK) :: istack - REAL(DP) :: a - -! Executable code - n = SIZE(arr) - IF (n /= SIZE(index)) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " Array size mismatch in util_index" - CALL util_exit(FAILURE) - END IF - index = arth(1, 1, n) - jstack = 0 - l = 1 - r = n - DO - IF ((r - l) < NN) THEN - DO j = l + 1, r - indext = index(j) - a = arr(indext) - DO i = j - 1, l, -1 - IF (arr(index(i)) <= a) EXIT - index(i+1) = index(i) - END DO - index(i+1) = indext - END DO - IF (jstack == 0) RETURN - r = istack(jstack) - l = istack(jstack-1) - jstack = jstack - 2 - ELSE - k = (l + r)/2 - dum = index(k); index(k) = index(l+1); index(l+1) = dum - IF (arr(index(l)) > arr(index(r))) THEN - dum = index(l); index(l) = index(r); index(r) = dum - END IF - IF (arr(index(l+1)) > arr(index(r))) THEN - dum = index(l+1); index(l+1) = index(r); index(r) = dum - END IF - IF (arr(index(l)) > arr(index(l+1))) THEN - dum = index(l); index(l) = index(l+1); index(l+1) = dum - END IF - i = l + 1 - j = r - indext = index(l+1) - a = arr(indext) - DO - DO - i = i + 1 - IF (arr(index(i)) >= a) EXIT - END DO - DO - j = j - 1 - IF (arr(index(j)) <= a) EXIT - END DO - IF (j < i) EXIT - dum = index(i); index(i) = index(j); index(j) = dum - END DO - index(l+1) = index(j) - index(j) = indext - jstack = jstack + 2 - IF (jstack > NSTACK) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " NSTACK too small in util_sort" - CALL util_exit(FAILURE) - END IF - IF ((r - i + 1) >= (j - l)) THEN - istack(jstack) = r - istack(jstack-1) = i - r = j - 1 - ELSE - istack(jstack) = j - 1 - istack(jstack-1) = l - l = i - END IF - END IF - END DO - - RETURN - -END SUBROUTINE util_index -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_kahan_sum.f90 b/util/util_kahan_sum.f90 deleted file mode 100644 index 4fd9082d4..000000000 --- a/util/util_kahan_sum.f90 +++ /dev/null @@ -1,40 +0,0 @@ - FUNCTION util_kahan_sum(xsum_current, xi, xerror) RESULT(xsum_new) - !------------------------------------------------------------------------------------------- - ! UTIL_KAHAN_SUM.F90 - !------------------------------------------------------------------------------------------- - ! Sums two floating point scalars more accurately utilitizing the Kahan summation formula - ! This function is designed to be used inside a do or while loop, where the initial value of - ! of xsum_current is initialized appropriately and the initial value of xerror is 0.0_dp - ! - ! N.B. Use this function if the summation is being performed for more than *three* terms - ! - ! Input: xsum_current - Current value of the sum - ! xi - i-th term to be added to the sum - ! xerror - Error term from the previous term of the sum - ! - ! Output: xsum_new - The updated value of the sum - ! xerror - The error term for this term of the sum - ! - ! By: Chris Capobianco - ! Date: 05/04/09 - ! 01/26/10 D. Minton - added to SWIFTER and modified types - !------------------------------------------------------------------------------------------- -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_kahan_sum - implicit none - - ! Input/Output variables - real(dp), intent(in) :: xsum_current, xi - real(dp), intent(inout) :: xerror - real(dp) :: xsum_new - - ! Internal variables - real(dp) :: low_bits - - low_bits = xi - xerror - xsum_new = xsum_current + low_bits - xerror = (xsum_new - xsum_current) - low_bits - - return - end function util_kahan_sum diff --git a/util/util_peri.f90 b/util/util_peri.f90 deleted file mode 100644 index e1c1016e7..000000000 --- a/util/util_peri.f90 +++ /dev/null @@ -1,146 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_peri -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Determine system pericenter passages for test particles -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! ntp : number of active test particles -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! mu : G * (m1 + m2) = mass of the Sun in this routine -! msys : total system mass -! qmin_coord : coordinate frame for qmin -! Terminal : none -! File : none -! -! Output -! Arguments : swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL util_peri(lfirst, ntp, swifter_tp1P, mu, msys, qmin_coord) -! -! Notes : Adapted from Hal Levison's Swift routine util_peri.f -! -! If the coordinate system used is barycentric, then this routine assumes that the barycentric coordinates in the -! test particle structures are up-to-date and are not recomputed -! -!********************************************************************************************************************************** -SUBROUTINE util_peri(lfirst, ntp, swifter_tp1P, mu, msys, qmin_coord) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => util_peri - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirst - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, msys - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: vdotr, e - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - swifter_tpP => swifter_tp1P - IF (lfirst) THEN - IF (qmin_coord == "HELIO") THEN - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_tpP%xh(:), swifter_tpP%vh(:)) - IF (vdotr > 0.0_DP) THEN - swifter_tpP%isperi = 1 - ELSE - swifter_tpP%isperi = -1 - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - ELSE - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_tpP%xb(:), swifter_tpP%vb(:)) - IF (vdotr > 0.0_DP) THEN - swifter_tpP%isperi = 1 - ELSE - swifter_tpP%isperi = -1 - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - END IF - ELSE - IF (qmin_coord == "HELIO") THEN - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_tpP%xh(:), swifter_tpP%vh(:)) - IF (swifter_tpP%isperi == -1) THEN - IF (vdotr >= 0.0_DP) THEN - swifter_tpP%isperi = 0 - CALL orbel_xv2aeq(swifter_tpP%xh(:), swifter_tpP%vh(:), mu, swifter_tpP%atp, e, & - swifter_tpP%peri) - END IF - ELSE - IF (vdotr > 0.0_DP) THEN - swifter_tpP%isperi = 1 - ELSE - swifter_tpP%isperi = -1 - END IF - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - ELSE - DO i = 1, ntp - IF (swifter_tpP%status == ACTIVE) THEN - vdotr = DOT_PRODUCT(swifter_tpP%xb(:), swifter_tpP%vb(:)) - IF (swifter_tpP%isperi == -1) THEN - IF (vdotr >= 0.0_DP) THEN - swifter_tpP%isperi = 0 - CALL orbel_xv2aeq(swifter_tpP%xb(:), swifter_tpP%vb(:), msys, swifter_tpP%atp, e, & - swifter_tpP%peri) - END IF - ELSE - IF (vdotr > 0.0_DP) THEN - swifter_tpP%isperi = 1 - ELSE - swifter_tpP%isperi = -1 - END IF - END IF - END IF - swifter_tpP => swifter_tpP%nextP - END DO - END IF - END IF - - RETURN - -END SUBROUTINE util_peri -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_sort_dp.f90 b/util/util_sort_dp.f90 deleted file mode 100644 index f94f81bfa..000000000 --- a/util/util_sort_dp.f90 +++ /dev/null @@ -1,129 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_sort_dp -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Sort input double precision array into ascending numerical order using Quicksort algorithm -! -! Input -! Arguments : arr : array to sort -! Terminal : none -! File : none -! -! Output -! Arguments : arr : sorted array -! Terminal : error message -! File : none -! -! Invocation : CALL util_sort(arr) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1169-70 -! -!********************************************************************************************************************************** -SUBROUTINE util_sort_dp(arr) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_sort_dp - IMPLICIT NONE - -! Arguments - REAL(DP), DIMENSION(:), INTENT(INOUT) :: arr - -! Internals - INTEGER(I4B), PARAMETER :: NN = 15, NSTACK = 50 - REAL(DP) :: a, dum - INTEGER(I4B) :: n, k, i, j, jstack, l, r - INTEGER(I4B), DIMENSION(NSTACK) :: istack - -! Executable code - n = SIZE(arr) - jstack = 0 - l = 1 - r = n - DO - IF ((r - l) < NN) THEN - DO j = l + 1, r - a = arr(j) - DO i = j - 1, l, -1 - IF (arr(i) <= a) EXIT - arr(i+1) = arr(i) - END DO - arr(i+1) = a - END DO - IF (jstack == 0) RETURN - r = istack(jstack) - l = istack(jstack-1) - jstack = jstack - 2 - ELSE - k = (l + r)/2 - dum = arr(k); arr(k) = arr(l+1); arr(l+1) = dum - IF (arr(l) > arr(r)) THEN - dum = arr(l); arr(l) = arr(r); arr(r) = dum - END IF - IF (arr(l+1) > arr(r)) THEN - dum = arr(l+1); arr(l+1) = arr(r); arr(r) = dum - END IF - IF (arr(l) > arr(l+1)) THEN - dum = arr(l); arr(l) = arr(l+1); arr(l+1) = dum - END IF - i = l + 1 - j = r - a = arr(l+1) - DO - DO - i = i + 1 - IF (arr(i) >= a) EXIT - END DO - DO - j = j - 1 - IF (arr(j) <= a) EXIT - END DO - IF (j < i) EXIT - dum = arr(i); arr(i) = arr(j); arr(j) = dum - END DO - arr(l+1) = arr(j) - arr(j) = a - jstack = jstack + 2 - IF (jstack > NSTACK) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " NSTACK too small in util_sort_i4b" - CALL util_exit(FAILURE) - END IF - IF ((r - i + 1) >= (j - l)) THEN - istack(jstack) = r - istack(jstack-1) = i - r = j - 1 - ELSE - istack(jstack) = j - 1 - istack(jstack-1) = l - l = i - END IF - END IF - END DO - - RETURN - -END SUBROUTINE util_sort_dp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_sort_i4b.f90 b/util/util_sort_i4b.f90 deleted file mode 100644 index 0d7622598..000000000 --- a/util/util_sort_i4b.f90 +++ /dev/null @@ -1,128 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_sort_i4b -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Sort input integer array into ascending numerical order using Quicksort algorithm -! -! Input -! Arguments : arr : array to sort -! Terminal : none -! File : none -! -! Output -! Arguments : arr : sorted array -! Terminal : error message -! File : none -! -! Invocation : CALL util_sort(arr) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1169-70 -! -!********************************************************************************************************************************** -SUBROUTINE util_sort_i4b(arr) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_sort_i4b - IMPLICIT NONE - -! Arguments - INTEGER(I4B), DIMENSION(:), INTENT(INOUT) :: arr - -! Internals - INTEGER(I4B), PARAMETER :: NN = 15, NSTACK = 50 - INTEGER(I4B) :: a, n, k, i, j, jstack, l, r, dum - INTEGER(I4B), DIMENSION(NSTACK) :: istack - -! Executable code - n = SIZE(arr) - jstack = 0 - l = 1 - r = n - DO - IF ((r - l) < NN) THEN - DO j = l + 1, r - a = arr(j) - DO i = j - 1, l, -1 - IF (arr(i) <= a) EXIT - arr(i+1) = arr(i) - END DO - arr(i+1) = a - END DO - IF (jstack == 0) RETURN - r = istack(jstack) - l = istack(jstack-1) - jstack = jstack - 2 - ELSE - k = (l + r)/2 - dum = arr(k); arr(k) = arr(l+1); arr(l+1) = dum - IF (arr(l) > arr(r)) THEN - dum = arr(l); arr(l) = arr(r); arr(r) = dum - END IF - IF (arr(l+1) > arr(r)) THEN - dum = arr(l+1); arr(l+1) = arr(r); arr(r) = dum - END IF - IF (arr(l) > arr(l+1)) THEN - dum = arr(l); arr(l) = arr(l+1); arr(l+1) = dum - END IF - i = l + 1 - j = r - a = arr(l+1) - DO - DO - i = i + 1 - IF (arr(i) >= a) EXIT - END DO - DO - j = j - 1 - IF (arr(j) <= a) EXIT - END DO - IF (j < i) EXIT - dum = arr(i); arr(i) = arr(j); arr(j) = dum - END DO - arr(l+1) = arr(j) - arr(j) = a - jstack = jstack + 2 - IF (jstack > NSTACK) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " NSTACK too small in util_sort_i4b" - CALL util_exit(FAILURE) - END IF - IF ((r - i + 1) >= (j - l)) THEN - istack(jstack) = r - istack(jstack-1) = i - r = j - 1 - ELSE - istack(jstack) = j - 1 - istack(jstack-1) = l - l = i - END IF - END IF - END DO - - RETURN - -END SUBROUTINE util_sort_i4b -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_sort_sp.f90 b/util/util_sort_sp.f90 deleted file mode 100644 index 4d84af156..000000000 --- a/util/util_sort_sp.f90 +++ /dev/null @@ -1,129 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_sort_sp -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Sort input single precision array into ascending numerical order using Quicksort algorithm -! -! Input -! Arguments : arr : array to sort -! Terminal : none -! File : none -! -! Output -! Arguments : arr : sorted array -! Terminal : error message -! File : none -! -! Invocation : CALL util_sort(arr) -! -! Notes : Adapted from Numerical Recipes in Fortran 90: The Art of Parallel Scientific Computing, by Press, Teukolsky, -! Vetterling, and Flannery, 2nd ed., pp. 1169-70 -! -!********************************************************************************************************************************** -SUBROUTINE util_sort_sp(arr) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_sort_sp - IMPLICIT NONE - -! Arguments - REAL(SP), DIMENSION(:), INTENT(INOUT) :: arr - -! Internals - INTEGER(I4B), PARAMETER :: NN = 15, NSTACK = 50 - REAL(SP) :: a, dum - INTEGER(I4B) :: n, k, i, j, jstack, l, r - INTEGER(I4B), DIMENSION(NSTACK) :: istack - -! Executable code - n = SIZE(arr) - jstack = 0 - l = 1 - r = n - DO - IF ((r - l) < NN) THEN - DO j = l + 1, r - a = arr(j) - DO i = j - 1, l, -1 - IF (arr(i) <= a) EXIT - arr(i+1) = arr(i) - END DO - arr(i+1) = a - END DO - IF (jstack == 0) RETURN - r = istack(jstack) - l = istack(jstack-1) - jstack = jstack - 2 - ELSE - k = (l + r)/2 - dum = arr(k); arr(k) = arr(l+1); arr(l+1) = dum - IF (arr(l) > arr(r)) THEN - dum = arr(l); arr(l) = arr(r); arr(r) = dum - END IF - IF (arr(l+1) > arr(r)) THEN - dum = arr(l+1); arr(l+1) = arr(r); arr(r) = dum - END IF - IF (arr(l) > arr(l+1)) THEN - dum = arr(l); arr(l) = arr(l+1); arr(l+1) = dum - END IF - i = l + 1 - j = r - a = arr(l+1) - DO - DO - i = i + 1 - IF (arr(i) >= a) EXIT - END DO - DO - j = j - 1 - IF (arr(j) <= a) EXIT - END DO - IF (j < i) EXIT - dum = arr(i); arr(i) = arr(j); arr(j) = dum - END DO - arr(l+1) = arr(j) - arr(j) = a - jstack = jstack + 2 - IF (jstack > NSTACK) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " NSTACK too small in util_sort_i4b" - CALL util_exit(FAILURE) - END IF - IF ((r - i + 1) >= (j - l)) THEN - istack(jstack) = r - istack(jstack-1) = i - r = j - 1 - ELSE - istack(jstack) = j - 1 - istack(jstack-1) = l - l = i - END IF - END IF - END DO - - RETURN - -END SUBROUTINE util_sort_sp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_toupper.f90 b/util/util_toupper.f90 deleted file mode 100644 index e24993cb7..000000000 --- a/util/util_toupper.f90 +++ /dev/null @@ -1,69 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_toupper -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Convert string to uppercase -! -! Input -! Arguments : string : string to convert -! Terminal : none -! File : none -! -! Output -! Arguments : string : converted string -! Terminal : none -! File : none -! -! Invocation : CALL util_toupper(string) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE util_toupper(string) - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_toupper - IMPLICIT NONE - -! Arguments - CHARACTER(*), INTENT(INOUT) :: string - -! Internals - INTEGER(I4B) :: i, length, index - -! Executable code - length = LEN(string) - DO i = 1, length - index = IACHAR(string(i:i)) - IF ((index >= LOWERCASE_BEGIN) .AND. (index <= LOWERCASE_END)) THEN - index = index + UPPERCASE_OFFSET - string(i:i) = ACHAR(index) - END IF - END DO - - RETURN - -END SUBROUTINE util_toupper -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_valid.f90 b/util/util_valid.f90 deleted file mode 100644 index d07df3f1d..000000000 --- a/util/util_valid.f90 +++ /dev/null @@ -1,90 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_valid -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Validate planet and test particle ids -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : error message -! File : none -! -! Invocation : CALL util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) -! -! Notes : Subroutine causes program to exit with error if any ids are not unique -! -!********************************************************************************************************************************** -SUBROUTINE util_valid(npl, ntp, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_interfaces, EXCEPT_THIS_ONE => util_valid - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - -! Internals - INTEGER(I4B) :: i - INTEGER(I4B), DIMENSION(:), ALLOCATABLE :: idarr - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - ALLOCATE(idarr(npl+ntp)) - swifter_plP => swifter_pl1P - DO i = 1, npl - idarr(i) = swifter_plP%id - swifter_plP => swifter_plP%nextP - END DO - swifter_tpP => swifter_tp1P - DO i = npl + 1, npl + ntp - idarr(i) = swifter_tpP%id - swifter_tpP => swifter_tpP%nextP - END DO - CALL util_sort(idarr) - DO i = 1, npl + ntp - 1 - IF (idarr(i) == idarr(i+1)) THEN - WRITE(*, *) "SWIFTER Error:" - WRITE(*, *) " More than one body/particle has id = ", idarr(i) - CALL util_exit(FAILURE) - END IF - END DO - DEALLOCATE(idarr) - - RETURN - -END SUBROUTINE util_valid -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/util/util_version.f90 b/util/util_version.f90 deleted file mode 100644 index 26750decc..000000000 --- a/util/util_version.f90 +++ /dev/null @@ -1,71 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : util_version -! Unit Type : subroutine -! Project : Swifter -! Package : util -! Language : Fortran 90/95 -! -! Description : Print program version information to terminal -! -! Input -! Arguments : none -! Terminal : none -! File : none -! -! Output -! Arguments : none -! Terminal : Program version information -! File : none -! -! Invocation : CALL util_version -! -! Notes : Adapted from Hal Levison's Swift routine util_version.f -! -!********************************************************************************************************************************** -SUBROUTINE util_version - -! Modules - USE module_parameters - USE module_interfaces, EXCEPT_THIS_ONE => util_version - IMPLICIT NONE - -! Executable code - WRITE(*, 100) VERSION_NUMBER - 100 FORMAT(/, "************* SWIFTER: Version ", F3.1, " *************", //, & - "Authors:", //, & - " Martin Duncan: Queen's University", /, & - " Hal Levison : Southwest Research Institute", //, & - "Please address comments and questions to:", //, & - " Hal Levison or David Kaufmann", /, & - " Department of Space Studies", /, & - " Southwest Research Institute", /, & - " 1050 Walnut Street, Suite 400", /, & - " Boulder, Colorado 80302", /, & - " 303-546-0290 (HFL), 720-240-0119 (DEK)", /, & - " 303-546-9687 (fax)", /, & - " hal@gort.boulder.swri.edu (HFL)", /, & - " kaufmann@boulder.swri.edu (DEK)", //, & - "************************************************", /) - - RETURN - -END SUBROUTINE util_version -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_discard.f90 b/whm/whm_discard.f90 deleted file mode 100644 index 0627dfe30..000000000 --- a/whm/whm_discard.f90 +++ /dev/null @@ -1,104 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_discard -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Call discard routine to determine spilled test particles, then remove them from active list -! -! Input -! Arguments : t : time -! npl : number of planets -! ntp : number of active test particles -! nsp : number of spilled test particles -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! whm_tpd1P : pointer to head of discard WHM test particle structure linked-list -! dt : time step -! rmin : minimum allowed heliocentric radius for test particles -! rmax : maximum allowed heliocentric radius for test particles -! rmaxu : maximum allowed heliocentric radius for unbound test particles -! qmin : minimum allowed pericenter distance for test particles -! qmin_coord : coordinate frame for qmin -! qmin_alo : minimum semimajor axis for qmin -! qmin_ahi : maximum semimajor axis for qmin -! lclose : logical flag indicating whether to check for close planet-test particle encounters -! lrhill_present : logical flag indicating whether Hill sphere radii for planets are present -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! whm_tpd1P : pointer to head of discard WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_discard(t, npl, ntp, nsp, whm_pl1P, whm_tp1P, whm_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, -! qmin_alo, qmin_ahi, lclose, lrhill_present) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE whm_discard(t, npl, ntp, nsp, whm_pl1P, whm_tp1P, whm_tpd1P, dt, rmin, rmax, rmaxu, qmin, qmin_coord, qmin_alo, & - qmin_ahi, lclose, lrhill_present) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_discard - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lclose, lrhill_present - INTEGER(I4B), INTENT(IN) :: npl - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - REAL(DP), INTENT(IN) :: t, dt, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi - CHARACTER(*), INTENT(IN) :: qmin_coord - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpd1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpspP - TYPE(whm_tp), POINTER :: whm_tpP, whm_tpspP - -! Executable code - swifter_pl1P => whm_pl1P%swifter - swifter_tp1P => whm_tp1P%swifter - CALL discard(t, dt, npl, ntp, swifter_pl1P, swifter_tp1P, rmin, rmax, rmaxu, qmin, qmin_alo, qmin_ahi, qmin_coord, lclose, & - lrhill_present) - whm_tpP => whm_tp1P - DO i = 1, ntp - whm_tpspP => whm_tpP - whm_tpP => whm_tpP%nextP - swifter_tpspP => whm_tpspP%swifter - IF (swifter_tpspP%status /= ACTIVE) CALL whm_discard_spill(ntp, nsp, whm_tp1P, whm_tpd1P, whm_tpspP) - END DO - - RETURN - -END SUBROUTINE whm_discard -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_discard_spill.f90 b/whm/whm_discard_spill.f90 deleted file mode 100644 index 1adca8813..000000000 --- a/whm/whm_discard_spill.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_discard_spill -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Move spilled (discarded) WHM test particle structure from active list to discard list -! -! Input -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! whm_tpd1P : pointer to head of discard WHM test particle structure linked-list -! whm_tpspP : pointer to WHM test particle structure to be discarded -! Terminal : none -! File : none -! -! Output -! Arguments : ntp : number of active test particles -! nsp : number of spilled test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! whm_tpd1P : pointer to head of discard WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_discard_spill(ntp, nsp, whm_tp1P, whm_tpd1P, whm_tpspP) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE whm_discard_spill(ntp, nsp, whm_tp1P, whm_tpd1P, whm_tpspP) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_discard_spill - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(INOUT) :: ntp, nsp - TYPE(whm_tp), POINTER :: whm_tp1P, whm_tpd1P, whm_tpspP - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_tp), POINTER :: swifter_tpspP - TYPE(whm_tp), POINTER :: whm_tpP - -! Executable code - swifter_tpspP => whm_tpspP%swifter - IF (nsp == 0) THEN - whm_tpd1P => whm_tpspP - ELSE - whm_tpP => whm_tpd1P - DO i = 1, nsp - 1 - whm_tpP => whm_tpP%nextP - END DO - whm_tpP%nextP => whm_tpspP - whm_tpP%swifter%nextP => swifter_tpspP - END IF - IF (ASSOCIATED(whm_tpspP%prevP)) THEN - whm_tpspP%prevP%nextP => whm_tpspP%nextP - swifter_tpspP%prevP%nextP => swifter_tpspP%nextP - ELSE - whm_tp1P => whm_tpspP%nextP - END IF - IF (ASSOCIATED(whm_tpspP%nextP)) THEN - whm_tpspP%nextP%prevP => whm_tpspP%prevP - swifter_tpspP%nextP%prevP => swifter_tpspP%prevP - END IF - IF (nsp == 0) THEN - NULLIFY(whm_tpspP%prevP) - NULLIFY(swifter_tpspP%prevP) - ELSE - whm_tpspP%prevP => whm_tpP - swifter_tpspP%prevP => whm_tpP%swifter - END IF - NULLIFY(whm_tpspP%nextP) - NULLIFY(swifter_tpspP%nextP) - nsp = nsp + 1 - ntp = ntp - 1 - - RETURN - -END SUBROUTINE whm_discard_spill -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_drift.f90 b/whm/whm_drift.f90 deleted file mode 100644 index 8a4967b8a..000000000 --- a/whm/whm_drift.f90 +++ /dev/null @@ -1,90 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_drift -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Loop through planets and call Danby drift routine -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL whm_drift(npl, whm_pl1P, dt) -! -! Notes : Adapted from Hal Levison's Swift routine drift.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_drift(npl, whm_pl1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_drift - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i, iflag - REAL(DP) :: etajm1, etaj, mu, msun - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - whm_plP => whm_pl1P - swifter_plP => whm_plP%swifter - msun = swifter_plP%mass - etajm1 = msun - DO i = 2, npl - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - etaj = etajm1 + swifter_plP%mass - mu = msun*etaj/etajm1 - CALL drift_one(mu, whm_plP%xj(:), whm_plP%vj(:), dt, iflag) - IF (iflag /= 0) THEN - WRITE(*, *) " Planet ", swifter_plP%id, " is lost!!!!!!!!!!" - WRITE(*, *) mu, dt - WRITE(*, *) whm_plP%xj(:) - WRITE(*, *) whm_plP%vj(:) - WRITE(*, *) " STOPPING " - CALL util_exit(FAILURE) - END IF - etajm1 = etaj - END DO - - RETURN - -END SUBROUTINE whm_drift -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_drift_tp.f90 b/whm/whm_drift_tp.f90 deleted file mode 100644 index 1fa68fac5..000000000 --- a/whm/whm_drift_tp.f90 +++ /dev/null @@ -1,82 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_drift_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Loop through test particles and call Danby drift routine -! -! Input -! Arguments : ntp : number of active test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! mu : mass of the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : error message -! File : none -! -! Invocation : CALL whm_drift_tp(ntp, whm_tp1P, mu, dt) -! -! Notes : Adapted from Hal Levison's Swift routine drift_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_drift_tp(ntp, whm_tp1P, mu, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_drift_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: mu, dt - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - INTEGER(I4B) :: i, iflag - TYPE(swifter_tp), POINTER :: swifter_tpP - TYPE(whm_tp), POINTER :: whm_tpP - -! Executable code - whm_tpP => whm_tp1P - DO i = 1, ntp - swifter_tpP => whm_tpP%swifter - IF (swifter_tpP%status == ACTIVE) THEN - CALL drift_one(mu, swifter_tpP%xh(:), swifter_tpP%vh(:), dt, iflag) - IF (iflag /= 0) THEN - swifter_tpP%status = DISCARDED_DRIFTERR - WRITE(*, *) "Particle ", swifter_tpP%id, " lost due to error in Danby drift" - END IF - END IF - whm_tpP => whm_tpP%nextP - END DO - - RETURN - -END SUBROUTINE whm_drift_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch.f90 b/whm/whm_getacch.f90 deleted file mode 100644 index c58f8a184..000000000 --- a/whm/whm_getacch.f90 +++ /dev/null @@ -1,127 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of planets -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch(lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine getacch.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch(lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh, irj, ir3h, ir3j - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xh, aobl - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(xh(NDIM, nplmax), aobl(NDIM, nplmax), irh(nplmax), irj(nplmax), ir3h(nplmax), ir3j(nplmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => whm_pl1P%swifter - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - r2 = DOT_PRODUCT(whm_plP%xj(:), whm_plP%xj(:)) - irj(i) = 1.0_DP/SQRT(r2) - ir3j(i) = irj(i)/r2 - END DO - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - r2 = DOT_PRODUCT(swifter_plP%xh(:), swifter_plP%xh(:)) - irh(i) = 1.0_DP/SQRT(r2) - ir3h(i) = irh(i)/r2 - END DO - ah0(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - swifter_plP => swifter_pl1P%nextP - DO i = 3, npl - swifter_plP => swifter_plP%nextP - fac = swifter_plP%mass*ir3h(i) - ah0(:) = ah0(:) - fac*swifter_plP%xh(:) - END DO - CALL whm_getacch_ah1(npl, whm_pl1P, ir3h, ir3j) - CALL whm_getacch_ah2(npl, whm_pl1P, ir3j) - CALL whm_getacch_ah3(npl, whm_pl1P) - whm_plP => whm_pl1P - whm_plP%ah(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - DO i = 2, npl - whm_plP => whm_plP%nextP - whm_plP%ah(:) = ah0(:) + whm_plP%ah1(:) + whm_plP%ah2(:) + whm_plP%ah3(:) - END DO - IF (j2rp2 /= 0.0_DP) THEN - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - xh(:, i) = swifter_plP%xh(:) - END DO - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - whm_plP%ah(:) = whm_plP%ah(:) + aobl(:, i) - aobl(:, 1) - END DO - END IF - IF (lextra_force) CALL whm_user_getacch(t, npl, whm_pl1P) - - RETURN - -END SUBROUTINE whm_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch_ah1.f90 b/whm/whm_getacch_ah1.f90 deleted file mode 100644 index 60b4d38de..000000000 --- a/whm/whm_getacch_ah1.f90 +++ /dev/null @@ -1,80 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch_ah1 -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute first term heliocentric accelerations of planets -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! ir3h : inverse cubed heliocentric radii of planets -! ir3j : inverse cubed Jacobi radii of planets -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch_ah1(npl, whm_pl1P, ir3h, ir3j) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah1.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch_ah1(npl, whm_pl1P, ir3h, ir3j) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch_ah1 - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), DIMENSION(:), INTENT(IN) :: ir3h, ir3j - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: msun - REAL(DP), DIMENSION(NDIM) :: ah1h, ah1j - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - msun = whm_pl1P%swifter%mass - whm_pl1P%ah1(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP => whm_pl1P%nextP - whm_plP%ah1(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - DO i = 3, npl - whm_plP => whm_plP%nextP - ah1j(:) = whm_plP%xj(:)*ir3j(i) - ah1h(:) = whm_plP%swifter%xh(:)*ir3h(i) - whm_plP%ah1(:) = msun*(ah1j(:) - ah1h(:)) - END DO - - RETURN - -END SUBROUTINE whm_getacch_ah1 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch_ah2.f90 b/whm/whm_getacch_ah2.f90 deleted file mode 100644 index b0eba7145..000000000 --- a/whm/whm_getacch_ah2.f90 +++ /dev/null @@ -1,80 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch_ah2 -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute second term heliocentric accelerations of planets -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! ir3j : inverse cubed Jacobi radii of planets -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch_ah2(npl, whm_pl1P, ir3j) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah2.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch_ah2(npl, whm_pl1P, ir3j) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch_ah2 - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), DIMENSION(:), INTENT(IN) :: ir3j - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - REAL(DP) :: etaj, fac, msun - TYPE(whm_pl), POINTER :: whm_plP, whm_ploP - -! Executable code - msun = whm_pl1P%swifter%mass - whm_pl1P%ah2(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_plP => whm_pl1P%nextP - whm_plP%ah2(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - etaj = msun - DO i = 3, npl - whm_ploP => whm_plP - whm_plP => whm_plP%nextP - etaj = etaj + whm_ploP%swifter%mass - fac = whm_plP%swifter%mass*msun*ir3j(i)/etaj - whm_plP%ah2(:) = whm_ploP%ah2(:) + fac*whm_plP%xj(:) - END DO - - RETURN - -END SUBROUTINE whm_getacch_ah2 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch_ah3.f90 b/whm/whm_getacch_ah3.f90 deleted file mode 100644 index 981abf237..000000000 --- a/whm/whm_getacch_ah3.f90 +++ /dev/null @@ -1,87 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch_ah3 -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute direct cross (third) term heliocentric accelerations of planets -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch_ah3(npl, whm_pl1P) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah3.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch_ah3(npl, whm_pl1P) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch_ah3 - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, faci, facj - REAL(DP), DIMENSION(NDIM) :: dx - TYPE(whm_pl), POINTER :: whm_pliP, whm_pljP - -! Executable code - whm_pliP => whm_pl1P - DO i = 1, npl - whm_pliP%ah3(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - whm_pliP => whm_pliP%nextP - END DO - whm_pliP => whm_pl1P - DO i = 2, npl - 1 - whm_pliP => whm_pliP%nextP - whm_pljP => whm_pliP - DO j = i + 1, npl - whm_pljP => whm_pljP%nextP - dx(:) = whm_pljP%swifter%xh(:) - whm_pliP%swifter%xh(:) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - faci = whm_pliP%swifter%mass*irij3 - facj = whm_pljP%swifter%mass*irij3 - whm_pliP%ah3(:) = whm_pliP%ah3(:) + facj*dx(:) - whm_pljP%ah3(:) = whm_pljP%ah3(:) - faci*dx(:) - END DO - END DO - - RETURN - -END SUBROUTINE whm_getacch_ah3 -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch_ah3_tp.f90 b/whm/whm_getacch_ah3_tp.f90 deleted file mode 100644 index 91443a386..000000000 --- a/whm/whm_getacch_ah3_tp.f90 +++ /dev/null @@ -1,89 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch_ah3_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute direct cross (third) term heliocentric accelerations of test particles -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! xh : heliocentric planet positions -! Terminal : none -! File : none -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch_ah3_tp(npl, ntp, whm_pl1P, whm_tp1P, xh) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_ah3_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch_ah3_tp(npl, ntp, whm_pl1P, whm_tp1P, xh) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch_ah3_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - INTEGER(I4B) :: i, j - REAL(DP) :: rji2, irij3, fac - REAL(DP), DIMENSION(NDIM) :: dx, acc, xht - TYPE(whm_pl), POINTER :: whm_plP - TYPE(whm_tp), POINTER :: whm_tpP - -! Executable code - whm_tpP => whm_tp1P - DO i = 1, ntp - acc(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - xht(:) = whm_tpP%swifter%xh(:) - whm_plP => whm_pl1P - DO j = 2, npl - whm_plP => whm_plP%nextP - dx(:) = xht(:) - xh(:, j) - rji2 = DOT_PRODUCT(dx(:), dx(:)) - irij3 = 1.0_DP/(rji2*SQRT(rji2)) - fac = whm_plP%swifter%mass*irij3 - acc(:) = acc(:) - fac*dx(:) - END DO - whm_tpP%ah(:) = acc(:) - whm_tpP => whm_tpP%nextP - END DO - - RETURN - -END SUBROUTINE whm_getacch_ah3_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_getacch_tp.f90 b/whm/whm_getacch_tp.f90 deleted file mode 100644 index dba97aaa7..000000000 --- a/whm/whm_getacch_tp.f90 +++ /dev/null @@ -1,130 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Compute heliocentric accelerations of test particles -! -! Input -! Arguments : lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! xh : heliocentric positions of planets at time t -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! Terminal : none -! File : none -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_getacch_tp(lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xh, j2rp2, j4rp4) -! -! Notes : Adapted from Hal Levison's Swift routine getacch_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_getacch_tp(lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xh, j2rp2, j4rp4) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_getacch_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4 - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xh - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP) :: r2, fac, mu - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irh, ir3h - REAL(DP), DIMENSION(:), ALLOCATABLE, SAVE :: irht - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: aobl - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xht, aoblt - TYPE(swifter_pl), POINTER :: swifter_pl1P, swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tp1P, swifter_tpP - TYPE(whm_pl), POINTER :: whm_plP - TYPE(whm_tp), POINTER :: whm_tpP - -! Executable code - IF (lmalloc) THEN - ALLOCATE(aobl(NDIM, nplmax), irh(nplmax), ir3h(nplmax), xht(NDIM, ntpmax), aoblt(NDIM, ntpmax), irht(ntpmax)) - lmalloc = .FALSE. - END IF - swifter_pl1P => whm_pl1P%swifter - swifter_tp1P => whm_tp1P%swifter - DO i = 2, npl - r2 = DOT_PRODUCT(xh(:, i), xh(:, i)) - irh(i) = 1.0_DP/SQRT(r2) - ir3h(i) = irh(i)/r2 - END DO - swifter_tpP => swifter_tp1P - DO i = 1, ntp - xht(:, i) = swifter_tpP%xh(:) - r2 = DOT_PRODUCT(xht(:, i), xht(:, i)) - irht(i) = 1.0_DP/SQRT(r2) - swifter_tpP => swifter_tpP%nextP - END DO - ah0(:) = (/ 0.0_DP, 0.0_DP, 0.0_DP /) - swifter_plP => swifter_pl1P - DO i = 2, npl - swifter_plP => swifter_plP%nextP - fac = swifter_plP%mass*ir3h(i) - ah0(:) = ah0(:) - fac*xh(:, i) - END DO - CALL whm_getacch_ah3_tp(npl, ntp, whm_pl1P, whm_tp1P, xh) - whm_tpP => whm_tp1P - DO i = 1, ntp - whm_tpP%ah(:) = whm_tpP%ah(:) + ah0(:) - whm_tpP => whm_tpP%nextP - END DO - IF (j2rp2 /= 0.0_DP) THEN - CALL obl_acc(npl, swifter_pl1P, j2rp2, j4rp4, xh, irh, aobl) - mu = whm_pl1P%swifter%mass - CALL obl_acc_tp(ntp, xht, j2rp2, j4rp4, irht, aoblt, mu) - whm_tpP => whm_tp1P - DO i = 1, ntp - whm_tpP%ah(:) = whm_tpP%ah(:) + aoblt(:, i) - aobl(:, 1) - whm_tpP => whm_tpP%nextP - END DO - END IF - IF (lextra_force) CALL whm_user_getacch_tp(t, ntp, whm_tp1P) - - RETURN - -END SUBROUTINE whm_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_kickvh.f90 b/whm/whm_kickvh.f90 deleted file mode 100644 index f1f0219eb..000000000 --- a/whm/whm_kickvh.f90 +++ /dev/null @@ -1,75 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_kickvh -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Kick heliocentric velocities of planets -! -! Input -! Arguments : npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_kickvh(npl, whm_pl1P, dt) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine kickvh.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_kickvh(npl, whm_pl1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_kickvh - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: dt - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - INTEGER(I4B) :: i - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - swifter_plP => whm_plP%swifter - swifter_plP%vh(:) = swifter_plP%vh(:) + whm_plP%ah(:)*dt - END DO - - RETURN - -END SUBROUTINE whm_kickvh -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_kickvh_tp.f90 b/whm/whm_kickvh_tp.f90 deleted file mode 100644 index fb2b8552d..000000000 --- a/whm/whm_kickvh_tp.f90 +++ /dev/null @@ -1,75 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_kickvh_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Kick heliocentric velocities of active test particles -! -! Input -! Arguments : ntp : number of active test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_kickvh_tp(ntp, whm_tp1P, dt) -! -! Notes : Adapted from Martin Duncan and Hal Levison's Swift routine kickvh_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_kickvh_tp(ntp, whm_tp1P, dt) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_kickvh_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: dt - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(whm_tp), POINTER :: whm_tpP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - whm_tpP => whm_tp1P - DO i = 1, ntp - swifter_tpP => whm_tpP%swifter - IF (swifter_tpP%status == ACTIVE) swifter_tpP%vh(:) = swifter_tpP%vh(:) + whm_tpP%ah(:)*dt - whm_tpP => whm_tpP%nextP - END DO - - RETURN - -END SUBROUTINE whm_kickvh_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_setup.f90 b/whm/whm_setup.f90 deleted file mode 100644 index b0008831f..000000000 --- a/whm/whm_setup.f90 +++ /dev/null @@ -1,133 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_setup -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Set up pointers within WHM and SWIFTER planet and test particle structure linked-lists -! -! Input -! Arguments : npl : number of planets -! ntp : number of active test particles -! whm_plA : WHM planet structure array -! whm_tpA : WHM test particle structure array -! Terminal : none -! File : none -! -! Output -! Arguments : whm_plA : WHM planet structure array -! whm_tpA : WHM test particle structure array -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! swifter_pl1P : pointer to head of SWIFTER planet structure linked-list -! swifter_tp1P : pointer to head of active SWIFTER test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_setup(npl, ntp, whm_plA, whm_tpA, whm_pl1P, whm_tp1P, swifter_pl1P, swifter_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE whm_setup(npl, ntp, whm_plA, whm_tpA, whm_pl1P, whm_tp1P, swifter_pl1P, swifter_tp1P) - -! Modules - USE module_parameters - USE module_swifter - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_setup - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl, ntp - TYPE(swifter_pl), POINTER :: swifter_pl1P - TYPE(swifter_tp), POINTER :: swifter_tp1P - TYPE(whm_pl), DIMENSION(:), TARGET, INTENT(INOUT) :: whm_plA - TYPE(whm_tp), DIMENSION(:), TARGET, INTENT(INOUT) :: whm_tpA - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - INTEGER(I4B) :: i - TYPE(whm_pl), POINTER :: whm_plP - TYPE(whm_tp), POINTER :: whm_tpP - TYPE(swifter_pl), POINTER :: swifter_plP - TYPE(swifter_tp), POINTER :: swifter_tpP - -! Executable code - whm_pl1P => whm_plA(1) - swifter_pl1P => whm_plA(1)%swifter - NULLIFY(whm_pl1P%prevP) - NULLIFY(swifter_pl1P%prevP) - IF (npl == 1) THEN - NULLIFY(whm_pl1P%nextP) - NULLIFY(swifter_pl1P%nextP) - ELSE - whm_pl1P%nextP => whm_plA(2) - swifter_pl1P%nextP => whm_plA(2)%swifter - DO i = 2, npl - 1 - whm_plA(i)%prevP => whm_plA(i-1) - whm_plA(i)%nextP => whm_plA(i+1) - swifter_plP => whm_plA(i)%swifter - swifter_plP%prevP => whm_plA(i-1)%swifter - swifter_plP%nextP => whm_plA(i+1)%swifter - END DO - whm_plA(npl)%prevP => whm_plA(npl-1) - whm_plP => whm_plA(npl) - NULLIFY(whm_plP%nextP) - swifter_plP => whm_plA(npl)%swifter - swifter_plP%prevP => whm_plA(npl-1)%swifter - NULLIFY(swifter_plP%nextP) - END IF - NULLIFY(whm_tp1P) - NULLIFY(swifter_tp1P) - IF (ntp > 0) THEN - whm_tp1P => whm_tpA(1) - swifter_tp1P => whm_tpA(1)%swifter - NULLIFY(whm_tp1P%prevP) - NULLIFY(swifter_tp1P%prevP) - IF (ntp == 1) THEN - NULLIFY(whm_tp1P%nextP) - NULLIFY(swifter_tp1P%nextP) - ELSE - whm_tp1P%nextP => whm_tpA(2) - swifter_tp1P%nextP => whm_tpA(2)%swifter - DO i = 2, ntp - 1 - whm_tpA(i)%prevP => whm_tpA(i-1) - whm_tpA(i)%nextP => whm_tpA(i+1) - swifter_tpP => whm_tpA(i)%swifter - swifter_tpP%prevP => whm_tpA(i-1)%swifter - swifter_tpP%nextP => whm_tpA(i+1)%swifter - END DO - whm_tpA(ntp)%prevP => whm_tpA(ntp-1) - whm_tpP => whm_tpA(ntp) - NULLIFY(whm_tpP%nextP) - swifter_tpP => whm_tpA(ntp)%swifter - swifter_tpP%prevP => whm_tpA(ntp-1)%swifter - NULLIFY(swifter_tpP%nextP) - END IF - END IF - - RETURN - -END SUBROUTINE whm_setup -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_step.f90 b/whm/whm_step.f90 deleted file mode 100644 index 9b991ebe0..000000000 --- a/whm/whm_step.f90 +++ /dev/null @@ -1,105 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_step -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Step planets and active test particles ahead in heliocentric coordinates -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine step_kdk.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_step(lfirst, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_step - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - LOGICAL(LGT) :: lfirsttp - LOGICAL(LGT), SAVE :: lmalloc = .TRUE. - INTEGER(I4B) :: i - REAL(DP), DIMENSION(:, :), ALLOCATABLE, SAVE :: xbeg, xend - TYPE(whm_pl), POINTER :: whm_plP - -! Executable code - lfirsttp = lfirst - IF (ntp > 0) THEN - IF (lmalloc) THEN - ALLOCATE(xbeg(NDIM, nplmax), xend(NDIM, nplmax)) - lmalloc = .FALSE. - END IF - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - xbeg(:, i) = whm_plP%swifter%xh(:) - END DO - END IF - CALL whm_step_pl(lfirst, lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4, dt) - IF (ntp > 0) THEN - whm_plP => whm_pl1P - DO i = 2, npl - whm_plP => whm_plP%nextP - xend(:, i) = whm_plP%swifter%xh(:) - END DO - CALL whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, j4rp4, dt) - END IF - - RETURN - -END SUBROUTINE whm_step -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_step_pl.f90 b/whm/whm_step_pl.f90 deleted file mode 100644 index 7e1d6b04c..000000000 --- a/whm/whm_step_pl.f90 +++ /dev/null @@ -1,87 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_step_pl -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Step planets ahead using kick-drift-kick algorithm -! -! Input -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : lfirst : logical flag indicating whether current invocation is the first -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_step_pl(lfirst, lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine step_kdk_pl.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_step_pl(lfirst, lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_step_pl - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lextra_force - LOGICAL(LGT), INTENT(INOUT) :: lfirst - INTEGER(I4B), INTENT(IN) :: npl, nplmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - REAL(DP) :: dth - -! Executable code - dth = 0.5_DP*dt - IF (lfirst) THEN - CALL coord_h2j(npl, whm_pl1P) - CALL whm_getacch(lextra_force, t, npl, nplmax, whm_pl1P, j2rp2, j4rp4) - lfirst = .FALSE. - END IF - CALL whm_kickvh(npl, whm_pl1P, dth) - CALL coord_vh2vj(npl, whm_pl1P) - CALL whm_drift(npl, whm_pl1P, dt) - CALL coord_j2h(npl, whm_pl1P) - CALL whm_getacch(lextra_force, t+dt, npl, nplmax, whm_pl1P, j2rp2, j4rp4) - CALL whm_kickvh(npl, whm_pl1P, dth) - - RETURN - -END SUBROUTINE whm_step_pl -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_step_tp.f90 b/whm/whm_step_tp.f90 deleted file mode 100644 index 4cd2c990d..000000000 --- a/whm/whm_step_tp.f90 +++ /dev/null @@ -1,87 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_step_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Step active test particles ahead using kick-drift-kick algorithm -! -! Input -! Arguments : lfirsttp : logical flag indicating whether current invocation is the first -! lextra_force : logical flag indicating whether to include user-supplied accelerations -! t : time -! npl : number of planets -! nplmax : maximum allowed number of planets -! ntp : number of active test particles -! ntpmax : maximum allowed number of test particles -! whm_pl1P : pointer to head of WHM planet structure linked-list -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! xbeg : heliocentric planet positions at beginning of time step -! xend : heliocentric planet positions at end of time step -! j2rp2 : J2 * R**2 for the Sun -! j4rp4 : J4 * R**4 for the Sun -! dt : time step -! Terminal : none -! File : none -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : none -! File : none -! -! Invocation : CALL whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, -! j4rp4, dt) -! -! Notes : Adapted from Hal Levison's Swift routine step_kdk_tp.f -! -!********************************************************************************************************************************** -SUBROUTINE whm_step_tp(lfirsttp, lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, xend, j2rp2, j4rp4, dt) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_step_tp - IMPLICIT NONE - -! Arguments - LOGICAL(LGT), INTENT(IN) :: lfirsttp, lextra_force - INTEGER(I4B), INTENT(IN) :: npl, nplmax, ntp, ntpmax - REAL(DP), INTENT(IN) :: t, j2rp2, j4rp4, dt - REAL(DP), DIMENSION(NDIM, npl), INTENT(IN) :: xbeg, xend - TYPE(whm_pl), POINTER :: whm_pl1P - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - REAL(DP) :: dth - -! Executable code - dth = 0.5_DP*dt - IF (lfirsttp) CALL whm_getacch_tp(lextra_force, t, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xbeg, j2rp2, j4rp4) - CALL whm_kickvh_tp(ntp, whm_tp1P, dth) - CALL whm_drift_tp(ntp, whm_tp1P, whm_pl1P%swifter%mass, dt) - CALL whm_getacch_tp(lextra_force, t+dt, npl, nplmax, ntp, ntpmax, whm_pl1P, whm_tp1P, xend, j2rp2, j4rp4) - CALL whm_kickvh_tp(ntp, whm_tp1P, dth) - - RETURN - -END SUBROUTINE whm_step_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_user_getacch.f90 b/whm/whm_user_getacch.f90 deleted file mode 100644 index 7790e7ca3..000000000 --- a/whm/whm_user_getacch.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_user_getacch -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to planets -! -! Input -! Arguments : t : time -! npl : number of planets -! whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : whm_pl1P : pointer to head of WHM planet structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL whm_user_getacch(t, npl, whm_pl1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE whm_user_getacch(t, npl, whm_pl1P) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_user_getacch - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: npl - REAL(DP), INTENT(IN) :: t - TYPE(whm_pl), POINTER :: whm_pl1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE whm_user_getacch -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!********************************************************************************************************************************** diff --git a/whm/whm_user_getacch_tp.f90 b/whm/whm_user_getacch_tp.f90 deleted file mode 100644 index 3141a5546..000000000 --- a/whm/whm_user_getacch_tp.f90 +++ /dev/null @@ -1,65 +0,0 @@ -!********************************************************************************************************************************** -! -! Unit Name : whm_user_getacch_tp -! Unit Type : subroutine -! Project : Swifter -! Package : whm -! Language : Fortran 90/95 -! -! Description : Add user-supplied heliocentric accelerations to test particles -! -! Input -! Arguments : t : time -! ntp : number of active test particles -! whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Output -! Arguments : whm_tp1P : pointer to head of active WHM test particle structure linked-list -! Terminal : TBS as needed by user -! File : TBS as needed by user -! -! Invocation : CALL whm_user_getacch_tp(t, ntp, whm_tp1P) -! -! Notes : -! -!********************************************************************************************************************************** -SUBROUTINE whm_user_getacch_tp(t, ntp, whm_tp1P) - -! Modules - USE module_parameters - USE module_whm - USE module_interfaces, EXCEPT_THIS_ONE => whm_user_getacch_tp - IMPLICIT NONE - -! Arguments - INTEGER(I4B), INTENT(IN) :: ntp - REAL(DP), INTENT(IN) :: t - TYPE(whm_tp), POINTER :: whm_tp1P - -! Internals - -! Executable code - - RETURN - -END SUBROUTINE whm_user_getacch_tp -!********************************************************************************************************************************** -! -! Author(s) : David E. Kaufmann -! -! Revision Control System (RCS) Information -! -! Source File : $RCSfile$ -! Full Path : $Source$ -! Revision : $Revision$ -! Date : $Date$ -! Programmer : $Author$ -! Locked By : $Locker$ -! State : $State$ -! -! Modification History: -! -! $Log$ -!**********************************************************************************************************************************